diff --git a/crates/proof-of-sql/src/proof_primitive/sumcheck/mod.rs b/crates/proof-of-sql/src/proof_primitive/sumcheck/mod.rs index 36de38a5f..8a171629b 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/mod.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/mod.rs @@ -4,7 +4,7 @@ mod proof_test; pub use proof::SumcheckProof; mod prover_state; -use prover_state::ProverState; +pub(crate) use prover_state::ProverState; mod prover_round; use prover_round::prove_round; diff --git a/crates/proof-of-sql/src/proof_primitive/sumcheck/proof.rs b/crates/proof-of-sql/src/proof_primitive/sumcheck/proof.rs index 3d90095bf..45d92c601 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/proof.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/proof.rs @@ -1,6 +1,6 @@ use crate::{ base::{ - polynomial::{interpolate_evaluations_to_reverse_coefficients, CompositePolynomial}, + polynomial::interpolate_evaluations_to_reverse_coefficients, proof::{ProofError, Transcript}, scalar::Scalar, }, @@ -28,19 +28,15 @@ impl SumcheckProof { pub fn create( transcript: &mut impl Transcript, evaluation_point: &mut [S], - polynomial: &CompositePolynomial, + mut state: ProverState, ) -> Self { - assert_eq!(evaluation_point.len(), polynomial.num_variables); - transcript.extend_as_be([ - polynomial.max_multiplicands as u64, - polynomial.num_variables as u64, - ]); + assert_eq!(evaluation_point.len(), state.num_vars); + transcript.extend_as_be([state.max_multiplicands as u64, state.num_vars as u64]); // This challenge is in order to keep transcript messages grouped. (This simplifies the Solidity implementation.) transcript.scalar_challenge_as_be::(); let mut r = None; - let mut state = ProverState::create(polynomial); - let mut coefficients = Vec::with_capacity(polynomial.num_variables); - for scalar in evaluation_point.iter_mut().take(polynomial.num_variables) { + let mut coefficients = Vec::with_capacity(state.num_vars); + for scalar in evaluation_point.iter_mut().take(state.num_vars) { let round_evaluations = prove_round(&mut state, &r); let round_coefficients = interpolate_evaluations_to_reverse_coefficients(&round_evaluations); diff --git a/crates/proof-of-sql/src/proof_primitive/sumcheck/proof_test.rs b/crates/proof-of-sql/src/proof_primitive/sumcheck/proof_test.rs index 1c0e03997..cebdc79b0 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/proof_test.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/proof_test.rs @@ -1,15 +1,17 @@ -use super::test_cases::sumcheck_test_cases; -use crate::base::{ - polynomial::CompositePolynomial, - proof::Transcript as _, - scalar::{test_scalar::TestScalar, Curve25519Scalar, MontScalar, Scalar}, -}; /* * Adopted from arkworks * * See third_party/license/arkworks.LICENSE */ -use crate::proof_primitive::sumcheck::proof::*; +use super::test_cases::sumcheck_test_cases; +use crate::{ + base::{ + polynomial::CompositePolynomial, + proof::Transcript as _, + scalar::{test_scalar::TestScalar, Curve25519Scalar, MontScalar, Scalar}, + }, + proof_primitive::sumcheck::{ProverState, SumcheckProof}, +}; use alloc::rc::Rc; use ark_std::UniformRand; use merlin::Transcript; @@ -29,7 +31,11 @@ fn test_create_verify_proof() { let fa = Rc::new(a_vec.to_vec()); poly.add_product([fa], Curve25519Scalar::from(1u64)); let mut transcript = Transcript::new(b"sumchecktest"); - let mut proof = SumcheckProof::create(&mut transcript, &mut evaluation_point, &poly); + let mut proof = SumcheckProof::create( + &mut transcript, + &mut evaluation_point, + ProverState::create(&poly), + ); // verify proof let mut transcript = Transcript::new(b"sumchecktest"); @@ -133,7 +139,11 @@ fn test_polynomial(nv: usize, num_multiplicands_range: (usize, usize), num_produ // create a proof let mut transcript = Transcript::new(b"sumchecktest"); let mut evaluation_point = vec![Curve25519Scalar::zero(); poly.num_variables]; - let proof = SumcheckProof::create(&mut transcript, &mut evaluation_point, &poly); + let proof = SumcheckProof::create( + &mut transcript, + &mut evaluation_point, + ProverState::create(&poly), + ); // verify proof let mut transcript = Transcript::new(b"sumchecktest"); @@ -180,7 +190,7 @@ fn we_can_verify_many_random_test_cases() { let proof = SumcheckProof::create( &mut transcript, &mut evaluation_point, - &test_case.polynomial, + ProverState::create(&test_case.polynomial), ); let mut transcript = Transcript::new(b"sumchecktest"); diff --git a/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_round.rs b/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_round.rs index 9ceb42b00..60c29d1aa 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_round.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_round.rs @@ -19,20 +19,13 @@ pub fn prove_round(prover_state: &mut ProverState, r_maybe: &Optio "first round should be prover first." ); - prover_state.randomness.push(*r); - // fix argument - let r_as_field = prover_state.randomness[prover_state.round - 1]; if_rayon!( prover_state.flattened_ml_extensions.par_iter_mut(), prover_state.flattened_ml_extensions.iter_mut() ) .for_each(|multiplicand| { - in_place_fix_variable( - multiplicand, - r_as_field, - prover_state.num_vars - prover_state.round, - ); + in_place_fix_variable(multiplicand, *r, prover_state.num_vars - prover_state.round); }); } else if prover_state.round > 0 { panic!("verifier message is empty"); diff --git a/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_state.rs b/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_state.rs index 44138378c..af3544c39 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_state.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/prover_state.rs @@ -8,8 +8,6 @@ use crate::base::scalar::Scalar; use alloc::vec::Vec; pub struct ProverState { - /// sampled randomness given by the verifier - pub randomness: Vec, /// Stores the list of products that is meant to be added together. Each multiplicand is represented by /// the index in `flattened_ml_extensions` pub list_of_products: Vec<(S, Vec)>, @@ -21,6 +19,21 @@ pub struct ProverState { } impl ProverState { + pub fn new( + list_of_products: Vec<(S, Vec)>, + flattened_ml_extensions: Vec>, + num_vars: usize, + max_multiplicands: usize, + ) -> Self { + ProverState { + list_of_products, + flattened_ml_extensions, + num_vars, + max_multiplicands, + round: 0, + } + } + #[tracing::instrument(name = "ProverState::create", level = "debug", skip_all)] pub fn create(polynomial: &CompositePolynomial) -> Self { assert!( @@ -35,13 +48,11 @@ impl ProverState { .map(|x| x.as_ref().clone()) .collect(); - ProverState { - randomness: Vec::with_capacity(polynomial.num_variables), - list_of_products: polynomial.products.clone(), + ProverState::new( + polynomial.products.clone(), flattened_ml_extensions, - num_vars: polynomial.num_variables, - max_multiplicands: polynomial.max_multiplicands, - round: 0, - } + polynomial.num_variables, + polynomial.max_multiplicands, + ) } } diff --git a/crates/proof-of-sql/src/sql/proof/final_round_builder.rs b/crates/proof-of-sql/src/sql/proof/final_round_builder.rs index 85f973256..1ce16dbd6 100644 --- a/crates/proof-of-sql/src/sql/proof/final_round_builder.rs +++ b/crates/proof-of-sql/src/sql/proof/final_round_builder.rs @@ -1,11 +1,8 @@ -use super::{ - CompositePolynomialBuilder, SumcheckRandomScalars, SumcheckSubpolynomial, - SumcheckSubpolynomialTerm, SumcheckSubpolynomialType, -}; +use super::{SumcheckSubpolynomial, SumcheckSubpolynomialTerm, SumcheckSubpolynomialType}; use crate::base::{ bit::BitDistribution, commitment::{Commitment, CommittableColumn, VecCommitmentExt}, - polynomial::{CompositePolynomial, MultilinearExtension}, + polynomial::MultilinearExtension, scalar::Scalar, }; use alloc::{boxed::Box, vec::Vec}; @@ -105,29 +102,10 @@ impl<'a, S: Scalar> FinalRoundBuilder<'a, S> { ) } - /// Given random multipliers, construct an aggregatated sumcheck polynomial from all - /// the individual subpolynomials. - #[tracing::instrument( - name = "FinalRoundBuilder::make_sumcheck_polynomial", - level = "debug", - skip_all - )] - pub fn make_sumcheck_polynomial( - &self, - scalars: &SumcheckRandomScalars, - ) -> CompositePolynomial { - let mut builder = CompositePolynomialBuilder::new( - self.num_sumcheck_variables, - &scalars.compute_entrywise_multipliers(), - ); - for (multiplier, subpoly) in scalars - .subpolynomial_multipliers - .iter() - .zip(self.sumcheck_subpolynomials.iter()) - { - subpoly.compose(&mut builder, *multiplier); - } - builder.make_composite_polynomial() + /// Produce a subpolynomial to be aggegated into sumcheck where the sum across binary + /// values of the variables is zero. + pub fn sumcheck_subpolynomials(&self) -> &[SumcheckSubpolynomial<'a, S>] { + &self.sumcheck_subpolynomials } /// Given the evaluation vector, compute evaluations of all the MLEs used in sumcheck except diff --git a/crates/proof-of-sql/src/sql/proof/final_round_builder_test.rs b/crates/proof-of-sql/src/sql/proof/final_round_builder_test.rs index 81c24fade..b1e8b9d2e 100644 --- a/crates/proof-of-sql/src/sql/proof/final_round_builder_test.rs +++ b/crates/proof-of-sql/src/sql/proof/final_round_builder_test.rs @@ -1,12 +1,8 @@ -use super::{FinalRoundBuilder, ProvableQueryResult, SumcheckRandomScalars}; -use crate::{ - base::{ - commitment::{Commitment, CommittableColumn}, - database::{Column, ColumnField, ColumnType}, - polynomial::{compute_evaluation_vector, CompositePolynomial, MultilinearExtension}, - scalar::Curve25519Scalar, - }, - sql::proof::SumcheckSubpolynomialType, +use super::{FinalRoundBuilder, ProvableQueryResult}; +use crate::base::{ + commitment::{Commitment, CommittableColumn}, + database::{Column, ColumnField, ColumnType}, + scalar::Curve25519Scalar, }; use alloc::sync::Arc; #[cfg(feature = "arrow")] @@ -16,7 +12,6 @@ use arrow::{ record_batch::RecordBatch, }; use curve25519_dalek::RistrettoPoint; -use num_traits::{One, Zero}; #[test] fn we_can_compute_commitments_for_intermediate_mles_using_a_zero_offset() { @@ -75,64 +70,6 @@ fn we_can_evaluate_pcs_proof_mles() { assert_eq!(evals, expected_evals); } -#[test] -fn we_can_form_an_aggregated_sumcheck_polynomial() { - let mle1 = [1, 2, -1]; - let mle2 = [10i64, 20, 100, 30]; - let mle3 = [2000i64, 3000, 5000, 7000]; - let mut builder = FinalRoundBuilder::new(2, Vec::new()); - builder.produce_anchored_mle(&mle1); - builder.produce_intermediate_mle(&mle2[..]); - builder.produce_intermediate_mle(&mle3[..]); - - builder.produce_sumcheck_subpolynomial( - SumcheckSubpolynomialType::Identity, - vec![(-Curve25519Scalar::one(), vec![Box::new(&mle1)])], - ); - builder.produce_sumcheck_subpolynomial( - SumcheckSubpolynomialType::Identity, - vec![(-Curve25519Scalar::from(10u64), vec![Box::new(&mle2)])], - ); - builder.produce_sumcheck_subpolynomial( - SumcheckSubpolynomialType::ZeroSum, - vec![(Curve25519Scalar::from(9876u64), vec![Box::new(&mle3)])], - ); - - let multipliers = [ - Curve25519Scalar::from(5u64), - Curve25519Scalar::from(2u64), - Curve25519Scalar::from(50u64), - Curve25519Scalar::from(25u64), - Curve25519Scalar::from(11u64), - ]; - - let mut evaluation_vector = vec![Zero::zero(); 4]; - compute_evaluation_vector(&mut evaluation_vector, &multipliers[..2]); - - let poly = builder.make_sumcheck_polynomial(&SumcheckRandomScalars::new(&multipliers, 4, 2)); - let mut expected_poly = CompositePolynomial::new(2); - let fr = (&evaluation_vector).to_sumcheck_term(2); - expected_poly.add_product( - [fr.clone(), (&mle1).to_sumcheck_term(2)], - -Curve25519Scalar::from(1u64) * multipliers[2], - ); - expected_poly.add_product( - [fr, (&mle2).to_sumcheck_term(2)], - -Curve25519Scalar::from(10u64) * multipliers[3], - ); - expected_poly.add_product( - [(&mle3).to_sumcheck_term(2)], - Curve25519Scalar::from(9876u64) * multipliers[4], - ); - let random_point = [ - Curve25519Scalar::from(123u64), - Curve25519Scalar::from(101_112_u64), - ]; - let eval = poly.evaluate(&random_point); - let expected_eval = expected_poly.evaluate(&random_point); - assert_eq!(eval, expected_eval); -} - #[cfg(feature = "arrow")] #[test] fn we_can_form_the_provable_query_result() { diff --git a/crates/proof-of-sql/src/sql/proof/make_sumcheck_state.rs b/crates/proof-of-sql/src/sql/proof/make_sumcheck_state.rs new file mode 100644 index 000000000..b07ded361 --- /dev/null +++ b/crates/proof-of-sql/src/sql/proof/make_sumcheck_state.rs @@ -0,0 +1,107 @@ +use super::{CompositePolynomialBuilder, SumcheckRandomScalars, SumcheckSubpolynomial}; +use crate::{ + base::{polynomial::CompositePolynomial, scalar::Scalar}, + proof_primitive::sumcheck::ProverState, +}; + +pub fn make_sumcheck_prover_state( + subpolynomials: &[SumcheckSubpolynomial<'_, S>], + num_vars: usize, + scalars: &SumcheckRandomScalars, +) -> ProverState { + ProverState::create(&make_sumcheck_polynomial(subpolynomials, num_vars, scalars)) +} + +/// Given random multipliers, construct an aggregatated sumcheck polynomial from all +/// the individual subpolynomials. +#[tracing::instrument(name = "proof::make_sumcheck_polynomial", level = "debug", skip_all)] +fn make_sumcheck_polynomial( + subpolynomials: &[SumcheckSubpolynomial<'_, S>], + num_vars: usize, + scalars: &SumcheckRandomScalars, +) -> CompositePolynomial { + let mut builder = + CompositePolynomialBuilder::new(num_vars, &scalars.compute_entrywise_multipliers()); + for (multiplier, subpoly) in scalars + .subpolynomial_multipliers + .iter() + .zip(subpolynomials.iter()) + { + subpoly.compose(&mut builder, *multiplier); + } + builder.make_composite_polynomial() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + base::{ + polynomial::{compute_evaluation_vector, CompositePolynomial, MultilinearExtension}, + scalar::Curve25519Scalar, + }, + sql::proof::SumcheckSubpolynomialType, + }; + use alloc::boxed::Box; + use num_traits::{One, Zero}; + + #[test] + fn we_can_form_an_aggregated_sumcheck_polynomial() { + let mle1 = [1, 2, -1]; + let mle2 = [10i64, 20, 100, 30]; + let mle3 = [2000i64, 3000, 5000, 7000]; + + let subpolynomials = &[ + SumcheckSubpolynomial::new( + SumcheckSubpolynomialType::Identity, + vec![(-Curve25519Scalar::one(), vec![Box::new(&mle1)])], + ), + SumcheckSubpolynomial::new( + SumcheckSubpolynomialType::Identity, + vec![(-Curve25519Scalar::from(10u64), vec![Box::new(&mle2)])], + ), + SumcheckSubpolynomial::new( + SumcheckSubpolynomialType::ZeroSum, + vec![(Curve25519Scalar::from(9876u64), vec![Box::new(&mle3)])], + ), + ]; + + let multipliers = [ + Curve25519Scalar::from(5u64), + Curve25519Scalar::from(2u64), + Curve25519Scalar::from(50u64), + Curve25519Scalar::from(25u64), + Curve25519Scalar::from(11u64), + ]; + + let mut evaluation_vector = vec![Zero::zero(); 4]; + compute_evaluation_vector(&mut evaluation_vector, &multipliers[..2]); + + let poly = make_sumcheck_polynomial( + subpolynomials, + 2, + &SumcheckRandomScalars::new(&multipliers, 4, 2), + ); + let mut expected_poly = CompositePolynomial::new(2); + let fr = (&evaluation_vector).to_sumcheck_term(2); + expected_poly.add_product( + [fr.clone(), (&mle1).to_sumcheck_term(2)], + -Curve25519Scalar::from(1u64) * multipliers[2], + ); + expected_poly.add_product( + [fr, (&mle2).to_sumcheck_term(2)], + -Curve25519Scalar::from(10u64) * multipliers[3], + ); + expected_poly.add_product( + [(&mle3).to_sumcheck_term(2)], + Curve25519Scalar::from(9876u64) * multipliers[4], + ); + let random_point = [ + Curve25519Scalar::from(123u64), + Curve25519Scalar::from(101_112_u64), + ]; + let eval = poly.evaluate(&random_point); + let expected_eval = expected_poly.evaluate(&random_point); + assert_eq!(eval, expected_eval); + } +} diff --git a/crates/proof-of-sql/src/sql/proof/mod.rs b/crates/proof-of-sql/src/sql/proof/mod.rs index 8e191e1f7..f31e456ee 100644 --- a/crates/proof-of-sql/src/sql/proof/mod.rs +++ b/crates/proof-of-sql/src/sql/proof/mod.rs @@ -71,3 +71,5 @@ pub(crate) use first_round_builder::FirstRoundBuilder; #[cfg(all(test, feature = "arrow"))] mod provable_query_result_test; + +mod make_sumcheck_state; diff --git a/crates/proof-of-sql/src/sql/proof/query_proof.rs b/crates/proof-of-sql/src/sql/proof/query_proof.rs index 77bf6a37d..27d882ba7 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -1,5 +1,6 @@ use super::{ - CountBuilder, FinalRoundBuilder, ProofCounts, ProofPlan, QueryResult, SumcheckMleEvaluations, + make_sumcheck_state::make_sumcheck_prover_state, CountBuilder, FinalRoundBuilder, + FirstRoundBuilder, ProofCounts, ProofPlan, QueryData, QueryResult, SumcheckMleEvaluations, SumcheckRandomScalars, VerificationBuilder, }; use crate::{ @@ -17,7 +18,6 @@ use crate::{ scalar::Scalar, }, proof_primitive::sumcheck::SumcheckProof, - sql::proof::{FirstRoundBuilder, QueryData}, }; use alloc::{string::String, vec, vec::Vec}; use bumpalo::Bump; @@ -156,15 +156,15 @@ impl QueryProof { core::iter::repeat_with(|| transcript.scalar_challenge_as_be()) .take(num_random_scalars) .collect(); - let poly = builder.make_sumcheck_polynomial(&SumcheckRandomScalars::new( - &random_scalars, - range_length, + let state = make_sumcheck_prover_state( + builder.sumcheck_subpolynomials(), num_sumcheck_variables, - )); + &SumcheckRandomScalars::new(&random_scalars, range_length, num_sumcheck_variables), + ); // create the sumcheck proof -- this is the main part of proving a query - let mut evaluation_point = vec![Zero::zero(); poly.num_variables]; - let sumcheck_proof = SumcheckProof::create(&mut transcript, &mut evaluation_point, &poly); + let mut evaluation_point = vec![Zero::zero(); state.num_vars]; + let sumcheck_proof = SumcheckProof::create(&mut transcript, &mut evaluation_point, state); // evaluate the MLEs used in sumcheck except for the result columns let mut evaluation_vec = vec![Zero::zero(); range_length]; diff --git a/crates/proof-of-sql/src/sql/proof/query_proof_test.rs b/crates/proof-of-sql/src/sql/proof/query_proof_test.rs index 6ee0eccac..72d38e22d 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof_test.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof_test.rs @@ -89,7 +89,7 @@ impl ProofPlan for TrivialTestProofPlan { ) -> Result, ProofError> { assert_eq!(builder.consume_intermediate_mle(), S::ZERO); builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::ZeroSum, + SumcheckSubpolynomialType::ZeroSum, S::from(self.evaluation), ); Ok(TableEvaluation::new( @@ -280,7 +280,7 @@ impl ProofPlan for SquareTestProofPlan { .unwrap(); let res_eval = builder.consume_intermediate_mle(); builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, res_eval - x_eval * x_eval, ); Ok(TableEvaluation::new( @@ -479,13 +479,13 @@ impl ProofPlan for DoubleSquareTestProofPlan { // poly1 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, z_eval - x_eval * x_eval, ); // poly2 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, res_eval - z_eval * z_eval, ); Ok(TableEvaluation::new( @@ -683,7 +683,7 @@ impl ProofPlan for ChallengeTestProofPlan { .unwrap(); let res_eval = builder.consume_intermediate_mle(); builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, alpha * res_eval - alpha * x_eval * x_eval, ); Ok(TableEvaluation::new( diff --git a/crates/proof-of-sql/src/sql/proof/sumcheck_subpolynomial.rs b/crates/proof-of-sql/src/sql/proof/sumcheck_subpolynomial.rs index 110389c5e..1a9437fa3 100644 --- a/crates/proof-of-sql/src/sql/proof/sumcheck_subpolynomial.rs +++ b/crates/proof-of-sql/src/sql/proof/sumcheck_subpolynomial.rs @@ -3,6 +3,7 @@ use crate::base::{polynomial::MultilinearExtension, scalar::Scalar}; use alloc::{boxed::Box, vec::Vec}; /// The type of a sumcheck subpolynomial +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum SumcheckSubpolynomialType { /// The subpolynomial should be zero at every entry/row Identity, @@ -55,4 +56,72 @@ impl<'a, S: Scalar> SumcheckSubpolynomial<'a, S> { } } } + + #[allow(dead_code)] + pub(crate) fn subpolynomial_type(&self) -> SumcheckSubpolynomialType { + self.subpolynomial_type + } + + /// Returns an iterator over the terms of the subpolynomial, where each term's + /// coefficient is multiplied by the given multiplier. + /// + /// # Arguments + /// + /// * `multiplier` - The scalar value to multiply each term's coefficient by. + /// + /// # Returns + /// + /// An iterator that yields tuples containing the subpolynomial type, the + /// multiplied coefficient, and a slice of multilinear extensions. + #[allow(dead_code)] + pub(crate) fn iter_mul_by( + &self, + multiplier: S, + ) -> impl Iterator< + Item = ( + SumcheckSubpolynomialType, + S, + &[Box + 'a>], + ), + > { + self.terms.iter().map(move |(coeff, multiplicands)| { + ( + self.subpolynomial_type, + multiplier * *coeff, + multiplicands.as_slice(), + ) + }) + } +} + +#[cfg(test)] +mod tests { + use super::{SumcheckSubpolynomial, SumcheckSubpolynomialTerm, SumcheckSubpolynomialType}; + use crate::base::scalar::test_scalar::TestScalar; + use alloc::boxed::Box; + + #[test] + fn test_iter_mul_by() { + let mle1 = vec![TestScalar::from(1), TestScalar::from(2)]; + let mle2 = vec![TestScalar::from(3), TestScalar::from(4)]; + + let terms: Vec> = vec![ + (TestScalar::from(2), vec![Box::new(&mle1)]), + (TestScalar::from(3), vec![Box::new(&mle2)]), + ]; + let subpoly = SumcheckSubpolynomial::new(SumcheckSubpolynomialType::Identity, terms); + + let multiplier = TestScalar::from(5); + let mut iter = subpoly.iter_mul_by(multiplier); + + let (subpoly_type, coeff, _extensions) = iter.next().unwrap(); + assert_eq!(subpoly_type, SumcheckSubpolynomialType::Identity); + assert_eq!(coeff, TestScalar::from(10)); + + let (subpoly_type, coeff, _extensions) = iter.next().unwrap(); + assert_eq!(subpoly_type, SumcheckSubpolynomialType::Identity); + assert_eq!(coeff, TestScalar::from(15)); + + assert!(iter.next().is_none()); + } } diff --git a/crates/proof-of-sql/src/sql/proof/verification_builder.rs b/crates/proof-of-sql/src/sql/proof/verification_builder.rs index 7385bf353..bc0743167 100644 --- a/crates/proof-of-sql/src/sql/proof/verification_builder.rs +++ b/crates/proof-of-sql/src/sql/proof/verification_builder.rs @@ -111,7 +111,7 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { /// Produce the evaluation of a subpolynomial used in sumcheck pub fn produce_sumcheck_subpolynomial_evaluation( &mut self, - subpolynomial_type: &SumcheckSubpolynomialType, + subpolynomial_type: SumcheckSubpolynomialType, eval: S, ) { self.sumcheck_evaluation += self.subpolynomial_multipliers[self.produced_subpolynomials] diff --git a/crates/proof-of-sql/src/sql/proof/verification_builder_test.rs b/crates/proof-of-sql/src/sql/proof/verification_builder_test.rs index ba71c2087..647294312 100644 --- a/crates/proof-of-sql/src/sql/proof/verification_builder_test.rs +++ b/crates/proof-of-sql/src/sql/proof/verification_builder_test.rs @@ -41,11 +41,11 @@ fn we_build_up_a_sumcheck_polynomial_evaluation_from_subpolynomial_evaluations() Vec::new(), ); builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::ZeroSum, + SumcheckSubpolynomialType::ZeroSum, Curve25519Scalar::from(2u64), ); builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::ZeroSum, + SumcheckSubpolynomialType::ZeroSum, Curve25519Scalar::from(3u64), ); let expected_sumcheck_evaluation = subpolynomial_multipliers[0] * Curve25519Scalar::from(2u64) diff --git a/crates/proof-of-sql/src/sql/proof_exprs/and_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/and_expr.rs index 6cd6dcdcb..8f496a216 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/and_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/and_expr.rs @@ -96,7 +96,7 @@ impl ProofExpr for AndExpr { // subpolynomial: lhs_and_rhs - lhs * rhs builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, lhs_and_rhs - lhs * rhs, ); diff --git a/crates/proof-of-sql/src/sql/proof_exprs/equals_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/equals_expr.rs index c3ee789e9..aded010c8 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/equals_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/equals_expr.rs @@ -160,13 +160,13 @@ pub fn verifier_evaluate_equals_zero( // subpolynomial: selection * lhs builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, selection_eval * lhs_eval, ); // subpolynomial: selection_not - lhs * lhs_pseudo_inv builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, selection_not_eval - lhs_eval * lhs_pseudo_inv_eval, ); diff --git a/crates/proof-of-sql/src/sql/proof_exprs/multiply_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/multiply_expr.rs index f4af9209e..1b1c203db 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/multiply_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/multiply_expr.rs @@ -98,7 +98,7 @@ impl ProofExpr for MultiplyExpr { // subpolynomial: lhs_times_rhs - lhs * rhs builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, lhs_times_rhs - lhs * rhs, ); diff --git a/crates/proof-of-sql/src/sql/proof_exprs/or_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/or_expr.rs index 5e25866ce..fb6d27a3b 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/or_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/or_expr.rs @@ -138,7 +138,7 @@ pub fn verifier_evaluate_or( // subpolynomial: lhs_and_rhs - lhs * rhs builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, lhs_and_rhs - *lhs * *rhs, ); diff --git a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr.rs index 0ffccaa84..a8322652b 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr.rs @@ -191,7 +191,7 @@ fn prove_bits_are_binary<'a, S: Scalar>( fn verify_bits_are_binary(builder: &mut VerificationBuilder, bit_evals: &[S]) { for bit_eval in bit_evals { builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, *bit_eval - *bit_eval * *bit_eval, ); } @@ -257,5 +257,5 @@ fn verify_bit_decomposition( eval -= S::from(mult) * sign_eval * bit_eval; vary_index += 1; }); - builder.produce_sumcheck_subpolynomial_evaluation(&SumcheckSubpolynomialType::Identity, eval); + builder.produce_sumcheck_subpolynomial_evaluation(SumcheckSubpolynomialType::Identity, eval); } diff --git a/crates/proof-of-sql/src/sql/proof_plans/filter_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/filter_exec.rs index 5872564fe..5d2ea8332 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/filter_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/filter_exec.rs @@ -267,19 +267,19 @@ pub(super) fn verify_filter( // sum c_star * s - d_star = 0 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::ZeroSum, + SumcheckSubpolynomialType::ZeroSum, c_star_eval * s_eval - d_star_eval, ); // c_fold * c_star - input_ones = 0 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, c_fold_eval * c_star_eval - one_eval, ); // d_bar_fold * d_star - chi = 0 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, d_bar_fold_eval * d_star_eval - chi_eval, ); diff --git a/crates/proof-of-sql/src/sql/proof_plans/group_by_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/group_by_exec.rs index 2ac025ff6..2d8fb8d90 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/group_by_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/group_by_exec.rs @@ -361,19 +361,19 @@ fn verify_group_by( // sum g_in_star * sel_in * sum_in_fold - g_out_star * sum_out_bar_fold = 0 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::ZeroSum, + SumcheckSubpolynomialType::ZeroSum, g_in_star_eval * sel_in_eval * sum_in_fold_eval - g_out_star_eval * sum_out_bar_fold_eval, ); // g_in_star * g_in_fold - input_ones = 0 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, g_in_star_eval * g_in_fold_eval - one_eval, ); // g_out_star * g_out_bar_fold - input_ones = 0 builder.produce_sumcheck_subpolynomial_evaluation( - &SumcheckSubpolynomialType::Identity, + SumcheckSubpolynomialType::Identity, g_out_star_eval * g_out_bar_fold_eval - one_eval, );