use core::ops::{Add, Mul, Sub};
use group::prime::{PrimeCurve, PrimeCurveAffine};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
pub trait CurveExt:
PrimeCurve<Affine = <Self as CurveExt>::AffineExt>
+ group::Group<Scalar = <Self as CurveExt>::ScalarExt>
+ Default
+ ConditionallySelectable
+ ConstantTimeEq
+ From<<Self as PrimeCurve>::Affine>
{
type ScalarExt: ff::WithSmallOrderMulGroup<3>;
type Base: ff::WithSmallOrderMulGroup<3>;
type AffineExt: CurveAffine<CurveExt = Self, ScalarExt = <Self as CurveExt>::ScalarExt>
+ Mul<Self::ScalarExt, Output = Self>
+ for<'r> Mul<Self::ScalarExt, Output = Self>;
const CURVE_ID: &'static str;
fn endo(&self) -> Self;
fn jacobian_coordinates(&self) -> (Self::Base, Self::Base, Self::Base);
#[allow(clippy::type_complexity)]
fn hash_to_curve<'a>(domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a>;
fn is_on_curve(&self) -> Choice;
fn a() -> Self::Base;
fn b() -> Self::Base;
fn new_jacobian(x: Self::Base, y: Self::Base, z: Self::Base) -> CtOption<Self>;
}
pub trait CurveAffine:
PrimeCurveAffine<
Scalar = <Self as CurveAffine>::ScalarExt,
Curve = <Self as CurveAffine>::CurveExt,
> + Default
+ Add<Output = <Self as PrimeCurveAffine>::Curve>
+ Sub<Output = <Self as PrimeCurveAffine>::Curve>
+ ConditionallySelectable
+ ConstantTimeEq
+ From<<Self as PrimeCurveAffine>::Curve>
{
type ScalarExt: ff::WithSmallOrderMulGroup<3> + Ord;
type Base: ff::WithSmallOrderMulGroup<3> + Ord;
type CurveExt: CurveExt<AffineExt = Self, ScalarExt = <Self as CurveAffine>::ScalarExt>;
fn coordinates(&self) -> CtOption<Coordinates<Self>>;
fn from_xy(x: Self::Base, y: Self::Base) -> CtOption<Self>;
fn is_on_curve(&self) -> Choice;
fn a() -> Self::Base;
fn b() -> Self::Base;
}
#[derive(Clone, Copy, Debug, Default)]
pub struct Coordinates<C: CurveAffine> {
pub(crate) x: C::Base,
pub(crate) y: C::Base,
}
impl<C: CurveAffine> Coordinates<C> {
pub fn from_xy(x: C::Base, y: C::Base) -> CtOption<Self> {
C::from_xy(x, y).map(|_| Coordinates { x, y })
}
pub fn x(&self) -> &C::Base {
&self.x
}
pub fn y(&self) -> &C::Base {
&self.y
}
pub fn u(&self) -> &C::Base {
&self.x
}
pub fn v(&self) -> &C::Base {
&self.y
}
}
impl<C: CurveAffine> ConditionallySelectable for Coordinates<C> {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
Coordinates {
x: C::Base::conditional_select(&a.x, &b.x, choice),
y: C::Base::conditional_select(&a.y, &b.y, choice),
}
}
}