pairing/
lib.rs

1//! A library for working with pairing-friendly curves.
2
3#![no_std]
4// `clippy` is a code linting tool for improving code quality by catching
5// common mistakes or strange code patterns. If the `cargo-clippy` feature
6// is provided, all compiler warnings are prohibited.
7#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
8#![cfg_attr(feature = "cargo-clippy", allow(clippy::inline_always))]
9#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
10#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
11#![cfg_attr(feature = "cargo-clippy", allow(clippy::many_single_char_names))]
12#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
13#![cfg_attr(feature = "cargo-clippy", allow(clippy::write_literal))]
14// Catch documentation errors caused by code changes.
15#![deny(rustdoc::broken_intra_doc_links)]
16// Force public structures to implement Debug
17#![deny(missing_debug_implementations)]
18
19// Re-export group to make version-matching easier.
20pub use group;
21
22use core::ops::{Add, AddAssign, Mul};
23use group::{
24    ff::PrimeField,
25    prime::{PrimeCurve, PrimeCurveAffine},
26    Group, GroupOps, GroupOpsOwned, ScalarMul, ScalarMulOwned, UncompressedEncoding,
27};
28
29/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
30/// with well-defined relationships. In particular, the G1/G2 curve groups are
31/// of prime order `r`, and are equipped with a bilinear pairing function.
32pub trait Engine: Sized + 'static + Clone + Sync + Send + core::fmt::Debug {
33    /// This is the scalar field of the engine's groups.
34    type Fr: PrimeField;
35
36    /// The projective representation of an element in G1.
37    type G1: PrimeCurve<Scalar = Self::Fr, Affine = Self::G1Affine>
38        + From<Self::G1Affine>
39        + GroupOps<Self::G1Affine>
40        + GroupOpsOwned<Self::G1Affine>
41        + ScalarMul<Self::Fr>
42        + ScalarMulOwned<Self::Fr>;
43
44    /// The affine representation of an element in G1.
45    type G1Affine: PairingCurveAffine<
46            Scalar = Self::Fr,
47            Curve = Self::G1,
48            Pair = Self::G2Affine,
49            PairingResult = Self::Gt,
50        > + From<Self::G1>
51        + Mul<Self::Fr, Output = Self::G1>
52        + for<'a> Mul<&'a Self::Fr, Output = Self::G1>;
53
54    /// The projective representation of an element in G2.
55    type G2: PrimeCurve<Scalar = Self::Fr, Affine = Self::G2Affine>
56        + From<Self::G2Affine>
57        + GroupOps<Self::G2Affine>
58        + GroupOpsOwned<Self::G2Affine>
59        + ScalarMul<Self::Fr>
60        + ScalarMulOwned<Self::Fr>;
61
62    /// The affine representation of an element in G2.
63    type G2Affine: PairingCurveAffine<
64            Scalar = Self::Fr,
65            Curve = Self::G2,
66            Pair = Self::G1Affine,
67            PairingResult = Self::Gt,
68        > + From<Self::G2>
69        + Mul<Self::Fr, Output = Self::G2>
70        + for<'a> Mul<&'a Self::Fr, Output = Self::G2>;
71
72    /// The extension field that hosts the target group of the pairing.
73    type Gt: Group<Scalar = Self::Fr> + ScalarMul<Self::Fr> + ScalarMulOwned<Self::Fr>;
74
75    /// Invoke the pairing function `G1 x G2 -> Gt` without the use of precomputation and
76    /// other optimizations.
77    fn pairing(p: &Self::G1Affine, q: &Self::G2Affine) -> Self::Gt;
78}
79
80/// Affine representation of an elliptic curve point that can be used
81/// to perform pairings.
82pub trait PairingCurveAffine: PrimeCurveAffine + UncompressedEncoding {
83    type Pair: PairingCurveAffine<Pair = Self>;
84    type PairingResult: Group;
85
86    /// Perform a pairing
87    fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
88}
89
90/// An engine that can compute sums of pairings in an efficient way.
91pub trait MultiMillerLoop: Engine {
92    /// The prepared form of `Self::G2Affine`.
93    type G2Prepared: Clone + Send + Sync + From<Self::G2Affine>;
94
95    /// The type returned by `Engine::miller_loop`.
96    type Result: MillerLoopResult<Gt = Self::Gt>;
97
98    /// Computes $$\sum_{i=1}^n \textbf{ML}(a_i, b_i)$$ given a series of terms
99    /// $$(a_1, b_1), (a_2, b_2), ..., (a_n, b_n).$$
100    fn multi_miller_loop(terms: &[(&Self::G1Affine, &Self::G2Prepared)]) -> Self::Result;
101}
102
103/// Represents results of a Miller loop, one of the most expensive portions of the pairing
104/// function.
105///
106/// `MillerLoopResult`s cannot be compared with each other until
107/// [`MillerLoopResult::final_exponentiation`] is called, which is also expensive.
108pub trait MillerLoopResult:
109    Clone
110    + Copy
111    + Default
112    + core::fmt::Debug
113    + Send
114    + Sync
115    + Add<Output = Self>
116    + for<'a> Add<&'a Self, Output = Self>
117    + AddAssign
118    + for<'a> AddAssign<&'a Self>
119{
120    /// The extension field that hosts the target group of the pairing.
121    type Gt: Group;
122
123    /// This performs a "final exponentiation" routine to convert the result of a Miller
124    /// loop into an element of [`MillerLoopResult::Gt`], so that it can be compared with
125    /// other elements of `Gt`.
126    fn final_exponentiation(&self) -> Self::Gt;
127}