Skip to content

Commit

Permalink
refactor!: rename ResultBuilder to FirstRoundBuilder, `ProofBuild…
Browse files Browse the repository at this point in the history
…er` to `FinalRoundBuilder` && split first round proof out of `ProofPlan::result_evaluate` (#257)

Please be sure to look over the pull request guidelines here:
https://github.com/spaceandtimelabs/sxt-proof-of-sql/blob/main/CONTRIBUTING.md#submit-pr.

# Please go through the following checklist
- [x] The PR title and commit messages adhere to guidelines here:
https://github.com/spaceandtimelabs/sxt-proof-of-sql/blob/main/CONTRIBUTING.md.
In particular `!` is used if and only if at least one breaking change
has been introduced.
- [x] I have run the ci check script with `source
scripts/run_ci_checks.sh`.

# Rationale for this change
`ResultBuilder` isn't really needed for `result_evaluate` when all we
need are input table lengths. However it is crucial in producing the
query proof. Hence we need to remove it from the actual query result
computation process (`expr.result_evaluate`). At the same time it should
be correctly named as builder of the first round of the proof because
that's what it is.
<!--
Why are you proposing this change? If this is already explained clearly
in the linked issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand
your changes and offer better suggestions for fixes.

 Example:
 Add `NestedLoopJoinExec`.
 Closes #345.

Since we added `HashJoinExec` in #323 it has been possible to do
provable inner joins. However performance is not satisfactory in some
cases. Hence we need to fix the problem by implement
`NestedLoopJoinExec` and speed up the code
 for `HashJoinExec`.
-->

# What changes are included in this PR?
The 4 commits are supposed to be reviewed individually.
- rename `ResultBuilder` to `FirstRoundBuilder`, `ProofBuilder` to
`FinalRoundBuilder`.
- rename `proof-of-sql/src/sql/proof/result_builder.rs` to
`first_round_builder.rs`, `proof-of-sql/src/sql/proof/proof_builder.rs`
to `final_round_builder.rs`.
- split out post result challenges into
`ProofPlan::first_round_evaluate`
- replace `FirstRoundBuilder` in `result_evaluate` with `input_length`
- rename `ProverEvaluate::prover_evaluate` to `final_round_evaluate`
<!--
There is no need to duplicate the description in the ticket here but it
is sometimes worth providing a summary of the individual changes in this
PR.

Example:
- Add `NestedLoopJoinExec`.
- Speed up `HashJoinExec`.
- Route joins to `NestedLoopJoinExec` if the outer input is sufficiently
small.
-->

# Are these changes tested?
<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code

If tests are not included in your PR, please explain why (for example,
are they covered by existing tests)?

Example:
Yes.
-->
Yes
  • Loading branch information
iajoiner authored Oct 11, 2024
2 parents 1e33fcc + 42f3069 commit 140faf1
Show file tree
Hide file tree
Showing 29 changed files with 220 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use alloc::{boxed::Box, vec, vec::Vec};
use num_traits::Zero;

/// Track components used to form a query's proof
pub struct ProofBuilder<'a, S: Scalar> {
pub struct FinalRoundBuilder<'a, S: Scalar> {
table_length: usize,
num_sumcheck_variables: usize,
bit_distributions: Vec<BitDistribution>,
Expand All @@ -29,7 +29,7 @@ pub struct ProofBuilder<'a, S: Scalar> {
post_result_challenges: Vec<S>,
}

