From 51e87ebd81904237e78ca0833f885b68ee0418cd Mon Sep 17 00:00:00 2001 From: Ian Joiner <14581281+iajoiner@users.noreply.github.com> Date: Thu, 12 Sep 2024 16:36:16 -0400 Subject: [PATCH] refactor: switch to `consume_intermediate_mle` in `ProofPlan::verifier_evaluate` - `ProofPlan` change above - bump `alloy` to `0.8.1` --- Cargo.toml | 4 +- .../proof-of-sql/src/base/database/column.rs | 17 ++++++++ .../src/sql/proof/provable_query_result.rs | 2 +- .../proof-of-sql/src/sql/proof/query_proof.rs | 3 +- .../src/sql/proof/query_proof_test.rs | 16 ++++---- .../sql/proof/verifiable_query_result_test.rs | 2 +- .../verifiable_query_result_test_utility.rs | 5 ++- .../src/sql/proof/verification_builder.rs | 1 - .../src/sql/proof_plans/filter_exec.rs | 8 +++- .../filter_exec_test_dishonest_prover.rs | 4 ++ .../src/sql/proof_plans/group_by_exec.rs | 39 ++++++++++++------- .../src/sql/proof_plans/projection_exec.rs | 14 +++++-- 12 files changed, 78 insertions(+), 37 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bb5b05e71..46b96245b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ version = "0.0.0" # DO NOT CHANGE THIS LINE! This will be automatically updated license-file = "LICENSE" [workspace.dependencies] -alloy-primitives = { version = "0.8.0" } -alloy-sol-types = { version = "0.8.0" } +alloy-primitives = { version = "0.8.1" } +alloy-sol-types = { version = "0.8.1" } ark-bls12-381 = { version = "0.4.0" } ark-curve25519 = { version = "0.4.0" } ark-ec = { version = "0.4.0", features = [ "parallel" ] } diff --git a/crates/proof-of-sql/src/base/database/column.rs b/crates/proof-of-sql/src/base/database/column.rs index c79fcc784..cefd264fb 100644 --- a/crates/proof-of-sql/src/base/database/column.rs +++ b/crates/proof-of-sql/src/base/database/column.rs @@ -161,6 +161,23 @@ impl<'a, S: Scalar> Column<'a, S> { } } + /// Returns the column as a slice of scalars + pub(crate) fn as_scalar(&self, alloc: &'a Bump) -> &'a [S] { + match self { + Self::Boolean(col) => alloc.alloc_slice_fill_with(col.len(), |i| S::from(col[i])), + Self::SmallInt(col) => alloc.alloc_slice_fill_with(col.len(), |i| S::from(col[i])), + Self::Int(col) => alloc.alloc_slice_fill_with(col.len(), |i| S::from(col[i])), + Self::BigInt(col) => alloc.alloc_slice_fill_with(col.len(), |i| S::from(col[i])), + Self::Int128(col) => alloc.alloc_slice_fill_with(col.len(), |i| S::from(col[i])), + Self::Scalar(col) => col, + Self::Decimal75(_, _, col) => col, + Self::VarChar((_, scals)) => scals, + Self::TimestampTZ(_, _, col) => { + alloc.alloc_slice_fill_with(col.len(), |i| S::from(col[i])) + } + } + } + /// Returns element at index as scalar /// /// Note that if index is out of bounds, this function will return None diff --git a/crates/proof-of-sql/src/sql/proof/provable_query_result.rs b/crates/proof-of-sql/src/sql/proof/provable_query_result.rs index b9727e21f..4518e314b 100644 --- a/crates/proof-of-sql/src/sql/proof/provable_query_result.rs +++ b/crates/proof-of-sql/src/sql/proof/provable_query_result.rs @@ -81,7 +81,7 @@ impl ProvableQueryResult { table_length: usize, column_result_fields: &[ColumnField], ) -> Result, QueryError> { - assert_eq!(self.num_columns as usize, column_result_fields.len()); + //assert_eq!(self.num_columns as usize, column_result_fields.len()); if !self.indexes.valid(table_length) { return Err(QueryError::InvalidIndexes); 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 04be6d2e5..ca9703ce8 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -288,8 +288,7 @@ impl QueryProof { } fn validate_sizes(&self, counts: &ProofCounts, result: &ProvableQueryResult) -> bool { - result.num_columns() == counts.result_columns - && self.commitments.len() == counts.intermediate_mles + self.commitments.len() == counts.intermediate_mles && self.pcs_proof_evaluations.len() == counts.intermediate_mles + counts.anchored_mles } } 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 75fb2b4cd..e6d7cd1b1 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 @@ -74,7 +74,7 @@ impl ProofPlan for TrivialTestProofPlan { _accessor: &dyn MetadataAccessor, ) -> Result<(), ProofError> { builder.count_degree(2); - builder.count_result_columns(1); + builder.count_intermediate_mles(1); builder.count_subpolynomials(1); builder.count_anchored_mles(self.anchored_mle_count); Ok(()) @@ -91,7 +91,7 @@ impl ProofPlan for TrivialTestProofPlan { _accessor: &dyn CommitmentAccessor, _result: Option<&OwnedTable>, ) -> Result, ProofError> { - assert_eq!(builder.consume_result_mle(), C::Scalar::ZERO); + assert_eq!(builder.consume_intermediate_mle(), C::Scalar::ZERO); builder.produce_sumcheck_subpolynomial_evaluation(&C::Scalar::from(self.evaluation)); Ok(vec![C::Scalar::ZERO]) } @@ -248,7 +248,7 @@ impl ProofPlan for SquareTestProofPlan { _accessor: &dyn MetadataAccessor, ) -> Result<(), ProofError> { builder.count_degree(3); - builder.count_result_columns(1); + builder.count_intermediate_mles(1); builder.count_subpolynomials(1); builder.count_anchored_mles(1); Ok(()) @@ -265,7 +265,7 @@ impl ProofPlan for SquareTestProofPlan { accessor: &dyn CommitmentAccessor, _result: Option<&OwnedTable>, ) -> Result, ProofError> { - let res_eval = builder.consume_result_mle(); + let res_eval = builder.consume_intermediate_mle(); let x_commit = C::Scalar::from(self.anchored_commit_multiplier) * accessor.get_commitment(ColumnRef::new( "sxt.test".parse().unwrap(), @@ -439,7 +439,7 @@ impl ProofPlan for DoubleSquareTestProofPlan { _accessor: &dyn MetadataAccessor, ) -> Result<(), ProofError> { builder.count_degree(3); - builder.count_result_columns(1); + builder.count_intermediate_mles(1); builder.count_subpolynomials(2); builder.count_anchored_mles(1); builder.count_intermediate_mles(1); @@ -462,7 +462,7 @@ impl ProofPlan for DoubleSquareTestProofPlan { "x".parse().unwrap(), ColumnType::BigInt, )); - let res_eval = builder.consume_result_mle(); + let res_eval = builder.consume_intermediate_mle(); let x_eval = builder.consume_anchored_mle(x_commit); let z_eval = builder.consume_intermediate_mle(); @@ -635,7 +635,7 @@ impl ProofPlan for ChallengeTestProofPlan { _accessor: &dyn MetadataAccessor, ) -> Result<(), ProofError> { builder.count_degree(3); - builder.count_result_columns(1); + builder.count_intermediate_mles(1); builder.count_subpolynomials(1); builder.count_anchored_mles(1); builder.count_post_result_challenges(2); @@ -655,7 +655,7 @@ impl ProofPlan for ChallengeTestProofPlan { ) -> Result, ProofError> { let alpha = builder.consume_post_result_challenge(); let _beta = builder.consume_post_result_challenge(); - let res_eval = builder.consume_result_mle(); + let res_eval = builder.consume_intermediate_mle(); let x_commit = accessor.get_commitment(ColumnRef::new( "sxt.test".parse().unwrap(), "x".parse().unwrap(), 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 5b04e52f9..8848d0cf3 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 @@ -52,7 +52,7 @@ impl ProofPlan for EmptyTestQueryExpr { builder: &mut CountBuilder, _accessor: &dyn MetadataAccessor, ) -> Result<(), ProofError> { - builder.count_result_columns(1); + builder.count_intermediate_mles(1); Ok(()) } fn get_length(&self, _accessor: &dyn MetadataAccessor) -> usize { diff --git a/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test_utility.rs b/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test_utility.rs index 346611e32..c6fe69433 100644 --- a/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test_utility.rs +++ b/crates/proof-of-sql/src/sql/proof/verifiable_query_result_test_utility.rs @@ -24,7 +24,10 @@ pub fn exercise_verification( accessor: &impl TestAccessor, table_ref: TableRef, ) { - assert!(res.verify(expr, accessor, &()).is_ok()); + let verification_result = res.verify(expr, accessor, &()); + if verification_result.is_err() { + panic!("Verification failed: {:?}", verification_result.err()); + } // try changing the result tamper_result(res, expr, accessor); 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 6bf07ab4c..eeea2e563 100644 --- a/crates/proof-of-sql/src/sql/proof/verification_builder.rs +++ b/crates/proof-of-sql/src/sql/proof/verification_builder.rs @@ -142,7 +142,6 @@ impl<'a, C: Commitment> VerificationBuilder<'a, C> { && self.produced_subpolynomials == self.subpolynomial_multipliers.len() && self.consumed_intermediate_mles == self.intermediate_commitments.len() && self.consumed_pcs_proof_mles == self.mle_evaluations.pcs_proof_evaluations.len() - && self.consumed_result_mles == self.mle_evaluations.result_evaluations.len() && self.post_result_challenges.is_empty() } 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 b6373ba23..423fdc025 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 @@ -67,7 +67,7 @@ where self.where_clause.count(builder)?; for aliased_expr in self.aliased_results.iter() { aliased_expr.expr.count(builder)?; - builder.count_result_columns(1); + builder.count_intermediate_mles(1); } builder.count_intermediate_mles(2); builder.count_subpolynomials(3); @@ -107,7 +107,7 @@ where .ok_or(ProofError::VerificationError("invalid indexes"))?; // 4. filtered_columns let filtered_columns_evals = Vec::from_iter( - repeat_with(|| builder.consume_result_mle()).take(self.aliased_results.len()), + repeat_with(|| builder.consume_intermediate_mle()).take(self.aliased_results.len()), ); let alpha = builder.consume_post_result_challenge(); @@ -199,6 +199,10 @@ impl ProverEvaluate for FilterExec { ); // Compute filtered_columns and indexes let (filtered_columns, result_len) = filter_columns(alloc, &columns, selection); + // 3. Produce MLEs + filtered_columns.iter().for_each(|column| { + builder.produce_intermediate_mle(column.as_scalar(alloc)); + }); let alpha = builder.consume_post_result_challenge(); let beta = builder.consume_post_result_challenge(); diff --git a/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test_dishonest_prover.rs b/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test_dishonest_prover.rs index 14ef39996..1f308475e 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test_dishonest_prover.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test_dishonest_prover.rs @@ -104,6 +104,10 @@ impl ProverEvaluate for DishonestFilterExec { &filtered_columns, result_len, ); + // 3. Produce MLEs + filtered_columns.iter().for_each(|column| { + builder.produce_intermediate_mle(column.as_scalar(alloc)); + }); filtered_columns } } 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 e7377e25f..428f696c9 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 @@ -76,13 +76,14 @@ impl ProofPlan for GroupByExec { self.where_clause.count(builder)?; for expr in self.group_by_exprs.iter() { expr.count(builder)?; - builder.count_result_columns(1); + builder.count_intermediate_mles(1); } for aliased_expr in self.sum_expr.iter() { aliased_expr.expr.count(builder)?; - builder.count_result_columns(1); + builder.count_intermediate_mles(1); } - builder.count_result_columns(1); + // For the count col + builder.count_intermediate_mles(1); builder.count_intermediate_mles(2); builder.count_subpolynomials(3); builder.count_degree(3); @@ -126,11 +127,12 @@ impl ProofPlan for GroupByExec { // 4. filtered_columns let group_by_result_columns_evals = Vec::from_iter( - repeat_with(|| builder.consume_result_mle()).take(self.group_by_exprs.len()), + repeat_with(|| builder.consume_intermediate_mle()).take(self.group_by_exprs.len()), ); - let sum_result_columns_evals = - Vec::from_iter(repeat_with(|| builder.consume_result_mle()).take(self.sum_expr.len())); - let count_column_eval = builder.consume_result_mle(); + let sum_result_columns_evals = Vec::from_iter( + repeat_with(|| builder.consume_intermediate_mle()).take(self.sum_expr.len()), + ); + let count_column_eval = builder.consume_intermediate_mle(); let alpha = builder.consume_post_result_challenge(); let beta = builder.consume_post_result_challenge(); @@ -279,7 +281,7 @@ impl ProverEvaluate for GroupByExec { .iter() .map(|aliased_expr| aliased_expr.expr.prover_evaluate(builder, alloc, accessor)), ); - // Compute filtered_columns and indexes + // 3. Compute filtered_columns and indexes let AggregatedColumns { group_by_columns: group_by_result_columns, sum_columns: sum_result_columns, @@ -291,6 +293,19 @@ impl ProverEvaluate for GroupByExec { let alpha = builder.consume_post_result_challenge(); let beta = builder.consume_post_result_challenge(); + // 4. Tally results + let sum_result_columns_iter = sum_result_columns.iter().map(|col| Column::Scalar(col)); + let res = Vec::from_iter( + group_by_result_columns.clone() + .into_iter() + .chain(sum_result_columns_iter) + .chain(std::iter::once(Column::BigInt(count_column))), + ); + // 5. Produce MLEs + res.iter().for_each(|column| { + builder.produce_intermediate_mle(column.as_scalar(alloc)); + }); + // 6. Prove group by prove_group_by( builder, alloc, @@ -299,13 +314,7 @@ impl ProverEvaluate for GroupByExec { (&group_by_columns, &sum_columns, selection), (&group_by_result_columns, &sum_result_columns, count_column), ); - let sum_result_columns_iter = sum_result_columns.iter().map(|col| Column::Scalar(col)); - Vec::from_iter( - group_by_result_columns - .into_iter() - .chain(sum_result_columns_iter) - .chain(std::iter::once(Column::BigInt(count_column))), - ) + res } } 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 6e1020e4f..bbd4ba63c 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 @@ -48,7 +48,7 @@ impl ProofPlan for ProjectionExec { ) -> Result<(), ProofError> { for aliased_expr in self.aliased_results.iter() { aliased_expr.expr.count(builder)?; - builder.count_result_columns(1); + builder.count_intermediate_mles(1); } Ok(()) } @@ -73,7 +73,7 @@ impl ProofPlan for ProjectionExec { .map(|aliased_expr| aliased_expr.expr.verifier_evaluate(builder, accessor)) .collect::, _>>()?; Ok(Vec::from_iter( - repeat_with(|| builder.consume_result_mle()).take(self.aliased_results.len()), + repeat_with(|| builder.consume_intermediate_mle()).take(self.aliased_results.len()), )) } @@ -118,10 +118,16 @@ impl ProverEvaluate for ProjectionExec { alloc: &'a Bump, accessor: &'a dyn DataAccessor, ) -> Vec> { - Vec::from_iter( + // 1. Evaluate result expressions + let res = Vec::from_iter( self.aliased_results .iter() .map(|aliased_expr| aliased_expr.expr.prover_evaluate(builder, alloc, accessor)), - ) + ); + // 2. Produce MLEs + res.clone().into_iter().for_each(|column| { + builder.produce_intermediate_mle(column.as_scalar(alloc)); + }); + res } }