jf_utils/
multi_pairing.rs

1// Copyright (c) 2022 Espresso Systems (espressosys.com)
2// This file is part of the Jellyfish library.
3
4// You should have received a copy of the MIT License
5// along with the Jellyfish library. If not, see <https://mit-license.org/>.
6
7//! This module implements a simple wrapper of multi-pairing function
8
9use ark_ec::pairing::{Pairing, PairingOutput};
10use ark_std::vec::Vec;
11
12/// A simple wrapper of multi-pairing function.
13pub 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        // generators with single pairing
48        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        // random elements with single pairing
55        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        // random multi pairing products
64        let ht = PairingOutput(gt.0 * ft.0);
65        assert_eq!(multi_pairing::<E>(&[g1, f1], &[g2, f2]), ht);
66
67        // equality test
68        assert!(multi_pairing::<E>(
69            &[g1, (g1 * -E::ScalarField::one()).into_affine()],
70            &[g2, g2]
71        )
72        .0
73        .is_one());
74    }
75}