fn compute_batch(
        pairs: &[(&Self::G1Point, &Self::G2Point)],
    ) -> Result<FieldElement<Self::OutputField>, PairingError> {
        let mut result = Fp12E::one();
        for (p, q) in pairs {
            // We don't need to check if p is in the subgroup because the subgroup oF G1 is G1.
            // See https://hackmd.io/@jpw/bn254#Subgroup-checks.
            if !q.is_in_subgroup() {
                return Err(PairingError::PointNotInSubgroup);
            }
            if !p.is_neutral_element() && !q.is_neutral_element() {
                let p = p.to_affine();
                let q = q.to_affine();
                result *= miller_optimized(&p, &q);
            }
        }
        Ok(final_exponentiation_optimized(&result))
    }
Computes the product of the ate pairing for a list of point pairs.
To optimize the pairing computation, we compute first all the miller loops
and multiply each other (so that we can then do the final exponentiation).
crates/math/src/elliptic_curve/short_weierstrass/curves/bn_254/pairing.rs