1#![no_std]
4#![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#![deny(rustdoc::broken_intra_doc_links)]
16#![deny(missing_debug_implementations)]
18
19pub 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
29pub trait Engine: Sized + 'static + Clone + Sync + Send + core::fmt::Debug {
33 type Fr: PrimeField;
35
36 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 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 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 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 type Gt: Group<Scalar = Self::Fr> + ScalarMul<Self::Fr> + ScalarMulOwned<Self::Fr>;
74
75 fn pairing(p: &Self::G1Affine, q: &Self::G2Affine) -> Self::Gt;
78}
79
80pub trait PairingCurveAffine: PrimeCurveAffine + UncompressedEncoding {
83 type Pair: PairingCurveAffine<Pair = Self>;
84 type PairingResult: Group;
85
86 fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
88}
89
90pub trait MultiMillerLoop: Engine {
92 type G2Prepared: Clone + Send + Sync + From<Self::G2Affine>;
94
95 type Result: MillerLoopResult<Gt = Self::Gt>;
97
98 fn multi_miller_loop(terms: &[(&Self::G1Affine, &Self::G2Prepared)]) -> Self::Result;
101}
102
103pub 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 type Gt: Group;
122
123 fn final_exponentiation(&self) -> Self::Gt;
127}