#![no_std]
#![cfg_attr(not(test), forbid(unused_crate_dependencies))]
#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))]
#![forbid(missing_docs)]
use core::fmt::Debug;
use core::hash::Hash;
use generic_array::{ArrayLength, GenericArray};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
use zeroize::Zeroize;
pub mod coords;
pub trait Curve: Debug + Copy + Eq + Ord + Hash + Default + Sync + Send + 'static {
const CURVE_NAME: &'static str;
type Point: Additive
+ From<CurveGenerator>
+ Zero
+ Zeroize
+ OnCurve
+ SmallFactor
+ Copy
+ Eq
+ ConstantTimeEq
+ ConditionallySelectable
+ Default
+ CompressedEncoding<Bytes = Self::CompressedPointArray>
+ UncompressedEncoding<Bytes = Self::UncompressedPointArray>
+ Decode
+ Unpin
+ Sync
+ Send;
type Scalar: Additive
+ Multiplicative<Self::Scalar, Output = Self::Scalar>
+ Multiplicative<CurveGenerator, Output = Self::Point>
+ Multiplicative<Self::Point, Output = Self::Point>
+ Invertible
+ Zero
+ One
+ FromUniformBytes
+ SamplableVartime
+ Zeroize
+ Copy
+ Eq
+ ConstantTimeEq
+ ConditionallySelectable
+ Default
+ IntegerEncoding<Bytes = Self::ScalarArray>
+ Unpin
+ Sync
+ Send;
type CompressedPointArray: ByteArray;
type UncompressedPointArray: ByteArray;
type ScalarArray: ByteArray;
type CoordinateArray: ByteArray;
}
pub trait Additive {
fn add(a: &Self, b: &Self) -> Self;
fn sub(a: &Self, b: &Self) -> Self;
fn negate(x: &Self) -> Self;
fn double(x: &Self) -> Self
where
Self: Sized,
{
Self::add(x, x)
}
}
pub trait Multiplicative<Rhs> {
type Output;
fn mul(a: &Self, b: &Rhs) -> Self::Output;
}
pub trait Invertible
where
Self: Sized,
{
fn invert(x: &Self) -> CtOption<Self>;
}
pub trait Zero {
fn zero() -> Self;
fn is_zero(x: &Self) -> Choice;
}
pub trait One {
fn one() -> Self;
fn is_one(x: &Self) -> Choice;
}
pub trait FromUniformBytes {
type Bytes: ByteArray;
fn from_uniform_bytes(bytes: &Self::Bytes) -> Self;
}
pub trait SamplableVartime {
fn random_vartime(rng: &mut impl rand_core::RngCore) -> Self;
}
pub trait OnCurve {
fn is_on_curve(&self) -> Choice;
}
pub trait SmallFactor {
fn is_torsion_free(&self) -> Choice;
}
pub struct CurveGenerator;
pub trait CompressedEncoding
where
Self: Sized,
{
type Bytes: ByteArray;
fn to_bytes_compressed(&self) -> Self::Bytes;
}
pub trait UncompressedEncoding
where
Self: Sized,
{
type Bytes: ByteArray;
fn to_bytes_uncompressed(&self) -> Self::Bytes;
}
pub trait IntegerEncoding
where
Self: Sized,
{
type Bytes: ByteArray;
fn to_be_bytes(&self) -> Self::Bytes;
fn to_le_bytes(&self) -> Self::Bytes;
fn from_be_bytes_exact(bytes: &Self::Bytes) -> Option<Self>;
fn from_le_bytes_exact(bytes: &Self::Bytes) -> Option<Self>;
fn from_be_bytes_mod_order(bytes: &[u8]) -> Self;
fn from_le_bytes_mod_order(bytes: &[u8]) -> Self;
}
pub trait Decode: Sized {
fn decode(bytes: &[u8]) -> Option<Self>;
}
pub struct Error;
pub trait ByteArray: AsRef<[u8]> + AsMut<[u8]> + Clone + Send + Sync + 'static {
fn zeroes() -> Self;
}
impl<const N: usize> ByteArray for [u8; N] {
fn zeroes() -> Self {
[0; N]
}
}
impl<N: ArrayLength<u8>> ByteArray for GenericArray<u8, N> {
fn zeroes() -> Self {
GenericArray::default()
}
}
pub trait Reduce<const N: usize> {
fn from_be_array_mod_order(bytes: &[u8; N]) -> Self;
fn from_le_array_mod_order(bytes: &[u8; N]) -> Self;
}
pub unsafe trait NoInvalidPoints {}