mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-05 20:30:57 +00:00
Change all from_slice() constructors to return Option<T>s.
We due this in lieu of implementing `TryFrom` to allow for API consumers to use the `?` operator to convert potential `None`s into their own `Result<T, CustomError>` types for better error handling with less boilerplate. Note that this is a breaking API change.
This commit is contained in:
parent
c21224170a
commit
9ae2e3b482
5 changed files with 41 additions and 141 deletions
|
|
@ -93,7 +93,6 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::convert::TryFrom;
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::iter::Iterator;
|
use core::iter::Iterator;
|
||||||
use core::iter::Sum;
|
use core::iter::Sum;
|
||||||
|
|
@ -108,8 +107,6 @@ use subtle::ConstantTimeEq;
|
||||||
|
|
||||||
use constants;
|
use constants;
|
||||||
|
|
||||||
use errors::{CurveError, InternalError};
|
|
||||||
|
|
||||||
use field::FieldElement;
|
use field::FieldElement;
|
||||||
use scalar::Scalar;
|
use scalar::Scalar;
|
||||||
|
|
||||||
|
|
@ -338,33 +335,23 @@ impl Default for CompressedEdwardsY {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&[u8]> for CompressedEdwardsY {
|
|
||||||
type Error = CurveError;
|
|
||||||
|
|
||||||
fn try_from(bytes: &[u8]) -> Result<CompressedEdwardsY, CurveError> {
|
|
||||||
if bytes.len() != 32 {
|
|
||||||
return Err(CurveError(
|
|
||||||
InternalError::BytesLengthError{name: "CompressedEdwardsY", length: 32}));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(CompressedEdwardsY::from_slice(bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompressedEdwardsY {
|
impl CompressedEdwardsY {
|
||||||
/// Construct a `CompressedEdwardsY` from a slice of bytes.
|
/// Construct a `CompressedEdwardsY` from a slice of bytes.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// If the input `bytes` slice does not have a length of 32. For
|
/// An `Option<CompressedEdwardsY>` which is `None` if the input `bytes`
|
||||||
/// a panic-safe version of this API, see the implementation of
|
/// slice does not have a length of 32.
|
||||||
/// `TryFrom<&[u8]>`.
|
pub fn from_slice(bytes: &[u8]) -> Option<CompressedEdwardsY> {
|
||||||
pub fn from_slice(bytes: &[u8]) -> CompressedEdwardsY {
|
if bytes.len() != 32 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let mut tmp = [0u8; 32];
|
let mut tmp = [0u8; 32];
|
||||||
|
|
||||||
tmp.copy_from_slice(bytes);
|
tmp.copy_from_slice(bytes);
|
||||||
|
|
||||||
CompressedEdwardsY(tmp)
|
Some(CompressedEdwardsY(tmp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
// -*- 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`.
|
|
||||||
//!
|
|
||||||
//! If used with `std` support, this public types in this module implement the
|
|
||||||
//! `std::error::Error` trait.
|
|
||||||
|
|
||||||
use core::fmt;
|
|
||||||
use core::fmt::Display;
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
/// 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 = "std")]
|
|
||||||
impl Error 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 = "std")]
|
|
||||||
impl Error for CurveError {
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
Some(&self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -82,9 +82,6 @@ pub mod constants;
|
||||||
// External (and internal) traits.
|
// External (and internal) traits.
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
|
|
||||||
// Errors which may occur.
|
|
||||||
pub mod errors;
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// curve25519-dalek internal modules
|
// curve25519-dalek internal modules
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,10 @@
|
||||||
// affine and projective cakes and eat both of them too.
|
// affine and projective cakes and eat both of them too.
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use core::convert::TryFrom;
|
|
||||||
use core::ops::{Mul, MulAssign};
|
use core::ops::{Mul, MulAssign};
|
||||||
|
|
||||||
use constants::APLUS2_OVER_FOUR;
|
use constants::APLUS2_OVER_FOUR;
|
||||||
use edwards::{CompressedEdwardsY, EdwardsPoint};
|
use edwards::{CompressedEdwardsY, EdwardsPoint};
|
||||||
use errors::{CurveError, InternalError};
|
|
||||||
use field::FieldElement;
|
use field::FieldElement;
|
||||||
use scalar::Scalar;
|
use scalar::Scalar;
|
||||||
|
|
||||||
|
|
@ -112,29 +110,6 @@ impl ValidityCheck for MontgomeryPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&[u8]> for MontgomeryPoint {
|
|
||||||
type Error = CurveError;
|
|
||||||
|
|
||||||
fn try_from(bytes: &[u8]) -> Result<MontgomeryPoint, CurveError> {
|
|
||||||
if bytes.len() != 32 {
|
|
||||||
return Err(CurveError(
|
|
||||||
InternalError::BytesLengthError{name: "MontgomeryPoint", length: 32}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut array = [0u8; 32];
|
|
||||||
array.copy_from_slice(&bytes[..32]);
|
|
||||||
|
|
||||||
let P = MontgomeryPoint(array);
|
|
||||||
|
|
||||||
if P.is_valid() {
|
|
||||||
return Ok(P);
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(CurveError(
|
|
||||||
InternalError::BytesLengthError{name: "MontgomeryPoint", length: 32}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MontgomeryPoint {
|
impl MontgomeryPoint {
|
||||||
/// View this `MontgomeryPoint` as an array of bytes.
|
/// View this `MontgomeryPoint` as an array of bytes.
|
||||||
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
|
pub fn as_bytes<'a>(&'a self) -> &'a [u8; 32] {
|
||||||
|
|
@ -146,6 +121,29 @@ impl MontgomeryPoint {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to create a `MontgomeryPoint` from a slice of bytes.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// An `Option<MontgomeryPoint>` which is `None` if the length of the slice
|
||||||
|
/// of bytes is not 32, or if the bytes did not represent a canonical
|
||||||
|
/// `FieldElement`.
|
||||||
|
pub fn from_slice(bytes: &[u8]) -> Option<MontgomeryPoint> {
|
||||||
|
if bytes.len() != 32 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut array = [0u8; 32];
|
||||||
|
array.copy_from_slice(&bytes[..32]);
|
||||||
|
|
||||||
|
let P = MontgomeryPoint(array);
|
||||||
|
|
||||||
|
if P.is_valid() {
|
||||||
|
return Some(P);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempt to convert to an `EdwardsPoint`, using the supplied
|
/// Attempt to convert to an `EdwardsPoint`, using the supplied
|
||||||
/// choice of sign for the `EdwardsPoint`.
|
/// choice of sign for the `EdwardsPoint`.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,6 @@
|
||||||
//! https://ristretto.group/
|
//! https://ristretto.group/
|
||||||
|
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::convert::TryFrom;
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::iter::Sum;
|
use core::iter::Sum;
|
||||||
use core::ops::{Add, Neg, Sub};
|
use core::ops::{Add, Neg, Sub};
|
||||||
|
|
@ -181,8 +180,6 @@ use subtle::ConstantTimeEq;
|
||||||
use edwards::EdwardsBasepointTable;
|
use edwards::EdwardsBasepointTable;
|
||||||
use edwards::EdwardsPoint;
|
use edwards::EdwardsPoint;
|
||||||
|
|
||||||
use errors::{CurveError, InternalError};
|
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
|
|
@ -220,19 +217,6 @@ impl ConstantTimeEq for CompressedRistretto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&[u8]> for CompressedRistretto {
|
|
||||||
type Error = CurveError;
|
|
||||||
|
|
||||||
fn try_from(bytes: &[u8]) -> Result<CompressedRistretto, CurveError> {
|
|
||||||
if bytes.len() != 32 {
|
|
||||||
return Err(CurveError(
|
|
||||||
InternalError::BytesLengthError{name: "CompressedRistretto", length: 32}));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(CompressedRistretto::from_slice(bytes))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompressedRistretto {
|
impl CompressedRistretto {
|
||||||
/// Copy the bytes of this `CompressedRistretto`.
|
/// Copy the bytes of this `CompressedRistretto`.
|
||||||
pub fn to_bytes(&self) -> [u8; 32] {
|
pub fn to_bytes(&self) -> [u8; 32] {
|
||||||
|
|
@ -246,17 +230,20 @@ impl CompressedRistretto {
|
||||||
|
|
||||||
/// Construct a `CompressedRistretto` from a slice of bytes.
|
/// Construct a `CompressedRistretto` from a slice of bytes.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// If the input `bytes` slice does not have a length of 32. For a
|
/// An `Option<CompressedRistretto>` which is `None` if the input `bytes`
|
||||||
/// panic-safe version of this API, see the implementation of
|
/// slice does not have a length of 32.
|
||||||
/// `TryFrom<&[u8]>`.
|
pub fn from_slice(bytes: &[u8]) -> Option<CompressedRistretto> {
|
||||||
pub fn from_slice(bytes: &[u8]) -> CompressedRistretto {
|
if bytes.len() != 32 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let mut tmp = [0u8; 32];
|
let mut tmp = [0u8; 32];
|
||||||
|
|
||||||
tmp.copy_from_slice(bytes);
|
tmp.copy_from_slice(bytes);
|
||||||
|
|
||||||
CompressedRistretto(tmp)
|
Some(CompressedRistretto(tmp))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to decompress to an `RistrettoPoint`.
|
/// Attempt to decompress to an `RistrettoPoint`.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue