From 4594467ff481d348b8ac8e0af662236cc3c2dd77 Mon Sep 17 00:00:00 2001 From: Jay White Date: Tue, 10 Dec 2024 11:19:02 -0500 Subject: [PATCH 1/8] refactor: make `VerificationBuilder::produce_sumcheck_subpolynomial_evaluation` fallible This is fallible in two ways: 1) the degree is too big 2) there are not enough subpolynomial multipliers --- crates/proof-of-sql/src/base/proof/error.rs | 10 +++++++ crates/proof-of-sql/src/base/proof/mod.rs | 2 +- .../proof-of-sql/src/sql/proof/query_proof.rs | 1 + .../src/sql/proof/query_proof_test.rs | 27 +++++++++++-------- .../src/sql/proof/verification_builder.rs | 21 ++++++++++++--- .../sql/proof/verification_builder_test.rs | 25 +++++++++++------ .../src/sql/proof_exprs/and_expr.rs | 5 ++-- .../src/sql/proof_exprs/equals_expr.rs | 16 ++++++----- .../src/sql/proof_exprs/inequality_expr.rs | 4 +-- .../src/sql/proof_exprs/multiply_expr.rs | 5 ++-- .../src/sql/proof_exprs/or_expr.rs | 11 ++++---- .../src/sql/proof_exprs/sign_expr.rs | 24 ++++++++++++----- .../src/sql/proof_exprs/sign_expr_test.rs | 22 ++++++++++++--- .../src/sql/proof_plans/filter_exec.rs | 15 ++++++----- .../src/sql/proof_plans/group_by_exec.rs | 15 ++++++----- .../src/sql/proof_plans/union_exec.rs | 26 ++++++++++-------- 16 files changed, 153 insertions(+), 76 deletions(-) diff --git a/crates/proof-of-sql/src/base/proof/error.rs b/crates/proof-of-sql/src/base/proof/error.rs index c12e56fd8..054692c1d 100644 --- a/crates/proof-of-sql/src/base/proof/error.rs +++ b/crates/proof-of-sql/src/base/proof/error.rs @@ -18,4 +18,14 @@ pub enum ProofError { /// This error occurs when the number of fields in the result table does not match the query. #[snafu(display("Result does not match query: field count mismatch"))] FieldCountMismatch, + #[snafu(transparent)] + ProofSizeMismatch { source: ProofSizeMismatch }, +} + +#[derive(Snafu, Debug)] +/// These errors occur when the proof size does not match the expected size. +pub enum ProofSizeMismatch { + /// This error occurs when the sumcheck proof doesn't have enough coefficients. + #[snafu(display("Sumcheck proof is too small"))] + SumcheckProofTooSmall, } diff --git a/crates/proof-of-sql/src/base/proof/mod.rs b/crates/proof-of-sql/src/base/proof/mod.rs index 4c03150ca..3f2446aa9 100644 --- a/crates/proof-of-sql/src/base/proof/mod.rs +++ b/crates/proof-of-sql/src/base/proof/mod.rs @@ -1,7 +1,7 @@ //! Contains the transcript protocol used to construct a proof, //! as well as an error type which can occur when verification fails. mod error; -pub use error::ProofError; +pub use error::{ProofError, ProofSizeMismatch}; /// Contains an extension trait for `merlin::Transcript`, which is used to construct a proof. #[cfg(any(test, feature = "blitzar"))] 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 69532f9b2..8b7c6761d 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -331,6 +331,7 @@ impl QueryProof { sumcheck_random_scalars.subpolynomial_multipliers, post_result_challenges, self.one_evaluation_lengths.clone(), + core::cmp::max(counts.sumcheck_max_multiplicands, 2), ); let pcs_proof_commitments: Vec<_> = column_references 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 4cbe7f667..0bb5cfd65 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 @@ -88,10 +88,11 @@ impl ProofPlan for TrivialTestProofPlan { _one_eval_map: &IndexMap, ) -> Result, ProofError> { assert_eq!(builder.consume_mle_evaluation(), S::ZERO); - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::ZeroSum, S::from(self.evaluation), - ); + 1, + )?; Ok(TableEvaluation::new( vec![S::ZERO], builder.consume_one_evaluation(), @@ -279,10 +280,11 @@ impl ProofPlan for SquareTestProofPlan { )) .unwrap(); let res_eval = builder.consume_mle_evaluation(); - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, res_eval - x_eval * x_eval, - ); + 2, + )?; Ok(TableEvaluation::new( vec![res_eval], builder.consume_one_evaluation(), @@ -478,16 +480,18 @@ impl ProofPlan for DoubleSquareTestProofPlan { let res_eval = builder.consume_mle_evaluation(); // poly1 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, z_eval - x_eval * x_eval, - ); + 2, + )?; // poly2 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, res_eval - z_eval * z_eval, - ); + 2, + )?; Ok(TableEvaluation::new( vec![res_eval], builder.consume_one_evaluation(), @@ -659,7 +663,7 @@ impl ProverEvaluate for ChallengeTestProofPlan { } impl ProofPlan for ChallengeTestProofPlan { fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - builder.count_degree(3); + builder.count_degree(4); builder.count_intermediate_mles(1); builder.count_subpolynomials(1); builder.count_post_result_challenges(2); @@ -682,10 +686,11 @@ impl ProofPlan for ChallengeTestProofPlan { )) .unwrap(); let res_eval = builder.consume_mle_evaluation(); - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, alpha * res_eval - alpha * x_eval * x_eval, - ); + 2, + )?; Ok(TableEvaluation::new( vec![res_eval], builder.consume_one_evaluation(), 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 62c000a33..867756839 100644 --- a/crates/proof-of-sql/src/sql/proof/verification_builder.rs +++ b/crates/proof-of-sql/src/sql/proof/verification_builder.rs @@ -1,5 +1,5 @@ use super::{SumcheckMleEvaluations, SumcheckSubpolynomialType}; -use crate::base::{bit::BitDistribution, scalar::Scalar}; +use crate::base::{bit::BitDistribution, proof::ProofSizeMismatch, scalar::Scalar}; use alloc::vec::Vec; use core::iter; @@ -22,6 +22,7 @@ pub struct VerificationBuilder<'a, S: Scalar> { /// challenge is the last entry in the vector. post_result_challenges: Vec, one_evaluation_length_queue: Vec, + subpolynomial_max_multiplicands: usize, } impl<'a, S: Scalar> VerificationBuilder<'a, S> { @@ -36,6 +37,7 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { subpolynomial_multipliers: &'a [S], post_result_challenges: Vec, one_evaluation_length_queue: Vec, + subpolynomial_max_multiplicands: usize, ) -> Self { Self { mle_evaluations, @@ -48,6 +50,7 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { produced_subpolynomials: 0, post_result_challenges, one_evaluation_length_queue, + subpolynomial_max_multiplicands, } } @@ -95,19 +98,29 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { } /// Produce the evaluation of a subpolynomial used in sumcheck - pub fn produce_sumcheck_subpolynomial_evaluation( + pub fn try_produce_sumcheck_subpolynomial_evaluation( &mut self, subpolynomial_type: SumcheckSubpolynomialType, eval: S, - ) { + degree: usize, + ) -> Result<(), ProofSizeMismatch> { self.sumcheck_evaluation += self.subpolynomial_multipliers[self.produced_subpolynomials] * match subpolynomial_type { SumcheckSubpolynomialType::Identity => { + if degree + 1 > self.subpolynomial_max_multiplicands { + Err(ProofSizeMismatch::SumcheckProofTooSmall)?; + } eval * self.mle_evaluations.random_evaluation } - SumcheckSubpolynomialType::ZeroSum => eval, + SumcheckSubpolynomialType::ZeroSum => { + if degree > self.subpolynomial_max_multiplicands { + Err(ProofSizeMismatch::SumcheckProofTooSmall)?; + } + eval + } }; self.produced_subpolynomials += 1; + Ok(()) } #[allow( 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 a36fc2bcb..c1f6750f4 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 @@ -15,6 +15,7 @@ fn an_empty_sumcheck_polynomial_evaluates_to_zero() { &[][..], Vec::new(), Vec::new(), + 0, ); assert_eq!(builder.sumcheck_evaluation(), Curve25519Scalar::zero()); } @@ -36,15 +37,22 @@ fn we_build_up_a_sumcheck_polynomial_evaluation_from_subpolynomial_evaluations() &subpolynomial_multipliers, Vec::new(), Vec::new(), + 1, ); - builder.produce_sumcheck_subpolynomial_evaluation( - SumcheckSubpolynomialType::ZeroSum, - Curve25519Scalar::from(2u64), - ); - builder.produce_sumcheck_subpolynomial_evaluation( - SumcheckSubpolynomialType::ZeroSum, - Curve25519Scalar::from(3u64), - ); + builder + .try_produce_sumcheck_subpolynomial_evaluation( + SumcheckSubpolynomialType::ZeroSum, + Curve25519Scalar::from(2u64), + 1, + ) + .unwrap(); + builder + .try_produce_sumcheck_subpolynomial_evaluation( + SumcheckSubpolynomialType::ZeroSum, + Curve25519Scalar::from(3u64), + 1, + ) + .unwrap(); let expected_sumcheck_evaluation = subpolynomial_multipliers[0] * Curve25519Scalar::from(2u64) + subpolynomial_multipliers[1] * Curve25519Scalar::from(3u64); assert_eq!(builder.sumcheck_evaluation(), expected_sumcheck_evaluation); @@ -63,6 +71,7 @@ fn we_can_consume_post_result_challenges_in_proof_builder() { Curve25519Scalar::from(789), ], Vec::new(), + 0, ); assert_eq!( Curve25519Scalar::from(789), 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 3ef9c7972..25372b51d 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 @@ -95,10 +95,11 @@ impl ProofExpr for AndExpr { let lhs_and_rhs = builder.consume_mle_evaluation(); // subpolynomial: lhs_and_rhs - lhs * rhs - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, lhs_and_rhs - lhs * rhs, - ); + 2, + )?; // selection Ok(lhs_and_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 69841b550..7837605dc 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 @@ -86,7 +86,7 @@ impl ProofExpr for EqualsExpr { let lhs_scale = self.lhs.data_type().scale().unwrap_or(0); let rhs_scale = self.rhs.data_type().scale().unwrap_or(0); let res = scale_and_add_subtract_eval(lhs_eval, rhs_eval, lhs_scale, rhs_scale, true); - Ok(verifier_evaluate_equals_zero(builder, res, one_eval)) + verifier_evaluate_equals_zero(builder, res, one_eval) } fn get_column_references(&self, columns: &mut IndexSet) { @@ -152,25 +152,27 @@ pub fn verifier_evaluate_equals_zero( builder: &mut VerificationBuilder, lhs_eval: S, one_eval: S, -) -> S { +) -> Result { // consume mle evaluations let lhs_pseudo_inv_eval = builder.consume_mle_evaluation(); let selection_not_eval = builder.consume_mle_evaluation(); let selection_eval = one_eval - selection_not_eval; // subpolynomial: selection * lhs - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, selection_eval * lhs_eval, - ); + 2, + )?; // subpolynomial: selection_not - lhs * lhs_pseudo_inv - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, selection_not_eval - lhs_eval * lhs_pseudo_inv_eval, - ); + 2, + )?; - selection_eval + Ok(selection_eval) } pub fn count_equals_zero(builder: &mut CountBuilder) { diff --git a/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs index 4e463d0d4..48c397d5f 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs @@ -135,13 +135,13 @@ impl ProofExpr for InequalityExpr { }; // diff == 0 - let equals_zero = verifier_evaluate_equals_zero(builder, diff_eval, one_eval); + let equals_zero = verifier_evaluate_equals_zero(builder, diff_eval, one_eval)?; // sign(diff) == -1 let sign = verifier_evaluate_sign(builder, diff_eval, one_eval)?; // (diff == 0) || (sign(diff) == -1) - Ok(verifier_evaluate_or(builder, &equals_zero, &sign)) + verifier_evaluate_or(builder, &equals_zero, &sign) } fn get_column_references(&self, columns: &mut IndexSet) { 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 270a59be9..184c3f189 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 @@ -97,10 +97,11 @@ impl ProofExpr for MultiplyExpr { let lhs_times_rhs = builder.consume_mle_evaluation(); // subpolynomial: lhs_times_rhs - lhs * rhs - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, lhs_times_rhs - lhs * rhs, - ); + 2, + )?; // selection Ok(lhs_times_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 4176cdea6..83d48774c 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 @@ -74,7 +74,7 @@ impl ProofExpr for OrExpr { let lhs = self.lhs.verifier_evaluate(builder, accessor, one_eval)?; let rhs = self.rhs.verifier_evaluate(builder, accessor, one_eval)?; - Ok(verifier_evaluate_or(builder, &lhs, &rhs)) + verifier_evaluate_or(builder, &lhs, &rhs) } fn get_column_references(&self, columns: &mut IndexSet) { @@ -132,18 +132,19 @@ pub fn verifier_evaluate_or( builder: &mut VerificationBuilder, lhs: &S, rhs: &S, -) -> S { +) -> Result { // lhs_and_rhs let lhs_and_rhs = builder.consume_mle_evaluation(); // subpolynomial: lhs_and_rhs - lhs * rhs - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, lhs_and_rhs - *lhs * *rhs, - ); + 2, + )?; // selection - *lhs + *rhs - lhs_and_rhs + Ok(*lhs + *rhs - lhs_and_rhs) } pub fn count_or(builder: &mut CountBuilder) { 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 a5d957979..077b3ad7f 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 @@ -141,7 +141,7 @@ pub fn verifier_evaluate_sign( } // establish that the bits are binary - verify_bits_are_binary(builder, &bit_evals); + verify_bits_are_binary(builder, &bit_evals)?; // handle the special case of the sign bit being constant if !dist.has_varying_sign_bit() { @@ -152,7 +152,7 @@ pub fn verifier_evaluate_sign( if dist.num_varying_bits() == 1 { verify_constant_abs_decomposition(&dist, eval, one_eval, bit_evals[0])?; } else { - verify_bit_decomposition(builder, eval, one_eval, &bit_evals, &dist); + verify_bit_decomposition(builder, eval, one_eval, &bit_evals, &dist)?; } Ok(*bit_evals.last().unwrap()) @@ -188,13 +188,18 @@ fn prove_bits_are_binary<'a, S: Scalar>( } } -fn verify_bits_are_binary(builder: &mut VerificationBuilder, bit_evals: &[S]) { +fn verify_bits_are_binary( + builder: &mut VerificationBuilder, + bit_evals: &[S], +) -> Result<(), ProofError> { for bit_eval in bit_evals { - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, *bit_eval - *bit_eval * *bit_eval, - ); + 2, + )?; } + Ok(()) } /// # Panics @@ -244,7 +249,7 @@ fn verify_bit_decomposition( one_eval: S, bit_evals: &[S], dist: &BitDistribution, -) { +) -> Result<(), ProofError> { let mut eval = expr_eval; let sign_eval = bit_evals.last().unwrap(); let sign_eval = one_eval - S::TWO * *sign_eval; @@ -257,5 +262,10 @@ fn verify_bit_decomposition( eval -= S::from(mult) * sign_eval * bit_eval; vary_index += 1; }); - builder.produce_sumcheck_subpolynomial_evaluation(SumcheckSubpolynomialType::Identity, eval); + builder.try_produce_sumcheck_subpolynomial_evaluation( + SumcheckSubpolynomialType::Identity, + eval, + 2, + )?; + Ok(()) } diff --git a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs index 99badc6b5..789d08648 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs @@ -66,8 +66,15 @@ fn we_can_verify_a_constant_decomposition() { let one_evals = sumcheck_evaluations.one_evaluations.clone(); let one_eval = one_evals.values().next().unwrap(); - let mut builder = - VerificationBuilder::new(0, sumcheck_evaluations, &dists, &[], Vec::new(), Vec::new()); + let mut builder = VerificationBuilder::new( + 0, + sumcheck_evaluations, + &dists, + &[], + Vec::new(), + Vec::new(), + 3, + ); let data_eval = (&data).evaluate_at_point(&evaluation_point); let eval = verifier_evaluate_sign(&mut builder, data_eval, *one_eval).unwrap(); assert_eq!(eval, Curve25519Scalar::zero()); @@ -91,8 +98,15 @@ fn verification_of_constant_data_fails_if_the_commitment_doesnt_match_the_bit_di let one_evals = sumcheck_evaluations.one_evaluations.clone(); let one_eval = one_evals.values().next().unwrap(); - let mut builder = - VerificationBuilder::new(0, sumcheck_evaluations, &dists, &[], Vec::new(), Vec::new()); + let mut builder = VerificationBuilder::new( + 0, + sumcheck_evaluations, + &dists, + &[], + Vec::new(), + Vec::new(), + 3, + ); let data_eval = Curve25519Scalar::from(2) * (&data).evaluate_at_point(&evaluation_point); assert!(verifier_evaluate_sign(&mut builder, data_eval, *one_eval).is_err()); } 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 3c8e79ce8..e1addd46a 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 @@ -264,22 +264,25 @@ pub(super) fn verify_filter( let d_star_eval = builder.consume_mle_evaluation(); // sum c_star * s - d_star = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::ZeroSum, c_star_eval * s_eval - d_star_eval, - ); + 2, + )?; // c_star + c_fold * c_star - input_ones = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, c_star_eval + c_fold_eval * c_star_eval - one_eval, - ); + 2, + )?; // d_star + d_fold * d_star - chi = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, d_star_eval + d_fold_eval * d_star_eval - chi_eval, - ); + 2, + )?; Ok(()) } 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 aa096fed6..6ebeec804 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 @@ -358,22 +358,25 @@ fn verify_group_by( let g_out_star_eval = builder.consume_mle_evaluation(); // sum g_in_star * sel_in * sum_in_fold - g_out_star * sum_out_fold = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::ZeroSum, g_in_star_eval * sel_in_eval * sum_in_fold_eval - g_out_star_eval * sum_out_fold_eval, - ); + 3, + )?; // g_in_star + g_in_star * g_in_fold - input_ones = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, g_in_star_eval + g_in_star_eval * g_in_fold_eval - input_one_eval, - ); + 2, + )?; // g_out_star + g_out_star * g_out_fold - output_ones = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, g_out_star_eval + g_out_star_eval * g_out_fold_eval - output_one_eval, - ); + 2, + )?; Ok(()) } diff --git a/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs index c16431c7a..1729976a9 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs @@ -93,7 +93,7 @@ where &output_column_evals, &input_one_evals, output_one_eval, - ); + )?; Ok(TableEvaluation::new(output_column_evals, output_one_eval)) } @@ -189,41 +189,45 @@ fn verify_union( output_eval: &[S], input_one_evals: &[S], output_one_eval: S, -) { +) -> Result<(), ProofError> { assert_eq!(input_evals.len(), input_one_evals.len()); let c_star_evals = input_evals .iter() .zip(input_one_evals) - .map(|(&input_eval, &input_one_eval)| { + .map(|(&input_eval, &input_one_eval)| -> Result<_, ProofError> { let c_fold_eval = gamma * fold_vals(beta, input_eval); let c_star_eval = builder.consume_mle_evaluation(); // c_star + c_fold * c_star - input_ones = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, c_star_eval + c_fold_eval * c_star_eval - input_one_eval, - ); - c_star_eval + 2, + )?; + Ok(c_star_eval) }) - .collect::>(); + .collect::, _>>()?; let d_bar_fold_eval = gamma * fold_vals(beta, output_eval); let d_star_eval = builder.consume_mle_evaluation(); // d_star + d_bar_fold * d_star - output_ones = 0 - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, d_star_eval + d_bar_fold_eval * d_star_eval - output_one_eval, - ); + 2, + )?; // sum (sum c_star) - d_star = 0 let zero_sum_terms_eval = c_star_evals .into_iter() .chain(core::iter::once(-d_star_eval)) .sum::(); - builder.produce_sumcheck_subpolynomial_evaluation( + builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::ZeroSum, zero_sum_terms_eval, - ); + 1, + )?; + Ok(()) } /// Proves the union of tables. From 6ed87b3b8055a87ab9ba9192d52fd669f295100c Mon Sep 17 00:00:00 2001 From: Jay White Date: Tue, 10 Dec 2024 23:45:39 -0500 Subject: [PATCH 2/8] refactor: make `VerificationBuilder` methods fallible We make the remainind method in `VerificationBuilder` fallible by returning an Error when there are not enough values to consume another. This ensures that the verifier will catch any issues with the proof size. --- crates/proof-of-sql/src/base/proof/error.rs | 15 ++++++ .../proof-of-sql/src/sql/proof/query_proof.rs | 4 +- .../src/sql/proof/query_proof_test.rs | 22 ++++----- .../sql/proof/verifiable_query_result_test.rs | 4 +- .../src/sql/proof/verification_builder.rs | 49 +++++++++++++------ .../sql/proof/verification_builder_test.rs | 6 +-- .../src/sql/proof_exprs/and_expr.rs | 2 +- .../src/sql/proof_exprs/equals_expr.rs | 4 +- .../src/sql/proof_exprs/multiply_expr.rs | 2 +- .../src/sql/proof_exprs/or_expr.rs | 2 +- .../src/sql/proof_exprs/sign_expr.rs | 4 +- .../src/sql/proof_plans/filter_exec.rs | 13 ++--- .../src/sql/proof_plans/group_by_exec.rs | 16 +++--- .../src/sql/proof_plans/projection_exec.rs | 2 +- .../src/sql/proof_plans/slice_exec.rs | 12 ++--- .../src/sql/proof_plans/union_exec.rs | 12 ++--- 16 files changed, 103 insertions(+), 66 deletions(-) diff --git a/crates/proof-of-sql/src/base/proof/error.rs b/crates/proof-of-sql/src/base/proof/error.rs index 054692c1d..5988aec56 100644 --- a/crates/proof-of-sql/src/base/proof/error.rs +++ b/crates/proof-of-sql/src/base/proof/error.rs @@ -28,4 +28,19 @@ pub enum ProofSizeMismatch { /// This error occurs when the sumcheck proof doesn't have enough coefficients. #[snafu(display("Sumcheck proof is too small"))] SumcheckProofTooSmall, + /// This error occurs when the proof has too few MLE evaluations. + #[snafu(display("Proof has too few MLE evaluations"))] + TooFewMLEEvaluations, + /// This error occurs when the number of post result challenges in the proof plan doesn't match the number specified in the proof + #[snafu(display("Post result challenge count mismatch"))] + PostResultCountMismatch, + /// This error occurs when the number of constraints in the proof plan doesn't match the number specified in the proof + #[snafu(display("Constraint count mismatch"))] + ConstraintCountMismatch, + /// This error occurs when the proof has too few bit distributions. + #[snafu(display("Proof has too few bit distributions"))] + TooFewBitDistributions, + /// This error occurs when the proof has too few one lengths. + #[snafu(display("Proof has too few one lengths"))] + TooFewOneLengths, } 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 8b7c6761d..e91191908 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -341,8 +341,8 @@ impl QueryProof { .collect(); let evaluation_accessor: IndexMap<_, _> = column_references .into_iter() - .map(|col| (col, builder.consume_mle_evaluation())) - .collect(); + .map(|col| Ok((col, builder.try_consume_mle_evaluation()?))) + .collect::>()?; let verifier_evaluations = expr.verifier_evaluate( &mut builder, 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 0bb5cfd65..3a4e97025 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 @@ -87,7 +87,7 @@ impl ProofPlan for TrivialTestProofPlan { _result: Option<&OwnedTable>, _one_eval_map: &IndexMap, ) -> Result, ProofError> { - assert_eq!(builder.consume_mle_evaluation(), S::ZERO); + assert_eq!(builder.try_consume_mle_evaluation()?, S::ZERO); builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::ZeroSum, S::from(self.evaluation), @@ -95,7 +95,7 @@ impl ProofPlan for TrivialTestProofPlan { )?; Ok(TableEvaluation::new( vec![S::ZERO], - builder.consume_one_evaluation(), + builder.try_consume_one_evaluation()?, )) } /// @@ -279,7 +279,7 @@ impl ProofPlan for SquareTestProofPlan { ColumnType::BigInt, )) .unwrap(); - let res_eval = builder.consume_mle_evaluation(); + let res_eval = builder.try_consume_mle_evaluation()?; builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, res_eval - x_eval * x_eval, @@ -287,7 +287,7 @@ impl ProofPlan for SquareTestProofPlan { )?; Ok(TableEvaluation::new( vec![res_eval], - builder.consume_one_evaluation(), + builder.try_consume_one_evaluation()?, )) } fn get_column_result_fields(&self) -> Vec { @@ -476,8 +476,8 @@ impl ProofPlan for DoubleSquareTestProofPlan { ColumnType::BigInt, )) .unwrap(); - let z_eval = builder.consume_mle_evaluation(); - let res_eval = builder.consume_mle_evaluation(); + let z_eval = builder.try_consume_mle_evaluation()?; + let res_eval = builder.try_consume_mle_evaluation()?; // poly1 builder.try_produce_sumcheck_subpolynomial_evaluation( @@ -494,7 +494,7 @@ impl ProofPlan for DoubleSquareTestProofPlan { )?; Ok(TableEvaluation::new( vec![res_eval], - builder.consume_one_evaluation(), + builder.try_consume_one_evaluation()?, )) } fn get_column_result_fields(&self) -> Vec { @@ -676,8 +676,8 @@ impl ProofPlan for ChallengeTestProofPlan { _result: Option<&OwnedTable>, _one_eval_map: &IndexMap, ) -> Result, ProofError> { - let alpha = builder.consume_post_result_challenge(); - let _beta = builder.consume_post_result_challenge(); + let alpha = builder.try_consume_post_result_challenge()?; + let _beta = builder.try_consume_post_result_challenge()?; let x_eval = *accessor .get(&ColumnRef::new( "sxt.test".parse().unwrap(), @@ -685,7 +685,7 @@ impl ProofPlan for ChallengeTestProofPlan { ColumnType::BigInt, )) .unwrap(); - let res_eval = builder.consume_mle_evaluation(); + let res_eval = builder.try_consume_mle_evaluation()?; builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, alpha * res_eval - alpha * x_eval * x_eval, @@ -693,7 +693,7 @@ impl ProofPlan for ChallengeTestProofPlan { )?; Ok(TableEvaluation::new( vec![res_eval], - builder.consume_one_evaluation(), + builder.try_consume_one_evaluation()?, )) } fn get_column_result_fields(&self) -> Vec { diff --git a/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs b/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs index 044c85874..eb6a3ddd7 100644 --- a/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs +++ b/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs @@ -71,12 +71,12 @@ impl ProofPlan for EmptyTestQueryExpr { _one_eval_map: &IndexMap, ) -> Result, ProofError> { assert_eq!( - builder.consume_mle_evaluations(self.columns), + builder.try_consume_mle_evaluations(self.columns)?, vec![S::ZERO; self.columns] ); Ok(TableEvaluation::new( vec![S::ZERO; self.columns], - builder.consume_one_evaluation(), + builder.try_consume_one_evaluation()?, )) } 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 867756839..f04435471 100644 --- a/crates/proof-of-sql/src/sql/proof/verification_builder.rs +++ b/crates/proof-of-sql/src/sql/proof/verification_builder.rs @@ -58,15 +58,19 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { /// /// # Panics /// It should never panic, as the length of the one evaluation is guaranteed to be present - pub fn consume_one_evaluation(&mut self) -> S { + pub fn try_consume_one_evaluation(&mut self) -> Result { let index = self.consumed_one_evaluations; - let length = self.one_evaluation_length_queue[index]; + let length = self + .one_evaluation_length_queue + .get(index) + .copied() + .ok_or(ProofSizeMismatch::TooFewOneLengths)?; self.consumed_one_evaluations += 1; - *self + Ok(*self .mle_evaluations .one_evaluations .get(&length) - .expect("One evaluation not found") + .expect("One evaluation not found")) } pub fn generator_offset(&self) -> usize { @@ -76,25 +80,36 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { /// Consume the evaluation of an anchored MLE used in sumcheck and provide the commitment of the MLE /// /// An anchored MLE is an MLE where the verifier has access to the commitment - pub fn consume_mle_evaluation(&mut self) -> S { + pub fn try_consume_mle_evaluation(&mut self) -> Result { let index = self.consumed_pcs_proof_mles; self.consumed_pcs_proof_mles += 1; - self.mle_evaluations.pcs_proof_evaluations[index] + self.mle_evaluations + .pcs_proof_evaluations + .get(index) + .copied() + .ok_or(ProofSizeMismatch::TooFewMLEEvaluations) } /// Consume multiple MLE evaluations - pub fn consume_mle_evaluations(&mut self, count: usize) -> Vec { - iter::repeat_with(|| self.consume_mle_evaluation()) + pub fn try_consume_mle_evaluations( + &mut self, + count: usize, + ) -> Result, ProofSizeMismatch> { + iter::repeat_with(|| self.try_consume_mle_evaluation()) .take(count) .collect() } /// Consume a bit distribution that describes which bits are constant /// and which bits varying in a column of data - pub fn consume_bit_distribution(&mut self) -> BitDistribution { - let res = self.bit_distributions[0].clone(); + pub fn try_consume_bit_distribution(&mut self) -> Result { + let res = self + .bit_distributions + .first() + .cloned() + .ok_or(ProofSizeMismatch::TooFewBitDistributions)?; self.bit_distributions = &self.bit_distributions[1..]; - res + Ok(res) } /// Produce the evaluation of a subpolynomial used in sumcheck @@ -104,7 +119,11 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { eval: S, degree: usize, ) -> Result<(), ProofSizeMismatch> { - self.sumcheck_evaluation += self.subpolynomial_multipliers[self.produced_subpolynomials] + self.sumcheck_evaluation += self + .subpolynomial_multipliers + .get(self.produced_subpolynomials) + .copied() + .ok_or(ProofSizeMismatch::ConstraintCountMismatch)? * match subpolynomial_type { SumcheckSubpolynomialType::Identity => { if degree + 1 > self.subpolynomial_max_multiplicands { @@ -154,7 +173,9 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> { /// # Panics /// This function will panic if `post_result_challenges` is empty, /// as it attempts to pop an element from the vector and unwraps the result. - pub fn consume_post_result_challenge(&mut self) -> S { - self.post_result_challenges.pop().unwrap() + pub fn try_consume_post_result_challenge(&mut self) -> Result { + self.post_result_challenges + .pop() + .ok_or(ProofSizeMismatch::PostResultCountMismatch) } } 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 c1f6750f4..6a725f5ab 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 @@ -75,14 +75,14 @@ fn we_can_consume_post_result_challenges_in_proof_builder() { ); assert_eq!( Curve25519Scalar::from(789), - builder.consume_post_result_challenge() + builder.try_consume_post_result_challenge().unwrap() ); assert_eq!( Curve25519Scalar::from(456), - builder.consume_post_result_challenge() + builder.try_consume_post_result_challenge().unwrap() ); assert_eq!( Curve25519Scalar::from(123), - builder.consume_post_result_challenge() + builder.try_consume_post_result_challenge().unwrap() ); } 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 25372b51d..e0b7cc6db 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 @@ -92,7 +92,7 @@ impl ProofExpr for AndExpr { let rhs = self.rhs.verifier_evaluate(builder, accessor, one_eval)?; // lhs_and_rhs - let lhs_and_rhs = builder.consume_mle_evaluation(); + let lhs_and_rhs = builder.try_consume_mle_evaluation()?; // subpolynomial: lhs_and_rhs - lhs * rhs builder.try_produce_sumcheck_subpolynomial_evaluation( 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 7837605dc..a762b615e 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 @@ -154,8 +154,8 @@ pub fn verifier_evaluate_equals_zero( one_eval: S, ) -> Result { // consume mle evaluations - let lhs_pseudo_inv_eval = builder.consume_mle_evaluation(); - let selection_not_eval = builder.consume_mle_evaluation(); + let lhs_pseudo_inv_eval = builder.try_consume_mle_evaluation()?; + let selection_not_eval = builder.try_consume_mle_evaluation()?; let selection_eval = one_eval - selection_not_eval; // subpolynomial: selection * lhs 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 184c3f189..4a2f39b13 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 @@ -94,7 +94,7 @@ impl ProofExpr for MultiplyExpr { let rhs = self.rhs.verifier_evaluate(builder, accessor, one_eval)?; // lhs_times_rhs - let lhs_times_rhs = builder.consume_mle_evaluation(); + let lhs_times_rhs = builder.try_consume_mle_evaluation()?; // subpolynomial: lhs_times_rhs - lhs * rhs builder.try_produce_sumcheck_subpolynomial_evaluation( 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 83d48774c..6b443a41b 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 @@ -134,7 +134,7 @@ pub fn verifier_evaluate_or( rhs: &S, ) -> Result { // lhs_and_rhs - let lhs_and_rhs = builder.consume_mle_evaluation(); + let lhs_and_rhs = builder.try_consume_mle_evaluation()?; // subpolynomial: lhs_and_rhs - lhs * rhs builder.try_produce_sumcheck_subpolynomial_evaluation( 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 077b3ad7f..a6beee821 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 @@ -129,14 +129,14 @@ pub fn verifier_evaluate_sign( one_eval: S, ) -> Result { // bit_distribution - let dist = builder.consume_bit_distribution(); + let dist = builder.try_consume_bit_distribution()?; let num_varying_bits = dist.num_varying_bits(); // extract evaluations and commitmens of the multilinear extensions for the varying // bits of the expression let mut bit_evals = Vec::with_capacity(num_varying_bits); for _ in 0..num_varying_bits { - let eval = builder.consume_mle_evaluation(); + let eval = builder.try_consume_mle_evaluation()?; bit_evals.push(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 e1addd46a..2c6e05c29 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 @@ -99,13 +99,14 @@ where .collect::, _>>()?, ); // 3. filtered_columns - let filtered_columns_evals = builder.consume_mle_evaluations(self.aliased_results.len()); + let filtered_columns_evals = + builder.try_consume_mle_evaluations(self.aliased_results.len())?; assert!(filtered_columns_evals.len() == self.aliased_results.len()); - let alpha = builder.consume_post_result_challenge(); - let beta = builder.consume_post_result_challenge(); + let alpha = builder.try_consume_post_result_challenge()?; + let beta = builder.try_consume_post_result_challenge()?; - let output_one_eval = builder.consume_one_evaluation(); + let output_one_eval = builder.try_consume_one_evaluation()?; verify_filter( builder, @@ -260,8 +261,8 @@ pub(super) fn verify_filter( ) -> Result<(), ProofError> { let c_fold_eval = alpha * fold_vals(beta, c_evals); let d_fold_eval = alpha * fold_vals(beta, d_evals); - let c_star_eval = builder.consume_mle_evaluation(); - let d_star_eval = builder.consume_mle_evaluation(); + let c_star_eval = builder.try_consume_mle_evaluation()?; + let d_star_eval = builder.try_consume_mle_evaluation()?; // sum c_star * s - d_star = 0 builder.try_produce_sumcheck_subpolynomial_evaluation( 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 6ebeec804..64dd2ad02 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 @@ -118,13 +118,13 @@ impl ProofPlan for GroupByExec { .collect::, _>>()?; // 3. filtered_columns let group_by_result_columns_evals = - builder.consume_mle_evaluations(self.group_by_exprs.len()); - let sum_result_columns_evals = builder.consume_mle_evaluations(self.sum_expr.len()); - let count_column_eval = builder.consume_mle_evaluation(); + builder.try_consume_mle_evaluations(self.group_by_exprs.len())?; + let sum_result_columns_evals = builder.try_consume_mle_evaluations(self.sum_expr.len())?; + let count_column_eval = builder.try_consume_mle_evaluation()?; - let alpha = builder.consume_post_result_challenge(); - let beta = builder.consume_post_result_challenge(); - let output_one_eval = builder.consume_one_evaluation(); + let alpha = builder.try_consume_post_result_challenge()?; + let beta = builder.try_consume_post_result_challenge()?; + let output_one_eval = builder.try_consume_one_evaluation()?; verify_group_by( builder, @@ -354,8 +354,8 @@ fn verify_group_by( // sum_out_fold = count_out + sum beta^(j+1) * sum_out[j] let sum_out_fold_eval = count_out_eval + beta * fold_vals(beta, &sum_out_evals); - let g_in_star_eval = builder.consume_mle_evaluation(); - let g_out_star_eval = builder.consume_mle_evaluation(); + let g_in_star_eval = builder.try_consume_mle_evaluation()?; + let g_out_star_eval = builder.try_consume_mle_evaluation()?; // sum g_in_star * sel_in * sum_in_fold - g_out_star * sum_out_fold = 0 builder.try_produce_sumcheck_subpolynomial_evaluation( diff --git a/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs index 1ff274281..a02092d44 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs @@ -68,7 +68,7 @@ impl ProofPlan for ProjectionExec { .verifier_evaluate(builder, accessor, one_eval) }) .collect::, _>>()?; - let column_evals = builder.consume_mle_evaluations(self.aliased_results.len()); + let column_evals = builder.try_consume_mle_evaluations(self.aliased_results.len())?; Ok(TableEvaluation::new(column_evals, one_eval)) } diff --git a/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs index 17df1ad64..3466178c2 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs @@ -77,17 +77,17 @@ where let input_table_eval = self.input .verifier_evaluate(builder, accessor, None, one_eval_map)?; - let output_one_eval = builder.consume_one_evaluation(); + let output_one_eval = builder.try_consume_one_evaluation()?; let columns_evals = input_table_eval.column_evals(); // 2. selection // The selected range is (offset_index, max_index] - let offset_one_eval = builder.consume_one_evaluation(); - let max_one_eval = builder.consume_one_evaluation(); + let offset_one_eval = builder.try_consume_one_evaluation()?; + let max_one_eval = builder.try_consume_one_evaluation()?; let selection_eval = max_one_eval - offset_one_eval; // 3. filtered_columns - let filtered_columns_evals = builder.consume_mle_evaluations(columns_evals.len()); - let alpha = builder.consume_post_result_challenge(); - let beta = builder.consume_post_result_challenge(); + let filtered_columns_evals = builder.try_consume_mle_evaluations(columns_evals.len())?; + let alpha = builder.try_consume_post_result_challenge()?; + let beta = builder.try_consume_post_result_challenge()?; verify_filter( builder, diff --git a/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs index 1729976a9..dfee32c44 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs @@ -77,14 +77,14 @@ where .iter() .map(TableEvaluation::column_evals) .collect::>(); - let output_column_evals = builder.consume_mle_evaluations(self.schema.len()); + let output_column_evals = builder.try_consume_mle_evaluations(self.schema.len())?; let input_one_evals = input_table_evals .iter() .map(TableEvaluation::one_eval) .collect::>(); - let output_one_eval = builder.consume_one_evaluation(); - let gamma = builder.consume_post_result_challenge(); - let beta = builder.consume_post_result_challenge(); + let output_one_eval = builder.try_consume_one_evaluation()?; + let gamma = builder.try_consume_post_result_challenge()?; + let beta = builder.try_consume_post_result_challenge()?; verify_union( builder, gamma, @@ -196,7 +196,7 @@ fn verify_union( .zip(input_one_evals) .map(|(&input_eval, &input_one_eval)| -> Result<_, ProofError> { let c_fold_eval = gamma * fold_vals(beta, input_eval); - let c_star_eval = builder.consume_mle_evaluation(); + let c_star_eval = builder.try_consume_mle_evaluation()?; // c_star + c_fold * c_star - input_ones = 0 builder.try_produce_sumcheck_subpolynomial_evaluation( SumcheckSubpolynomialType::Identity, @@ -208,7 +208,7 @@ fn verify_union( .collect::, _>>()?; let d_bar_fold_eval = gamma * fold_vals(beta, output_eval); - let d_star_eval = builder.consume_mle_evaluation(); + let d_star_eval = builder.try_consume_mle_evaluation()?; // d_star + d_bar_fold * d_star - output_ones = 0 builder.try_produce_sumcheck_subpolynomial_evaluation( From 9c256e642272fe848ac396a8a1fcdae490123a57 Mon Sep 17 00:00:00 2001 From: Jay White Date: Tue, 10 Dec 2024 11:27:14 -0500 Subject: [PATCH 3/8] refactor: infer `max_multiplicands` from sumcheck proof this is secure since the VerificationBuilder checks the degree of any new polynomial --- .../src/proof_primitive/sumcheck/proof.rs | 13 ++++--- .../proof_primitive/sumcheck/proof_test.rs | 34 +++---------------- .../proof_primitive/sumcheck/test_cases.rs | 2 -- .../proof-of-sql/src/sql/proof/query_proof.rs | 3 +- 4 files changed, 14 insertions(+), 38 deletions(-) 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 45d92c601..6ce2c7e12 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/proof.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/proof.rs @@ -21,6 +21,7 @@ pub struct SumcheckProof { pub struct Subclaim { pub evaluation_point: Vec, pub expected_evaluation: S, + pub max_multiplicands: usize, } impl SumcheckProof { @@ -57,18 +58,19 @@ impl SumcheckProof { pub fn verify_without_evaluation( &self, transcript: &mut impl Transcript, - max_multiplicands: usize, num_variables: usize, claimed_sum: &S, ) -> Result, ProofError> { - transcript.extend_as_be([max_multiplicands as u64, num_variables as u64]); - // This challenge is in order to keep transcript messages grouped. (This simplifies the Solidity implementation.) - transcript.scalar_challenge_as_be::(); - if self.coefficients.len() != num_variables * (max_multiplicands + 1) { + let coefficients_len = self.coefficients.len(); + if coefficients_len % num_variables != 0 { return Err(ProofError::VerificationError { error: "invalid proof size", }); } + let max_multiplicands = (coefficients_len / num_variables) - 1; + transcript.extend_as_be([max_multiplicands as u64, num_variables as u64]); + // This challenge is in order to keep transcript messages grouped. (This simplifies the Solidity implementation.) + transcript.scalar_challenge_as_be::(); let mut evaluation_point = Vec::with_capacity(num_variables); let mut expected_evaluation = *claimed_sum; @@ -97,6 +99,7 @@ impl SumcheckProof { Ok(Subclaim { evaluation_point, expected_evaluation, + max_multiplicands, }) } } 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 cebdc79b0..18c908b58 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 @@ -42,7 +42,6 @@ fn test_create_verify_proof() { let subclaim = proof .verify_without_evaluation( &mut transcript, - poly.max_multiplicands, poly.num_variables, &Curve25519Scalar::from(579u64), ) @@ -59,7 +58,6 @@ fn test_create_verify_proof() { let subclaim = proof .verify_without_evaluation( &mut transcript, - poly.max_multiplicands, poly.num_variables, &Curve25519Scalar::from(579u64), ) @@ -70,7 +68,6 @@ fn test_create_verify_proof() { let mut transcript = Transcript::new(b"sumchecktest"); let subclaim = proof.verify_without_evaluation( &mut transcript, - poly.max_multiplicands, poly.num_variables, &Curve25519Scalar::from(123u64), ); @@ -80,7 +77,6 @@ fn test_create_verify_proof() { proof.coefficients[0] += Curve25519Scalar::from(3u64); let subclaim = proof.verify_without_evaluation( &mut transcript, - poly.max_multiplicands, poly.num_variables, &Curve25519Scalar::from(579u64), ); @@ -148,12 +144,7 @@ fn test_polynomial(nv: usize, num_multiplicands_range: (usize, usize), num_produ // verify proof let mut transcript = Transcript::new(b"sumchecktest"); let subclaim = proof - .verify_without_evaluation( - &mut transcript, - poly.max_multiplicands, - poly.num_variables, - &asserted_sum, - ) + .verify_without_evaluation(&mut transcript, poly.num_variables, &asserted_sum) .expect("verify failed"); assert_eq!(subclaim.evaluation_point, evaluation_point); assert_eq!( @@ -195,12 +186,7 @@ fn we_can_verify_many_random_test_cases() { let mut transcript = Transcript::new(b"sumchecktest"); let subclaim = proof - .verify_without_evaluation( - &mut transcript, - test_case.max_multiplicands, - test_case.num_vars, - &test_case.sum, - ) + .verify_without_evaluation(&mut transcript, test_case.num_vars, &test_case.sum) .expect("verification should succeed with the correct setup"); assert_eq!( subclaim.evaluation_point, evaluation_point, @@ -214,12 +200,8 @@ fn we_can_verify_many_random_test_cases() { let mut transcript = Transcript::new(b"sumchecktest"); transcript.extend_serialize_as_le(&123u64); - let verify_result = proof.verify_without_evaluation( - &mut transcript, - test_case.max_multiplicands, - test_case.num_vars, - &test_case.sum, - ); + let verify_result = + proof.verify_without_evaluation(&mut transcript, test_case.num_vars, &test_case.sum); if let Ok(subclaim) = verify_result { assert_ne!( subclaim.evaluation_point, evaluation_point, @@ -232,7 +214,6 @@ fn we_can_verify_many_random_test_cases() { proof .verify_without_evaluation( &mut transcript, - test_case.max_multiplicands, test_case.num_vars, &(test_case.sum + TestScalar::ONE), ) @@ -245,12 +226,7 @@ fn we_can_verify_many_random_test_cases() { let mut transcript = Transcript::new(b"sumchecktest"); assert!( modified_proof - .verify_without_evaluation( - &mut transcript, - test_case.max_multiplicands, - test_case.num_vars, - &test_case.sum, - ) + .verify_without_evaluation(&mut transcript, test_case.num_vars, &test_case.sum,) .is_err(), "verification should fail when the proof is modified" ); diff --git a/crates/proof-of-sql/src/proof_primitive/sumcheck/test_cases.rs b/crates/proof-of-sql/src/proof_primitive/sumcheck/test_cases.rs index dcc6f0079..9d03d888b 100644 --- a/crates/proof-of-sql/src/proof_primitive/sumcheck/test_cases.rs +++ b/crates/proof-of-sql/src/proof_primitive/sumcheck/test_cases.rs @@ -5,7 +5,6 @@ use itertools::Itertools; pub struct SumcheckTestCase { pub polynomial: CompositePolynomial, pub num_vars: usize, - pub max_multiplicands: usize, pub sum: S, } @@ -38,7 +37,6 @@ impl SumcheckTestCase { Self { polynomial, num_vars, - max_multiplicands, sum, } } 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 e91191908..b4234c4b8 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -286,7 +286,6 @@ impl QueryProof { &mut transcript, // This needs to be at least 2 since `CompositePolynomialBuilder::make_composite_polynomial` // always adds a degree 2 term. - core::cmp::max(counts.sumcheck_max_multiplicands, 2), num_sumcheck_variables, &Zero::zero(), )?; @@ -331,7 +330,7 @@ impl QueryProof { sumcheck_random_scalars.subpolynomial_multipliers, post_result_challenges, self.one_evaluation_lengths.clone(), - core::cmp::max(counts.sumcheck_max_multiplicands, 2), + subclaim.max_multiplicands, ); let pcs_proof_commitments: Vec<_> = column_references From 84ec8ff08790943e1a22fb214b8b6da7e8ed29db Mon Sep 17 00:00:00 2001 From: Jay White Date: Wed, 11 Dec 2024 11:21:32 -0500 Subject: [PATCH 4/8] refactor: move BitDistribution range validation from `count_sign` to `QueryProof::verify` --- .../src/base/bit/bit_distribution.rs | 19 ++++++++++++ .../src/base/bit/bit_distribution_test.rs | 23 ++++++++++++++ .../proof-of-sql/src/sql/proof/query_proof.rs | 4 +++ .../sql/proof_exprs/bitwise_verification.rs | 22 ++----------- .../proof_exprs/bitwise_verification_test.rs | 31 +------------------ .../proof-of-sql/src/sql/proof_exprs/mod.rs | 5 +-- .../src/sql/proof_exprs/sign_expr.rs | 10 +----- 7 files changed, 51 insertions(+), 63 deletions(-) diff --git a/crates/proof-of-sql/src/base/bit/bit_distribution.rs b/crates/proof-of-sql/src/base/bit/bit_distribution.rs index 8f803a9ef..81db9bd60 100644 --- a/crates/proof-of-sql/src/base/bit/bit_distribution.rs +++ b/crates/proof-of-sql/src/base/bit/bit_distribution.rs @@ -67,6 +67,25 @@ impl BitDistribution { true } + /// In order to avoid cases with large numbers where there can be both a positive and negative + /// representation, we restrict the range of bit distributions that we accept. + /// + /// Currently this is set to be the minimal value that will include the sum of two signed 128-bit + /// integers. The range will likely be expanded in the future as we support additional expressions. + pub fn is_within_acceptable_range(&self) -> bool { + // handle the case of everything zero + if self.num_varying_bits() == 0 && self.constant_part() == [0; 4] { + return true; + } + + // signed 128 bit numbers range from + // -2^127 to 2^127-1 + // the maximum absolute value of the sum of two signed 128-integers is + // then + // 2 * (2^127) = 2^128 + self.most_significant_abs_bit() <= 128 + } + /// If `{b_i}` represents the non-varying 1-bits of the absolute values, return the value /// `sum_i b_i 2 ^ i` pub fn constant_part(&self) -> [u64; 4] { diff --git a/crates/proof-of-sql/src/base/bit/bit_distribution_test.rs b/crates/proof-of-sql/src/base/bit/bit_distribution_test.rs index 5a0699b19..f0fc693c2 100644 --- a/crates/proof-of-sql/src/base/bit/bit_distribution_test.rs +++ b/crates/proof-of-sql/src/base/bit/bit_distribution_test.rs @@ -289,3 +289,26 @@ fn we_can_detect_invalid_bit_distributions() { }; assert!(!dist.is_valid()); } + +#[test] +fn zero_is_within_range() { + let data: Vec = vec![TestScalar::from(0)]; + let dist = BitDistribution::new::(&data); + assert!(dist.is_within_acceptable_range()); +} + +#[test] +fn the_sum_of_two_signed_128_bit_numbers_is_within_range() { + let data: Vec = vec![TestScalar::from(i128::MIN) + TestScalar::from(i128::MIN)]; + let dist = BitDistribution::new::(&data); + assert!(dist.is_within_acceptable_range()); +} + +#[test] +fn we_reject_distributions_that_are_outside_of_maximum_range() { + let data: Vec = vec![ + TestScalar::from(u128::MAX) + TestScalar::from(u128::MAX) + TestScalar::from(u128::MAX), + ]; + let dist = BitDistribution::new::(&data); + assert!(!dist.is_within_acceptable_range()); +} 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 b4234c4b8..e735dbfd6 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -228,6 +228,10 @@ impl QueryProof { Err(ProofError::VerificationError { error: "invalid bit distributions", })?; + } else if !dist.is_within_acceptable_range() { + Err(ProofError::VerificationError { + error: "bit distribution outside of acceptable range", + })?; } } diff --git a/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification.rs b/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification.rs index 37d0d719c..fe4b772e1 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification.rs @@ -1,22 +1,4 @@ use crate::base::{bit::BitDistribution, proof::ProofError, scalar::Scalar}; -/// In order to avoid cases with large numbers where there can be both a positive and negative -/// representation, we restrict the range of bit distributions that we accept. -/// -/// Currently this is set to be the minimal value that will include the sum of two signed 128-bit -/// integers. The range will likely be expanded in the future as we support additional expressions. -pub fn is_within_acceptable_range(dist: &BitDistribution) -> bool { - // handle the case of everything zero - if dist.num_varying_bits() == 0 && dist.constant_part() == [0; 4] { - return true; - } - - // signed 128 bit numbers range from - // -2^127 to 2^127-1 - // the maximum absolute value of the sum of two signed 128-integers is - // then - // 2 * (2^127) = 2^128 - dist.most_significant_abs_bit() <= 128 -} #[allow( clippy::missing_panics_doc, @@ -33,7 +15,7 @@ pub fn verify_constant_sign_decomposition( ) -> Result<(), ProofError> { assert!( dist.is_valid() - && is_within_acceptable_range(dist) + && dist.is_within_acceptable_range() && dist.num_varying_bits() == bit_evals.len() && !dist.has_varying_sign_bit() ); @@ -67,7 +49,7 @@ pub fn verify_constant_abs_decomposition( ) -> Result<(), ProofError> { assert!( dist.is_valid() - && is_within_acceptable_range(dist) + && dist.is_within_acceptable_range() && dist.num_varying_bits() == 1 && dist.has_varying_sign_bit() ); diff --git a/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification_test.rs b/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification_test.rs index 664e8580e..4d0c99ef3 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification_test.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/bitwise_verification_test.rs @@ -1,7 +1,4 @@ -use super::{ - is_within_acceptable_range, verify_constant_abs_decomposition, - verify_constant_sign_decomposition, -}; +use super::{verify_constant_abs_decomposition, verify_constant_sign_decomposition}; use crate::base::{ bit::BitDistribution, scalar::Curve25519Scalar, @@ -17,32 +14,6 @@ fn rand_eval_vec(len: usize) -> Vec { .collect() } -#[test] -fn zero_is_within_range() { - let data: Vec = vec![Curve25519Scalar::from(0)]; - let dist = BitDistribution::new::(&data); - assert!(is_within_acceptable_range(&dist)); -} - -#[test] -fn the_sum_of_two_signed_128_bit_numbers_is_within_range() { - let data: Vec = - vec![Curve25519Scalar::from(i128::MIN) + Curve25519Scalar::from(i128::MIN)]; - let dist = BitDistribution::new::(&data); - assert!(is_within_acceptable_range(&dist)); -} - -#[test] -fn we_reject_distributions_that_are_outside_of_maximum_range() { - let data: Vec = vec![ - Curve25519Scalar::from(u128::MAX) - + Curve25519Scalar::from(u128::MAX) - + Curve25519Scalar::from(u128::MAX), - ]; - let dist = BitDistribution::new::(&data); - assert!(!is_within_acceptable_range(&dist)); -} - #[test] fn we_can_verify_the_decomposition_of_a_constant_column() { let data: Vec = diff --git a/crates/proof-of-sql/src/sql/proof_exprs/mod.rs b/crates/proof-of-sql/src/sql/proof_exprs/mod.rs index d2b8c3f27..1b45db80e 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/mod.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/mod.rs @@ -21,10 +21,7 @@ use multiply_expr::MultiplyExpr; mod multiply_expr_test; mod bitwise_verification; -use bitwise_verification::{ - is_within_acceptable_range, verify_constant_abs_decomposition, - verify_constant_sign_decomposition, -}; +use bitwise_verification::{verify_constant_abs_decomposition, verify_constant_sign_decomposition}; #[cfg(test)] mod bitwise_verification_test; 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 a6beee821..e2ba148be 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 @@ -1,7 +1,4 @@ -use super::{ - is_within_acceptable_range, verify_constant_abs_decomposition, - verify_constant_sign_decomposition, -}; +use super::{verify_constant_abs_decomposition, verify_constant_sign_decomposition}; use crate::{ base::{ bit::{compute_varying_bit_matrix, BitDistribution}, @@ -19,11 +16,6 @@ use bumpalo::Bump; /// Count the number of components needed to prove a sign decomposition pub fn count_sign(builder: &mut CountBuilder) -> Result<(), ProofError> { let dist = builder.consume_bit_distribution()?; - if !is_within_acceptable_range(&dist) { - return Err(ProofError::VerificationError { - error: "bit distribution outside of acceptable range", - }); - } if dist.num_varying_bits() == 0 { return Ok(()); } From e3433c912dc3ec57c0c42d4e3cf9cb561c99c1ab Mon Sep 17 00:00:00 2001 From: Jay White Date: Wed, 11 Dec 2024 11:22:52 -0500 Subject: [PATCH 5/8] refactor!: remove use of `CountBuilder` within `QueryProof::verify` To do this, we put `subpolynomial_constraint_count` and `post_result_challenge_count` in the proof itself. This is secure because the validation of the counts is done just-in-time within the VerificationBuilder consume method --- .../proof-of-sql/src/sql/proof/query_proof.rs | 42 ++++++++----------- .../src/sql/proof/query_proof_test.rs | 11 ++--- 2 files changed, 23 insertions(+), 30 deletions(-) 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 e735dbfd6..9db4dbac1 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -1,7 +1,7 @@ use super::{ - make_sumcheck_state::make_sumcheck_prover_state, CountBuilder, FinalRoundBuilder, - FirstRoundBuilder, ProofCounts, ProofPlan, QueryData, QueryResult, SumcheckMleEvaluations, - SumcheckRandomScalars, VerificationBuilder, + make_sumcheck_state::make_sumcheck_prover_state, FinalRoundBuilder, FirstRoundBuilder, + ProofPlan, QueryData, QueryResult, SumcheckMleEvaluations, SumcheckRandomScalars, + VerificationBuilder, }; use crate::{ base::{ @@ -66,6 +66,8 @@ pub(super) struct QueryProof { pub evaluation_proof: CP, /// Length of the range of generators we use pub range_length: usize, + pub subpolynomial_constraint_count: usize, + pub post_result_challenge_count: usize, } impl QueryProof { @@ -110,6 +112,7 @@ impl QueryProof { let num_sumcheck_variables = cmp::max(log2_up(range_length), 1); assert!(num_sumcheck_variables > 0); + let post_result_challenge_count = first_round_builder.num_post_result_challenges(); // construct a transcript for the proof let mut transcript: Keccak256Transcript = make_transcript( @@ -118,6 +121,7 @@ impl QueryProof { range_length, min_row_num, one_evaluation_lengths, + post_result_challenge_count, ); // These are the challenges that will be consumed by the proof @@ -127,7 +131,7 @@ impl QueryProof { // Note: the last challenge in the vec is the first one that is consumed. let post_result_challenges = core::iter::repeat_with(|| transcript.scalar_challenge_as_be()) - .take(first_round_builder.num_post_result_challenges()) + .take(post_result_challenge_count) .collect(); let mut builder = FinalRoundBuilder::new(num_sumcheck_variables, post_result_challenges); @@ -151,7 +155,8 @@ impl QueryProof { ); // construct the sumcheck polynomial - let num_random_scalars = num_sumcheck_variables + builder.num_sumcheck_subpolynomials(); + let subpolynomial_constraint_count = builder.num_sumcheck_subpolynomials(); + let num_random_scalars = num_sumcheck_variables + subpolynomial_constraint_count; let random_scalars: Vec<_> = core::iter::repeat_with(|| transcript.scalar_challenge_as_be()) .take(num_random_scalars) @@ -204,6 +209,8 @@ impl QueryProof { pcs_proof_evaluations, evaluation_proof, range_length, + subpolynomial_constraint_count, + post_result_challenge_count, }; (proof, provable_result) } @@ -236,19 +243,6 @@ impl QueryProof { } let column_references = expr.get_column_references(); - // count terms - - let mut builder = CountBuilder::new(&self.bit_distributions); - builder.count_anchored_mles(column_references.len()); - expr.count(&mut builder)?; - let counts = builder.counts()?; - - // verify sizes - if !self.validate_sizes(&counts) { - Err(ProofError::VerificationError { - error: "invalid proof size", - })?; - } // construct a transcript for the proof let mut transcript: Keccak256Transcript = make_transcript( @@ -257,6 +251,7 @@ impl QueryProof { self.range_length, min_row_num, &self.one_evaluation_lengths, + self.post_result_challenge_count, ); // These are the challenges that will be consumed by the proof @@ -266,7 +261,7 @@ impl QueryProof { // Note: the last challenge in the vec is the first one that is consumed. let post_result_challenges = core::iter::repeat_with(|| transcript.scalar_challenge_as_be()) - .take(counts.post_result_challenges) + .take(self.post_result_challenge_count) .collect(); // add the commitments and bit disctibutions to the proof @@ -277,7 +272,7 @@ impl QueryProof { ); // draw the random scalars for sumcheck - let num_random_scalars = num_sumcheck_variables + counts.sumcheck_subpolynomials; + let num_random_scalars = num_sumcheck_variables + self.subpolynomial_constraint_count; let random_scalars: Vec<_> = core::iter::repeat_with(|| transcript.scalar_challenge_as_be()) .take(num_random_scalars) @@ -391,11 +386,6 @@ impl QueryProof { verification_hash, }) } - - fn validate_sizes(&self, counts: &ProofCounts) -> bool { - self.commitments.len() == counts.intermediate_mles - && self.pcs_proof_evaluations.len() == counts.intermediate_mles + counts.anchored_mles - } } /// Constructs a transcript for the proof process. @@ -421,6 +411,7 @@ fn make_transcript( range_length: usize, min_row_num: usize, one_evaluation_lengths: &[usize], + post_result_challenge_count: usize, ) -> T { let mut transcript = T::new(); extend_transcript_with_owned_table(&mut transcript, result); @@ -428,6 +419,7 @@ fn make_transcript( transcript.extend_serialize_as_le(&range_length); transcript.extend_serialize_as_le(&min_row_num); transcript.extend_serialize_as_le(one_evaluation_lengths); + transcript.extend_serialize_as_le(&post_result_challenge_count); transcript } 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 3a4e97025..5ab21a7de 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 @@ -28,7 +28,7 @@ struct TrivialTestProofPlan { offset: usize, column_fill_value: i64, evaluation: i64, - anchored_mle_count: usize, + produce_length: bool, } impl Default for TrivialTestProofPlan { fn default() -> Self { @@ -37,7 +37,7 @@ impl Default for TrivialTestProofPlan { offset: 0, column_fill_value: 0, evaluation: 0, - anchored_mle_count: 0, + produce_length: true, } } } @@ -49,7 +49,9 @@ impl ProverEvaluate for TrivialTestProofPlan { _table_map: &IndexMap>, ) -> Table<'a, S> { let col = vec![self.column_fill_value; self.length]; - builder.produce_one_evaluation_length(self.length); + if self.produce_length { + builder.produce_one_evaluation_length(self.length); + } table([borrowed_bigint("a1", col, alloc)]) } @@ -77,7 +79,6 @@ impl ProofPlan for TrivialTestProofPlan { builder.count_degree(2); builder.count_intermediate_mles(1); builder.count_subpolynomials(1); - builder.count_anchored_mles(self.anchored_mle_count); Ok(()) } fn verifier_evaluate( @@ -193,7 +194,7 @@ fn verify_fails_if_counts_dont_match() { // prove and verify an artificial polynomial where we try to prove // that every entry in the result is zero let expr = TrivialTestProofPlan { - anchored_mle_count: 1, + produce_length: false, ..Default::default() }; let accessor = OwnedTableTestAccessor::::new_from_table( From 3d37e881cde94c27e483bf44ee51b15a1b3f3026 Mon Sep 17 00:00:00 2001 From: Jay White Date: Wed, 11 Dec 2024 00:18:30 -0500 Subject: [PATCH 6/8] chore: drop dead `ProofCounts` In addition to `ProofCounts`, the `count` method of the SQL nodes is removed as it is now handled by fallible methods in the `VerificationBuilder`. --- .../src/sql/proof/count_builder.rs | 74 ------------------- .../src/sql/proof/first_round_builder.rs | 2 - crates/proof-of-sql/src/sql/proof/mod.rs | 5 -- .../src/sql/proof/proof_counts.rs | 36 --------- .../proof-of-sql/src/sql/proof/proof_plan.rs | 5 +- .../src/sql/proof/query_proof_test.rs | 29 +------- .../sql/proof/verifiable_query_result_test.rs | 8 +- .../src/sql/proof_exprs/add_subtract_expr.rs | 8 +- .../src/sql/proof_exprs/aggregate_expr.rs | 7 +- .../src/sql/proof_exprs/and_expr.rs | 11 +-- .../src/sql/proof_exprs/column_expr.rs | 7 +- .../src/sql/proof_exprs/dyn_proof_expr.rs | 2 +- .../src/sql/proof_exprs/equals_expr.rs | 15 +--- .../src/sql/proof_exprs/inequality_expr.rs | 15 +--- .../src/sql/proof_exprs/literal_expr.rs | 6 +- .../proof-of-sql/src/sql/proof_exprs/mod.rs | 8 +- .../src/sql/proof_exprs/multiply_expr.rs | 11 +-- .../src/sql/proof_exprs/not_expr.rs | 6 +- .../src/sql/proof_exprs/or_expr.rs | 15 +--- .../src/sql/proof_exprs/proof_expr.rs | 5 +- .../src/sql/proof_exprs/sign_expr.rs | 17 +---- .../src/sql/proof_exprs/sign_expr_test.rs | 31 ++++---- .../src/sql/proof_plans/demo_mock_plan.rs | 9 +-- .../src/sql/proof_plans/dyn_proof_plan.rs | 3 +- .../src/sql/proof_plans/empty_exec.rs | 7 +- .../src/sql/proof_plans/filter_exec.rs | 17 +---- .../src/sql/proof_plans/group_by_exec.rs | 21 +----- .../src/sql/proof_plans/projection_exec.rs | 11 +-- .../src/sql/proof_plans/slice_exec.rs | 13 +--- .../src/sql/proof_plans/table_exec.rs | 7 +- .../src/sql/proof_plans/union_exec.rs | 16 +--- 31 files changed, 49 insertions(+), 378 deletions(-) delete mode 100644 crates/proof-of-sql/src/sql/proof/count_builder.rs delete mode 100644 crates/proof-of-sql/src/sql/proof/proof_counts.rs diff --git a/crates/proof-of-sql/src/sql/proof/count_builder.rs b/crates/proof-of-sql/src/sql/proof/count_builder.rs deleted file mode 100644 index 3229b9edc..000000000 --- a/crates/proof-of-sql/src/sql/proof/count_builder.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::{ - base::{bit::BitDistribution, proof::ProofError}, - sql::proof::ProofCounts, -}; -use core::cmp::max; - -/// Track the number of components expected for in a query's proof -pub struct CountBuilder<'a> { - bit_distributions: &'a [BitDistribution], - counts: ProofCounts, -} - -impl<'a> CountBuilder<'a> { - pub fn new(bit_distributions: &'a [BitDistribution]) -> Self { - Self { - bit_distributions, - counts: ProofCounts::default(), - } - } - - /// Proof counts can be dependent on how bits are distributed in a column of data. - /// - /// This method provides access to the bit distributions of a proof during the counting - /// pass of verification. - pub fn consume_bit_distribution(&mut self) -> Result { - if self.bit_distributions.is_empty() { - Err(ProofError::VerificationError { - error: "expected prover to provide bit distribution", - }) - } else { - let res = self.bit_distributions[0].clone(); - self.bit_distributions = &self.bit_distributions[1..]; - Ok(res) - } - } - - pub fn count_result_columns(&mut self, cnt: usize) { - self.counts.result_columns += cnt; - } - - pub fn count_subpolynomials(&mut self, cnt: usize) { - self.counts.sumcheck_subpolynomials += cnt; - } - - pub fn count_anchored_mles(&mut self, cnt: usize) { - self.counts.anchored_mles += cnt; - } - - pub fn count_intermediate_mles(&mut self, cnt: usize) { - self.counts.intermediate_mles += cnt; - } - - pub fn count_degree(&mut self, degree: usize) { - self.counts.sumcheck_max_multiplicands = - max(self.counts.sumcheck_max_multiplicands, degree); - } - - pub fn counts(&self) -> Result { - if !self.bit_distributions.is_empty() { - return Err(ProofError::VerificationError { - error: "incorrect number of bit distributions provided", - }); - } - Ok(self.counts) - } - - /// Adds `cnt` to the number of challenges used in the proof. - /// Specifically, these are the challenges that the verifier sends to - /// the prover after the prover sends the result, but before the prover - /// send commitments to the intermediate witness columns. - pub fn count_post_result_challenges(&mut self, cnt: usize) { - self.counts.post_result_challenges += cnt; - } -} diff --git a/crates/proof-of-sql/src/sql/proof/first_round_builder.rs b/crates/proof-of-sql/src/sql/proof/first_round_builder.rs index 9742098bc..15989adf4 100644 --- a/crates/proof-of-sql/src/sql/proof/first_round_builder.rs +++ b/crates/proof-of-sql/src/sql/proof/first_round_builder.rs @@ -46,8 +46,6 @@ impl FirstRoundBuilder { /// Specifically, these are the challenges that the verifier sends to /// the prover after the prover sends the result, but before the prover /// send commitments to the intermediate witness columns. - /// - /// Note: this must be matched with the same count in the [`CountBuilder`](crate::sql::proof::CountBuilder). pub fn request_post_result_challenges(&mut self, cnt: usize) { self.num_post_result_challenges += cnt; } diff --git a/crates/proof-of-sql/src/sql/proof/mod.rs b/crates/proof-of-sql/src/sql/proof/mod.rs index f31e456ee..96dfc5874 100644 --- a/crates/proof-of-sql/src/sql/proof/mod.rs +++ b/crates/proof-of-sql/src/sql/proof/mod.rs @@ -1,6 +1,4 @@ //! TODO: add docs -mod count_builder; -pub(crate) use count_builder::CountBuilder; mod final_round_builder; pub(crate) use final_round_builder::FinalRoundBuilder; @@ -12,9 +10,6 @@ pub(crate) use composite_polynomial_builder::CompositePolynomialBuilder; #[cfg(test)] mod composite_polynomial_builder_test; -mod proof_counts; -pub(crate) use proof_counts::ProofCounts; - mod verification_builder; pub(crate) use verification_builder::VerificationBuilder; #[cfg(test)] diff --git a/crates/proof-of-sql/src/sql/proof/proof_counts.rs b/crates/proof-of-sql/src/sql/proof/proof_counts.rs deleted file mode 100644 index 4ce127eda..000000000 --- a/crates/proof-of-sql/src/sql/proof/proof_counts.rs +++ /dev/null @@ -1,36 +0,0 @@ -use core::fmt::Debug; -use serde::{Deserialize, Serialize}; - -/// Counters for different terms used within a proof -#[derive(Default, Debug, Clone, Copy, Serialize, Deserialize)] -pub struct ProofCounts { - pub sumcheck_max_multiplicands: usize, - pub result_columns: usize, - pub anchored_mles: usize, - pub intermediate_mles: usize, - pub sumcheck_subpolynomials: usize, - - /// The number of challenges used in the proof. - /// Specifically, these are the challenges that the verifier sends to - /// the prover after the prover sends the result, but before the prover - /// send commitments to the intermediate witness columns. - pub post_result_challenges: usize, -} - -impl ProofCounts { - #[tracing::instrument(name = "ProofCounts::annotate_trace", level = "debug", skip_all)] - pub fn annotate_trace(&self) { - tracing::info!( - "sumcheck_max_multiplicands = {:?}", - self.sumcheck_max_multiplicands - ); - tracing::info!("result_columns = {:?}", self.result_columns); - tracing::info!("anchored_mles = {:?}", self.anchored_mles); - tracing::info!("intermediate_mles = {:?}", self.intermediate_mles); - tracing::info!( - "sumcheck_subpolynomials = {:?}", - self.sumcheck_subpolynomials - ); - tracing::info!("post_result_challenges = {:?}", self.post_result_challenges); - } -} diff --git a/crates/proof-of-sql/src/sql/proof/proof_plan.rs b/crates/proof-of-sql/src/sql/proof/proof_plan.rs index f033b3451..67547cde8 100644 --- a/crates/proof-of-sql/src/sql/proof/proof_plan.rs +++ b/crates/proof-of-sql/src/sql/proof/proof_plan.rs @@ -1,4 +1,4 @@ -use super::{CountBuilder, FinalRoundBuilder, FirstRoundBuilder, VerificationBuilder}; +use super::{FinalRoundBuilder, FirstRoundBuilder, VerificationBuilder}; use crate::base::{ database::{ColumnField, ColumnRef, OwnedTable, Table, TableEvaluation, TableRef}, map::{IndexMap, IndexSet}, @@ -12,9 +12,6 @@ use core::fmt::Debug; /// Provable nodes in the provable AST. #[enum_dispatch::enum_dispatch(DynProofPlan)] pub trait ProofPlan: Debug + Send + Sync + ProverEvaluate { - /// Count terms used within the Query's proof - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError>; - /// Form components needed to verify and proof store into `VerificationBuilder` fn verifier_evaluate( &self, 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 5ab21a7de..46029dc6a 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 @@ -1,6 +1,4 @@ -use super::{ - CountBuilder, FinalRoundBuilder, ProofPlan, ProverEvaluate, QueryProof, VerificationBuilder, -}; +use super::{FinalRoundBuilder, ProofPlan, ProverEvaluate, QueryProof, VerificationBuilder}; use crate::{ base::{ commitment::InnerProductProof, @@ -75,12 +73,6 @@ impl ProverEvaluate for TrivialTestProofPlan { } } impl ProofPlan for TrivialTestProofPlan { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - builder.count_degree(2); - builder.count_intermediate_mles(1); - builder.count_subpolynomials(1); - Ok(()) - } fn verifier_evaluate( &self, builder: &mut VerificationBuilder, @@ -259,12 +251,6 @@ impl ProverEvaluate for SquareTestProofPlan { } } impl ProofPlan for SquareTestProofPlan { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - builder.count_degree(3); - builder.count_intermediate_mles(1); - builder.count_subpolynomials(1); - Ok(()) - } fn verifier_evaluate( &self, builder: &mut VerificationBuilder, @@ -457,12 +443,6 @@ impl ProverEvaluate for DoubleSquareTestProofPlan { } } impl ProofPlan for DoubleSquareTestProofPlan { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - builder.count_degree(3); - builder.count_intermediate_mles(2); - builder.count_subpolynomials(2); - Ok(()) - } fn verifier_evaluate( &self, builder: &mut VerificationBuilder, @@ -663,13 +643,6 @@ impl ProverEvaluate for ChallengeTestProofPlan { } } impl ProofPlan for ChallengeTestProofPlan { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - builder.count_degree(4); - builder.count_intermediate_mles(1); - builder.count_subpolynomials(1); - builder.count_post_result_challenges(2); - Ok(()) - } fn verifier_evaluate( &self, builder: &mut VerificationBuilder, diff --git a/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs b/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs index eb6a3ddd7..b95334b95 100644 --- a/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs +++ b/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test.rs @@ -1,6 +1,5 @@ use super::{ - CountBuilder, FinalRoundBuilder, ProofPlan, ProverEvaluate, VerifiableQueryResult, - VerificationBuilder, + FinalRoundBuilder, ProofPlan, ProverEvaluate, VerifiableQueryResult, VerificationBuilder, }; use crate::{ base::{ @@ -58,11 +57,6 @@ impl ProverEvaluate for EmptyTestQueryExpr { } } impl ProofPlan for EmptyTestQueryExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - builder.count_intermediate_mles(self.columns); - Ok(()) - } - fn verifier_evaluate( &self, builder: &mut VerificationBuilder, diff --git a/crates/proof-of-sql/src/sql/proof_exprs/add_subtract_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/add_subtract_expr.rs index 96e89271e..0e10f1188 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/add_subtract_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/add_subtract_expr.rs @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use alloc::boxed::Box; use bumpalo::Bump; @@ -32,12 +32,6 @@ impl AddSubtractExpr { } impl ProofExpr for AddSubtractExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.lhs.count(builder)?; - self.rhs.count(builder)?; - Ok(()) - } - fn data_type(&self) -> ColumnType { try_add_subtract_column_types(self.lhs.data_type(), self.rhs.data_type()) .expect("Failed to add/subtract column types") diff --git a/crates/proof-of-sql/src/sql/proof_exprs/aggregate_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/aggregate_expr.rs index af721a9dd..41b15e102 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/aggregate_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/aggregate_expr.rs @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use alloc::boxed::Box; use bumpalo::Bump; @@ -30,10 +30,7 @@ impl AggregateExpr { } impl ProofExpr for AggregateExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.expr.count(builder) - } - + // Remove the count method fn data_type(&self) -> ColumnType { match self.op { AggregationOperator::Count => ColumnType::BigInt, 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 e0b7cc6db..0536c9068 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 @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, }; use alloc::{boxed::Box, vec}; use bumpalo::Bump; @@ -27,15 +27,6 @@ impl AndExpr { } impl ProofExpr for AndExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.lhs.count(builder)?; - self.rhs.count(builder)?; - builder.count_subpolynomials(1); - builder.count_intermediate_mles(1); - builder.count_degree(3); - Ok(()) - } - fn data_type(&self) -> ColumnType { ColumnType::Boolean } diff --git a/crates/proof-of-sql/src/sql/proof_exprs/column_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/column_expr.rs index aae7ffd0c..58493099e 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/column_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/column_expr.rs @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use bumpalo::Bump; use proof_of_sql_parser::Identifier; @@ -54,11 +54,6 @@ impl ColumnExpr { } impl ProofExpr for ColumnExpr { - /// Count the number of proof terms needed by this expression - fn count(&self, _builder: &mut CountBuilder) -> Result<(), ProofError> { - Ok(()) - } - /// Get the data type of the expression fn data_type(&self) -> ColumnType { *self.get_column_reference().column_type() diff --git a/crates/proof-of-sql/src/sql/proof_exprs/dyn_proof_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/dyn_proof_expr.rs index 5f3082a52..efe540b52 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/dyn_proof_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/dyn_proof_expr.rs @@ -11,7 +11,7 @@ use crate::{ }, sql::{ parse::{type_check_binary_operation, ConversionError, ConversionResult}, - proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + proof::{FinalRoundBuilder, VerificationBuilder}, }, }; use alloc::{boxed::Box, string::ToString}; 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 a762b615e..94d1035e8 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 @@ -7,7 +7,7 @@ use crate::{ scalar::Scalar, slice_ops, }, - sql::proof::{CountBuilder, FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, }; use alloc::{boxed::Box, vec}; use bumpalo::Bump; @@ -28,13 +28,6 @@ impl EqualsExpr { } impl ProofExpr for EqualsExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.lhs.count(builder)?; - self.rhs.count(builder)?; - count_equals_zero(builder); - Ok(()) - } - fn data_type(&self) -> ColumnType { ColumnType::Boolean } @@ -174,9 +167,3 @@ pub fn verifier_evaluate_equals_zero( Ok(selection_eval) } - -pub fn count_equals_zero(builder: &mut CountBuilder) { - builder.count_subpolynomials(2); - builder.count_intermediate_mles(2); - builder.count_degree(3); -} diff --git a/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs index 48c397d5f..2f2af814a 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/inequality_expr.rs @@ -1,6 +1,6 @@ use super::{ - count_equals_zero, count_or, count_sign, prover_evaluate_equals_zero, prover_evaluate_or, - prover_evaluate_sign, result_evaluate_equals_zero, result_evaluate_or, result_evaluate_sign, + prover_evaluate_equals_zero, prover_evaluate_or, prover_evaluate_sign, + result_evaluate_equals_zero, result_evaluate_or, result_evaluate_sign, scale_and_add_subtract_eval, scale_and_subtract, verifier_evaluate_equals_zero, verifier_evaluate_or, verifier_evaluate_sign, DynProofExpr, ProofExpr, }; @@ -11,7 +11,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use alloc::boxed::Box; use bumpalo::Bump; @@ -41,15 +41,6 @@ impl InequalityExpr { } impl ProofExpr for InequalityExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.lhs.count(builder)?; - self.rhs.count(builder)?; - count_equals_zero(builder); - count_sign(builder)?; - count_or(builder); - Ok(()) - } - fn data_type(&self) -> ColumnType { ColumnType::Boolean } diff --git a/crates/proof-of-sql/src/sql/proof_exprs/literal_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/literal_expr.rs index a942fc67d..f4a5f36e4 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/literal_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/literal_expr.rs @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use bumpalo::Bump; use serde::{Deserialize, Serialize}; @@ -35,10 +35,6 @@ impl LiteralExpr { } impl ProofExpr for LiteralExpr { - fn count(&self, _builder: &mut CountBuilder) -> Result<(), ProofError> { - Ok(()) - } - fn data_type(&self) -> ColumnType { self.value.column_type() } diff --git a/crates/proof-of-sql/src/sql/proof_exprs/mod.rs b/crates/proof-of-sql/src/sql/proof_exprs/mod.rs index 1b45db80e..73ad59d34 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/mod.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/mod.rs @@ -44,7 +44,7 @@ use inequality_expr::InequalityExpr; mod inequality_expr_test; mod or_expr; -use or_expr::{count_or, prover_evaluate_or, result_evaluate_or, verifier_evaluate_or, OrExpr}; +use or_expr::{prover_evaluate_or, result_evaluate_or, verifier_evaluate_or, OrExpr}; #[cfg(all(test, feature = "blitzar"))] mod or_expr_test; @@ -63,14 +63,14 @@ pub(crate) use numerical_util::{ mod equals_expr; use equals_expr::{ - count_equals_zero, prover_evaluate_equals_zero, result_evaluate_equals_zero, - verifier_evaluate_equals_zero, EqualsExpr, + prover_evaluate_equals_zero, result_evaluate_equals_zero, verifier_evaluate_equals_zero, + EqualsExpr, }; #[cfg(all(test, feature = "blitzar"))] mod equals_expr_test; mod sign_expr; -use sign_expr::{count_sign, prover_evaluate_sign, result_evaluate_sign, verifier_evaluate_sign}; +use sign_expr::{prover_evaluate_sign, result_evaluate_sign, verifier_evaluate_sign}; #[cfg(all(test, feature = "blitzar"))] mod sign_expr_test; 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 4a2f39b13..10861c66a 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 @@ -7,7 +7,7 @@ use crate::{ scalar::Scalar, }, sql::{ - proof::{CountBuilder, FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, + proof::{FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, proof_exprs::multiply_columns, }, }; @@ -30,15 +30,6 @@ impl MultiplyExpr { } impl ProofExpr for MultiplyExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.lhs.count(builder)?; - self.rhs.count(builder)?; - builder.count_subpolynomials(1); - builder.count_intermediate_mles(1); - builder.count_degree(3); - Ok(()) - } - fn data_type(&self) -> ColumnType { try_multiply_column_types(self.lhs.data_type(), self.rhs.data_type()) .expect("Failed to multiply column types") diff --git a/crates/proof-of-sql/src/sql/proof_exprs/not_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/not_expr.rs index c52b4e987..a85944742 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/not_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/not_expr.rs @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use alloc::boxed::Box; use bumpalo::Bump; @@ -26,10 +26,6 @@ impl NotExpr { } impl ProofExpr for NotExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.expr.count(builder) - } - fn data_type(&self) -> ColumnType { ColumnType::Boolean } 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 6b443a41b..71697722f 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 @@ -6,7 +6,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, }; use alloc::{boxed::Box, vec}; use bumpalo::Bump; @@ -27,13 +27,6 @@ impl OrExpr { } impl ProofExpr for OrExpr { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.lhs.count(builder)?; - self.rhs.count(builder)?; - count_or(builder); - Ok(()) - } - fn data_type(&self) -> ColumnType { ColumnType::Boolean } @@ -146,9 +139,3 @@ pub fn verifier_evaluate_or( // selection Ok(*lhs + *rhs - lhs_and_rhs) } - -pub fn count_or(builder: &mut CountBuilder) { - builder.count_subpolynomials(1); - builder.count_intermediate_mles(1); - builder.count_degree(3); -} diff --git a/crates/proof-of-sql/src/sql/proof_exprs/proof_expr.rs b/crates/proof-of-sql/src/sql/proof_exprs/proof_expr.rs index d3bfdef5e..6e85b6b95 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/proof_expr.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/proof_expr.rs @@ -5,7 +5,7 @@ use crate::{ proof::ProofError, scalar::Scalar, }, - sql::proof::{CountBuilder, FinalRoundBuilder, VerificationBuilder}, + sql::proof::{FinalRoundBuilder, VerificationBuilder}, }; use bumpalo::Bump; use core::fmt::Debug; @@ -13,9 +13,6 @@ use core::fmt::Debug; /// Provable AST column expression that evaluates to a `Column` #[enum_dispatch::enum_dispatch(DynProofExpr)] pub trait ProofExpr: Debug + Send + Sync { - /// Count the number of proof terms needed for this expression - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError>; - /// Get the data type of the expression fn data_type(&self) -> ColumnType; 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 e2ba148be..85821bf26 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 @@ -6,28 +6,13 @@ use crate::{ scalar::Scalar, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, SumcheckSubpolynomialTerm, SumcheckSubpolynomialType, + FinalRoundBuilder, SumcheckSubpolynomialTerm, SumcheckSubpolynomialType, VerificationBuilder, }, }; use alloc::{boxed::Box, vec, vec::Vec}; use bumpalo::Bump; -/// Count the number of components needed to prove a sign decomposition -pub fn count_sign(builder: &mut CountBuilder) -> Result<(), ProofError> { - let dist = builder.consume_bit_distribution()?; - if dist.num_varying_bits() == 0 { - return Ok(()); - } - builder.count_intermediate_mles(dist.num_varying_bits()); - builder.count_subpolynomials(dist.num_varying_bits()); - builder.count_degree(3); - if dist.has_varying_sign_bit() && dist.num_varying_bits() > 1 { - builder.count_subpolynomials(1); - } - Ok(()) -} - /// Compute the sign bit for a column of scalars. /// /// # Panics diff --git a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs index 789d08648..e1aa7e1f2 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs @@ -1,9 +1,8 @@ -use super::{count_sign, prover_evaluate_sign, result_evaluate_sign, verifier_evaluate_sign}; +use super::{prover_evaluate_sign, result_evaluate_sign, verifier_evaluate_sign}; use crate::{ base::{bit::BitDistribution, polynomial::MultilinearExtension, scalar::Curve25519Scalar}, sql::proof::{ - CountBuilder, FinalRoundBuilder, SumcheckMleEvaluations, SumcheckRandomScalars, - VerificationBuilder, + FinalRoundBuilder, SumcheckMleEvaluations, SumcheckRandomScalars, VerificationBuilder, }, }; use bumpalo::Bump; @@ -33,20 +32,20 @@ fn prover_evaluation_generates_the_bit_distribution_of_a_negative_constant_colum assert_eq!(builder.bit_distributions(), [dist]); } -#[test] -fn count_fails_if_a_bit_distribution_is_out_of_range() { - let dists = [BitDistribution::new::(&[ - Curve25519Scalar::from(3) * Curve25519Scalar::from(u128::MAX), - ])]; - let mut builder = CountBuilder::new(&dists); - assert!(count_sign(&mut builder).is_err()); -} +// #[test] +// fn count_fails_if_a_bit_distribution_is_out_of_range() { +// let dists = [BitDistribution::new::(&[ +// Curve25519Scalar::from(3) * Curve25519Scalar::from(u128::MAX), +// ])]; +// let mut builder = CountBuilder::new(&dists); +// assert!(count_sign(&mut builder).is_err()); +// } -#[test] -fn count_fails_if_no_bit_distribution_is_available() { - let mut builder = CountBuilder::new(&[]); - assert!(count_sign(&mut builder).is_err()); -} +// #[test] +// fn count_fails_if_no_bit_distribution_is_available() { +// let mut builder = CountBuilder::new(&[]); +// assert!(count_sign(&mut builder).is_err()); +// } #[test] fn we_can_verify_a_constant_decomposition() { diff --git a/crates/proof-of-sql/src/sql/proof_plans/demo_mock_plan.rs b/crates/proof-of-sql/src/sql/proof_plans/demo_mock_plan.rs index 52c3e9421..8b865b885 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/demo_mock_plan.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/demo_mock_plan.rs @@ -6,8 +6,7 @@ use crate::{ scalar::Scalar, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder, }, }; use alloc::vec::Vec; @@ -20,12 +19,6 @@ pub(crate) struct DemoMockPlan { } impl ProofPlan for DemoMockPlan { - fn count(&self, _builder: &mut CountBuilder) -> Result<(), ProofError> { - // place verification logic you want to test here - - Ok(()) - } - fn verifier_evaluate( &self, _builder: &mut VerificationBuilder, diff --git a/crates/proof-of-sql/src/sql/proof_plans/dyn_proof_plan.rs b/crates/proof-of-sql/src/sql/proof_plans/dyn_proof_plan.rs index eb5b2b4cc..22e69c2b2 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/dyn_proof_plan.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/dyn_proof_plan.rs @@ -7,8 +7,7 @@ use crate::{ scalar::Scalar, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder, }, }; use alloc::vec::Vec; diff --git a/crates/proof-of-sql/src/sql/proof_plans/empty_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/empty_exec.rs index 3c6fba360..1ed5bf0f3 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/empty_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/empty_exec.rs @@ -8,8 +8,7 @@ use crate::{ scalar::Scalar, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder, }, }; use alloc::vec::Vec; @@ -36,10 +35,6 @@ impl EmptyExec { } impl ProofPlan for EmptyExec { - fn count(&self, _builder: &mut CountBuilder) -> Result<(), ProofError> { - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, 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 2c6e05c29..32c7e7cf0 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 @@ -12,8 +12,8 @@ use crate::{ }, sql::{ proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, HonestProver, ProofPlan, - ProverEvaluate, ProverHonestyMarker, SumcheckSubpolynomialType, VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, HonestProver, ProofPlan, ProverEvaluate, + ProverHonestyMarker, SumcheckSubpolynomialType, VerificationBuilder, }, proof_exprs::{AliasedDynProofExpr, DynProofExpr, ProofExpr, TableExpr}, }, @@ -59,19 +59,6 @@ impl ProofPlan for OstensibleFilterExec where OstensibleFilterExec: ProverEvaluate, { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.where_clause.count(builder)?; - for aliased_expr in &self.aliased_results { - aliased_expr.expr.count(builder)?; - builder.count_intermediate_mles(1); - } - builder.count_intermediate_mles(2); - builder.count_subpolynomials(3); - builder.count_degree(3); - builder.count_post_result_challenges(2); - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, 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 64dd2ad02..883bf7fca 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 @@ -14,7 +14,7 @@ use crate::{ }, sql::{ proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, SumcheckSubpolynomialType, VerificationBuilder, }, proof_exprs::{AliasedDynProofExpr, ColumnExpr, DynProofExpr, ProofExpr, TableExpr}, @@ -67,25 +67,6 @@ impl GroupByExec { } impl ProofPlan for GroupByExec { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.where_clause.count(builder)?; - for expr in &self.group_by_exprs { - expr.count(builder)?; - builder.count_intermediate_mles(1); - } - for aliased_expr in &self.sum_expr { - aliased_expr.expr.count(builder)?; - builder.count_intermediate_mles(1); - } - // For the count col - builder.count_intermediate_mles(1); - builder.count_intermediate_mles(2); - builder.count_subpolynomials(3); - builder.count_degree(3); - builder.count_post_result_challenges(2); - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, diff --git a/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs index a02092d44..7e0981bbb 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/projection_exec.rs @@ -9,8 +9,7 @@ use crate::{ }, sql::{ proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder, }, proof_exprs::{AliasedDynProofExpr, ProofExpr, TableExpr}, }, @@ -40,14 +39,6 @@ impl ProjectionExec { } impl ProofPlan for ProjectionExec { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - for aliased_expr in &self.aliased_results { - aliased_expr.expr.count(builder)?; - builder.count_intermediate_mles(1); - } - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, diff --git a/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs index 3466178c2..313ee7c65 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/slice_exec.rs @@ -13,8 +13,7 @@ use crate::{ scalar::Scalar, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder, }, }; use alloc::{boxed::Box, vec::Vec}; @@ -55,16 +54,6 @@ impl ProofPlan for SliceExec where SliceExec: ProverEvaluate, { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - self.input.count(builder)?; - builder.count_intermediate_mles(self.input.get_column_result_fields().len()); - builder.count_intermediate_mles(2); - builder.count_subpolynomials(3); - builder.count_degree(3); - builder.count_post_result_challenges(2); - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, diff --git a/crates/proof-of-sql/src/sql/proof_plans/table_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/table_exec.rs index dc90fdf88..b86339afb 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/table_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/table_exec.rs @@ -6,8 +6,7 @@ use crate::{ scalar::Scalar, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder, }, }; use alloc::vec::Vec; @@ -34,10 +33,6 @@ impl TableExec { } impl ProofPlan for TableExec { - fn count(&self, _builder: &mut CountBuilder) -> Result<(), ProofError> { - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, diff --git a/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs b/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs index dfee32c44..0fca988a0 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/union_exec.rs @@ -12,8 +12,8 @@ use crate::{ slice_ops, }, sql::proof::{ - CountBuilder, FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, - SumcheckSubpolynomialType, VerificationBuilder, + FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, SumcheckSubpolynomialType, + VerificationBuilder, }, }; use alloc::{boxed::Box, vec, vec::Vec}; @@ -47,18 +47,6 @@ impl ProofPlan for UnionExec where UnionExec: ProverEvaluate, { - fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> { - let num_parts = self.inputs.len(); - self.inputs - .iter() - .try_for_each(|input| input.count(builder))?; - builder.count_intermediate_mles(num_parts + self.schema.len() + 1); - builder.count_subpolynomials(num_parts + 2); - builder.count_degree(3); - builder.count_post_result_challenges(2); - Ok(()) - } - #[allow(unused_variables)] fn verifier_evaluate( &self, From 799b363d1b2195ae9b337fb8b510fc39418d3caf Mon Sep 17 00:00:00 2001 From: Jay White Date: Wed, 11 Dec 2024 21:51:16 -0500 Subject: [PATCH 7/8] fixup! refactor: move BitDistribution range validation from `count_sign` to `QueryProof::verify` --- .../src/sql/proof/query_proof_test.rs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) 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 46029dc6a..0d043fb68 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 @@ -1,6 +1,7 @@ use super::{FinalRoundBuilder, ProofPlan, ProverEvaluate, QueryProof, VerificationBuilder}; use crate::{ base::{ + bit::BitDistribution, commitment::InnerProductProof, database::{ owned_table_utility::{bigint, owned_table}, @@ -27,6 +28,7 @@ struct TrivialTestProofPlan { column_fill_value: i64, evaluation: i64, produce_length: bool, + bit_distribution: Option, } impl Default for TrivialTestProofPlan { fn default() -> Self { @@ -36,6 +38,10 @@ impl Default for TrivialTestProofPlan { column_fill_value: 0, evaluation: 0, produce_length: true, + bit_distribution: Some(BitDistribution { + or_all: [0; 4], + vary_mask: [0; 4], + }), } } } @@ -65,6 +71,9 @@ impl ProverEvaluate for TrivialTestProofPlan { SumcheckSubpolynomialType::Identity, vec![(S::ONE, vec![Box::new(col as &[_])])], ); + if let Some(bit_distribution) = &self.bit_distribution { + builder.produce_bit_distribution(bit_distribution.clone()); + } table([borrowed_bigint( "a1", vec![self.column_fill_value; self.length], @@ -86,6 +95,7 @@ impl ProofPlan for TrivialTestProofPlan { S::from(self.evaluation), 1, )?; + let _ = builder.try_consume_bit_distribution()?; Ok(TableEvaluation::new( vec![S::ZERO], builder.try_consume_one_evaluation()?, @@ -199,6 +209,41 @@ fn verify_fails_if_counts_dont_match() { assert!(proof.verify(&expr, &accessor, result, &()).is_err()); } +#[test] +fn verify_fails_if_the_number_of_bit_distributions_is_not_enough() { + let expr = TrivialTestProofPlan { + bit_distribution: None, + ..Default::default() + }; + let accessor = OwnedTableTestAccessor::::new_from_table( + "sxt.test".parse().unwrap(), + owned_table([bigint("a1", [0_i64; 2])]), + 0, + (), + ); + let (proof, result) = QueryProof::::new(&expr, &accessor, &()); + assert!(proof.verify(&expr, &accessor, result, &()).is_err()); +} + +#[test] +fn verify_fails_if_a_bit_distribution_is_invalid() { + let expr = TrivialTestProofPlan { + bit_distribution: Some(BitDistribution { + or_all: [1; 4], + vary_mask: [1; 4], + }), + ..Default::default() + }; + let accessor = OwnedTableTestAccessor::::new_from_table( + "sxt.test".parse().unwrap(), + owned_table([bigint("a1", [0_i64; 2])]), + 0, + (), + ); + let (proof, result) = QueryProof::::new(&expr, &accessor, &()); + assert!(proof.verify(&expr, &accessor, result, &()).is_err()); +} + /// prove and verify an artificial query where /// `res_i = x_i * x_i` /// where the commitment for x is known From 4aafb4984888066c973439a8cd2f730f438fd88b Mon Sep 17 00:00:00 2001 From: Jay White Date: Wed, 11 Dec 2024 21:52:27 -0500 Subject: [PATCH 8/8] fixup! chore: drop dead `ProofCounts` --- .../src/sql/proof_exprs/sign_expr_test.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs index e1aa7e1f2..215f4b4f2 100644 --- a/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs +++ b/crates/proof-of-sql/src/sql/proof_exprs/sign_expr_test.rs @@ -32,21 +32,6 @@ fn prover_evaluation_generates_the_bit_distribution_of_a_negative_constant_colum assert_eq!(builder.bit_distributions(), [dist]); } -// #[test] -// fn count_fails_if_a_bit_distribution_is_out_of_range() { -// let dists = [BitDistribution::new::(&[ -// Curve25519Scalar::from(3) * Curve25519Scalar::from(u128::MAX), -// ])]; -// let mut builder = CountBuilder::new(&dists); -// assert!(count_sign(&mut builder).is_err()); -// } - -// #[test] -// fn count_fails_if_no_bit_distribution_is_available() { -// let mut builder = CountBuilder::new(&[]); -// assert!(count_sign(&mut builder).is_err()); -// } - #[test] fn we_can_verify_a_constant_decomposition() { let data = [123_i64, 123, 123];