paired/
lib.rs

1//! A library for working with pairing-friendly curves.
2
3// `clippy` is a code linting tool for improving code quality by catching
4// common mistakes or strange code patterns. If the `cargo-clippy` feature
5// is provided, all compiler warnings are prohibited.
6#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
7#![cfg_attr(feature = "cargo-clippy", allow(clippy::inline_always))]
8#![cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
9#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
10#![cfg_attr(feature = "cargo-clippy", allow(clippy::many_single_char_names))]
11#![cfg_attr(feature = "cargo-clippy", allow(clippy::new_without_default))]
12#![cfg_attr(feature = "cargo-clippy", allow(clippy::write_literal))]
13// Catch documentation errors caused by code changes.
14#![deny(intra_doc_link_resolution_failure)]
15// Force public structures to implement Debug
16#![deny(missing_debug_implementations)]
17
18#[cfg(test)]
19pub mod tests;
20
21pub mod bls12_381;
22mod hash_to_curve;
23mod hash_to_field;
24mod signum;
25
26pub use self::hash_to_curve::HashToCurve;
27pub use self::hash_to_field::{hash_to_field, BaseFromRO, ExpandMsgXmd, ExpandMsgXof, FromRO};
28pub use self::signum::{Sgn0Result, Signum0};
29
30use fff::{Field, PrimeField, ScalarEngine, SqrtField};
31use groupy::{CurveAffine, CurveProjective};
32
33/// This traits enables reading and writing a compressed version.
34pub trait Compress: Sized {
35    fn write_compressed<W: std::io::Write>(self, out: W) -> std::io::Result<()>;
36    fn read_compressed<R: std::io::Read>(source: R) -> std::io::Result<Self>;
37}
38
39/// An "engine" is a collection of types (fields, elliptic curve groups, etc.)
40/// with well-defined relationships. In particular, the G1/G2 curve groups are
41/// of prime order `r`, and are equipped with a bilinear pairing function.
42pub trait Engine: ScalarEngine {
43    /// The projective representation of an element in G1.
44    type G1: CurveProjective<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Affine = Self::G1Affine>
45        + From<Self::G1Affine>;
46
47    /// The affine representation of an element in G1.
48    type G1Affine: PairingCurveAffine<
49            Engine = Self,
50            Base = Self::Fq,
51            Scalar = Self::Fr,
52            Projective = Self::G1,
53            Pair = Self::G2Affine,
54            PairingResult = Self::Fqk,
55        > + From<Self::G1>;
56
57    /// The projective representation of an element in G2.
58    type G2: CurveProjective<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine>
59        + From<Self::G2Affine>;
60
61    /// The affine representation of an element in G2.
62    type G2Affine: PairingCurveAffine<
63            Engine = Self,
64            Base = Self::Fqe,
65            Scalar = Self::Fr,
66            Projective = Self::G2,
67            Pair = Self::G1Affine,
68            PairingResult = Self::Fqk,
69        > + From<Self::G2>;
70
71    /// The base field that hosts G1.
72    type Fq: PrimeField + SqrtField;
73
74    /// The extension field that hosts G2.
75    type Fqe: SqrtField;
76
77    /// The extension field that hosts the target group of the pairing.
78    type Fqk: Field + Compress;
79
80    /// Perform a miller loop with some number of (G1, G2) pairs.
81    fn miller_loop<'a, I>(i: I) -> Self::Fqk
82    where
83        I: IntoIterator<
84            Item = &'a (
85                &'a <Self::G1Affine as PairingCurveAffine>::Prepared,
86                &'a <Self::G2Affine as PairingCurveAffine>::Prepared,
87            ),
88        >;
89
90    /// Perform final exponentiation of the result of a miller loop.
91    fn final_exponentiation(_: &Self::Fqk) -> Option<Self::Fqk>;
92
93    /// Performs a complete pairing operation `(p, q)`.
94    fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
95    where
96        G1: Into<Self::G1Affine>,
97        G2: Into<Self::G2Affine>,
98    {
99        Self::final_exponentiation(&Self::miller_loop(
100            [(&(p.into().prepare()), &(q.into().prepare()))].iter(),
101        ))
102        .unwrap()
103    }
104}
105
106/// Affine representation of an elliptic curve point that can be used
107/// to perform pairings.
108pub trait PairingCurveAffine: CurveAffine {
109    type Prepared: Clone + Send + Sync + 'static;
110    type Pair: PairingCurveAffine<Pair = Self>;
111    type PairingResult: Field;
112
113    /// Prepares this element for pairing purposes.
114    fn prepare(&self) -> Self::Prepared;
115
116    /// Perform a pairing
117    fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
118}