Skip to content

Commit

Permalink
refactor: add is_top_level to prover_evaluate and `verifier_evalu…
Browse files Browse the repository at this point in the history
…ate` for `ProofPlan`s

- add `is_top_level` to `prover_evaluate` and `verifier_evaluate` for `ProofPlan`
- bump `alloy` to `0.8.1`
  • Loading branch information
iajoiner committed Sep 16, 2024
1 parent f6b0fbe commit 35de9cc
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 27 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" ] }
Expand Down
17 changes: 17 additions & 0 deletions crates/proof-of-sql/src/base/database/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions crates/proof-of-sql/src/sql/proof/proof_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub trait ProofPlan<C: Commitment>: Debug + Send + Sync + ProverEvaluate<C::Scal
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
result: Option<&OwnedTable<C::Scalar>>,
is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError>;

/// Return all the result column fields
Expand Down Expand Up @@ -67,6 +68,7 @@ pub trait ProverEvaluate<S: Scalar> {
builder: &mut ProofBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
is_top_level: bool,
) -> Vec<Column<'a, S>>;
}

Expand Down
4 changes: 2 additions & 2 deletions crates/proof-of-sql/src/sql/proof/query_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {

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

let num_sumcheck_variables = builder.num_sumcheck_variables();
let table_length = builder.table_length();
Expand Down Expand Up @@ -250,7 +250,7 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
post_result_challenges,
);
let owned_table_result = result.to_owned_table(&column_result_fields[..])?;
expr.verifier_evaluate(&mut builder, accessor, Some(&owned_table_result))?;
expr.verifier_evaluate(&mut builder, accessor, Some(&owned_table_result), true)?;

