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 hybrid_array::{Array, ArraySize};
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
+ ToCoordinates<BaseFieldElement = BaseFieldElement<Self>>
+ FromCoordinates<
BaseFieldElement = BaseFieldElement<Self>,
NumCoordinates = <Self::Point as ToCoordinates>::NumCoordinates,
>;
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 FromCoordinates: Sized {
type BaseFieldElement;
type NumCoordinates: ArraySize;
fn from_coordinates(
coordinates: Array<Self::BaseFieldElement, Self::NumCoordinates>,
) -> Option<Self>;
}
#[derive(Debug, Display)]
pub struct PointAtInfinityError;
pub trait ToCoordinates {
type BaseFieldElement;
type NumCoordinates: ArraySize;
fn to_coordinates(
self,
) -> Result<Array<Self::BaseFieldElement, Self::NumCoordinates>, 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>>;
pub type NumCoordinates<C> = <<C as Curve>::Point as ToCoordinates>::NumCoordinates;
pub type PointCoordinates<C> = Array<BaseFieldElement<C>, NumCoordinates<C>>;