pub fn verify(
        a: &[E::G1Affine],
        b: &[E::G2Affine],
        r: &[E::Fr],
        claimed_value: E::Fqk,
        proof: &Proof<E>,
    ) -> Result<bool, ()> {
        // Ensure the order of the input vectors is a power of 2
        let length = a.len();
        assert_eq!(length.count_ones(), 1);
        assert!(length >= 2);
        assert_eq!(length, b.len());
        // Ensure there are the correct number of proof elements
        let proof_len = proof.gt_elems.len();
        assert_eq!(proof_len as f32, f32::log2(length as f32));

        // 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, claimed_value].unwrap());

        let x_s = proof
            .gt_elems
            .iter()
            .map(|(z_l, z_r)| {
                rng.absorb(&to_bytes![z_l, z_r].unwrap());
                let x: E::Fr = u128::rand(&mut rng).into();
                x
            })
            .collect::<Vec<_>>();

        let mut x_invs = x_s.clone();
        ark_ff::batch_inversion(&mut x_invs);

        let z_prime = claimed_value
            * &proof
                .gt_elems
                .par_iter()
                .zip(&x_s)
                .zip(&x_invs)
                .map(|(((z_l, z_r), x), x_inv)| {
                    z_l.pow(x.into_repr()) * &z_r.pow(x_inv.into_repr())
                })
                .reduce(|| E::Fqk::one(), |a, b| a * &b);

        let mut s: Vec<E::Fr> = vec![E::Fr::one(); length];
        let mut s_invs: Vec<E::Fr> = vec![E::Fr::one(); length];
        // TODO(psi): batch verify
        for (j, (x, x_inv)) in x_s.into_iter().zip(x_invs).enumerate() {
            for i in 0..length {
                if i & (1 << (proof_len - j - 1)) != 0 {
                    s[i] *= &x;
                    s_invs[i] *= &x_inv;
                }
            }
        }

        let s = s
            .into_iter()
            .zip(r)
            .map(|(x, r)| (x * r).into_repr())
            .collect::<Vec<_>>();
        let s_invs = s_invs
            .iter()
            .map(|x_inv| x_inv.into_repr())
            .collect::<Vec<_>>();

        let a_prime = VariableBaseMSM::multi_scalar_mul(&a, &s);
        let b_prime = VariableBaseMSM::multi_scalar_mul(&b, &s_invs);

        let accept = E::pairing(a_prime, b_prime) == z_prime;

        Ok(accept)
    }
/// Verify an inner-pairing-product proof.
Verify an inner-pairing-product proof.
Verify an inner - pairing - product proof .
pub fn verify(
        a: &[E::G1Affine],
        b: &[E::G2Affine],
        r: &[E::Fr],
        claimed_value: E::Fqk,
        proof: &Proof<E>,
    ) -> Result<bool, ()> {
        // Ensure the order of the input vectors is a power of 2
        let length = a.len();
        assert_eq!(length.count_ones(), 1);
        assert!(length >= 2);
        assert_eq!(length, b.len());
        // Ensure there are the correct number of proof elements
        let proof_len = proof.gt_elems.len();
        assert_eq!(proof_len as f32, f32::log2(length as f32));
        // 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, claimed_value].unwrap());
        let x_s = proof
            .gt_elems
            .iter()
            .map(|(z_l, z_r)| {
                rng.absorb(&to_bytes![z_l, z_r].unwrap());
                let x: E::Fr = u128::rand(&mut rng).into();
                x
            })
            .collect::<Vec<_>>();
        let mut x_invs = x_s.clone();
        ark_ff::batch_inversion(&mut x_invs);
        let z_prime = claimed_value
            * &proof
                .gt_elems
                .par_iter()
                .zip(&x_s)
                .zip(&x_invs)
                .map(|(((z_l, z_r), x), x_inv)| {
                    z_l.pow(x.into_repr()) * &z_r.pow(x_inv.into_repr())
                })
                .reduce(|| E::Fqk::one(), |a, b| a * &b);
        let mut s: Vec<E::Fr> = vec![E::Fr::one(); length];
        let mut s_invs: Vec<E::Fr> = vec![E::Fr::one(); length];
        // TODO(psi): batch verify
        for (j, (x, x_inv)) in x_s.into_iter().zip(x_invs).enumerate() {
            for i in 0..length {
                if i & (1 << (proof_len - j - 1)) != 0 {
                    s[i] *= &x;
                    s_invs[i] *= &x_inv;
                }
            }
        }
        let s = s
            .into_iter()
            .zip(r)
            .map(|(x, r)| (x * r).into_repr())
            .collect::<Vec<_>>();
        let s_invs = s_invs
            .iter()
            .map(|x_inv| x_inv.into_repr())
            .collect::<Vec<_>>();
        let a_prime = VariableBaseMSM::multi_scalar_mul(&a, &s);
        let b_prime = VariableBaseMSM::multi_scalar_mul(&b, &s_invs);
        let accept = E::pairing(a_prime, b_prime) == z_prime;
        Ok(accept)
    }
