use crate::common::Basic;
use core::{
fmt::Debug,
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
};
use rand_core::RngCore;
use super::{CurveAffine, CurveExtended, FftField, PrimeField};
pub trait Group:
PartialEq
+ Eq
+ Add<Output = Self>
+ AddAssign
+ Neg<Output = Self>
+ Sub<Output = Self>
+ SubAssign
+ Mul<Self::Scalar, Output = Self>
+ MulAssign<Self::Scalar>
+ Sized
+ Copy
{
type Scalar: PrimeField;
const ADDITIVE_GENERATOR: Self;
const ADDITIVE_IDENTITY: Self;
fn zero() -> Self;
fn invert(self) -> Option<Self>
where
Self: Sized;
fn random(rand: impl RngCore) -> Self;
}
pub trait CurveGroup:
PartialEq
+ Eq
+ Sized
+ Copy
+ Debug
+ Default
+ Add<Self, Output = Self::Extended>
+ for<'a> Add<&'a Self, Output = Self::Extended>
+ for<'b> Add<&'b Self, Output = Self::Extended>
+ for<'a, 'b> Add<&'b Self, Output = Self::Extended>
+ Sub<Self, Output = Self::Extended>
+ for<'a> Sub<&'a Self, Output = Self::Extended>
+ for<'b> Sub<&'b Self, Output = Self::Extended>
+ for<'a, 'b> Sub<&'b Self, Output = Self::Extended>
+ Neg<Output = Self>
+ Mul<Self::Scalar, Output = Self::Extended>
+ for<'a> Mul<&'a Self::Scalar, Output = Self::Extended>
+ for<'b> Mul<&'b Self::Scalar, Output = Self::Extended>
+ for<'a, 'b> Mul<&'b Self::Scalar, Output = Self::Extended>
{
type Range: PrimeField;
type Scalar: FftField + From<Self::Range>;
type Affine: CurveAffine<Range = Self::Range, Scalar = Self::Scalar, Extended = Self::Extended>;
type Extended: CurveExtended<Range = Self::Range, Scalar = Self::Scalar, Affine = Self::Affine>;
const PARAM_A: Self::Range;
const ADDITIVE_GENERATOR: Self;
const ADDITIVE_IDENTITY: Self;
fn zero() -> Self;
fn is_identity(&self) -> bool;
fn invert(self) -> Option<Self>
where
Self: Sized;
fn random(rand: impl RngCore) -> Self::Extended;
fn is_on_curve(self) -> bool;
fn get_x(&self) -> Self::Range;
fn get_y(&self) -> Self::Range;
fn double(self) -> <Self as CurveGroup>::Extended;
}
pub trait Ring: Group + Mul<Output = Self> + MulAssign + PartialOrd + Ord + Default {
const MULTIPLICATIVE_IDENTITY: Self;
fn one() -> Self;
}
pub trait Field: Ring + Basic + Div<Output = Self> + DivAssign + 'static {}