pasta_curves-source/src/arithmetic/curves.rs

167 lines
5.3 KiB
Rust
Raw Normal View History

//! 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};
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;
}