Skip to content

Commit

Permalink
Add custom error types, currently only used in TryFrom impls.
Browse files Browse the repository at this point in the history
  • Loading branch information
isislovecruft committed Oct 23, 2019
1 parent 5c98d00 commit 2d2fe9a
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ clear_on_drop = "=0.2.3"
subtle = { version = "2", default-features = false }
serde = { version = "1.0", default-features = false, optional = true }
packed_simd = { version = "0.3.0", features = ["into_bits"], optional = true }
failure = { version = "0.1", optional = true }

[build-dependencies]
rand_core = { version = "0.3.0", default-features = false }
Expand All @@ -60,6 +61,7 @@ clear_on_drop = "=0.2.3"
subtle = { version = "2", default-features = false }
serde = { version = "1.0", default-features = false, optional = true }
packed_simd = { version = "0.3.0", features = ["into_bits"], optional = true }
failure = { version = "0.1", optional = true }

[features]
nightly = ["subtle/nightly", "clear_on_drop/nightly"]
Expand Down
5 changes: 5 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ extern crate subtle;
#[cfg(all(feature = "nightly", feature = "packed_simd"))]
extern crate packed_simd;

#[cfg(feature = "failure")]
extern crate failure;

use std::env;
use std::fs::File;
use std::io::Write;
Expand All @@ -41,6 +44,8 @@ mod macros;
mod constants;
#[path = "src/edwards.rs"]
mod edwards;
#[path = "src/errors.rs"]
mod errors;
#[path = "src/montgomery.rs"]
mod montgomery;
#[path = "src/ristretto.rs"]
Expand Down
9 changes: 6 additions & 3 deletions src/edwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ use subtle::ConstantTimeEq;

use constants;

use errors::{CurveError, InternalError};

use field::FieldElement;
use scalar::Scalar;

Expand Down Expand Up @@ -329,11 +331,12 @@ impl Default for CompressedEdwardsY {
}

impl TryFrom<&[u8]> for CompressedEdwardsY {
type Error = ();
type Error = CurveError;

fn try_from(bytes: &[u8]) -> Result<CompressedEdwardsY, ()> {
fn try_from(bytes: &[u8]) -> Result<CompressedEdwardsY, CurveError> {
if bytes.len() != 32 {
return Err(());
return Err(CurveError(
InternalError::BytesLengthError{name: "CompressedEdwardsY", length: 32}));
}

Ok(CompressedEdwardsY::from_slice(bytes))
Expand Down
66 changes: 66 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// -*- mode: rust; -*-
//
// This file is part of curve25519-dalek.
// Copyright (c) 2019 Isis Lovecruft
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>

//! Errors which may occur.
//!
//! Currently, these are only used in the implementations of `TryFrom`.
//!
//! This module optionally implements support for the types in the `failure`
//! crate. This can be enabled by building with `--features failure`.

use core::fmt;
use core::fmt::Display;

/// Internal errors. Most application-level developers will likely not
/// need to pay any attention to these.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub(crate) enum InternalError {
/// An error in the length of bytes handed to a constructor.
///
/// To use this, pass a string specifying the `name` of the type which is
/// returning the error, and the `length` in bytes which its constructor
/// expects.
BytesLengthError {
name: &'static str,
length: usize,
},
}

impl Display for InternalError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
InternalError::BytesLengthError{ name: n, length: l}
=> write!(f, "{} must be {} bytes in length", n, l),
}
}
}

#[cfg(feature = "failure")]
impl ::failure::Fail for InternalError {}

/// Errors which may occur.
///
/// This error may arise due to:
///
/// * Being given bytes with a length different to what was expected.
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub struct CurveError(pub(crate) InternalError);

impl Display for CurveError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}

#[cfg(feature = "failure")]
impl ::failure::Fail for CurveError {
fn cause(&self) -> Option<&dyn (::failure::Fail)> {
Some(&self.0)
}
}
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ extern crate packed_simd;
extern crate byteorder;
extern crate clear_on_drop;
pub extern crate digest;
#[cfg(feature = "failure")]
extern crate failure;
extern crate rand_core;
#[cfg(all(test, feature = "stage2_build"))]
extern crate rand_os;
Expand Down Expand Up @@ -82,6 +84,9 @@ pub mod constants;
// External (and internal) traits.
pub mod traits;

// Errors which may occur.
pub mod errors;

//------------------------------------------------------------------------
// curve25519-dalek internal modules
//------------------------------------------------------------------------
Expand Down
11 changes: 7 additions & 4 deletions src/montgomery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use core::ops::{Mul, MulAssign};

use constants::APLUS2_OVER_FOUR;
use edwards::{CompressedEdwardsY, EdwardsPoint};
use errors::{CurveError, InternalError};
use field::FieldElement;
use scalar::Scalar;

Expand Down Expand Up @@ -111,11 +112,12 @@ impl ValidityCheck for MontgomeryPoint {
}

impl TryFrom<&[u8]> for MontgomeryPoint {
type Error = ();
type Error = CurveError;

fn try_from(bytes: &[u8]) -> Result<MontgomeryPoint, ()> {
fn try_from(bytes: &[u8]) -> Result<MontgomeryPoint, CurveError> {
if bytes.len() != 32 {
return Err(());
return Err(CurveError(
InternalError::BytesLengthError{name: "MontgomeryPoint", length: 32}));
}

let mut array = [0u8; 32];
Expand All @@ -127,7 +129,8 @@ impl TryFrom<&[u8]> for MontgomeryPoint {
return Ok(P);
}

Err(())
Err(CurveError(
InternalError::BytesLengthError{name: "MontgomeryPoint", length: 32}))
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/ristretto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ use subtle::ConstantTimeEq;
use edwards::EdwardsBasepointTable;
use edwards::EdwardsPoint;

use errors::{CurveError, InternalError};

#[allow(unused_imports)]
use prelude::*;

Expand Down Expand Up @@ -219,11 +221,12 @@ impl ConstantTimeEq for CompressedRistretto {
}

impl TryFrom<&[u8]> for CompressedRistretto {
type Error = ();
type Error = CurveError;

fn try_from(bytes: &[u8]) -> Result<CompressedRistretto, ()> {
fn try_from(bytes: &[u8]) -> Result<CompressedRistretto, CurveError> {
if bytes.len() != 32 {
return Err(());
return Err(CurveError(
InternalError::BytesLengthError{name: "CompressedRistretto", length: 32}));
}

Ok(CompressedRistretto::from_slice(bytes))
Expand Down

0 comments on commit 2d2fe9a

Please sign in to comment.