#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
#![deny(missing_debug_implementations)]
#![cfg_attr(feature = "asm", feature(asm_const))]
extern crate byteorder;
extern crate rand;
#[cfg(test)]
pub mod tests;
pub extern crate ff;
pub use ff::*;
pub mod bls12_381;
pub mod bn256;
pub mod compact_bn256;
mod wnaf;
pub use self::wnaf::Wnaf;
mod base;
pub use self::base::*;
use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField};
use std::{error::Error};
use std::fmt;
pub trait Engine: ScalarEngine {
type G1: CurveProjective<
Engine = Self,
Base = Self::Fq,
Scalar = Self::Fr,
Affine = Self::G1Affine,
>
+ From<Self::G1Affine>;
type G1Affine: CurveAffine<
Engine = Self,
Base = Self::Fq,
Scalar = Self::Fr,
Projective = Self::G1,
Pair = Self::G2Affine,
PairingResult = Self::Fqk,
>
+ From<Self::G1> + RawEncodable;
type G2: CurveProjective<
Engine = Self,
Base = Self::Fqe,
Scalar = Self::Fr,
Affine = Self::G2Affine,
>
+ From<Self::G2Affine>;
type G2Affine: CurveAffine<
Engine = Self,
Base = Self::Fqe,
Scalar = Self::Fr,
Projective = Self::G2,
Pair = Self::G1Affine,
PairingResult = Self::Fqk,
>
+ From<Self::G2>;
type Fq: PrimeField + SqrtField;
type Fqe: SqrtField;
type Fqk: Field;
fn miller_loop<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<
Item = &'a (
&'a <Self::G1Affine as CurveAffine>::Prepared,
&'a <Self::G2Affine as CurveAffine>::Prepared,
),
>;
fn final_exponentiation(r: &Self::Fqk) -> Option<Self::Fqk>;
fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
where
G1: Into<Self::G1Affine>,
G2: Into<Self::G2Affine>,
{
Self::final_exponentiation(&Self::miller_loop(
[(&(p.into().prepare()), &(q.into().prepare()))].iter(),
)).unwrap()
}
}
pub trait CurveProjective:
PartialEq
+ Eq
+ Sized
+ Copy
+ Clone
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ rand::Rand
+ 'static
{
type Engine: Engine<Fr = Self::Scalar>;
type Scalar: PrimeField + SqrtField;
type Base: SqrtField;
type Affine: CurveAffine<Projective = Self, Scalar = Self::Scalar, Base = Self::Base>;
fn zero() -> Self;
fn one() -> Self;
fn is_zero(&self) -> bool;
fn batch_normalization(v: &mut [Self]);
fn is_normalized(&self) -> bool;
fn double(&mut self);
fn add_assign(&mut self, other: &Self);
fn sub_assign(&mut self, other: &Self) {
let mut tmp = *other;
tmp.negate();
self.add_assign(&tmp);
}
fn add_assign_mixed(&mut self, other: &Self::Affine);
fn negate(&mut self);
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
fn into_affine(&self) -> Self::Affine;
fn recommended_wnaf_for_scalar(scalar: <Self::Scalar as PrimeField>::Repr) -> usize;
fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize;
fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) {
unimplemented!("default implementation does not exist for this function")
}
fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) {
unimplemented!("default implementation does not exist for this function")
}
fn from_xyz_unchecked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Self {
unimplemented!("default implementation does not exist for this function")
}
fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result<Self, GroupDecodingError> {
unimplemented!("default implementation does not exist for this function")
}
}
pub trait CurveAffine:
Copy
+ Clone
+ Sized
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ PartialEq
+ Eq
+ 'static
+ serde::Serialize
+ serde::de::DeserializeOwned
{
type Engine: Engine<Fr = Self::Scalar>;
type Scalar: PrimeField + SqrtField;
type Base: SqrtField;
type Projective: CurveProjective<Affine = Self, Scalar = Self::Scalar, Base = Self::Base>;
type Prepared: Clone + Send + Sync + 'static;
type Uncompressed: EncodedPoint<Affine = Self>;
type Compressed: EncodedPoint<Affine = Self>;
type Pair: CurveAffine<Pair = Self>;
type PairingResult: Field;
fn zero() -> Self;
fn one() -> Self;
fn is_zero(&self) -> bool;
fn negate(&mut self);
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;
fn prepare(&self) -> Self::Prepared;
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
fn into_projective(&self) -> Self::Projective;
fn into_compressed(&self) -> Self::Compressed {
<Self::Compressed as EncodedPoint>::from_affine(*self)
}
fn into_uncompressed(&self) -> Self::Uncompressed {
<Self::Uncompressed as EncodedPoint>::from_affine(*self)
}
fn as_xy(&self) -> (&Self::Base, &Self::Base);
fn into_xy_unchecked(self) -> (Self::Base, Self::Base);
fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self;
fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result<Self, GroupDecodingError>;
fn a_coeff() -> Self::Base;
fn b_coeff() -> Self::Base;
}
pub trait RawEncodable: CurveAffine {
fn into_raw_uncompressed_le(&self) -> Self::Uncompressed;
fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, infinity: bool) -> Result<Self, GroupDecodingError>;
}
pub trait EncodedPoint:
Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static
{
type Affine: CurveAffine;
fn empty() -> Self;
fn size() -> usize;
fn into_affine(&self) -> Result<Self::Affine, GroupDecodingError>;
fn into_affine_unchecked(&self) -> Result<Self::Affine, GroupDecodingError>;
fn from_affine(affine: Self::Affine) -> Self;
}
#[derive(Debug)]
pub enum GroupDecodingError {
NotOnCurve,
NotInSubgroup,
CoordinateDecodingError(&'static str, PrimeFieldDecodingError),
UnexpectedCompressionMode,
UnexpectedInformation,
}
impl GroupDecodingError {
fn self_description(&self) -> &str {
match *self {
GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve",
GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup",
GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded",
GroupDecodingError::UnexpectedCompressionMode => {
"encoding has unexpected compression mode"
}
GroupDecodingError::UnexpectedInformation => "encoding has unexpected information",
}
}
}
impl Error for GroupDecodingError {
fn description(&self) -> &str {
self.self_description()
}
}
impl fmt::Display for GroupDecodingError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
GroupDecodingError::CoordinateDecodingError(description, ref err) => {
write!(f, "{} decoding error: {}", description, err)
}
_ => write!(f, "{}", self.self_description()),
}
}
}