librustzcash/pairing/src/lib.rs

111 lines
4.0 KiB
Rust
Raw Normal View History

2019-09-24 02:54:15 -07:00
//! A library for working with pairing-friendly curves.
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))]
2019-07-30 13:28:27 -07:00
#![cfg_attr(feature = "cargo-clippy", allow(clippy::inline_always))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::many_single_char_names))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::write_literal))]
// Catch documentation errors caused by code changes.
#![deny(intra_doc_link_resolution_failure)]
// Force public structures to implement Debug
#![deny(missing_debug_implementations)]
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};
use group::{CurveAffine, CurveOps, CurveOpsOwned, CurveProjective};
use subtle::CtOption;
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.
2019-12-12 10:46:05 -08:00
type G1: CurveProjective<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Affine = Self::G1Affine>
+ From<Self::G1Affine>
+ CurveOps<Self::G1Affine>
+ CurveOpsOwned<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,
2019-08-15 09:38:40 -07:00
> + From<Self::G1>;
2017-07-08 09:55:43 -07:00
/// The projective representation of an element in G2.
2019-12-12 10:46:05 -08:00
type G2: CurveProjective<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine>
+ From<Self::G2Affine>
+ CurveOps<Self::G2Affine>
+ CurveOpsOwned<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,
2019-08-15 09:38:40 -07: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) -> CtOption<Self::Fqk>;
2017-07-08 09:55:43 -07:00
/// 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(
[(&(p.into().prepare()), &(q.into().prepare()))].iter(),
2019-08-15 09:38:40 -07:00
))
.unwrap()
2017-07-08 09:55:43 -07:00
}
}
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
}