From e886b6f133a294b0768271e9756872a7093ffc4a Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 24 Sep 2024 23:12:10 +0200 Subject: [PATCH 1/4] o1vm/pickles: define column_env.rs This is used to evaluate the quotient polynomial. --- o1vm/src/pickles/column_env.rs | 102 +++++++++++++++++++++++++++++++++ o1vm/src/pickles/mod.rs | 1 + 2 files changed, 103 insertions(+) create mode 100644 o1vm/src/pickles/column_env.rs diff --git a/o1vm/src/pickles/column_env.rs b/o1vm/src/pickles/column_env.rs new file mode 100644 index 0000000000..d2a44e5723 --- /dev/null +++ b/o1vm/src/pickles/column_env.rs @@ -0,0 +1,102 @@ +use ark_ff::FftField; +use ark_poly::{Evaluations, Radix2EvaluationDomain}; + +use crate::interpreters::mips::witness::SCRATCH_SIZE; +use kimchi::circuits::{ + domains::EvaluationDomains, + expr::{ + BerkeleyChallengeTerm, BerkeleyChallenges, ColumnEnvironment as TColumnEnvironment, + Constants, Domain, + }, +}; + +use super::proof::WitnessColumns; + +/// The collection of polynomials (all in evaluation form) and constants +/// required to evaluate an expression as a polynomial. +/// +/// All are evaluations. +pub struct ColumnEnvironment<'a, F: FftField> { + /// The witness column polynomials. Includes relation columns and dynamic + /// selector columns. + pub witness: &'a WitnessColumns>>, + /// The value `prod_{j != 1} (1 - ω^j)`, used for efficiently + /// computing the evaluations of the unnormalized Lagrange basis + /// polynomials. + pub l0_1: F, + /// Constant values required + pub constants: Constants, + /// Challenges from the IOP. + // FIXME: change for other challenges + pub challenges: BerkeleyChallenges, + /// The domains used in the PLONK argument. + pub domain: EvaluationDomains, +} + +impl<'a, F: FftField> TColumnEnvironment<'a, F, BerkeleyChallengeTerm, BerkeleyChallenges> + for ColumnEnvironment<'a, F> +{ + // FIXME: do we change to the MIPS column type? + // We do not want to keep kimchi_msm/generic prover + type Column = kimchi_msm::columns::Column; + + fn get_column( + &self, + col: &Self::Column, + ) -> Option<&'a Evaluations>> { + match *col { + Self::Column::Relation(i) => { + if i < SCRATCH_SIZE { + let res = &self.witness.scratch[i]; + Some(res) + } else if i == SCRATCH_SIZE { + let res = &self.witness.instruction_counter; + Some(res) + } else if i == SCRATCH_SIZE + 1 { + let res = &self.witness.error; + Some(res) + } else { + panic!("We should not have that many relation columns"); + } + } + Self::Column::DynamicSelector(_i) => { + // FIXME: add selectors + panic!("Not implemented yet"); + } + _ => { + panic!("We should not have any other type of columns") + } + } + } + + fn get_domain(&self, d: Domain) -> Radix2EvaluationDomain { + match d { + Domain::D1 => self.domain.d1, + Domain::D2 => self.domain.d2, + Domain::D4 => self.domain.d4, + Domain::D8 => self.domain.d8, + } + } + + fn column_domain(&self, _col: &Self::Column) -> Domain { + Domain::D8 + } + + fn get_constants(&self) -> &Constants { + &self.constants + } + + fn get_challenges(&self) -> &BerkeleyChallenges { + &self.challenges + } + + fn vanishes_on_zero_knowledge_and_previous_rows( + &self, + ) -> &'a Evaluations> { + panic!("Not supposed to be used in MIPS. We do not support zero-knowledge for now") + } + + fn l0_1(&self) -> F { + self.l0_1 + } +} diff --git a/o1vm/src/pickles/mod.rs b/o1vm/src/pickles/mod.rs index b7f7102655..701bd402ef 100644 --- a/o1vm/src/pickles/mod.rs +++ b/o1vm/src/pickles/mod.rs @@ -12,6 +12,7 @@ //! O1VM_FLAVOR=pickles bash run-code.sh //! ``` +pub mod column_env; pub mod proof; pub mod prover; From 80469c386f6bc094f08908678685ca72d5c225d8 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 3 Oct 2024 14:26:52 +0200 Subject: [PATCH 2/4] o1vm/pickles: pass the constraints to the prover Using a reference to avoid cloning at each call to the prover --- o1vm/src/pickles/main.rs | 15 ++++++++------- o1vm/src/pickles/prover.rs | 3 ++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/o1vm/src/pickles/main.rs b/o1vm/src/pickles/main.rs index 6c8d80c018..6ea4dcf2ff 100644 --- a/o1vm/src/pickles/main.rs +++ b/o1vm/src/pickles/main.rs @@ -79,7 +79,7 @@ pub fn main() -> ExitCode { mips_witness::Env::::create(cannon::PAGE_SIZE as usize, state, po); // TODO: give this to the prover + verifier - let _constraints = { + let constraints = { let mut mips_con_env = mips_constraints::Env::::default(); let mut constraints = Instruction::iter() .flat_map(|instr_typ| instr_typ.into_iter()) @@ -126,12 +126,13 @@ pub fn main() -> ExitCode { // FIXME let start_iteration = Instant::now(); debug!("Limit of {DOMAIN_SIZE} reached. We make a proof, verify it (for testing) and start with a new branch new chunk"); - let _proof: Proof = prover::prove::< - Vesta, - DefaultFqSponge, - DefaultFrSponge, - _, - >(domain_fp, &srs, curr_proof_inputs, &mut rng); + let _proof: Proof = + prover::prove::< + Vesta, + DefaultFqSponge, + DefaultFrSponge, + _, + >(domain_fp, &srs, curr_proof_inputs, &constraints, &mut rng); debug!( "Proof generated in {elapsed} μs", elapsed = start_iteration.elapsed().as_micros() diff --git a/o1vm/src/pickles/prover.rs b/o1vm/src/pickles/prover.rs index 238f469eb8..52b151986b 100644 --- a/o1vm/src/pickles/prover.rs +++ b/o1vm/src/pickles/prover.rs @@ -1,3 +1,4 @@ +use crate::E; use ark_ec::AffineRepr; use ark_ff::{PrimeField, Zero}; use ark_poly::{univariate::DensePolynomial, Evaluations, Polynomial, Radix2EvaluationDomain as D}; @@ -28,7 +29,6 @@ use super::proof::{Proof, ProofInputs, WitnessColumns}; /// /// The final proof consists of the opening proof, the commitments and the /// evaluations at ζ and ζω. -// FIXME: add constraints (come with the quotient polynomial) // TODO: we might need blinders when the evaluation of columns are zeroes. pub fn prove< G: KimchiCurve, @@ -39,6 +39,7 @@ pub fn prove< domain: EvaluationDomains, srs: &SRS, inputs: ProofInputs, + _constraints: &[E], rng: &mut RNG, ) -> Proof where From 893874792c068fec6d24af74a613f6a6fdb5e613 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 3 Oct 2024 14:36:59 +0200 Subject: [PATCH 3/4] o1vm/pickles: sketch usage of ColumnEnv in the prover We do still need to use a different structure for the challenges. Leaving it like this for now as it won't have any impact for now. --- o1vm/src/pickles/prover.rs | 46 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/o1vm/src/pickles/prover.rs b/o1vm/src/pickles/prover.rs index 52b151986b..eb584c1d90 100644 --- a/o1vm/src/pickles/prover.rs +++ b/o1vm/src/pickles/prover.rs @@ -1,9 +1,13 @@ -use crate::E; use ark_ec::AffineRepr; use ark_ff::{PrimeField, Zero}; use ark_poly::{univariate::DensePolynomial, Evaluations, Polynomial, Radix2EvaluationDomain as D}; use kimchi::{ - circuits::domains::EvaluationDomains, curve::KimchiCurve, groupmap::GroupMap, + circuits::{ + domains::EvaluationDomains, + expr::{l0_1, BerkeleyChallenges, Constants}, + }, + curve::KimchiCurve, + groupmap::GroupMap, plonk_sponge::FrSponge, }; use mina_poseidon::{sponge::ScalarChallenge, FqSponge}; @@ -15,7 +19,11 @@ use poly_commitment::{ use rand::{CryptoRng, RngCore}; use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator}; -use super::proof::{Proof, ProofInputs, WitnessColumns}; +use super::{ + column_env::ColumnEnvironment, + proof::{Proof, ProofInputs, WitnessColumns}, +}; +use crate::E; /// Make a PlonKish proof for the given circuit. As inputs, we get the execution /// trace consisting of evaluations of polynomials over a certain domain @@ -106,7 +114,7 @@ where // Based on the regression test // `test_regression_constraints_with_selectors`, the highest degree is 6. // Therefore, we do evaluate on d8. - let _evaluations_d8 = { + let evaluations_d8 = { let WitnessColumns { scratch, instruction_counter, @@ -139,6 +147,35 @@ where // Round 2: Creating and committing to the quotient polynomial //////////////////////////////////////////////////////////////////////////// + let (_, endo_r) = G::endos(); + + // Constraints combiner + let alpha: G::ScalarField = fq_sponge.challenge(); + + let zk_rows = 0; + let _column_env: ColumnEnvironment<'_, G::ScalarField> = { + // FIXME: use a proper Challenge structure + let challenges = BerkeleyChallenges { + alpha, + // No permutation argument for the moment + beta: G::ScalarField::zero(), + gamma: G::ScalarField::zero(), + // No lookup for the moment + joint_combiner: G::ScalarField::zero(), + }; + ColumnEnvironment { + constants: Constants { + endo_coefficient: *endo_r, + mds: &G::sponge_params().mds, + zk_rows, + }, + challenges, + witness: &evaluations_d8, + l0_1: l0_1(domain.d1), + domain, + } + }; + // FIXME: add quotient polynomial //////////////////////////////////////////////////////////////////////////// @@ -146,7 +183,6 @@ where //////////////////////////////////////////////////////////////////////////// let zeta_chal = ScalarChallenge(fq_sponge.challenge()); - let (_, endo_r) = G::endos(); let zeta = zeta_chal.to_field(endo_r); let zeta_omega = zeta * omega; From f9781afff8b27fb04fdb29ca3e073a2a044dc8ca Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 4 Oct 2024 17:22:22 +0200 Subject: [PATCH 4/4] o1vm/pickles: use new to build PolyComm Instead of building using the fields. --- o1vm/src/pickles/prover.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/o1vm/src/pickles/prover.rs b/o1vm/src/pickles/prover.rs index eb584c1d90..6266a3425d 100644 --- a/o1vm/src/pickles/prover.rs +++ b/o1vm/src/pickles/prover.rs @@ -246,9 +246,7 @@ where ( DensePolynomialOrEvaluations::DensePolynomial(poly), // We do not have any blinder, therefore we set to 0. - PolyComm { - elems: vec![G::ScalarField::zero()], - }, + PolyComm::new(vec![G::ScalarField::zero()]), ) }) .collect();