use core::fmt;
use core::ops::{Mul, Neg};
use ff::PrimeField;
use subtle::{Choice, CtOption};
use crate::{prime::PrimeGroup, Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned};
pub trait CofactorGroup:
Group
+ GroupEncoding
+ GroupOps<<Self as CofactorGroup>::Subgroup>
+ GroupOpsOwned<<Self as CofactorGroup>::Subgroup>
{
type Subgroup: PrimeGroup<Scalar = Self::Scalar> + Into<Self>;
fn clear_cofactor(&self) -> Self::Subgroup;
fn into_subgroup(self) -> CtOption<Self::Subgroup>;
fn is_small_order(&self) -> Choice {
self.clear_cofactor().is_identity()
}
fn is_torsion_free(&self) -> Choice;
}
pub trait CofactorCurve:
Curve<AffineRepr = <Self as CofactorCurve>::Affine> + CofactorGroup
{
type Affine: CofactorCurveAffine<Curve = Self, Scalar = Self::Scalar>
+ Mul<Self::Scalar, Output = Self>
+ for<'r> Mul<&'r Self::Scalar, Output = Self>;
}
pub trait CofactorCurveAffine:
GroupEncoding
+ Copy
+ Clone
+ Sized
+ Send
+ Sync
+ fmt::Debug
+ PartialEq
+ Eq
+ 'static
+ Neg<Output = Self>
+ Mul<<Self as CofactorCurveAffine>::Scalar, Output = <Self as CofactorCurveAffine>::Curve>
+ for<'r> Mul<
&'r <Self as CofactorCurveAffine>::Scalar,
Output = <Self as CofactorCurveAffine>::Curve,
>
{
type Scalar: PrimeField;
type Curve: CofactorCurve<Affine = Self, Scalar = Self::Scalar>;
fn identity() -> Self;
fn generator() -> Self;
fn is_identity(&self) -> Choice;
fn to_curve(&self) -> Self::Curve;
}