2017-07-16 20:50:03 -07:00
|
|
|
// `clippy` is a code linting tool for improving code quality by catching
|
2018-07-04 11:45:08 -07:00
|
|
|
// common mistakes or strange code patterns. If the `cargo-clippy` feature
|
|
|
|
// is provided, all compiler warnings are prohibited.
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(inline_always))]
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))]
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(new_without_default_derive))]
|
|
|
|
#![cfg_attr(feature = "cargo-clippy", allow(write_literal))]
|
2017-09-26 07:59:50 -07:00
|
|
|
// Force public structures to implement Debug
|
|
|
|
#![deny(missing_debug_implementations)]
|
|
|
|
|
2017-07-11 14:01:31 -07:00
|
|
|
extern crate byteorder;
|
2018-06-30 18:56:49 -07:00
|
|
|
extern crate ff;
|
2018-07-02 04:50:47 -07:00
|
|
|
extern crate group;
|
2018-02-21 10:08:58 -08:00
|
|
|
extern crate rand;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub mod tests;
|
|
|
|
|
|
|
|
pub mod bls12_381;
|
2017-07-14 10:56:55 -07:00
|
|
|
|
2018-07-02 12:02:51 -07:00
|
|
|
use ff::{Field, PrimeField, ScalarEngine, SqrtField};
|
2018-07-02 04:50:47 -07:00
|
|
|
use group::{CurveAffine, CurveProjective};
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
|
|
|
|
/// with well-defined relationships. In particular, the G1/G2 curve groups are
|
|
|
|
/// of prime order `r`, and are equipped with a bilinear pairing function.
|
2018-07-03 01:05:12 -07:00
|
|
|
pub trait Engine: ScalarEngine {
|
2017-07-08 09:55:43 -07:00
|
|
|
/// The projective representation of an element in G1.
|
2018-02-21 10:08:58 -08:00
|
|
|
type G1: CurveProjective<
|
2018-03-29 10:18:15 -07:00
|
|
|
Engine = Self,
|
|
|
|
Base = Self::Fq,
|
|
|
|
Scalar = Self::Fr,
|
|
|
|
Affine = Self::G1Affine,
|
|
|
|
>
|
2018-02-21 10:08:58 -08:00
|
|
|
+ From<Self::G1Affine>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The affine representation of an element in G1.
|
2018-07-02 04:50:47 -07:00
|
|
|
type G1Affine: PairingCurveAffine<
|
2018-03-29 10:18:15 -07:00
|
|
|
Engine = Self,
|
|
|
|
Base = Self::Fq,
|
|
|
|
Scalar = Self::Fr,
|
|
|
|
Projective = Self::G1,
|
|
|
|
Pair = Self::G2Affine,
|
|
|
|
PairingResult = Self::Fqk,
|
|
|
|
>
|
2018-02-21 10:08:58 -08:00
|
|
|
+ From<Self::G1>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The projective representation of an element in G2.
|
2018-02-21 10:08:58 -08:00
|
|
|
type G2: CurveProjective<
|
2018-03-29 10:18:15 -07:00
|
|
|
Engine = Self,
|
|
|
|
Base = Self::Fqe,
|
|
|
|
Scalar = Self::Fr,
|
|
|
|
Affine = Self::G2Affine,
|
|
|
|
>
|
2018-02-21 10:08:58 -08:00
|
|
|
+ From<Self::G2Affine>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The affine representation of an element in G2.
|
2018-07-02 04:50:47 -07:00
|
|
|
type G2Affine: PairingCurveAffine<
|
2018-03-29 10:18:15 -07:00
|
|
|
Engine = Self,
|
|
|
|
Base = Self::Fqe,
|
|
|
|
Scalar = Self::Fr,
|
|
|
|
Projective = Self::G2,
|
|
|
|
Pair = Self::G1Affine,
|
|
|
|
PairingResult = Self::Fqk,
|
|
|
|
>
|
2018-02-21 10:08:58 -08:00
|
|
|
+ From<Self::G2>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// The base field that hosts G1.
|
|
|
|
type Fq: PrimeField + SqrtField;
|
|
|
|
|
|
|
|
/// The extension field that hosts G2.
|
|
|
|
type Fqe: SqrtField;
|
|
|
|
|
|
|
|
/// The extension field that hosts the target group of the pairing.
|
|
|
|
type Fqk: Field;
|
|
|
|
|
|
|
|
/// Perform a miller loop with some number of (G1, G2) pairs.
|
|
|
|
fn miller_loop<'a, I>(i: I) -> Self::Fqk
|
2018-02-21 10:08:58 -08:00
|
|
|
where
|
|
|
|
I: IntoIterator<
|
|
|
|
Item = &'a (
|
2018-07-02 04:50:47 -07:00
|
|
|
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
|
|
|
|
&'a <Self::G2Affine as PairingCurveAffine>::Prepared,
|
2018-02-21 10:08:58 -08:00
|
|
|
),
|
|
|
|
>;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// Perform final exponentiation of the result of a miller loop.
|
|
|
|
fn final_exponentiation(&Self::Fqk) -> Option<Self::Fqk>;
|
|
|
|
|
|
|
|
/// Performs a complete pairing operation `(p, q)`.
|
|
|
|
fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
|
2018-02-21 10:08:58 -08:00
|
|
|
where
|
|
|
|
G1: Into<Self::G1Affine>,
|
|
|
|
G2: Into<Self::G2Affine>,
|
2017-07-08 09:55:43 -07:00
|
|
|
{
|
|
|
|
Self::final_exponentiation(&Self::miller_loop(
|
2018-02-21 10:08:58 -08:00
|
|
|
[(&(p.into().prepare()), &(q.into().prepare()))].into_iter(),
|
2017-07-08 09:55:43 -07:00
|
|
|
)).unwrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-02 04:50:47 -07:00
|
|
|
/// Affine representation of an elliptic curve point that can be used
|
|
|
|
/// to perform pairings.
|
|
|
|
pub trait PairingCurveAffine: CurveAffine {
|
2017-07-08 09:55:43 -07:00
|
|
|
type Prepared: Clone + Send + Sync + 'static;
|
2018-07-02 04:50:47 -07:00
|
|
|
type Pair: PairingCurveAffine<Pair = Self>;
|
2017-07-20 19:52:36 -07:00
|
|
|
type PairingResult: Field;
|
2017-07-08 09:55:43 -07:00
|
|
|
|
|
|
|
/// Prepares this element for pairing purposes.
|
|
|
|
fn prepare(&self) -> Self::Prepared;
|
|
|
|
|
2017-07-20 19:52:36 -07:00
|
|
|
/// Perform a pairing
|
|
|
|
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
|
2017-07-17 08:06:03 -07:00
|
|
|
}
|