Add custom error types, currently only used in TryFrom impls.

This commit is contained in:
Isis Lovecruft 2019-10-23 19:29:02 +00:00
parent 1fa0048262
commit 1d8b3995c9
No known key found for this signature in database
GPG key ID: AB41313533E8E812
5 changed files with 90 additions and 10 deletions

View file

@ -108,6 +108,8 @@ use subtle::ConstantTimeEq;
use constants;
use errors::{CurveError, InternalError};
use field::FieldElement;
use scalar::Scalar;
@ -337,11 +339,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))

66
src/errors.rs Normal file
View file

@ -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)
}
}

View file

@ -43,6 +43,8 @@ extern crate packed_simd;
extern crate byteorder;
pub extern crate digest;
#[cfg(feature = "failure")]
extern crate failure;
extern crate rand_core;
#[cfg(test)]
extern crate rand_os;
@ -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
//------------------------------------------------------------------------

View file

@ -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;
@ -112,11 +113,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];
@ -128,7 +130,8 @@ impl TryFrom<&[u8]> for MontgomeryPoint {
return Ok(P);
}
Err(())
Err(CurveError(
InternalError::BytesLengthError{name: "MontgomeryPoint", length: 32}))
}
}

View file

@ -181,6 +181,8 @@ use subtle::ConstantTimeEq;
use edwards::EdwardsBasepointTable;
use edwards::EdwardsPoint;
use errors::{CurveError, InternalError};
#[allow(unused_imports)]
use prelude::*;
@ -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))