Skip to content

Commit

Permalink
feat: add ProjectionExpr
Browse files Browse the repository at this point in the history
- add `ProjectionExpr`
- make sure `max_multiplicands` on the verifier side is correct
  • Loading branch information
iajoiner committed Jul 2, 2024
1 parent 2dbd966 commit 00d4f1a
Show file tree
Hide file tree
Showing 8 changed files with 516 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use std::{rc::Rc, vec::Vec};
/// $$\sum_{i=0}^{n}C_i\cdot\prod_{j=0}^{m_i}P_{ij}$$
///
/// The result polynomial is used as the prover key.
#[derive(Clone, Debug)]
pub struct CompositePolynomial<S: Scalar> {
/// max number of multiplicands in each product
pub max_multiplicands: usize,
Expand All @@ -36,6 +37,7 @@ pub struct CompositePolynomial<S: Scalar> {

/// Stores the number of variables and max number of multiplicands of the added polynomial used by the prover.
/// This data structures will is used as the verifier key.
#[derive(Clone, Debug)]
pub struct CompositePolynomialInfo {
/// max number of multiplicands in each product
pub max_multiplicands: usize,
Expand Down
2 changes: 2 additions & 0 deletions crates/proof-of-sql/src/proof_primitive/sumcheck/subclaim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ impl<S: Scalar> Subclaim<S> {
assert_eq!(num_vars, evaluations.len());
let mut expected_sum = *claimed_sum;
for round_index in 0..num_vars {

let round_evaluation = &evaluations[round_index];

if round_evaluation.len() != max_multiplicands + 1 {
return Err(ProofError::VerificationError(
"round evaluation length does not match max multiplicands",
Expand Down
5 changes: 5 additions & 0 deletions crates/proof-of-sql/src/sql/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ pub(crate) use provable_expr::ProvableExpr;
#[cfg(all(test, feature = "blitzar"))]
mod provable_expr_test;

mod projection_expr;
pub(crate) use projection_expr::ProjectionExpr;
#[cfg(all(test, feature = "blitzar"))]
mod projection_expr_test;

mod literal_expr;
pub(crate) use literal_expr::LiteralExpr;
#[cfg(all(test, feature = "blitzar"))]
Expand Down
125 changes: 125 additions & 0 deletions crates/proof-of-sql/src/sql/ast/projection_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use super::{AliasedProvableExprPlan, ProvableExpr, TableExpr};
use crate::{
base::{
commitment::Commitment,
database::{
ColumnField, ColumnRef, CommitmentAccessor, DataAccessor, MetadataAccessor, OwnedTable,
},
proof::ProofError,
},
sql::proof::{
CountBuilder, Indexes, ProofBuilder, ProofExpr, ProverEvaluate, ResultBuilder,
VerificationBuilder,
},
};
use bumpalo::Bump;
use core::iter::repeat_with;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

/// Provable expressions for queries of the form
/// ```ignore
/// SELECT <result_expr1>, ..., <result_exprN> FROM <table>
/// ```
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ProjectionExpr<C: Commitment> {
pub(super) aliased_results: Vec<AliasedProvableExprPlan<C>>,
pub(super) table: TableExpr,
}

impl<C: Commitment> ProjectionExpr<C> {
/// Creates a new projection expression.
pub fn new(aliased_results: Vec<AliasedProvableExprPlan<C>>, table: TableExpr) -> Self {
Self {
aliased_results,
table,
}
}
}

impl<C: Commitment> ProofExpr<C> for ProjectionExpr<C> {
fn count(
&self,
builder: &mut CountBuilder,
_accessor: &dyn MetadataAccessor,
) -> Result<(), ProofError> {
for aliased_expr in self.aliased_results.iter() {
aliased_expr.expr.count(builder)?;
builder.count_result_columns(1);
}
Ok(())
}

fn get_length(&self, accessor: &dyn MetadataAccessor) -> usize {
accessor.get_length(self.table.table_ref)
}

fn get_offset(&self, accessor: &dyn MetadataAccessor) -> usize {
accessor.get_offset(self.table.table_ref)
}

#[allow(unused_variables)]
fn verifier_evaluate(
&self,
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
_result: Option<&OwnedTable<C::Scalar>>,
) -> Result<(), ProofError> {
self.aliased_results
.iter()
.map(|aliased_expr| aliased_expr.expr.verifier_evaluate(builder, accessor))
.collect::<Result<Vec<_>, _>>()?;
let _columns_evals = Vec::from_iter(
repeat_with(|| builder.consume_result_mle()).take(self.aliased_results.len()),
);
Ok(())
}

fn get_column_result_fields(&self) -> Vec<ColumnField> {
self.aliased_results
.iter()
.map(|aliased_expr| ColumnField::new(aliased_expr.alias, aliased_expr.expr.data_type()))
.collect()
}

fn get_column_references(&self) -> HashSet<ColumnRef> {
let mut columns = HashSet::new();
self.aliased_results.iter().for_each(|aliased_expr| {
aliased_expr.expr.get_column_references(&mut columns);
});
columns
}
}

impl<C: Commitment> ProverEvaluate<C::Scalar> for ProjectionExpr<C> {
#[tracing::instrument(name = "ProjectionExpr::result_evaluate", level = "debug", skip_all)]
fn result_evaluate<'a>(
&self,
builder: &mut ResultBuilder<'a>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<C::Scalar>,
) {
let columns = Vec::from_iter(self.aliased_results.iter().map(|aliased_expr| {
aliased_expr
.expr
.result_evaluate(builder.table_length(), alloc, accessor)
}));
builder.set_result_indexes(Indexes::Dense(0..(builder.table_length() as u64)));
for col in columns {
builder.produce_result_column(col);
}
}

#[tracing::instrument(name = "ProjectionExpr::prover_evaluate", level = "debug", skip_all)]
#[allow(unused_variables)]
fn prover_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, C::Scalar>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<C::Scalar>,
) {
self.aliased_results.iter().for_each(|aliased_expr| {
aliased_expr.expr.prover_evaluate(builder, alloc, accessor);
});
}
}
Loading

0 comments on commit 00d4f1a

Please sign in to comment.