// perform the evaluation check of the sumcheck polynomial
if builder.sumcheck_evaluation() != subclaim.expected_evaluation {
Expand Down
19 changes: 15 additions & 4 deletions crates/proof-of-sql/src/sql/proof/query_proof_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ impl<S: Scalar> ProverEvaluate<S> for TrivialTestProofPlan {
builder: &mut ProofBuilder<'a, S>,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
_is_top_level: bool,
) -> Vec<Column<'a, S>> {
let col = alloc.alloc_slice_fill_copy(builder.table_length(), self.column_fill_value);
builder.produce_sumcheck_subpolynomial(
Expand Down Expand Up @@ -90,8 +91,12 @@ impl<C: Commitment> ProofPlan<C> for TrivialTestProofPlan {
builder: &mut VerificationBuilder<C>,
_accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<C::Scalar>>,
_is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError> {
assert_eq!(builder.consume_result_mle(), C::Scalar::ZERO);
assert_eq!(
builder.consume_result_or_intermediate_mle(true),
C::Scalar::ZERO
);
builder.produce_sumcheck_subpolynomial_evaluation(&C::Scalar::from(self.evaluation));
Ok(vec![C::Scalar::ZERO])
}
Expand Down Expand Up @@ -223,6 +228,7 @@ impl<S: Scalar> ProverEvaluate<S> for SquareTestProofPlan {
builder: &mut ProofBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
_is_top_level: bool,
) -> Vec<Column<'a, S>> {
let x = accessor.get_column(ColumnRef::new(
"sxt.test".parse().unwrap(),
Expand Down Expand Up @@ -264,8 +270,9 @@ impl<C: Commitment> ProofPlan<C> for SquareTestProofPlan {
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<C::Scalar>>,
_is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError> {
let res_eval = builder.consume_result_mle();
let res_eval = builder.consume_result_or_intermediate_mle(true);
let x_commit = C::Scalar::from(self.anchored_commit_multiplier)
* accessor.get_commitment(ColumnRef::new(
"sxt.test".parse().unwrap(),
Expand Down Expand Up @@ -401,6 +408,7 @@ impl<S: Scalar> ProverEvaluate<S> for DoubleSquareTestProofPlan {
builder: &mut ProofBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
_is_top_level: bool,
) -> Vec<Column<'a, S>> {
let x = accessor.get_column(ColumnRef::new(
"sxt.test".parse().unwrap(),
Expand Down Expand Up @@ -456,13 +464,14 @@ impl<C: Commitment> ProofPlan<C> for DoubleSquareTestProofPlan {
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<C::Scalar>>,
_is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError> {
let x_commit = accessor.get_commitment(ColumnRef::new(
"sxt.test".parse().unwrap(),
"x".parse().unwrap(),
ColumnType::BigInt,
));
let res_eval = builder.consume_result_mle();
let res_eval = builder.consume_result_or_intermediate_mle(true);
let x_eval = builder.consume_anchored_mle(x_commit);
let z_eval = builder.consume_intermediate_mle();

Expand Down Expand Up @@ -608,6 +617,7 @@ impl<S: Scalar> ProverEvaluate<S> for ChallengeTestProofPlan {
builder: &mut ProofBuilder<'a, S>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<S>,
_is_top_level: bool,
) -> Vec<Column<'a, S>> {
let x = accessor.get_column(ColumnRef::new(
"sxt.test".parse().unwrap(),
Expand Down Expand Up @@ -652,10 +662,11 @@ impl<C: Commitment> ProofPlan<C> for ChallengeTestProofPlan {
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<C::Scalar>>,
_is_top_level: bool,
) -> Result<Vec<C::Scalar>, 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_result_or_intermediate_mle(true);
let x_commit = accessor.get_commitment(ColumnRef::new(
"sxt.test".parse().unwrap(),
"x".parse().unwrap(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl<S: Scalar> ProverEvaluate<S> for EmptyTestQueryExpr {
_builder: &mut ProofBuilder<'a, S>,
alloc: &'a Bump,
_accessor: &'a dyn DataAccessor<S>,
_is_top_level: bool,
) -> Vec<Column<'a, S>> {
let zeros = vec![0; self.length];
let res: &[_] = alloc.alloc_slice_copy(&zeros);
Expand All @@ -66,6 +67,7 @@ impl<C: Commitment> ProofPlan<C> for EmptyTestQueryExpr {
_builder: &mut VerificationBuilder<C>,
_accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<<C as Commitment>::Scalar>>,
_is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError> {
Ok(vec![C::Scalar::ZERO])
}
Expand Down
12 changes: 12 additions & 0 deletions crates/proof-of-sql/src/sql/proof/verification_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ impl<'a, C: Commitment> VerificationBuilder<'a, C> {
self.mle_evaluations.result_evaluations[index]
}

/// Consume the evaluation of an intermediate MLE if NOT at the top level
/// and consume the evaluation of a result MLE if at the top level
///
/// This is used to consume the evaluation of an MLE used in sumcheck
pub fn consume_result_or_intermediate_mle(&mut self, is_top_level: bool) -> C::Scalar {
if is_top_level {
self.consume_result_mle()
} else {
self.consume_intermediate_mle()
}
}

/// Produce the evaluation of a subpolynomial used in sumcheck
pub fn produce_sumcheck_subpolynomial_evaluation(&mut self, eval: &C::Scalar) {
self.sumcheck_evaluation +=
Expand Down
10 changes: 8 additions & 2 deletions crates/proof-of-sql/src/sql/proof/verification_builder_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,14 @@ fn we_can_consume_result_evaluations() {
&[][..],
Vec::new(),
);
assert_eq!(builder.consume_result_mle(), Curve25519Scalar::from(123u64));
assert_eq!(builder.consume_result_mle(), Curve25519Scalar::from(456u64));
assert_eq!(
builder.consume_result_or_intermediate_mle(true),
Curve25519Scalar::from(123u64)
);
assert_eq!(
builder.consume_result_or_intermediate_mle(true),
Curve25519Scalar::from(456u64)
);
}

#[test]
Expand Down
26 changes: 20 additions & 6 deletions crates/proof-of-sql/src/sql/proof_plans/dyn_proof_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,18 @@ impl<C: Commitment> ProofPlan<C> for DynProofPlan<C> {
builder: &mut crate::sql::proof::VerificationBuilder<C>,
accessor: &dyn crate::base::database::CommitmentAccessor<C>,
result: Option<&crate::base::database::OwnedTable<C::Scalar>>,
is_top_level: bool,
) -> Result<Vec<C::Scalar>, crate::base::proof::ProofError> {
match self {
DynProofPlan::Projection(expr) => expr.verifier_evaluate(builder, accessor, result),
DynProofPlan::GroupBy(expr) => expr.verifier_evaluate(builder, accessor, result),
DynProofPlan::Filter(expr) => expr.verifier_evaluate(builder, accessor, result),
DynProofPlan::Projection(expr) => {
expr.verifier_evaluate(builder, accessor, result, is_top_level)
}
DynProofPlan::GroupBy(expr) => {
expr.verifier_evaluate(builder, accessor, result, is_top_level)
}
DynProofPlan::Filter(expr) => {
expr.verifier_evaluate(builder, accessor, result, is_top_level)
}
}
}

Expand Down Expand Up @@ -111,11 +118,18 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for DynProofPlan<C> {
builder: &mut crate::sql::proof::ProofBuilder<'a, C::Scalar>,
alloc: &'a bumpalo::Bump,
accessor: &'a dyn crate::base::database::DataAccessor<C::Scalar>,
is_top_level: bool,
) -> Vec<Column<'a, C::Scalar>> {
match self {
DynProofPlan::Projection(expr) => expr.prover_evaluate(builder, alloc, accessor),
DynProofPlan::GroupBy(expr) => expr.prover_evaluate(builder, alloc, accessor),
DynProofPlan::Filter(expr) => expr.prover_evaluate(builder, alloc, accessor),
DynProofPlan::Projection(expr) => {
expr.prover_evaluate(builder, alloc, accessor, is_top_level)
}
DynProofPlan::GroupBy(expr) => {
expr.prover_evaluate(builder, alloc, accessor, is_top_level)
}
DynProofPlan::Filter(expr) => {
expr.prover_evaluate(builder, alloc, accessor, is_top_level)
}
}
}
}
11 changes: 10 additions & 1 deletion crates/proof-of-sql/src/sql/proof_plans/filter_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ where
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<C::Scalar>>,
is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError> {
// 1. selection
let selection_eval = self.where_clause.verifier_evaluate(builder, accessor)?;
Expand All @@ -107,7 +108,8 @@ 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_result_or_intermediate_mle(is_top_level))
.take(self.aliased_results.len()),
);

let alpha = builder.consume_post_result_challenge();
Expand Down Expand Up @@ -183,6 +185,7 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for FilterExec<C> {
builder: &mut ProofBuilder<'a, C::Scalar>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<C::Scalar>,
is_top_level: bool,
) -> Vec<Column<'a, C::Scalar>> {
// 1. selection
let selection_column: Column<'a, C::Scalar> =
Expand All @@ -199,6 +202,12 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for FilterExec<C> {
);
// Compute filtered_columns and indexes
let (filtered_columns, result_len) = filter_columns(alloc, &columns, selection);
// 3. Produce MLEs if not top level
if !is_top_level {
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl ProverEvaluate<Curve25519Scalar> for DishonestFilterExec<RistrettoPoint> {
builder: &mut ProofBuilder<'a, Curve25519Scalar>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<Curve25519Scalar>,
is_top_level: bool,
) -> Vec<Column<'a, Curve25519Scalar>> {
// 1. selection
let selection_column: Column<'a, Curve25519Scalar> =
Expand Down Expand Up @@ -104,6 +105,12 @@ impl ProverEvaluate<Curve25519Scalar> for DishonestFilterExec<RistrettoPoint> {
&filtered_columns,
result_len,
);
// 3. Produce MLEs if not top level
if !is_top_level {
filtered_columns.iter().for_each(|column| {
builder.produce_intermediate_mle(column.as_scalar(alloc));
});
}
filtered_columns
}
}
Expand Down
28 changes: 21 additions & 7 deletions crates/proof-of-sql/src/sql/proof_plans/group_by_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ impl<C: Commitment> ProofPlan<C> for GroupByExec<C> {
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
result: Option<&OwnedTable<C::Scalar>>,
is_top_level: bool,
) -> Result<Vec<C::Scalar>, ProofError> {
// 1. selection
let where_eval = self.where_clause.verifier_evaluate(builder, accessor)?;
Expand All @@ -126,11 +127,14 @@ impl<C: Commitment> ProofPlan<C> for GroupByExec<C> {
// 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_result_or_intermediate_mle(is_top_level))
.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_result_or_intermediate_mle(is_top_level))
.take(self.sum_expr.len()),
);
let count_column_eval = builder.consume_result_or_intermediate_mle(is_top_level);

let alpha = builder.consume_post_result_challenge();
let beta = builder.consume_post_result_challenge();
Expand Down Expand Up @@ -260,6 +264,7 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for GroupByExec<C> {
builder: &mut ProofBuilder<'a, C::Scalar>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<C::Scalar>,
is_top_level: bool,
) -> Vec<Column<'a, C::Scalar>> {
// 1. selection
let selection_column: Column<'a, C::Scalar> =
Expand All @@ -279,7 +284,7 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for GroupByExec<C> {
.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,
Expand All @@ -291,6 +296,7 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for GroupByExec<C> {
let alpha = builder.consume_post_result_challenge();
let beta = builder.consume_post_result_challenge();

// 4. Prove group by
prove_group_by(
builder,
alloc,
Expand All @@ -299,13 +305,21 @@ impl<C: Commitment> ProverEvaluate<C::Scalar> for GroupByExec<C> {
(&group_by_columns, &sum_columns, selection),
(&group_by_result_columns, &sum_result_columns, count_column),
);
// 5. Tally results
let sum_result_columns_iter = sum_result_columns.iter().map(|col| Column::Scalar(col));
Vec::from_iter(
let res = Vec::from_iter(
group_by_result_columns
.into_iter()
.chain(sum_result_columns_iter)
.chain(std::iter::once(Column::BigInt(count_column))),
)
);
// 6. Produce MLEs if not top level
if !is_top_level {
res.iter().for_each(|column| {
builder.produce_intermediate_mle(column.as_scalar(alloc));
});
}
res
}
}

Expand Down
Loading

0 comments on commit 35de9cc

Please sign in to comment.