2020-11-12 20:13:13 +00:00
|
|
|
//! This module contains the `Curve`/`CurveAffine` abstractions that allow us to
|
|
|
|
|
//! write code that generalizes over a pair of groups.
|
2020-08-22 20:15:39 +00:00
|
|
|
|
|
|
|
|
use core::cmp;
|
|
|
|
|
use core::fmt::Debug;
|
|
|
|
|
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
|
|
|
|
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
|
|
|
|
|
|
2020-11-12 20:13:13 +00:00
|
|
|
use super::{Field, Group};
|
2020-08-22 20:15:39 +00:00
|
|
|
|
|
|
|
|
/// This trait is a common interface for dealing with elements of an elliptic
|
|
|
|
|
/// curve group in the "projective" form, where that arithmetic is usually more
|
|
|
|
|
/// efficient.
|
|
|
|
|
pub trait Curve:
|
|
|
|
|
Sized
|
|
|
|
|
+ Default
|
|
|
|
|
+ Copy
|
|
|
|
|
+ Clone
|
|
|
|
|
+ Send
|
|
|
|
|
+ Sync
|
|
|
|
|
+ 'static
|
|
|
|
|
+ Debug
|
|
|
|
|
+ Add<Output = Self>
|
|
|
|
|
+ Sub<Output = Self>
|
|
|
|
|
+ Mul<<Self as Curve>::Scalar, Output = Self>
|
|
|
|
|
+ Neg<Output = Self>
|
|
|
|
|
+ for<'a> Add<&'a Self, Output = Self>
|
|
|
|
|
+ for<'a> Sub<&'a Self, Output = Self>
|
|
|
|
|
+ MulAssign<<Self as Curve>::Scalar>
|
|
|
|
|
+ AddAssign
|
|
|
|
|
+ SubAssign
|
|
|
|
|
+ for<'a> AddAssign<&'a Self>
|
|
|
|
|
+ for<'a> SubAssign<&'a Self>
|
|
|
|
|
+ AddAssign<<Self as Curve>::Affine>
|
|
|
|
|
+ SubAssign<<Self as Curve>::Affine>
|
|
|
|
|
+ PartialEq
|
|
|
|
|
+ cmp::Eq
|
|
|
|
|
+ ConditionallySelectable
|
|
|
|
|
+ ConstantTimeEq
|
|
|
|
|
+ From<<Self as Curve>::Affine>
|
|
|
|
|
+ Group<Scalar = <Self as Curve>::Scalar>
|
|
|
|
|
{
|
|
|
|
|
/// The representation of a point on this curve in the affine coordinate space.
|
|
|
|
|
type Affine: CurveAffine<
|
|
|
|
|
Projective = Self,
|
|
|
|
|
Scalar = <Self as Curve>::Scalar,
|
|
|
|
|
Base = <Self as Curve>::Base,
|
|
|
|
|
> + Add<Output = Self>
|
|
|
|
|
+ Sub<Output = Self>
|
|
|
|
|
+ Mul<<Self as Curve>::Scalar, Output = Self>
|
|
|
|
|
+ Neg<Output = <Self as Curve>::Affine>
|
|
|
|
|
+ From<Self>;
|
|
|
|
|
/// The scalar field of this elliptic curve.
|
|
|
|
|
type Scalar: Field;
|
|
|
|
|
/// The base field over which this elliptic curve is constructed.
|
|
|
|
|
type Base: Field;
|
|
|
|
|
|
|
|
|
|
/// Obtains the additive identity.
|
|
|
|
|
fn zero() -> Self;
|
|
|
|
|
|
|
|
|
|
/// Obtains the base point of the curve.
|
|
|
|
|
fn one() -> Self;
|
|
|
|
|
|
|
|
|
|
/// Doubles this element.
|
|
|
|
|
fn double(&self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Returns whether or not this element is the identity.
|
|
|
|
|
fn is_zero(&self) -> Choice;
|
|
|
|
|
|
|
|
|
|
/// Apply the curve endomorphism by multiplying the x-coordinate
|
|
|
|
|
/// by an element of multiplicative order 3.
|
|
|
|
|
fn endo(&self) -> Self;
|
|
|
|
|
|
|
|
|
|
/// Converts this element into its affine form.
|
|
|
|
|
fn to_affine(&self) -> Self::Affine;
|
|
|
|
|
|
|
|
|
|
/// Returns whether or not this element is on the curve; should
|
|
|
|
|
/// always be true unless an "unchecked" API was used.
|
|
|
|
|
fn is_on_curve(&self) -> Choice;
|
|
|
|
|
|
|
|
|
|
/// Converts many elements into their affine form. Panics if the
|
|
|
|
|
/// sizes of the slices are different.
|
|
|
|
|
fn batch_to_affine(v: &[Self], target: &mut [Self::Affine]);
|
|
|
|
|
|
|
|
|
|
/// Returns the curve constant b
|
|
|
|
|
fn b() -> Self::Base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// This trait is the affine counterpart to `Curve` and is used for
|
|
|
|
|
/// serialization, storage in memory, and inspection of $x$ and $y$ coordinates.
|
|
|
|
|
pub trait CurveAffine:
|
|
|
|
|
Sized
|
|
|
|
|
+ Default
|
|
|
|
|
+ Copy
|
|
|
|
|
+ Clone
|
|
|
|
|
+ Send
|
|
|
|
|
+ Sync
|
|
|
|
|
+ 'static
|
|
|
|
|
+ Debug
|
|
|
|
|
+ Add<Output = <Self as CurveAffine>::Projective>
|
|
|
|
|
+ Sub<Output = <Self as CurveAffine>::Projective>
|
|
|
|
|
+ Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
|
|
|
|
|
+ Neg<Output = Self>
|
|
|
|
|
+ PartialEq
|
|
|
|
|
+ cmp::Eq
|
|
|
|
|
+ ConditionallySelectable
|
|
|
|
|
+ ConstantTimeEq
|
|
|
|
|
+ From<<Self as CurveAffine>::Projective>
|
|
|
|
|
{
|
|
|
|
|
/// The representation of a point on this curve in the projective coordinate space.
|
|
|
|
|
type Projective: Curve<
|
|
|
|
|
Affine = Self,
|
|
|
|
|
Scalar = <Self as CurveAffine>::Scalar,
|
|
|
|
|
Base = <Self as CurveAffine>::Base,
|
|
|
|
|
> + Mul<<Self as CurveAffine>::Scalar, Output = <Self as CurveAffine>::Projective>
|
|
|
|
|
+ MulAssign<<Self as CurveAffine>::Scalar>
|
|
|
|
|
+ AddAssign<Self>
|
|
|
|
|
+ SubAssign<Self>
|
|
|
|
|
+ From<Self>;
|
|
|
|
|
/// The scalar field of this elliptic curve.
|
|
|
|
|
type Scalar: Field;
|
|
|
|
|
/// The base field over which this elliptic curve is constructed.
|
|
|
|
|
type Base: Field;
|
|
|
|
|
|
|
|
|
|
/// Obtains the additive identity.
|
|
|
|
|
fn zero() -> Self;
|
|
|
|
|
|
|
|
|
|
/// Obtains the base point of the curve.
|
|
|
|
|
fn one() -> Self;
|
|
|
|
|
|
|
|
|
|
/// Returns whether or not this element is the identity.
|
|
|
|
|
fn is_zero(&self) -> Choice;
|
|
|
|
|
|
|
|
|
|
/// Converts this element into its projective form.
|
|
|
|
|
fn to_projective(&self) -> Self::Projective;
|
|
|
|
|
|
|
|
|
|
/// Gets the $(x, y)$ coordinates of this point.
|
|
|
|
|
fn get_xy(&self) -> CtOption<(Self::Base, Self::Base)>;
|
|
|
|
|
|
|
|
|
|
/// Obtains a point given $(x, y)$, failing if it is not on the
|
|
|
|
|
/// curve.
|
|
|
|
|
fn from_xy(x: Self::Base, y: Self::Base) -> CtOption<Self>;
|
|
|
|
|
|
|
|
|
|
/// Returns whether or not this element is on the curve; should
|
|
|
|
|
/// always be true unless an "unchecked" API was used.
|
|
|
|
|
fn is_on_curve(&self) -> Choice;
|
|
|
|
|
|
|
|
|
|
/// Attempts to obtain a group element from its compressed 32-byte little
|
|
|
|
|
/// endian representation.
|
|
|
|
|
fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self>;
|
|
|
|
|
|
|
|
|
|
/// Obtains the compressed, 32-byte little endian representation of this
|
|
|
|
|
/// element.
|
|
|
|
|
fn to_bytes(&self) -> [u8; 32];
|
|
|
|
|
|
|
|
|
|
/// Attempts to obtain a group element from its uncompressed 64-byte little
|
|
|
|
|
/// endian representation.
|
|
|
|
|
fn from_bytes_wide(bytes: &[u8; 64]) -> CtOption<Self>;
|
|
|
|
|
|
|
|
|
|
/// Obtains the uncompressed, 64-byte little endian representation of this
|
|
|
|
|
/// element.
|
|
|
|
|
fn to_bytes_wide(&self) -> [u8; 64];
|
|
|
|
|
|
|
|
|
|
/// Returns the curve constant $b$
|
|
|
|
|
fn b() -> Self::Base;
|
|
|
|
|
}
|