jf_utils/
multi_pairing.rs1use ark_ec::pairing::{Pairing, PairingOutput};
10use ark_std::vec::Vec;
11
12pub fn multi_pairing<E>(g1_elems: &[E::G1Affine], g2_elems: &[E::G2Affine]) -> PairingOutput<E>
14where
15 E: Pairing,
16{
17 let (inputs_g1, inputs_g2): (Vec<E::G1Prepared>, Vec<E::G2Prepared>) = g1_elems
18 .iter()
19 .zip(g2_elems.iter())
20 .map(|(g1, g2)| ((*g1).into(), (*g2).into()))
21 .unzip();
22
23 E::multi_pairing(inputs_g1, inputs_g2)
24}
25
26#[cfg(test)]
27mod test {
28 use crate::test_rng;
29
30 use super::*;
31 use ark_bls12_377::Bls12_377;
32 use ark_bls12_381::Bls12_381;
33 use ark_bn254::Bn254;
34 use ark_ec::{AffineRepr, CurveGroup};
35 use ark_std::{One, UniformRand};
36
37 #[test]
38 fn test_multi_pairing() {
39 test_multi_pairing_helper::<Bn254>();
40 test_multi_pairing_helper::<Bls12_377>();
41 test_multi_pairing_helper::<Bls12_381>();
42 }
43
44 fn test_multi_pairing_helper<E: Pairing>() {
45 let mut rng = test_rng();
46
47 let g1 = E::G1Affine::generator();
49 let g2 = E::G2Affine::generator();
50 let gt = E::pairing(g1, g2);
51
52 assert_eq!(multi_pairing::<E>(&[g1], &[g2]), gt);
53
54 let r1 = E::ScalarField::rand(&mut rng);
56 let r2 = E::ScalarField::rand(&mut rng);
57 let f1 = (g1 * r1).into_affine();
58 let f2 = (g2 * r2).into_affine();
59 let ft = E::pairing(f1, f2);
60
61 assert_eq!(multi_pairing::<E>(&[f1], &[f2]), ft);
62
63 let ht = PairingOutput(gt.0 * ft.0);
65 assert_eq!(multi_pairing::<E>(&[g1, f1], &[g2, f2]), ht);
66
67 assert!(multi_pairing::<E>(
69 &[g1, (g1 * -E::ScalarField::one()).into_affine()],
70 &[g2, g2]
71 )
72 .0
73 .is_one());
74 }
75}