use crate::error::{FastCryptoError, FastCryptoResult};
use crate::traits::AllowedRng;
use core::ops::{Add, Div, Mul, Neg, Sub};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::fmt::Debug;
use std::ops::{AddAssign, SubAssign};
pub mod bls12381;
pub mod ristretto255;
pub mod secp256r1;
pub mod multiplier;
pub trait GroupElement:
Copy
+ Clone
+ Debug
+ Eq
+ Add<Output = Self>
+ AddAssign
+ for<'a> Add<&'a Self, Output = Self>
+ Sub<Output = Self>
+ SubAssign
+ for<'a> Sub<&'a Self, Output = Self>
+ Neg<Output = Self>
+ Mul<Self::ScalarType, Output = Self>
+ Div<Self::ScalarType, Output = Result<Self, FastCryptoError>>
+ for<'a> Mul<&'a Self::ScalarType, Output = Self>
+ Sized
{
type ScalarType: Scalar;
fn zero() -> Self;
fn generator() -> Self;
}
pub trait Scalar:
GroupElement<ScalarType = Self> + Copy + From<u128> + Sized + Debug + Serialize + DeserializeOwned
{
fn rand<R: AllowedRng>(rng: &mut R) -> Self;
fn inverse(&self) -> FastCryptoResult<Self>;
}
pub trait Doubling: Clone {
fn double(self) -> Self;
fn repeated_doubling(self, repetitions: u64) -> Self {
(0..repetitions).fold(self, |acc, _| acc.double())
}
}
pub trait Pairing: GroupElement {
type Other: GroupElement<ScalarType = Self::ScalarType>;
type Output;
fn pairing(&self, other: &Self::Other) -> <Self as Pairing>::Output;
fn multi_pairing(
points_g1: &[Self],
points_g2: &[Self::Other],
) -> FastCryptoResult<<Self as Pairing>::Output>
where
<Self as Pairing>::Output: GroupElement,
{
if points_g1.len() != points_g2.len() {
return Err(FastCryptoError::InvalidInput);
}
if points_g1.is_empty() {
return Ok(<Self as Pairing>::Output::zero());
}
Ok(points_g1
.iter()
.skip(1)
.zip(points_g2.iter().skip(1))
.map(|(g1, g2)| g1.pairing(g2))
.fold(
points_g1[0].pairing(&points_g2[0]),
<Self as Pairing>::Output::add,
))
}
}
pub trait FiatShamirChallenge {
fn fiat_shamir_reduction_to_group_element(uniform_buffer: &[u8]) -> Self;
}
pub trait HashToGroupElement {
fn hash_to_group_element(msg: &[u8]) -> Self;
}
pub trait MultiScalarMul: GroupElement {
fn multi_scalar_mul(scalars: &[Self::ScalarType], points: &[Self]) -> FastCryptoResult<Self>;
}
pub trait FromTrustedByteArray<const LENGTH: usize>: Sized {
fn from_trusted_byte_array(bytes: &[u8; LENGTH]) -> FastCryptoResult<Self>;
}