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 432c04123..ecfca85c5 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 @@ -18,21 +18,30 @@ pub struct FirstRoundBuilder<'a, S> { num_post_result_challenges: usize, /// The extra one evaluation lengths used in the proof. one_evaluation_lengths: Vec, -} - -impl<'a, S: Scalar> Default for FirstRoundBuilder<'a, S> { - fn default() -> Self { - Self::new() - } + // The range_length used in sumcheck which is max of all possible ones. + range_length: usize, } impl<'a, S: Scalar> FirstRoundBuilder<'a, S> { - pub fn new() -> Self { + pub fn new(initial_range_length: usize) -> Self { Self { commitment_descriptor: Vec::new(), pcs_proof_mles: Vec::new(), num_post_result_challenges: 0, one_evaluation_lengths: Vec::new(), + range_length: initial_range_length, + } + } + + /// Get the range length used in the proof. + pub(crate) fn range_length(&self) -> usize { + self.range_length + } + + /// Update the range length used in the proof only if the new range is larger than the existing range. + pub(crate) fn update_range_length(&mut self, new_range_length: usize) { + if new_range_length > self.range_length { + self.range_length = new_range_length; } } @@ -47,6 +56,7 @@ impl<'a, S: Scalar> FirstRoundBuilder<'a, S> { /// Append the length to the list of one evaluation lengths. pub(crate) fn produce_one_evaluation_length(&mut self, length: usize) { + self.update_range_length(length); self.one_evaluation_lengths.push(length); } diff --git a/crates/proof-of-sql/src/sql/proof/first_round_builder_test.rs b/crates/proof-of-sql/src/sql/proof/first_round_builder_test.rs index 15171fc37..01b861092 100644 --- a/crates/proof-of-sql/src/sql/proof/first_round_builder_test.rs +++ b/crates/proof-of-sql/src/sql/proof/first_round_builder_test.rs @@ -9,7 +9,7 @@ use curve25519_dalek::RistrettoPoint; fn we_can_compute_commitments_for_intermediate_mles_using_a_zero_offset() { let mle1 = [1, 2]; let mle2 = [10i64, 20]; - let mut builder = FirstRoundBuilder::::new(); + let mut builder = FirstRoundBuilder::::new(2); builder.produce_intermediate_mle(&mle1[..]); builder.produce_intermediate_mle(&mle2[..]); let offset_generators = 0_usize; @@ -29,7 +29,7 @@ fn we_can_compute_commitments_for_intermediate_mles_using_a_zero_offset() { fn we_can_compute_commitments_for_intermediate_mles_using_a_non_zero_offset() { let mle1 = [1, 2]; let mle2 = [10i64, 20]; - let mut builder = FirstRoundBuilder::::new(); + let mut builder = FirstRoundBuilder::::new(2); builder.produce_intermediate_mle(&mle1[..]); builder.produce_intermediate_mle(&mle2[..]); let offset_generators = 123_usize; @@ -49,7 +49,7 @@ fn we_can_compute_commitments_for_intermediate_mles_using_a_non_zero_offset() { fn we_can_evaluate_pcs_proof_mles() { let mle1 = [1, 2]; let mle2 = [10i64, 20]; - let mut builder = FirstRoundBuilder::::new(); + let mut builder = FirstRoundBuilder::::new(2); builder.produce_intermediate_mle(&mle1[..]); builder.produce_intermediate_mle(&mle2[..]); let evaluation_vec = [ @@ -66,7 +66,7 @@ fn we_can_evaluate_pcs_proof_mles() { #[test] fn we_can_add_post_result_challenges() { - let mut builder = FirstRoundBuilder::::new(); + let mut builder = FirstRoundBuilder::::new(0); assert_eq!(builder.num_post_result_challenges(), 0); builder.request_post_result_challenges(1); assert_eq!(builder.num_post_result_challenges(), 1); 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 bfbfd2f9d..6b6e4c773 100644 --- a/crates/proof-of-sql/src/sql/proof/query_proof.rs +++ b/crates/proof-of-sql/src/sql/proof/query_proof.rs @@ -104,18 +104,13 @@ impl QueryProof { .collect(); // Prover First Round: Evaluate the query && get the right number of post result challenges - let mut first_round_builder = FirstRoundBuilder::::new(); + let mut first_round_builder = FirstRoundBuilder::new(initial_range_length); let query_result = expr.first_round_evaluate(&mut first_round_builder, &alloc, &table_map); let owned_table_result = OwnedTable::from(&query_result); let provable_result = query_result.into(); let one_evaluation_lengths = first_round_builder.one_evaluation_lengths(); - let range_length = one_evaluation_lengths - .iter() - .copied() - .chain(core::iter::once(initial_range_length)) - .max() - .expect("Will always have at least one element"); // safe to unwrap because we have at least one element + let range_length = first_round_builder.range_length(); let num_sumcheck_variables = cmp::max(log2_up(range_length), 1); assert!(num_sumcheck_variables > 0); diff --git a/crates/proof-of-sql/src/sql/proof_gadgets/range_check.rs b/crates/proof-of-sql/src/sql/proof_gadgets/range_check.rs index cd7b9c0de..f2a328cd6 100644 --- a/crates/proof-of-sql/src/sql/proof_gadgets/range_check.rs +++ b/crates/proof-of-sql/src/sql/proof_gadgets/range_check.rs @@ -22,13 +22,20 @@ //! * Parallelization: Single-threaded execution of these operations is a performance bottleneck use crate::{ base::{polynomial::MultilinearExtension, proof::ProofSizeMismatch, scalar::Scalar, slice_ops}, - sql::proof::{FinalRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder}, + sql::proof::{ + FinalRoundBuilder, FirstRoundBuilder, SumcheckSubpolynomialType, VerificationBuilder, + }, }; use alloc::{boxed::Box, vec::Vec}; use bumpalo::Bump; use bytemuck::cast_slice; use core::{cmp::max, iter::repeat}; +/// Update the max range length for the range check. +pub fn first_round_evaluate_range_check<'a, S: Scalar + 'a>(builder: &mut FirstRoundBuilder) { + builder.update_range_length(256); +} + /// Prove that a word-wise decomposition of a collection of scalars /// are all within the range 0 to 2^248. pub fn final_round_evaluate_range_check<'a, S: Scalar + 'a>( @@ -382,7 +389,6 @@ where .rho_256_evaluation .ok_or(ProofSizeMismatch::TooFewSumcheckVariables)?; // Ensures that we have enough sumcheck variables - let _ = builder.try_consume_one_evaluation()?; let word_vals_plus_alpha_inv = builder.try_consume_final_round_mle_evaluation()?; let word_value_constraint = word_vals_plus_alpha_inv * (word_vals_eval + alpha); diff --git a/crates/proof-of-sql/src/sql/proof_gadgets/range_check_test.rs b/crates/proof-of-sql/src/sql/proof_gadgets/range_check_test.rs index e7f7217a4..3735ee1b3 100644 --- a/crates/proof-of-sql/src/sql/proof_gadgets/range_check_test.rs +++ b/crates/proof-of-sql/src/sql/proof_gadgets/range_check_test.rs @@ -27,7 +27,7 @@ impl ProverEvaluate for RangeCheckTestPlan { table_map: &IndexMap>, ) -> Table<'a, S> { builder.request_post_result_challenges(1); - builder.produce_one_evaluation_length(256); + builder.update_range_length(256); table_map[&self.column.table_ref()].clone() } diff --git a/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test.rs b/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test.rs index 4bb70961b..3a74c0e6e 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/filter_exec_test.rs @@ -171,6 +171,7 @@ fn we_can_get_an_empty_result_from_a_basic_filter_on_an_empty_table_using_first_ borrowed_varchar("d", [""; 0], &alloc), borrowed_scalar("e", [0; 0], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -192,7 +193,7 @@ fn we_can_get_an_empty_result_from_a_basic_filter_on_an_empty_table_using_first_ ColumnType::Decimal75(Precision::new(75).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -220,6 +221,7 @@ fn we_can_get_an_empty_result_from_a_basic_filter_using_first_round_evaluate() { borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -241,7 +243,7 @@ fn we_can_get_an_empty_result_from_a_basic_filter_using_first_round_evaluate() { ColumnType::Decimal75(Precision::new(1).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -269,6 +271,7 @@ fn we_can_get_no_columns_from_a_basic_filter_with_no_selected_columns_using_firs borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -278,7 +281,7 @@ fn we_can_get_no_columns_from_a_basic_filter_with_no_selected_columns_using_firs let where_clause: DynProofExpr = equal(column(t, "a", &accessor), const_int128(5)); let expr = filter(cols_expr_plan(t, &[], &accessor), tab(t), where_clause); let fields = &[]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -300,6 +303,7 @@ fn we_can_get_the_correct_result_from_a_basic_filter_using_first_round_evaluate( borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -321,7 +325,7 @@ fn we_can_get_the_correct_result_from_a_basic_filter_using_first_round_evaluate( ColumnType::Decimal75(Precision::new(1).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, diff --git a/crates/proof-of-sql/src/sql/proof_plans/projection_exec_test.rs b/crates/proof-of-sql/src/sql/proof_plans/projection_exec_test.rs index 519bcb0b1..c5e153583 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/projection_exec_test.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/projection_exec_test.rs @@ -157,6 +157,7 @@ fn we_can_get_an_empty_result_from_a_basic_projection_on_an_empty_table_using_fi borrowed_varchar("d", [""; 0], &alloc), borrowed_scalar("e", [0; 0], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -174,7 +175,7 @@ fn we_can_get_an_empty_result_from_a_basic_projection_on_an_empty_table_using_fi ColumnType::Decimal75(Precision::new(75).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -203,6 +204,7 @@ fn we_can_get_no_columns_from_a_basic_projection_with_no_selected_columns_using_ borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -211,7 +213,7 @@ fn we_can_get_no_columns_from_a_basic_projection_with_no_selected_columns_using_ accessor.add_table(t, data, 0); let expr: DynProofPlan = projection(cols_expr_plan(t, &[], &accessor), tab(t)); let fields = &[]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -233,6 +235,7 @@ fn we_can_get_the_correct_result_from_a_basic_projection_using_first_round_evalu borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -260,7 +263,7 @@ fn we_can_get_the_correct_result_from_a_basic_projection_using_first_round_evalu ColumnType::Decimal75(Precision::new(1).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, diff --git a/crates/proof-of-sql/src/sql/proof_plans/slice_exec_test.rs b/crates/proof-of-sql/src/sql/proof_plans/slice_exec_test.rs index 27248127d..124b8c1ee 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/slice_exec_test.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/slice_exec_test.rs @@ -76,6 +76,7 @@ fn we_can_get_an_empty_result_from_a_slice_on_an_empty_table_using_first_round_e borrowed_varchar("d", [""; 0], &alloc), borrowed_scalar("e", [0; 0], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -102,7 +103,7 @@ fn we_can_get_an_empty_result_from_a_slice_on_an_empty_table_using_first_round_e ColumnType::Decimal75(Precision::new(75).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -130,6 +131,7 @@ fn we_can_get_an_empty_result_from_a_slice_using_first_round_evaluate() { borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -156,7 +158,7 @@ fn we_can_get_an_empty_result_from_a_slice_using_first_round_evaluate() { ColumnType::Decimal75(Precision::new(1).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -184,6 +186,7 @@ fn we_can_get_no_columns_from_a_slice_with_empty_input_using_first_round_evaluat borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -197,7 +200,7 @@ fn we_can_get_no_columns_from_a_slice_with_empty_input_using_first_round_evaluat None, ); let fields = &[]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, @@ -219,6 +222,7 @@ fn we_can_get_the_correct_result_from_a_slice_using_first_round_evaluate() { borrowed_varchar("d", ["1", "2", "3", "4", "5"], &alloc), borrowed_scalar("e", [1, 2, 3, 4, 5], &alloc), ]); + let data_length = data.num_rows(); let t = "sxt.t".parse().unwrap(); let table_map = indexmap! { t => data.clone() @@ -244,7 +248,7 @@ fn we_can_get_the_correct_result_from_a_slice_using_first_round_evaluate() { ColumnType::Decimal75(Precision::new(1).unwrap(), 0), ), ]; - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(expr.first_round_evaluate( first_round_builder, &alloc, diff --git a/crates/proof-of-sql/src/sql/proof_plans/union_exec_test.rs b/crates/proof-of-sql/src/sql/proof_plans/union_exec_test.rs index ba1061866..b32fb3f1e 100644 --- a/crates/proof-of-sql/src/sql/proof_plans/union_exec_test.rs +++ b/crates/proof-of-sql/src/sql/proof_plans/union_exec_test.rs @@ -248,6 +248,7 @@ fn we_can_get_result_from_union_using_first_round_evaluate() { borrowed_bigint("a0", [1_i64, 2, 3, 4, 5], &alloc), borrowed_varchar("b0", ["1", "2", "3", "4", "5"], &alloc), ]); + let len_0 = data0.num_rows(); let t0 = "sxt.t0".parse().unwrap(); let data1 = table([ borrowed_bigint("a1", [2_i64, 3, 4, 5, 6], &alloc), @@ -258,6 +259,11 @@ fn we_can_get_result_from_union_using_first_round_evaluate() { t0 => data0.clone(), t1 => data1.clone() }; + + let len_1 = data1.num_rows(); + + let data_length = std::cmp::max(len_0, len_1); + let mut accessor = TableTestAccessor::::new_empty_with_setup(()); accessor.add_table(t0, data0, 0); accessor.add_table(t1, data1, 0); @@ -272,7 +278,7 @@ fn we_can_get_result_from_union_using_first_round_evaluate() { ], fields.clone(), ); - let first_round_builder = &mut FirstRoundBuilder::new(); + let first_round_builder = &mut FirstRoundBuilder::new(data_length); let res: OwnedTable = ProvableQueryResult::from(ast.first_round_evaluate( first_round_builder, &alloc,