1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#![cfg_attr(feature = "cargo-clippy", deny(warnings))]
#![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))]
#![deny(intra_doc_link_resolution_failure)]
#![deny(missing_debug_implementations)]
#[cfg(test)]
pub mod tests;
pub mod bls12_381;
mod hash_to_curve;
mod hash_to_field;
mod signum;
pub use self::hash_to_curve::HashToCurve;
pub use self::hash_to_field::{hash_to_field, BaseFromRO, ExpandMsgXmd, ExpandMsgXof, FromRO};
pub use self::signum::{Sgn0Result, Signum0};
use fff::{Field, PrimeField, ScalarEngine, SqrtField};
use groupy::{CurveAffine, CurveProjective};
pub trait Compress: Sized {
fn write_compressed<W: std::io::Write>(self, out: W) -> std::io::Result<()>;
fn read_compressed<R: std::io::Read>(source: R) -> std::io::Result<Self>;
}
pub trait Engine: ScalarEngine {
type G1: CurveProjective<Engine = Self, Base = Self::Fq, Scalar = Self::Fr, Affine = Self::G1Affine>
+ From<Self::G1Affine>;
type G1Affine: PairingCurveAffine<
Engine = Self,
Base = Self::Fq,
Scalar = Self::Fr,
Projective = Self::G1,
Pair = Self::G2Affine,
PairingResult = Self::Fqk,
> + From<Self::G1>;
type G2: CurveProjective<Engine = Self, Base = Self::Fqe, Scalar = Self::Fr, Affine = Self::G2Affine>
+ From<Self::G2Affine>;
type G2Affine: PairingCurveAffine<
Engine = Self,
Base = Self::Fqe,
Scalar = Self::Fr,
Projective = Self::G2,
Pair = Self::G1Affine,
PairingResult = Self::Fqk,
> + From<Self::G2>;
type Fq: PrimeField + SqrtField;
type Fqe: SqrtField;
type Fqk: Field + Compress;
fn miller_loop<'a, I>(i: I) -> Self::Fqk
where
I: IntoIterator<
Item = &'a (
&'a <Self::G1Affine as PairingCurveAffine>::Prepared,
&'a <Self::G2Affine as PairingCurveAffine>::Prepared,
),
>;
fn final_exponentiation(_: &Self::Fqk) -> Option<Self::Fqk>;
fn pairing<G1, G2>(p: G1, q: G2) -> Self::Fqk
where
G1: Into<Self::G1Affine>,
G2: Into<Self::G2Affine>,
{
Self::final_exponentiation(&Self::miller_loop(
[(&(p.into().prepare()), &(q.into().prepare()))].iter(),
))
.unwrap()
}
}
pub trait PairingCurveAffine: CurveAffine {
type Prepared: Clone + Send + Sync + 'static;
type Pair: PairingCurveAffine<Pair = Self>;
type PairingResult: Field;
fn prepare(&self) -> Self::Prepared;
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult;
}