diff --git a/o1vm/src/pickles/proof.rs b/o1vm/src/pickles/proof.rs index 0a493a364f..23c02dbb45 100644 --- a/o1vm/src/pickles/proof.rs +++ b/o1vm/src/pickles/proof.rs @@ -34,7 +34,7 @@ pub struct Proof { pub zeta_evaluations: WitnessColumns, pub zeta_omega_evaluations: WitnessColumns, pub quotient_commitment: PolyComm, - pub quotient_evaluations: PointEvaluations, + pub quotient_evaluations: PointEvaluations>, /// IPA opening proof pub opening_proof: OpeningProof, } diff --git a/o1vm/src/pickles/prover.rs b/o1vm/src/pickles/prover.rs index 6eee0ca882..30b79c48db 100644 --- a/o1vm/src/pickles/prover.rs +++ b/o1vm/src/pickles/prover.rs @@ -16,6 +16,7 @@ use kimchi::{ }; use log::debug; use mina_poseidon::{sponge::ScalarChallenge, FqSponge}; +use o1_utils::ExtendedDensePolynomial; use poly_commitment::{ commitment::{absorb_commitment, PolyComm}, ipa::{DensePolynomialOrEvaluations, OpeningProof, SRS}, @@ -318,9 +319,19 @@ where [<::Group as Group>::ScalarField; N_MIPS_SEL_COLS], > = evals(&zeta_omega); + let chunked_quotient = quotient_poly + .to_chunked_polynomial(DEGREE_QUOTIENT_POLYNOMIAL as usize, domain.d1.size as usize); let quotient_evaluations = PointEvaluations { - zeta: quotient_poly.evaluate(&zeta), - zeta_omega: quotient_poly.evaluate(&zeta_omega), + zeta: chunked_quotient + .polys + .iter() + .map(|p| p.evaluate(&zeta)) + .collect::>(), + zeta_omega: chunked_quotient + .polys + .iter() + .map(|p| p.evaluate(&zeta_omega)) + .collect(), }; // Absorbing evaluations with a sponge for the other field @@ -349,9 +360,14 @@ where fr_sponge.absorb(zeta_eval); fr_sponge.absorb(zeta_omega_eval); } - fr_sponge.absorb("ient_evaluations.zeta); - fr_sponge.absorb("ient_evaluations.zeta_omega); - + for (quotient_zeta_eval, quotient_zeta_omega_eval) in quotient_evaluations + .zeta + .iter() + .zip(quotient_evaluations.zeta_omega.iter()) + { + fr_sponge.absorb(quotient_zeta_eval); + fr_sponge.absorb(quotient_zeta_omega_eval); + } //////////////////////////////////////////////////////////////////////////// // Round 4: Opening proof w/o linearization polynomial //////////////////////////////////////////////////////////////////////////// diff --git a/o1vm/src/pickles/verifier.rs b/o1vm/src/pickles/verifier.rs index 423cb7fbe5..df39810860 100644 --- a/o1vm/src/pickles/verifier.rs +++ b/o1vm/src/pickles/verifier.rs @@ -2,6 +2,7 @@ use ark_ec::{AffineRepr, Group}; use ark_ff::{Field, One, PrimeField, Zero}; +use itertools::Itertools; use rand::thread_rng; use kimchi::{ @@ -155,8 +156,14 @@ where fr_sponge.absorb(zeta_eval); fr_sponge.absorb(zeta_omega_eval); } - fr_sponge.absorb("ient_evaluations.zeta); - fr_sponge.absorb("ient_evaluations.zeta_omega); + for (quotient_zeta_eval, quotient_zeta_omega_eval) in quotient_evaluations + .zeta + .iter() + .zip(quotient_evaluations.zeta_omega.iter()) + { + fr_sponge.absorb(quotient_zeta_eval); + fr_sponge.absorb(quotient_zeta_omega_eval); + } // FIXME: use a proper Challenge structure let challenges = BerkeleyChallenges { @@ -220,8 +227,8 @@ where evaluations.push(Evaluation { commitment: proof.quotient_commitment.clone(), evaluations: vec![ - vec![quotient_evaluations.zeta], - vec![quotient_evaluations.zeta_omega], + quotient_evaluations.zeta.clone(), + quotient_evaluations.zeta_omega.clone(), ], }); evaluations @@ -249,7 +256,14 @@ where let group_map = G::Map::setup(); // Check the actual quotient works. - (quotient_evaluations.zeta - == numerator_zeta / (zeta.pow([domain.d1.size]) - G::ScalarField::one())) + let (quotient_zeta, _) = quotient_evaluations.zeta.iter().fold( + (G::ScalarField::zero(), G::ScalarField::one()), + |(res, zeta_i_n), chunk| { + let res = res + zeta_i_n * chunk; + let zeta_i_n = zeta_i_n * zeta.pow([domain.d1.size]); + (res, zeta_i_n) + }, + ); + (quotient_zeta == numerator_zeta / (zeta.pow([domain.d1.size]) - G::ScalarField::one())) && OpeningProof::verify(srs, &group_map, &mut [batch], &mut thread_rng()) }