Skip to content

Commit

Permalink
feat: add MultiplyExpr
Browse files Browse the repository at this point in the history
  • Loading branch information
iajoiner committed Jun 25, 2024
1 parent 55816c3 commit ecf78bc
Show file tree
Hide file tree
Showing 11 changed files with 647 additions and 29 deletions.
8 changes: 7 additions & 1 deletion crates/proof-of-sql/src/sql/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ pub(crate) use add_subtract_expr::AddSubtractExpr;
#[cfg(all(test, feature = "blitzar"))]
mod add_subtract_expr_test;

mod multiply_expr;
use multiply_expr::MultiplyExpr;
#[cfg(all(test, feature = "blitzar"))]
mod multiply_expr_test;

mod filter_expr;
pub(crate) use filter_expr::FilterExpr;
#[cfg(test)]
Expand Down Expand Up @@ -59,7 +64,8 @@ pub(crate) use comparison_util::scale_and_subtract;

mod numerical_util;
pub(crate) use numerical_util::{
add_subtract_columns, scale_and_add_subtract_eval, try_add_subtract_column_types,
add_subtract_columns, multiply_columns, scale_and_add_subtract_eval,
try_add_subtract_column_types, try_multiply_column_types,
};

mod equals_expr;
Expand Down
120 changes: 120 additions & 0 deletions crates/proof-of-sql/src/sql/ast/multiply_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
use super::{ProvableExpr, ProvableExprPlan};
use crate::{
base::{
commitment::Commitment,
database::{Column, ColumnRef, ColumnType, CommitmentAccessor, DataAccessor},
proof::ProofError,
},
sql::{
ast::{multiply_columns, try_multiply_column_types},
proof::{CountBuilder, ProofBuilder, SumcheckSubpolynomialType, VerificationBuilder},
},
};
use bumpalo::Bump;
use num_traits::One;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

/// Provable numerical * expression
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct MultiplyExpr<C: Commitment> {
lhs: Box<ProvableExprPlan<C>>,
rhs: Box<ProvableExprPlan<C>>,
}

impl<C: Commitment> MultiplyExpr<C> {
/// Create numerical `*` expression
pub fn new(lhs: Box<ProvableExprPlan<C>>, rhs: Box<ProvableExprPlan<C>>) -> Self {
Self { lhs, rhs }
}
}

impl<C: Commitment> ProvableExpr<C> for MultiplyExpr<C> {
fn count(&self, builder: &mut CountBuilder) -> Result<(), ProofError> {
self.lhs.count(builder)?;
self.rhs.count(builder)?;
builder.count_subpolynomials(1);
builder.count_intermediate_mles(1);
builder.count_degree(3);
Ok(())
}

fn data_type(&self) -> ColumnType {
try_multiply_column_types(self.lhs.data_type(), self.rhs.data_type())
.expect("Failed to multiply column types")
}

fn result_evaluate<'a>(
&self,
table_length: usize,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<C::Scalar>,
) -> Column<'a, C::Scalar> {
let lhs_column: Column<'a, C::Scalar> =
self.lhs.result_evaluate(table_length, alloc, accessor);
let rhs_column: Column<'a, C::Scalar> =
self.rhs.result_evaluate(table_length, alloc, accessor);
let scalars = multiply_columns(lhs_column, rhs_column, alloc);
Column::Scalar(scalars)
}

#[tracing::instrument(
name = "proofs.sql.ast.and_expr.prover_evaluate",
level = "info",
skip_all
)]
fn prover_evaluate<'a>(
&self,
builder: &mut ProofBuilder<'a, C::Scalar>,
alloc: &'a Bump,
accessor: &'a dyn DataAccessor<C::Scalar>,
) -> Column<'a, C::Scalar> {
let lhs_column: Column<'a, C::Scalar> = self.lhs.prover_evaluate(builder, alloc, accessor);
let rhs_column: Column<'a, C::Scalar> = self.rhs.prover_evaluate(builder, alloc, accessor);
let lhs_scalars = lhs_column.to_scalar_with_scaling(0);
let rhs_scalars = rhs_column.to_scalar_with_scaling(0);
let lhs_bump: &'a [C::Scalar] = alloc.alloc_slice_copy(&lhs_scalars);
let rhs_bump: &'a [C::Scalar] = alloc.alloc_slice_copy(&rhs_scalars);

// lhs_times_rhs
let lhs_times_rhs: &'a [C::Scalar] = multiply_columns(lhs_column, rhs_column, alloc);
builder.produce_intermediate_mle(lhs_times_rhs);

// subpolynomial: lhs_times_rhs - lhs * rhs
builder.produce_sumcheck_subpolynomial(
SumcheckSubpolynomialType::Identity,
vec![
(C::Scalar::one(), vec![Box::new(lhs_times_rhs)]),
(
-C::Scalar::one(),
vec![Box::new(lhs_bump), Box::new(rhs_bump)],
),
],
);
Column::Scalar(lhs_times_rhs)
}

fn verifier_evaluate(
&self,
builder: &mut VerificationBuilder<C>,
accessor: &dyn CommitmentAccessor<C>,
) -> Result<C::Scalar, ProofError> {
let lhs = self.lhs.verifier_evaluate(builder, accessor)?;
let rhs = self.rhs.verifier_evaluate(builder, accessor)?;

// lhs_times_rhs
let lhs_times_rhs = builder.consume_intermediate_mle();

// subpolynomial: lhs_times_rhs - lhs * rhs
let eval = builder.mle_evaluations.random_evaluation * (lhs_times_rhs - lhs * rhs);
builder.produce_sumcheck_subpolynomial_evaluation(&eval);

// selection
Ok(lhs_times_rhs)
}

fn get_column_references(&self, columns: &mut HashSet<ColumnRef>) {
self.lhs.get_column_references(columns);
self.rhs.get_column_references(columns);
}
}
Loading

0 comments on commit ecf78bc

Please sign in to comment.