// Catch documentation errors caused by code changes. #![deny(intra_doc_link_resolution_failure)] use ff::{PrimeField, PrimeFieldDecodingError, ScalarEngine, SqrtField}; use rand::RngCore; use std::error::Error; use std::fmt; pub mod tests; mod wnaf; pub use self::wnaf::Wnaf; /// Projective representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. pub trait CurveProjective: PartialEq + Eq + Sized + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static { type Engine: ScalarEngine; type Scalar: PrimeField + SqrtField; type Base: SqrtField; type Affine: CurveAffine; /// Returns an element chosen uniformly at random using a user-provided RNG. fn random(rng: &mut R) -> Self; /// Returns the additive identity. fn zero() -> Self; /// Returns a fixed generator of unknown exponent. fn one() -> Self; /// Determines if this point is the point at infinity. fn is_zero(&self) -> bool; /// Normalizes a slice of projective elements so that /// conversion to affine is cheap. fn batch_normalization(v: &mut [Self]); /// Checks if the point is already "normalized" so that /// cheap affine conversion is possible. fn is_normalized(&self) -> bool; /// Doubles this element. fn double(&mut self); /// Adds another element to this element. fn add_assign(&mut self, other: &Self); /// Subtracts another element from this element. fn sub_assign(&mut self, other: &Self) { let mut tmp = *other; tmp.negate(); self.add_assign(&tmp); } /// Adds an affine element to this element. fn add_assign_mixed(&mut self, other: &Self::Affine); /// Negates this element. fn negate(&mut self); /// Performs scalar multiplication of this element. fn mul_assign::Repr>>(&mut self, other: S); /// Converts this element into its affine representation. fn into_affine(&self) -> Self::Affine; /// Recommends a wNAF window table size given a scalar. Always returns a number /// between 2 and 22, inclusive. fn recommended_wnaf_for_scalar(scalar: ::Repr) -> usize; /// Recommends a wNAF window size given the number of scalars you intend to multiply /// a base by. Always returns a number between 2 and 22, inclusive. fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize; } /// Affine representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. pub trait CurveAffine: Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static { type Engine: ScalarEngine; type Scalar: PrimeField + SqrtField; type Base: SqrtField; type Projective: CurveProjective; type Uncompressed: EncodedPoint; type Compressed: EncodedPoint; /// Returns the additive identity. fn zero() -> Self; /// Returns a fixed generator of unknown exponent. fn one() -> Self; /// Determines if this point represents the point at infinity; the /// additive identity. fn is_zero(&self) -> bool; /// Negates this element. fn negate(&mut self); /// Performs scalar multiplication of this element with mixed addition. fn mul::Repr>>(&self, other: S) -> Self::Projective; /// Converts this element into its affine representation. fn into_projective(&self) -> Self::Projective; /// Converts this element into its compressed encoding, so long as it's not /// the point at infinity. fn into_compressed(&self) -> Self::Compressed { ::from_affine(*self) } /// Converts this element into its uncompressed encoding, so long as it's not /// the point at infinity. fn into_uncompressed(&self) -> Self::Uncompressed { ::from_affine(*self) } } /// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`. pub trait EncodedPoint: Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static { type Affine: CurveAffine; /// Creates an empty representation. fn empty() -> Self; /// Returns the number of bytes consumed by this representation. fn size() -> usize; /// Converts an `EncodedPoint` into a `CurveAffine` element, /// if the encoding represents a valid element. fn into_affine(&self) -> Result; /// Converts an `EncodedPoint` into a `CurveAffine` element, /// without guaranteeing that the encoding represents a valid /// element. This is useful when the caller knows the encoding is /// valid already. /// /// If the encoding is invalid, this can break API invariants, /// so caution is strongly encouraged. fn into_affine_unchecked(&self) -> Result; /// Creates an `EncodedPoint` from an affine point, as long as the /// point is not the point at infinity. fn from_affine(affine: Self::Affine) -> Self; } /// An error that may occur when trying to decode an `EncodedPoint`. #[derive(Debug)] pub enum GroupDecodingError { /// The coordinate(s) do not lie on the curve. NotOnCurve, /// The element is not part of the r-order subgroup. NotInSubgroup, /// One of the coordinates could not be decoded CoordinateDecodingError(&'static str, PrimeFieldDecodingError), /// The compression mode of the encoded element was not as expected UnexpectedCompressionMode, /// The encoding contained bits that should not have been set UnexpectedInformation, } impl Error for GroupDecodingError { fn description(&self) -> &str { match *self { GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve", GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup", GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded", GroupDecodingError::UnexpectedCompressionMode => { "encoding has unexpected compression mode" } GroupDecodingError::UnexpectedInformation => "encoding has unexpected information", } } } impl fmt::Display for GroupDecodingError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { GroupDecodingError::CoordinateDecodingError(description, ref err) => { write!(f, "{} decoding error: {}", description, err) } _ => write!(f, "{}", self.description()), } } }