1#![deny(clippy::all, clippy::perf, clippy::correctness)]
6#![allow(clippy::many_single_char_names)]
7#![allow(clippy::wrong_self_convention)]
8
9#[cfg(not(target_endian = "little"))]
10compile_error!("blstrs is only supported on little endian architectures");
11
12#[macro_use]
13mod macros;
14
15mod fp;
16mod fp12;
17mod fp2;
18mod fp6;
19mod g1;
20mod g2;
21mod gt;
22mod pairing;
23mod scalar;
24mod traits;
25
26pub use g1::{G1Affine, G1Compressed, G1Projective, G1Uncompressed};
27pub use g2::{G2Affine, G2Compressed, G2Prepared, G2Projective, G2Uncompressed};
28pub use gt::{Gt, GtCompressed};
29pub use pairing::*;
30pub use scalar::Scalar;
31pub use traits::Compress;
32
33#[cfg(feature = "serde")]
34mod serde_impl;
35
36#[cfg(test)]
37mod tests;
38
39#[cfg(feature = "__private_bench")]
41pub use crate::{fp::Fp, fp2::Fp2, fp12::Fp12};
42
43use ff::Field;
44use group::prime::PrimeCurveAffine;
45use pairing_lib::{Engine, MultiMillerLoop, PairingCurveAffine};
46
47#[derive(Debug, Copy, Clone)]
49pub struct Bls12;
50
51impl Engine for Bls12 {
52 type Fr = Scalar;
53 type G1 = G1Projective;
54 type G1Affine = G1Affine;
55 type G2 = G2Projective;
56 type G2Affine = G2Affine;
57 type Gt = Gt;
58
59 fn pairing(p: &Self::G1Affine, q: &Self::G2Affine) -> Self::Gt {
60 pairing(p, q)
61 }
62}
63
64impl MultiMillerLoop for Bls12 {
65 type G2Prepared = G2Prepared;
66 type Result = MillerLoopResult;
67
68 fn multi_miller_loop(terms: &[(&Self::G1Affine, &Self::G2Prepared)]) -> Self::Result {
71 let mut res = blst::blst_fp12::default();
72
73 for (i, (p, q)) in terms.iter().enumerate() {
74 let mut tmp = blst::blst_fp12::default();
75 if (p.is_identity() | q.is_identity()).into() {
76 tmp = crate::fp12::Fp12::ONE.0;
78 } else {
79 unsafe {
80 blst::blst_miller_loop_lines(&mut tmp, q.lines.as_ptr(), &p.0);
81 }
82 }
83 if i == 0 {
84 res = tmp;
85 } else {
86 unsafe {
87 blst::blst_fp12_mul(&mut res, &res, &tmp);
88 }
89 }
90 }
91
92 MillerLoopResult(crate::fp12::Fp12(res))
93 }
94}
95
96#[cfg(feature = "gpu")]
97fn u64_to_u32(limbs: &[u64]) -> Vec<u32> {
98 limbs
99 .iter()
100 .flat_map(|limb| vec![(limb & 0xFFFF_FFFF) as u32, (limb >> 32) as u32])
101 .collect()
102}
103
104#[test]
105fn bls12_engine_tests() {
106 crate::tests::engine::engine_tests::<Bls12>();
107}