#![cfg_attr(not(feature = "std"), no_std)]
#![warn(unused, future_incompatible, nonstandard_style, rust_2018_idioms)]
#![forbid(unsafe_code)]
#![allow(
clippy::op_ref,
clippy::suspicious_op_assign_impl,
clippy::many_single_char_names
)]
#[macro_use]
extern crate derivative;
#[macro_use]
extern crate ark_std;
use crate::group::Group;
use ark_ff::{
bytes::{FromBytes, ToBytes},
fields::{Field, PrimeField, SquareRootField},
UniformRand,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_std::{
fmt::{Debug, Display},
hash::Hash,
ops::{Add, AddAssign, MulAssign, Neg, Sub, SubAssign},
vec::Vec,
};
use num_traits::Zero;
use zeroize::Zeroize;
pub mod models;
pub use self::models::*;
pub mod group;
pub mod msm;
pub mod wnaf;
pub trait PairingEngine: Sized + 'static + Copy + Debug + Sync + Send + Eq + PartialEq {
type Fr: PrimeField + SquareRootField;
type G1Projective: ProjectiveCurve<BaseField = Self::Fq, ScalarField = Self::Fr, Affine = Self::G1Affine>
+ From<Self::G1Affine>
+ Into<Self::G1Affine>
+ MulAssign<Self::Fr>;
type G1Affine: AffineCurve<BaseField = Self::Fq, ScalarField = Self::Fr, Projective = Self::G1Projective>
+ From<Self::G1Projective>
+ Into<Self::G1Projective>
+ Into<Self::G1Prepared>;
type G1Prepared: ToBytes + Default + Clone + Send + Sync + Debug + From<Self::G1Affine>;
type G2Projective: ProjectiveCurve<BaseField = Self::Fqe, ScalarField = Self::Fr, Affine = Self::G2Affine>
+ From<Self::G2Affine>
+ Into<Self::G2Affine>
+ MulAssign<Self::Fr>;
type G2Affine: AffineCurve<BaseField = Self::Fqe, ScalarField = Self::Fr, Projective = Self::G2Projective>
+ From<Self::G2Projective>
+ Into<Self::G2Projective>
+ Into<Self::G2Prepared>;
type G2Prepared: ToBytes + Default + Clone + Send + Sync + Debug + From<Self::G2Affine>;
type Fq: PrimeField + SquareRootField;
type Fqe: SquareRootField;
type Fqk: Field;
#[must_use]
fn miller_loop<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>;
#[must_use]
fn final_exponentiation(_: &Self::Fqk) -> Option<Self::Fqk>;
#[must_use]
fn product_of_pairings<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<Item = &'a (Self::G1Prepared, Self::G2Prepared)>,
{
Self::final_exponentiation(&Self::miller_loop(i)).unwrap()
}
#[must_use]
fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
where
G1: Into<Self::G1Affine>,
G2: Into<Self::G2Affine>,
{
let g1_prep = Self::G1Prepared::from(p.into());
let g2_prep = Self::G2Prepared::from(q.into());
Self::product_of_pairings(core::iter::once(&(g1_prep, g2_prep)))
}
}
pub trait ProjectiveCurve:
Eq
+ 'static
+ Sized
+ ToBytes
+ FromBytes
+ CanonicalSerialize
+ CanonicalDeserialize
+ Copy
+ Clone
+ Default
+ Send
+ Sync
+ Hash
+ Debug
+ Display
+ UniformRand
+ Zeroize
+ Zero
+ Neg<Output = Self>
+ Add<Self, Output = Self>
+ Sub<Self, Output = Self>
+ AddAssign<Self>
+ SubAssign<Self>
+ MulAssign<<Self as ProjectiveCurve>::ScalarField>
+ for<'a> Add<&'a Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
+ core::iter::Sum<Self>
+ for<'a> core::iter::Sum<&'a Self>
+ From<<Self as ProjectiveCurve>::Affine>
{
const COFACTOR: &'static [u64];
type ScalarField: PrimeField + SquareRootField;
type BaseField: Field;
type Affine: AffineCurve<Projective = Self, ScalarField = Self::ScalarField, BaseField = Self::BaseField>
+ From<Self>
+ Into<Self>;
#[must_use]
fn prime_subgroup_generator() -> Self;
fn batch_normalization(v: &mut [Self]);
fn batch_normalization_into_affine(v: &[Self]) -> Vec<Self::Affine> {
let mut v = v.to_vec();
Self::batch_normalization(&mut v);
v.into_iter().map(|v| v.into()).collect()
}
#[must_use]
fn is_normalized(&self) -> bool;
#[must_use]
fn double(&self) -> Self {
let mut copy = *self;
copy.double_in_place();
copy
}
fn double_in_place(&mut self) -> &mut Self;
fn into_affine(&self) -> Self::Affine {
(*self).into()
}
fn add_mixed(mut self, other: &Self::Affine) -> Self {
self.add_assign_mixed(other);
self
}
fn add_assign_mixed(&mut self, other: &Self::Affine);
fn mul<S: AsRef<[u64]>>(mut self, other: S) -> Self {
let mut res = Self::zero();
for b in ark_ff::BitIteratorBE::without_leading_zeros(other) {
res.double_in_place();
if b {
res += self;
}
}
self = res;
self
}
}
pub trait AffineCurve:
Eq
+ 'static
+ Sized
+ ToBytes
+ FromBytes
+ CanonicalSerialize
+ CanonicalDeserialize
+ Copy
+ Clone
+ Default
+ Send
+ Sync
+ Hash
+ Debug
+ Display
+ Zero
+ Neg<Output = Self>
+ Zeroize
+ core::iter::Sum<Self>
+ for<'a> core::iter::Sum<&'a Self>
+ From<<Self as AffineCurve>::Projective>
{
const COFACTOR: &'static [u64];
type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInt>;
type BaseField: Field;
type Projective: ProjectiveCurve<Affine = Self, ScalarField = Self::ScalarField, BaseField = Self::BaseField>
+ From<Self>
+ Into<Self>
+ MulAssign<Self::ScalarField>;
#[must_use]
fn prime_subgroup_generator() -> Self;
fn into_projective(&self) -> Self::Projective {
(*self).into()
}
fn from_random_bytes(bytes: &[u8]) -> Option<Self>;
#[must_use]
fn mul<S: Into<<Self::ScalarField as PrimeField>::BigInt>>(&self, other: S)
-> Self::Projective;
#[must_use]
fn mul_by_cofactor_to_projective(&self) -> Self::Projective;
#[must_use]
fn mul_by_cofactor(&self) -> Self {
self.mul_by_cofactor_to_projective().into()
}
#[must_use]
fn mul_by_cofactor_inv(&self) -> Self;
}
impl<C: ProjectiveCurve> Group for C {
type ScalarField = C::ScalarField;
#[inline]
#[must_use]
fn double(&self) -> Self {
let mut tmp = *self;
tmp += self;
tmp
}
#[inline]
fn double_in_place(&mut self) -> &mut Self {
<C as ProjectiveCurve>::double_in_place(self)
}
}
pub fn prepare_g1<E: PairingEngine>(g: impl Into<E::G1Affine>) -> E::G1Prepared {
let g: E::G1Affine = g.into();
E::G1Prepared::from(g)
}
pub fn prepare_g2<E: PairingEngine>(g: impl Into<E::G2Affine>) -> E::G2Prepared {
let g: E::G2Affine = g.into();
E::G2Prepared::from(g)
}
pub trait CurveCycle
where
<Self::E1 as AffineCurve>::Projective: MulAssign<<Self::E2 as AffineCurve>::BaseField>,
<Self::E2 as AffineCurve>::Projective: MulAssign<<Self::E1 as AffineCurve>::BaseField>,
{
type E1: AffineCurve<
BaseField = <Self::E2 as AffineCurve>::ScalarField,
ScalarField = <Self::E2 as AffineCurve>::BaseField,
>;
type E2: AffineCurve;
}
pub trait PairingFriendlyCycle: CurveCycle {
type Engine1: PairingEngine<
G1Affine = Self::E1,
G1Projective = <Self::E1 as AffineCurve>::Projective,
Fq = <Self::E1 as AffineCurve>::BaseField,
Fr = <Self::E1 as AffineCurve>::ScalarField,
>;
type Engine2: PairingEngine<
G1Affine = Self::E2,
G1Projective = <Self::E2 as AffineCurve>::Projective,
Fq = <Self::E2 as AffineCurve>::BaseField,
Fr = <Self::E2 as AffineCurve>::ScalarField,
>;
}