pub fn prove(
        a: &[E::G1Affine],
        b: &[E::G2Affine],
        r: &[E::Fr],
        value: E::Fqk,
    ) -> Result<Proof<E>, ()> {
        assert_eq!(a.len(), b.len());
        // Ensure the order of the input vectors is a power of 2
        assert_eq!(a.len().count_ones(), 1);
        let mut length = a.len();
        assert_eq!(length, b.len());
        assert_eq!(length.count_ones(), 1);
        let mut proof_vec = Vec::new();
        // TODO(psi): should we also input a succinct bilinear group description to the rng?
        let mut rng = FiatShamirRng::<D>::from_seed(&to_bytes![a, b, r, value].unwrap());
        let a = a
            .into_par_iter()
            .zip(r)
            .map(|(a, r)| a.mul(*r))
            .collect::<Vec<_>>();
        let mut a = E::G1Projective::batch_normalization_into_affine(&a);
        let mut b = b.to_vec();

        while length != 1 {
            length /= 2;
            let a_l = &a[..length];
            let a_r = &a[length..];

            let b_l = &b[..length];
            let b_r = &b[length..];

            let z_l = product_of_pairings::<E>(a_r, b_l);
            let z_r = product_of_pairings::<E>(a_l, b_r);
            proof_vec.push((z_l, z_r));
            rng.absorb(&to_bytes![z_l, z_r].unwrap());
            let x: E::Fr = u128::rand(&mut rng).into();

            let a_proj = a_l
                .par_iter()
                .zip(a_r)
                .map(|(a_l, a_r)| {
                    let mut temp = a_r.mul(x);
                    temp.add_assign_mixed(a_l);
                    temp
                })
                .collect::<Vec<_>>();
            a = E::G1Projective::batch_normalization_into_affine(&a_proj);

            let x_inv = x.inverse().unwrap();
            let b_proj = b_l
                .par_iter()
                .zip(b_r)
                .map(|(b_l, b_r)| {
                    let mut temp = b_r.mul(x_inv);
                    temp.add_assign_mixed(b_l);
                    temp
                })
                .collect::<Vec<_>>();
            b = E::G2Projective::batch_normalization_into_affine(&b_proj);
        }

        Ok(Proof {
            gt_elems: proof_vec,
        })
    }
/// Produce a proof of the inner pairing product.
Produce a proof of the inner pairing product.
Produce a proof of the inner pairing product .
pub fn prove(
        a: &[E::G1Affine],
        b: &[E::G2Affine],
        r: &[E::Fr],
        value: E::Fqk,
    ) -> Result<Proof<E>, ()> {
        assert_eq!(a.len(), b.len());
        // Ensure the order of the input vectors is a power of 2
        assert_eq!(a.len().count_ones(), 1);
        let mut length = a.len();
        assert_eq!(length, b.len());
        assert_eq!(length.count_ones(), 1);
        let mut proof_vec = Vec::new();
        // TODO(psi): should we also input a succinct bilinear group description to the rng?
        let mut rng = FiatShamirRng::<D>::from_seed(&to_bytes![a, b, r, value].unwrap());
        let a = a
            .into_par_iter()
            .zip(r)
            .map(|(a, r)| a.mul(*r))
            .collect::<Vec<_>>();
        let mut a = E::G1Projective::batch_normalization_into_affine(&a);
        let mut b = b.to_vec();
        while length != 1 {
            length /= 2;
            let a_l = &a[..length];
            let a_r = &a[length..];
            let b_l = &b[..length];
            let b_r = &b[length..];
            let z_l = product_of_pairings::<E>(a_r, b_l);
            let z_r = product_of_pairings::<E>(a_l, b_r);
            proof_vec.push((z_l, z_r));
            rng.absorb(&to_bytes![z_l, z_r].unwrap());
            let x: E::Fr = u128::rand(&mut rng).into();
            let a_proj = a_l
                .par_iter()
                .zip(a_r)
                .map(|(a_l, a_r)| {
                    let mut temp = a_r.mul(x);
                    temp.add_assign_mixed(a_l);
                    temp
                })
                .collect::<Vec<_>>();
            a = E::G1Projective::batch_normalization_into_affine(&a_proj);
            let x_inv = x.inverse().unwrap();
            let b_proj = b_l
                .par_iter()
                .zip(b_r)
                .map(|(b_l, b_r)| {
                    let mut temp = b_r.mul(x_inv);
                    temp.add_assign_mixed(b_l);
                    temp
                })
                .collect::<Vec<_>>();
            b = E::G2Projective::batch_normalization_into_affine(&b_proj);
        }
        Ok(Proof {
            gt_elems: proof_vec,
        })
    }
pub fn prove ( a : & [ E :: G1Affine ] , b : & [ E :: G2Affine ] , r : & [ E :: Fr ] , value : E :: Fqk , ) -> Result < Proof < E > , ( ) > { assert_eq ! ( a len ( ) b len ( ) ) ; // Ensure the order of the input vectors is a power of 2 assert_eq ! ( a len ( ) count_ones ( ) 1 ) ; let mut length = a . len ( ) ; assert_eq ! ( length b len ( ) ) ; assert_eq ! ( length count_ones ( ) 1 ) ; let mut proof_vec = Vec :: new ( ) ; // TODO(psi): should we also input a succinct bilinear group description to the rng? let mut rng = FiatShamirRng :: < D > :: from_seed ( & to_bytes ! [ a b r value ] . unwrap ( ) ) ; let a = a . into_par_iter ( ) . zip ( r ) . map ( | ( a , r ) | a . mul ( * r ) ) . collect :: < Vec < _ > > ( ) ; let mut a = E :: G1Projective :: batch_normalization_into_affine ( & a ) ; let mut b = b . to_vec ( ) ; while length != 1 { length /= 2 ; let a_l = & a [ .. length ] ; let a_r = & a [ length .. ] ; let b_l = & b [ .. length ] ; let b_r = & b [ length .. ] ; let z_l = product_of_pairings :: < E > ( a_r , b_l ) ; let z_r = product_of_pairings :: < E > ( a_l , b_r ) ; proof_vec . push ( ( z_l , z_r ) ) ; rng . absorb ( & to_bytes ! [ z_l z_r ] . unwrap ( ) ) ; let x : E :: Fr = u128 :: rand ( & mut rng ) . into ( ) ; let a_proj = a_l . par_iter ( ) . zip ( a_r ) . map ( | ( a_l , a_r ) | { let mut temp = a_r . mul ( x ) ; temp . add_assign_mixed ( a_l ) ; temp } ) . collect :: < Vec < _ > > ( ) ; a = E :: G1Projective :: batch_normalization_into_affine ( & a_proj ) ; let x_inv = x . inverse ( ) . unwrap ( ) ; let b_proj = b_l . par_iter ( ) . zip ( b_r ) . map ( | ( b_l , b_r ) | { let mut temp = b_r . mul ( x_inv ) ; temp . add_assign_mixed ( b_l ) ; temp } ) . collect :: < Vec < _ > > ( ) ; b = E :: G2Projective :: batch_normalization_into_affine ( & b_proj ) ; } Ok ( Proof { gt_elems : proof_vec , } ) }
Produce a proof of the inner pairing product.
Produce a proof of the inner pairing product .
a
&[E::G1Affine]
b
&[E::G2Affine]
r
&[E::Fr]
value
E::Fqk
a
&[E::G1Affine]
b
&[E::G2Affine]
r
&[E::Fr]
value
E::Fqk