librustzcash/pairing/src/lib.rs

121 lines
3.9 KiB
Rust
Raw Normal View History

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))]
// Force public structures to implement Debug
#![deny(missing_debug_implementations)]
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;
2019-07-10 15:36:40 -07:00
extern crate rand_core;
#[cfg(test)]
extern crate rand_xorshift;
2017-07-08 09:55:43 -07:00
#[cfg(test)]
pub mod tests;
pub mod bls12_381;
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
}