# Batch Univariate KZG
```rust
impl<P: Pairing> BatchKZGUnivariateInterface<P> for UnivariateKZG {
fn open<F: PrimeField>(
srs: &SRS<P>,
poly: &UnivariantPolynomial<F>,
point: &Vec<F>,
) -> (Vec<F>, <P as Pairing>::G1) {
let point_evaluations: Vec<F> = point.iter().map(|point| poly.evaluate(point)).collect();
let i_poly = UnivariantPolynomial::interpolate(point_evaluations.clone(), point.clone());
let vanishing_polynomial = generate_vanishing_polynomial(&point);
let quotient =
<UnivariantPolynomial<F> as Sub>::sub(poly.clone(), i_poly) / vanishing_polynomial;
let proof = linear_combination_homomorphic_poly_eval_g1_primefield::<P, F>(
"ient,
&srs.g1_power_of_taus,
);
(point_evaluations, proof)
}
fn verify<F: PrimeField>(
srs: &SRS<P>,
commitment: &<P as Pairing>::G1,
point: &Vec<F>,
point_evaluation: &Vec<F>,
proof: &<P as Pairing>::G1,
) -> bool {
let r = UnivariantPolynomial::interpolate(point_evaluation.clone(), point.clone());
// first check: f(x) = r(x)
for (i, p) in point.iter().enumerate() {
if r.evaluate(p) != point_evaluation[i] {
return false;
}
}
// second check: e(commitment - reminder_poly_commitment, g) = e(proof, vanishing_polynomial_commitment)
let g2_generator = P::G2::generator();
let vanishing_polynomial = generate_vanishing_polynomial(&point);
let r_commitment = linear_combination_homomorphic_poly_eval_g1_primefield::<P, F>(
&r,
&srs.g1_power_of_taus,
);
let vanishing_poly_commitment = linear_combination_homomorphic_poly_eval_g2_primefield::<
P,
F,
>(&vanishing_polynomial, &srs.g2_power_of_tau);
let lhs = P::pairing(*commitment - r_commitment, g2_generator);
let rhs = P::pairing(*proof, vanishing_poly_commitment);
lhs == rhs
}
}
```