impl<'a, S: Scalar> ProofBuilder<'a, S> {
impl<'a, S: Scalar> FinalRoundBuilder<'a, S> {
pub fn new(
table_length: usize,
num_sumcheck_variables: usize,
Expand Down Expand Up @@ -96,7 +96,7 @@ impl<'a, S: Scalar> ProofBuilder<'a, S> {

/// Compute commitments of all the interemdiate MLEs used in sumcheck
#[tracing::instrument(
name = "ProofBuilder::commit_intermediate_mles",
name = "FinalRoundBuilder::commit_intermediate_mles",
level = "debug",
skip_all
)]
Expand All @@ -115,7 +115,7 @@ impl<'a, S: Scalar> ProofBuilder<'a, S> {
/// Given random multipliers, construct an aggregatated sumcheck polynomial from all
/// the individual subpolynomials.
#[tracing::instrument(
name = "ProofBuilder::make_sumcheck_polynomial",
name = "FinalRoundBuilder::make_sumcheck_polynomial",
level = "debug",
skip_all
)]
Expand All @@ -140,7 +140,7 @@ impl<'a, S: Scalar> ProofBuilder<'a, S> {
/// Given the evaluation vector, compute evaluations of all the MLEs used in sumcheck except
/// for those that correspond to result columns sent to the verifier.
#[tracing::instrument(
name = "ProofBuilder::evaluate_pcs_proof_mles",
name = "FinalRoundBuilder::evaluate_pcs_proof_mles",
level = "debug",
skip_all
)]
Expand All @@ -154,7 +154,11 @@ impl<'a, S: Scalar> ProofBuilder<'a, S> {

/// Given random multipliers, multiply and add together all of the MLEs used in sumcheck except
/// for those that correspond to result columns sent to the verifier.
#[tracing::instrument(name = "ProofBuilder::fold_pcs_proof_mles", level = "debug", skip_all)]
#[tracing::instrument(
name = "FinalRoundBuilder::fold_pcs_proof_mles",
level = "debug",
skip_all
)]
pub fn fold_pcs_proof_mles(&self, multipliers: &[S]) -> Vec<S> {
assert_eq!(multipliers.len(), self.pcs_proof_mles.len());
let mut res = vec![Zero::zero(); self.table_length];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{ProofBuilder, ProvableQueryResult, SumcheckRandomScalars};
use super::{FinalRoundBuilder, ProvableQueryResult, SumcheckRandomScalars};
use crate::{
base::{
commitment::{Commitment, CommittableColumn},
Expand All @@ -22,7 +22,7 @@ use num_traits::{One, Zero};
fn we_can_compute_commitments_for_intermediate_mles_using_a_zero_offset() {
let mle1 = [1, 2];
let mle2 = [10i64, 20];
let mut builder = ProofBuilder::<Curve25519Scalar>::new(2, 1, Vec::new());
let mut builder = FinalRoundBuilder::<Curve25519Scalar>::new(2, 1, Vec::new());
builder.produce_anchored_mle(&mle1);
builder.produce_intermediate_mle(&mle2[..]);
let offset_generators = 0_usize;
Expand All @@ -41,7 +41,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 = ProofBuilder::<Curve25519Scalar>::new(2, 1, Vec::new());
let mut builder = FinalRoundBuilder::<Curve25519Scalar>::new(2, 1, Vec::new());
builder.produce_anchored_mle(&mle1);
builder.produce_intermediate_mle(&mle2[..]);
let offset_generators = 123_usize;
Expand All @@ -60,7 +60,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 = ProofBuilder::new(2, 1, Vec::new());
let mut builder = FinalRoundBuilder::new(2, 1, Vec::new());
builder.produce_anchored_mle(&mle1);
builder.produce_intermediate_mle(&mle2[..]);
let evaluation_vec = [
Expand All @@ -80,7 +80,7 @@ fn we_can_form_an_aggregated_sumcheck_polynomial() {
let mle1 = [1, 2, -1];
let mle2 = [10i64, 20, 100, 30];
let mle3 = [2000i64, 3000, 5000, 7000];
let mut builder = ProofBuilder::new(4, 2, Vec::new());
let mut builder = FinalRoundBuilder::new(4, 2, Vec::new());
builder.produce_anchored_mle(&mle1);
builder.produce_intermediate_mle(&mle2[..]);
builder.produce_intermediate_mle(&mle3[..]);
Expand Down Expand Up @@ -170,7 +170,7 @@ fn we_can_form_the_provable_query_result() {
fn we_can_fold_pcs_proof_mles() {
let mle1 = [1, 2];
let mle2 = [10i64, 20];
let mut builder = ProofBuilder::new(2, 1, Vec::new());
let mut builder = FinalRoundBuilder::new(2, 1, Vec::new());
builder.produce_anchored_mle(&mle1);
builder.produce_intermediate_mle(&mle2[..]);
let multipliers = [Curve25519Scalar::from(100u64), Curve25519Scalar::from(2u64)];
Expand All @@ -184,7 +184,7 @@ fn we_can_fold_pcs_proof_mles() {

#[test]
fn we_can_consume_post_result_challenges_in_proof_builder() {
let mut builder = ProofBuilder::new(
let mut builder = FinalRoundBuilder::new(
0,
0,
vec![
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
/// Track the result created by a query
pub struct ResultBuilder {
result_table_length: usize,

pub struct FirstRoundBuilder {
/// 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.
num_post_result_challenges: usize,
}

impl Default for ResultBuilder {
impl Default for FirstRoundBuilder {
fn default() -> Self {
Self::new()
}
}

impl ResultBuilder {
impl FirstRoundBuilder {
/// Create a new result builder for a table with the given length. For multi table queries, this will likely need to change.
pub fn new() -> Self {
Self {
result_table_length: 0,
num_post_result_challenges: 0,
}
}

/// Get the length of the output table
pub fn result_table_length(&self) -> usize {
self.result_table_length
}

/// Set the length of the output table
pub fn set_result_table_length(&mut self, result_table_length: usize) {
self.result_table_length = result_table_length;
}

/// 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
Expand Down
10 changes: 5 additions & 5 deletions crates/proof-of-sql/src/sql/proof/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
mod count_builder;
pub(crate) use count_builder::CountBuilder;

mod proof_builder;
pub(crate) use proof_builder::ProofBuilder;
mod final_round_builder;
pub(crate) use final_round_builder::FinalRoundBuilder;
#[cfg(all(test, feature = "blitzar"))]
mod proof_builder_test;
mod final_round_builder_test;

mod composite_polynomial_builder;
pub(crate) use composite_polynomial_builder::CompositePolynomialBuilder;
Expand Down Expand Up @@ -68,5 +68,5 @@ pub(crate) use result_element_serialization::{
decode_and_convert, decode_multiple_elements, ProvableResultElement,
};

mod result_builder;
pub(crate) use result_builder::ResultBuilder;
mod first_round_builder;
pub(crate) use first_round_builder::FirstRoundBuilder;
15 changes: 9 additions & 6 deletions crates/proof-of-sql/src/sql/proof/proof_plan.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{CountBuilder, ProofBuilder, ResultBuilder, VerificationBuilder};
use super::{CountBuilder, FinalRoundBuilder, FirstRoundBuilder, VerificationBuilder};
use crate::base::{
commitment::Commitment,
database::{
Expand Down Expand Up @@ -49,23 +49,26 @@ pub trait ProofPlan<C: Commitment>: Debug + Send + Sync + ProverEvaluate<C::Scal
}

pub trait ProverEvaluate<S: Scalar> {
/// Evaluate the query and modify `ResultBuilder` to track the result of the query.
/// Evaluate the query and modify `FirstRoundBuilder` to track the result of the query.
fn result_evaluate<'a>(
&self,
builder: &mut ResultBuilder,
input_length: usize,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>>;

/// Evaluate the query and modify `ProofBuilder` to store an intermediate representation
/// Evaluate the query and modify `FirstRoundBuilder` to form the query's proof.
fn first_round_evaluate(&self, builder: &mut FirstRoundBuilder);

/// Evaluate the query and modify `FinalRoundBuilder` to store an intermediate representation
/// of the query result and track all the components needed to form the query's proof.
///
/// Intermediate values that are needed to form the proof are allocated into the arena
/// allocator alloc. These intermediate values will persist through proof creation and
/// will be bulk deallocated once the proof is formed.
fn prover_evaluate<'a>(
fn final_round_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, S>,
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>>;
Expand Down
25 changes: 15 additions & 10 deletions crates/proof-of-sql/src/sql/proof/query_proof.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use super::{
CountBuilder, ProofBuilder, ProofCounts, ProofPlan, ProvableQueryResult, QueryResult,
CountBuilder, FinalRoundBuilder, ProofCounts, ProofPlan, ProvableQueryResult, QueryResult,
SumcheckMleEvaluations, SumcheckRandomScalars, VerificationBuilder,
};
use crate::{
base::{
bit::BitDistribution,
commitment::{Commitment, CommitmentEvaluationProof},
database::{CommitmentAccessor, DataAccessor},
database::{Column, CommitmentAccessor, DataAccessor},
math::log2_up,
polynomial::{compute_evaluation_vector, CompositePolynomialInfo},
proof::{Keccak256Transcript, ProofError, Transcript},
},
proof_primitive::sumcheck::SumcheckProof,
sql::proof::{QueryData, ResultBuilder},
sql::proof::{FirstRoundBuilder, QueryData},
};
use alloc::{vec, vec::Vec};
use bumpalo::Bump;
Expand Down Expand Up @@ -53,10 +53,15 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
assert!(num_sumcheck_variables > 0);

let alloc = Bump::new();
let mut result_builder = ResultBuilder::new();
let result_cols = expr.result_evaluate(&mut result_builder, &alloc, accessor);
let provable_result =
ProvableQueryResult::new(result_builder.result_table_length() as u64, &result_cols);

// Evaluate query result
let result_cols = expr.result_evaluate(table_length, &alloc, accessor);
let output_length = result_cols.first().map_or(0, Column::len);
let provable_result = ProvableQueryResult::new(output_length as u64, &result_cols);

// Prover First Round
let mut first_round_builder = FirstRoundBuilder::new();
expr.first_round_evaluate(&mut first_round_builder);

// construct a transcript for the proof
let mut transcript: Keccak256Transcript =
Expand All @@ -69,12 +74,12 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
// 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(result_builder.num_post_result_challenges())
.take(first_round_builder.num_post_result_challenges())
.collect();

let mut builder =
ProofBuilder::new(table_length, num_sumcheck_variables, post_result_challenges);
expr.prover_evaluate(&mut builder, &alloc, accessor);
FinalRoundBuilder::new(table_length, num_sumcheck_variables, post_result_challenges);
expr.final_round_evaluate(&mut builder, &alloc, accessor);

let num_sumcheck_variables = builder.num_sumcheck_variables();
let table_length = builder.table_length();
Expand Down
46 changes: 25 additions & 21 deletions crates/proof-of-sql/src/sql/proof/query_proof_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{
CountBuilder, ProofBuilder, ProofPlan, ProverEvaluate, QueryProof, VerificationBuilder,
CountBuilder, FinalRoundBuilder, ProofPlan, ProverEvaluate, QueryProof, VerificationBuilder,
};
use crate::{
base::{
Expand All @@ -14,7 +14,7 @@ use crate::{
proof::ProofError,
scalar::{Curve25519Scalar, Scalar},
},
sql::proof::{QueryData, ResultBuilder, SumcheckSubpolynomialType},
sql::proof::{FirstRoundBuilder, QueryData, SumcheckSubpolynomialType},
};
use bumpalo::Bump;
use serde::Serialize;
Expand Down Expand Up @@ -43,19 +43,19 @@ impl Default for TrivialTestProofPlan {
impl<S: Scalar> ProverEvaluate<S> for TrivialTestProofPlan {
fn result_evaluate<'a>(
&self,
builder: &mut ResultBuilder,
_input_length: usize,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let input_length = self.length;
let col = alloc.alloc_slice_fill_copy(input_length, self.column_fill_value);
builder.set_result_table_length(input_length);
let col = alloc.alloc_slice_fill_copy(self.length, self.column_fill_value);
vec![Column::BigInt(col)]
}

fn prover_evaluate<'a>(
fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}

fn final_round_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, S>,
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
Expand Down Expand Up @@ -200,18 +200,19 @@ impl Default for SquareTestProofPlan {
impl<S: Scalar> ProverEvaluate<S> for SquareTestProofPlan {
fn result_evaluate<'a>(
&self,
builder: &mut ResultBuilder,
_table_length: usize,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let res: &[_] = alloc.alloc_slice_copy(&self.res);
builder.set_result_table_length(2);
vec![Column::BigInt(res)]
}

fn prover_evaluate<'a>(
fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}

fn final_round_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, S>,
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
Expand Down Expand Up @@ -381,18 +382,19 @@ impl Default for DoubleSquareTestProofPlan {
impl<S: Scalar> ProverEvaluate<S> for DoubleSquareTestProofPlan {
fn result_evaluate<'a>(
&self,
builder: &mut ResultBuilder,
_input_length: usize,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
let res: &[_] = alloc.alloc_slice_copy(&self.res);
builder.set_result_table_length(2);
vec![Column::BigInt(res)]
}

fn prover_evaluate<'a>(
fn first_round_evaluate(&self, _builder: &mut FirstRoundBuilder) {}

fn final_round_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, S>,
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
Expand Down Expand Up @@ -592,18 +594,20 @@ struct ChallengeTestProofPlan {}
impl<S: Scalar> ProverEvaluate<S> for ChallengeTestProofPlan {
fn result_evaluate<'a>(
&self,
builder: &mut ResultBuilder,
_input_length: usize,
_alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
builder.request_post_result_challenges(2);
builder.set_result_table_length(2);
vec![Column::BigInt(&[9, 25])]
}

fn prover_evaluate<'a>(
fn first_round_evaluate(&self, builder: &mut FirstRoundBuilder) {
builder.request_post_result_challenges(2);
}

fn final_round_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, S>,
builder: &mut FinalRoundBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
) -> Vec<Column<'a, S>> {
Expand Down
Loading

0 comments on commit 140faf1

Please sign in to comment.