#![cfg_attr(not(feature = "std"), no_std)]
#![warn(
unused,
future_incompatible,
nonstandard_style,
rust_2018_idioms,
rust_2021_compatibility
)]
#![forbid(unsafe_code)]
#![allow(
clippy::op_ref,
clippy::suspicious_op_assign_impl,
clippy::many_single_char_names
)]
#![doc = include_str!("../README.md")]
#[macro_use]
extern crate derivative;
#[macro_use]
extern crate ark_std;
use ark_ff::{
fields::{Field, PrimeField},
UniformRand,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::{
fmt::{Debug, Display},
hash::Hash,
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
vec::Vec,
};
use num_traits::Zero;
pub use scalar_mul::{variable_base::VariableBaseMSM, ScalarMul};
use zeroize::Zeroize;
pub mod models;
pub use self::models::*;
pub mod scalar_mul;
pub mod hashing;
pub mod pairing;
pub trait Group:
Eq
+ 'static
+ Sized
+ CanonicalSerialize
+ CanonicalDeserialize
+ Copy
+ Clone
+ Default
+ Send
+ Sync
+ Hash
+ Debug
+ Display
+ UniformRand
+ Zeroize
+ Zero
+ Neg<Output = Self>
+ Add<Self, Output = Self>
+ Sub<Self, Output = Self>
+ Mul<<Self as Group>::ScalarField, Output = Self>
+ AddAssign<Self>
+ SubAssign<Self>
+ MulAssign<<Self as Group>::ScalarField>
+ for<'a> Add<&'a Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ for<'a> Mul<&'a <Self as Group>::ScalarField, Output = Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
+ for<'a> MulAssign<&'a <Self as Group>::ScalarField>
+ core::iter::Sum<Self>
+ for<'a> core::iter::Sum<&'a Self>
{
type ScalarField: PrimeField;
#[must_use]
fn generator() -> Self;
#[must_use]
fn double(&self) -> Self {
let mut copy = *self;
copy.double_in_place();
copy
}
fn double_in_place(&mut self) -> &mut Self;
fn mul_bigint(&self, other: impl AsRef<[u64]>) -> Self;
fn mul_bits_be(&self, other: impl Iterator<Item = bool>) -> Self {
let mut res = Self::zero();
for b in other.skip_while(|b| !b) {
res.double_in_place();
if b {
res += self;
}
}
res
}
}
pub trait CurveGroup:
Group
+ Add<Self::Affine, Output = Self>
+ AddAssign<Self::Affine>
+ VariableBaseMSM
+ ScalarMul<MulBase = Self::Affine>
+ From<Self::Affine>
+ Into<Self::Affine>
+ core::iter::Sum<Self::Affine>
+ for<'a> core::iter::Sum<&'a Self::Affine>
{
type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
type BaseField: Field;
type Affine: AffineRepr<
Config = Self::Config,
Group = Self,
ScalarField = Self::ScalarField,
BaseField = Self::BaseField,
> + From<Self>
+ Into<Self>;
type FullGroup;
#[must_use]
fn normalize_batch(v: &[Self]) -> Vec<Self::Affine>;
fn into_affine(self) -> Self::Affine {
self.into()
}
}
pub trait AffineRepr:
Eq
+ 'static
+ Sized
+ CanonicalSerialize
+ CanonicalDeserialize
+ Copy
+ Clone
+ Default
+ UniformRand
+ Send
+ Sync
+ Hash
+ Debug
+ Display
+ Zeroize
+ From<<Self as AffineRepr>::Group>
+ Into<<Self as AffineRepr>::Group>
+ Add<Self, Output = Self::Group>
+ for<'a> Add<&'a Self, Output = Self::Group>
+ Add<Self::Group, Output = Self::Group>
+ for<'a> Add<&'a Self::Group, Output = Self::Group>
+ Mul<Self::ScalarField, Output = Self::Group>
+ for<'a> Mul<&'a Self::ScalarField, Output = Self::Group>
{
type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
type ScalarField: PrimeField + Into<<Self::ScalarField as PrimeField>::BigInt>;
type BaseField: Field;
type Group: CurveGroup<
Config = Self::Config,
Affine = Self,
ScalarField = Self::ScalarField,
BaseField = Self::BaseField,
> + From<Self>
+ Into<Self>
+ MulAssign<Self::ScalarField>;
fn xy(&self) -> Option<(&Self::BaseField, &Self::BaseField)>;
fn x(&self) -> Option<&Self::BaseField> {
self.xy().map(|(x, _)| x)
}
fn y(&self) -> Option<&Self::BaseField> {
self.xy().map(|(_, y)| y)
}
fn zero() -> Self;
fn is_zero(&self) -> bool {
self.xy().is_none()
}
#[must_use]
fn generator() -> Self;
fn into_group(self) -> Self::Group {
self.into()
}
fn from_random_bytes(bytes: &[u8]) -> Option<Self>;
#[must_use]
fn mul_bigint(&self, by: impl AsRef<[u64]>) -> Self::Group;
#[must_use]
fn clear_cofactor(&self) -> Self;
#[must_use]
fn mul_by_cofactor_to_group(&self) -> Self::Group;
#[must_use]
fn mul_by_cofactor(&self) -> Self {
self.mul_by_cofactor_to_group().into()
}
#[must_use]
fn mul_by_cofactor_inv(&self) -> Self {
self.mul_bigint(Self::Config::COFACTOR_INV.into_bigint())
.into()
}
}
pub trait CurveCycle
where
Self::E1: MulAssign<<Self::E2 as CurveGroup>::BaseField>,
Self::E2: MulAssign<<Self::E1 as CurveGroup>::BaseField>,
{
type E1: CurveGroup<
BaseField = <Self::E2 as Group>::ScalarField,
ScalarField = <Self::E2 as CurveGroup>::BaseField,
>;
type E2: CurveGroup;
}
pub trait PairingFriendlyCycle: CurveCycle {
type Engine1: pairing::Pairing<
G1 = Self::E1,
G1Affine = <Self::E1 as CurveGroup>::Affine,
ScalarField = <Self::E1 as Group>::ScalarField,
>;
type Engine2: pairing::Pairing<
G1 = Self::E2,
G1Affine = <Self::E2 as CurveGroup>::Affine,
ScalarField = <Self::E2 as Group>::ScalarField,
>;
}