//! This module contains the `Curve`/`CurveAffine` abstractions that allow us to //! write code that generalizes over a pair of groups. 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::{FieldExt, Group}; /// 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 + Sub + Mul<::Scalar, Output = Self> + Neg + for<'a> Add<&'a Self, Output = Self> + for<'a> Sub<&'a Self, Output = Self> + MulAssign<::Scalar> + AddAssign + SubAssign + for<'a> AddAssign<&'a Self> + for<'a> SubAssign<&'a Self> + AddAssign<::Affine> + SubAssign<::Affine> + PartialEq + cmp::Eq + ConditionallySelectable + ConstantTimeEq + From<::Affine> + Group::Scalar> { /// The representation of a point on this curve in the affine coordinate space. type Affine: CurveAffine< Projective = Self, Scalar = ::Scalar, Base = ::Base, > + Add + Sub + Mul<::Scalar, Output = Self> + Neg::Affine> + From; /// The scalar field of this elliptic curve. type Scalar: FieldExt; /// The base field over which this elliptic curve is constructed. type Base: FieldExt; /// 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::Projective> + Sub::Projective> + Mul<::Scalar, Output = ::Projective> + Neg + PartialEq + cmp::Eq + ConditionallySelectable + ConstantTimeEq + From<::Projective> { /// The representation of a point on this curve in the projective coordinate space. type Projective: Curve< Affine = Self, Scalar = ::Scalar, Base = ::Base, > + Mul<::Scalar, Output = ::Projective> + MulAssign<::Scalar> + AddAssign + SubAssign + From; /// The scalar field of this elliptic curve. type Scalar: FieldExt; /// The base field over which this elliptic curve is constructed. type Base: FieldExt; /// Personalization of BLAKE2b hasher used to generate the uniform /// random string. const BLAKE2B_PERSONALIZATION: &'static [u8; 16]; /// 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; /// 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; /// 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; /// 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; }