use std::hash::Hash;
use derive_more::derive::Display;
use elliptic_curve::{
group::{self, GroupEncoding},
ops::{Invert, MulByGenerator},
scalar::{FromUintUnchecked, IsHigh},
Curve as EllipticCurve,
FieldBytes,
ScalarPrimitive,
};
use ff::PrimeField;
use subtle::{ConditionallySelectable, ConstantTimeEq, CtOption};
use wincode::{SchemaRead, SchemaWrite};
use crate::algebra::{
field::{FieldElement, FieldExtension, SubfieldElement},
uniform_bytes::FromUniformBytes,
};
pub trait Curve: EllipticCurve + Hash {
const NAME: &'static str;
const SCALAR_BIG_ENDIAN: bool;
const POINT_BIG_ENDIAN: bool;
const BASE_FIELD_BIG_ENDIAN: bool;
type Point: ConditionallySelectable
+ ConstantTimeEq
+ Default
+ MulByGenerator
+ group::Group<Scalar = Self::Scalar>
+ GroupEncoding
+ for<'de> SchemaRead<'de, Dst = Self::Point>
+ SchemaWrite<Src = Self::Point>
+ Hash
+ FromExtendedEdwards<BaseFieldElement = BaseFieldElement<Self>>
+ ToExtendedEdwards<BaseFieldElement = BaseFieldElement<Self>>;
type Scalar: AsRef<Self::Scalar>
+ From<ScalarPrimitive<Self>>
+ FromUintUnchecked<Uint = Self::Uint>
+ Into<FieldBytes<Self>>
+ Into<ScalarPrimitive<Self>>
+ Into<Self::Uint>
+ Invert<Output = CtOption<Self::Scalar>>
+ FromUniformBytes
+ IsHigh
+ PartialOrd
+ PrimeField
+ FieldExtension<Subfield = Self::Scalar>
+ Hash;
type BaseField: PrimeField + FieldExtension + FromUniformBytes + Hash;
fn hash_to_curve(bytes: &[u8]) -> Self::Point;
}
pub trait FromExtendedEdwards {
type BaseFieldElement;
fn from_extended_edwards(coordinates: [Self::BaseFieldElement; 4]) -> Option<Self>
where
Self: Sized;
}
#[derive(Display)]
pub struct PointAtInfinityError;
pub trait ToExtendedEdwards {
type BaseFieldElement;
fn to_extended_edwards(self) -> Result<[Self::BaseFieldElement; 4], PointAtInfinityError>;
}
pub type ScalarField<C> = <C as Curve>::Scalar;
pub type BaseField<C> = <C as Curve>::BaseField;
pub type Scalar<C> = SubfieldElement<ScalarField<C>>;
pub type BaseFieldElement<C> = SubfieldElement<BaseField<C>>;
pub type ScalarAsExtension<C> = FieldElement<<C as Curve>::Scalar>;
pub type BaseFieldAsExtension<C> = FieldElement<BaseField<C>>;