Migrate curve traits and tests, and WNAF, from pairing
This commit is contained in:
196
src/lib.rs
196
src/lib.rs
@@ -0,0 +1,196 @@
|
||||
extern crate ff;
|
||||
extern crate rand;
|
||||
|
||||
use ff::{PrimeField, PrimeFieldDecodingError, ScalarEngine, SqrtField};
|
||||
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
|
||||
+ rand::Rand
|
||||
+ 'static
|
||||
{
|
||||
type Engine: ScalarEngine<Fr = Self::Scalar>;
|
||||
type Scalar: PrimeField + SqrtField;
|
||||
type Base: SqrtField;
|
||||
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar>;
|
||||
|
||||
/// 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<S: Into<<Self::Scalar as PrimeField>::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: <Self::Scalar as PrimeField>::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<Fr = Self::Scalar>;
|
||||
type Scalar: PrimeField + SqrtField;
|
||||
type Base: SqrtField;
|
||||
type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar>;
|
||||
type Uncompressed: EncodedPoint<Affine = Self>;
|
||||
type Compressed: EncodedPoint<Affine = Self>;
|
||||
|
||||
/// 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<S: Into<<Self::Scalar as PrimeField>::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 {
|
||||
<Self::Compressed as EncodedPoint>::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 {
|
||||
<Self::Uncompressed as EncodedPoint>::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<Self::Affine, GroupDecodingError>;
|
||||
|
||||
/// 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<Self::Affine, GroupDecodingError>;
|
||||
|
||||
/// 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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user