1#![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#![deny(intra_doc_link_resolution_failure)]
15#![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
33pub 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
39pub trait Engine: ScalarEngine {
43 type G1: CurveProjective<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Affine = Self::G1Affine>
45 + From<Self::G1Affine>;
46
47 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 type G2: CurveProjective<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine>
59 + From<Self::G2Affine>;
60
61 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 type Fq: PrimeField + SqrtField;
73
74 type Fqe: SqrtField;
76
77 type Fqk: Field + Compress;
79
80 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 fn final_exponentiation(_: &Self::Fqk) -> Option<Self::Fqk>;
92
93 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
106pub trait PairingCurveAffine: CurveAffine {
109 type Prepared: Clone + Send + Sync + 'static;
110 type Pair: PairingCurveAffine<Pair = Self>;
111 type PairingResult: Field;
112
113 fn prepare(&self) -> Self::Prepared;
115
116 fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
118}