# 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>( &quotient, &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 } } ```