pub fn verify ( a : & [ E :: G1Affine ] , b : & [ E :: G2Affine ] , r : & [ E :: Fr ] , claimed_value : E :: Fqk , proof : & Proof < E > , ) -> Result < bool , ( ) > { // Ensure the order of the input vectors is a power of 2 let length = a . len ( ) ; assert_eq ! ( length count_ones ( ) 1 ) ; assert ! ( length 2 ) ; assert_eq ! ( length b len ( ) ) ; // Ensure there are the correct number of proof elements let proof_len = proof . gt_elems . len ( ) ; assert_eq ! ( proof_len as f32 f32 log2 ( length as f32 ) ) ; // 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 claimed_value ] . unwrap ( ) ) ; let x_s = proof . gt_elems . iter ( ) . map ( | ( z_l , z_r ) | { rng . absorb ( & to_bytes ! [ z_l z_r ] . unwrap ( ) ) ; let x : E :: Fr = u128 :: rand ( & mut rng ) . into ( ) ; x } ) . collect :: < Vec < _ > > ( ) ; let mut x_invs = x_s . clone ( ) ; ark_ff :: batch_inversion ( & mut x_invs ) ; let z_prime = claimed_value * & proof . gt_elems . par_iter ( ) . zip ( & x_s ) . zip ( & x_invs ) . map ( | ( ( ( z_l , z_r ) , x ) , x_inv ) | { z_l . pow ( x . into_repr ( ) ) * & z_r . pow ( x_inv . into_repr ( ) ) } ) . reduce ( | | E :: Fqk :: one ( ) , | a , b | a * & b ) ; let mut s : Vec < E :: Fr > = vec ! [ E Fr one ( ) length ] ; let mut s_invs : Vec < E :: Fr > = vec ! [ E Fr one ( ) length ] ; // TODO(psi): batch verify for ( j , ( x , x_inv ) ) in x_s . into_iter ( ) . zip ( x_invs ) . enumerate ( ) { for i in 0 .. length { if i & ( 1 << ( proof_len - j - 1 ) ) != 0 { s [ i ] *= & x ; s_invs [ i ] *= & x_inv ; } } } let s = s . into_iter ( ) . zip ( r ) . map ( | ( x , r ) | ( x * r ) . into_repr ( ) ) . collect :: < Vec < _ > > ( ) ; let s_invs = s_invs . iter ( ) . map ( | x_inv | x_inv . into_repr ( ) ) . collect :: < Vec < _ > > ( ) ; let a_prime = VariableBaseMSM :: multi_scalar_mul ( & a , & s ) ; let b_prime = VariableBaseMSM :: multi_scalar_mul ( & b , & s_invs ) ; let accept = E :: pairing ( a_prime , b_prime ) == z_prime ; Ok ( accept ) }
Verify an inner-pairing-product proof.
Verify an inner - pairing - product proof .
a
&[E::G1Affine]
b
&[E::G2Affine]
r
&[E::Fr]
claimed_value
E::Fqk
proof
&Proof<E>
a
&[E::G1Affine]
b
&[E::G2Affine]
r
&[E::Fr]
claimed_value
E::Fqk
proof
&Proof<E>