Skip to content

Commit

Permalink
refactor: simplify into consume_mle_evaluations (#428)
Browse files Browse the repository at this point in the history
# Rationale for this change

The `VerificationBuilder` should be simplified for easier porting to
Solidity.

# What changes are included in this PR?

See individual commits.

# Are these changes tested?
Yes, by existing code.
  • Loading branch information
JayWhite2357 authored Dec 11, 2024
2 parents 8683e3c + 8dcc3cd commit 6dbd61e
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub trait CommitmentEvaluationProof {
transcript,
core::slice::from_ref(a_commit),
&[Self::Scalar::ONE],
product,
core::slice::from_ref(product),
b_point,
generators_offset,
table_length,
Expand All @@ -70,7 +70,7 @@ pub trait CommitmentEvaluationProof {
transcript: &mut impl Transcript,
commit_batch: &[Self::Commitment],
batching_factors: &[Self::Scalar],
product: &Self::Scalar,
evaluations: &[Self::Scalar],
b_point: &[Self::Scalar],
generators_offset: u64,
table_length: usize,
Expand Down Expand Up @@ -117,7 +117,7 @@ impl CommitmentEvaluationProof for InnerProductProof {
transcript: &mut impl Transcript,
commit_batch: &[Self::Commitment],
batching_factors: &[Self::Scalar],
product: &Self::Scalar,
evaluations: &[Self::Scalar],
b_point: &[Self::Scalar],
generators_offset: u64,
table_length: usize,
Expand All @@ -131,6 +131,11 @@ impl CommitmentEvaluationProof for InnerProductProof {
} else {
crate::base::polynomial::compute_evaluation_vector(b, b_point);
}
let product: Self::Scalar = evaluations
.iter()
.zip(batching_factors)
.map(|(&e, &f)| e * f)
.sum();
// The InnerProductProof from blitzar only works with the merlin Transcript.
// So, we wrap the call to it.
transcript.wrap_transcript(|transcript| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl CommitmentEvaluationProof for NaiveEvaluationProof {
transcript: &mut impl Transcript,
commit_batch: &[Self::Commitment],
batching_factors: &[Self::Scalar],
product: &Self::Scalar,
evaluations: &[Self::Scalar],
b_point: &[Self::Scalar],
generators_offset: u64,
_table_length: usize,
Expand All @@ -74,6 +74,11 @@ impl CommitmentEvaluationProof for NaiveEvaluationProof {
.zip(batching_factors)
.map(|(c, m)| *m * c)
.fold(NaiveCommitment(vec![]), Add::add);
let product = evaluations
.iter()
.zip(batching_factors)
.map(|(&e, &f)| e * f)
.sum();
if folded_commits != self.a {
return Err(NaiveEvaluationProofError);
}
Expand All @@ -87,7 +92,7 @@ impl CommitmentEvaluationProof for NaiveEvaluationProof {
.zip(b_vec)
.map(|(&a, b)| a * b)
.sum::<TestScalar>();
if expected_product != *product {
if expected_product != product {
return Err(NaiveEvaluationProofError);
}
transcript.extend_scalars_as_be(&self.a.0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl CommitmentEvaluationProof for DoryEvaluationProof {
transcript: &mut impl Transcript,
commit_batch: &[Self::Commitment],
batching_factors: &[Self::Scalar],
product: &Self::Scalar,
evaluations: &[Self::Scalar],
b_point: &[Self::Scalar],
generators_offset: u64,
_table_length: usize,
Expand All @@ -82,6 +82,11 @@ impl CommitmentEvaluationProof for DoryEvaluationProof {
commit_batch.iter().map(|c| c.0),
batching_factors.iter().map(|f| f.0),
);
let product: Self::Scalar = evaluations
.iter()
.zip(batching_factors)
.map(|(&e, &f)| e * f)
.sum();
// Dory PCS Logic
if generators_offset != 0 {
return Err(DoryError::InvalidGeneratorsOffset {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl CommitmentEvaluationProof for DynamicDoryEvaluationProof {
transcript: &mut impl Transcript,
commit_batch: &[Self::Commitment],
batching_factors: &[Self::Scalar],
product: &Self::Scalar,
evaluations: &[Self::Scalar],
b_point: &[Self::Scalar],
generators_offset: u64,
_table_length: usize,
Expand All @@ -83,6 +83,11 @@ impl CommitmentEvaluationProof for DynamicDoryEvaluationProof {
commit_batch.iter().map(|c| c.0),
batching_factors.iter().map(|f| f.0),
);
let product: Self::Scalar = evaluations
.iter()
.zip(batching_factors)
.map(|(&e, &f)| e * f)
.sum();
// Dory PCS Logic
if generators_offset != 0 {
return Err(DoryError::InvalidGeneratorsOffset {
Expand Down
8 changes: 3 additions & 5 deletions crates/proof-of-sql/src/sql/proof/query_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
sumcheck_evaluations,
&self.bit_distributions,
sumcheck_random_scalars.subpolynomial_multipliers,
&evaluation_random_scalars,
post_result_challenges,
self.one_evaluation_lengths.clone(),
);
Expand All @@ -341,7 +340,7 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
.collect();
let evaluation_accessor: IndexMap<_, _> = column_references
.into_iter()
.map(|col| (col, builder.consume_anchored_mle()))
.map(|col| (col, builder.consume_mle_evaluation()))
.collect();

let verifier_evaluations = expr.verifier_evaluate(
Expand All @@ -367,13 +366,12 @@ impl<CP: CommitmentEvaluationProof> QueryProof<CP> {
}

// finally, check the MLE evaluations with the inner product proof
let product = builder.folded_pcs_proof_evaluation();
self.evaluation_proof
.verify_batched_proof(
&mut transcript,
&pcs_proof_commitments,
builder.inner_product_multipliers(),
&product,
&evaluation_random_scalars,
&self.pcs_proof_evaluations,
&subclaim.evaluation_point,
min_row_num as u64,
self.range_length,
Expand Down
10 changes: 5 additions & 5 deletions crates/proof-of-sql/src/sql/proof/query_proof_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl ProofPlan for TrivialTestProofPlan {
_result: Option<&OwnedTable<S>>,
_one_eval_map: &IndexMap<TableRef, S>,
) -> Result<TableEvaluation<S>, ProofError> {
assert_eq!(builder.consume_intermediate_mle(), S::ZERO);
assert_eq!(builder.consume_mle_evaluation(), S::ZERO);
builder.produce_sumcheck_subpolynomial_evaluation(
SumcheckSubpolynomialType::ZeroSum,
S::from(self.evaluation),
Expand Down Expand Up @@ -278,7 +278,7 @@ impl ProofPlan for SquareTestProofPlan {
ColumnType::BigInt,
))
.unwrap();
let res_eval = builder.consume_intermediate_mle();
let res_eval = builder.consume_mle_evaluation();
builder.produce_sumcheck_subpolynomial_evaluation(
SumcheckSubpolynomialType::Identity,
res_eval - x_eval * x_eval,
Expand Down Expand Up @@ -474,8 +474,8 @@ impl ProofPlan for DoubleSquareTestProofPlan {
ColumnType::BigInt,
))
.unwrap();
let z_eval = builder.consume_intermediate_mle();
let res_eval = builder.consume_intermediate_mle();
let z_eval = builder.consume_mle_evaluation();
let res_eval = builder.consume_mle_evaluation();

// poly1
builder.produce_sumcheck_subpolynomial_evaluation(
Expand Down Expand Up @@ -681,7 +681,7 @@ impl ProofPlan for ChallengeTestProofPlan {
ColumnType::BigInt,
))
.unwrap();
let res_eval = builder.consume_intermediate_mle();
let res_eval = builder.consume_mle_evaluation();
builder.produce_sumcheck_subpolynomial_evaluation(
SumcheckSubpolynomialType::Identity,
alpha * res_eval - alpha * x_eval * x_eval,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,10 @@ impl ProofPlan for EmptyTestQueryExpr {
_result: Option<&OwnedTable<S>>,
_one_eval_map: &IndexMap<TableRef, S>,
) -> Result<TableEvaluation<S>, ProofError> {
let _ = std::iter::repeat_with(|| {
assert_eq!(builder.consume_intermediate_mle(), S::ZERO);
})
.take(self.columns)
.collect::<Vec<_>>();
assert_eq!(
builder.consume_mle_evaluations(self.columns),
vec![S::ZERO; self.columns]
);
Ok(TableEvaluation::new(
vec![S::ZERO; self.columns],
builder.consume_one_evaluation(),
Expand Down
55 changes: 10 additions & 45 deletions crates/proof-of-sql/src/sql/proof/verification_builder.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
use super::{SumcheckMleEvaluations, SumcheckSubpolynomialType};
use crate::base::{bit::BitDistribution, scalar::Scalar};
use alloc::vec::Vec;
use core::iter;

/// Track components used to verify a query's proof
pub struct VerificationBuilder<'a, S: Scalar> {
pub mle_evaluations: SumcheckMleEvaluations<'a, S>,
generator_offset: usize,
subpolynomial_multipliers: &'a [S],
inner_product_multipliers: &'a [S],
sumcheck_evaluation: S,
bit_distributions: &'a [BitDistribution],
folded_pcs_proof_evaluation: S,
consumed_one_evaluations: usize,
consumed_pcs_proof_mles: usize,
consumed_intermediate_mles: usize,
produced_subpolynomials: usize,
/// The challenges used in creation of the constraints in the proof.
/// Specifically, these are the challenges that the verifier sends to
Expand All @@ -36,25 +34,17 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> {
mle_evaluations: SumcheckMleEvaluations<'a, S>,
bit_distributions: &'a [BitDistribution],
subpolynomial_multipliers: &'a [S],
inner_product_multipliers: &'a [S],
post_result_challenges: Vec<S>,
one_evaluation_length_queue: Vec<usize>,
) -> Self {
assert_eq!(
inner_product_multipliers.len(),
mle_evaluations.pcs_proof_evaluations.len()
);
Self {
mle_evaluations,
generator_offset,
bit_distributions,
subpolynomial_multipliers,
inner_product_multipliers,
sumcheck_evaluation: S::zero(),
folded_pcs_proof_evaluation: S::zero(),
consumed_one_evaluations: 0,
consumed_pcs_proof_mles: 0,
consumed_intermediate_mles: 0,
produced_subpolynomials: 0,
post_result_challenges,
one_evaluation_length_queue,
Expand Down Expand Up @@ -83,13 +73,17 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> {
/// Consume the evaluation of an anchored MLE used in sumcheck and provide the commitment of the MLE
///
/// An anchored MLE is an MLE where the verifier has access to the commitment
pub fn consume_anchored_mle(&mut self) -> S {
pub fn consume_mle_evaluation(&mut self) -> S {
let index = self.consumed_pcs_proof_mles;
let multiplier = self.inner_product_multipliers[index];
self.consumed_pcs_proof_mles += 1;
let res = self.mle_evaluations.pcs_proof_evaluations[index];
self.folded_pcs_proof_evaluation += multiplier * res;
res
self.mle_evaluations.pcs_proof_evaluations[index]
}

/// Consume multiple MLE evaluations
pub fn consume_mle_evaluations(&mut self, count: usize) -> Vec<S> {
iter::repeat_with(|| self.consume_mle_evaluation())
.take(count)
.collect()
}

/// Consume a bit distribution that describes which bits are constant
Expand All @@ -100,14 +94,6 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> {
res
}

/// Consume the evaluation of an intermediate MLE used in sumcheck
///
/// An interemdiate MLE is one where the verifier doesn't have access to its commitment
pub fn consume_intermediate_mle(&mut self) -> S {
self.consumed_intermediate_mles += 1;
self.consume_anchored_mle()
}

/// Produce the evaluation of a subpolynomial used in sumcheck
pub fn produce_sumcheck_subpolynomial_evaluation(
&mut self,
Expand All @@ -134,27 +120,6 @@ impl<'a, S: Scalar> VerificationBuilder<'a, S> {
self.sumcheck_evaluation
}

#[allow(
clippy::missing_panics_doc,
reason = "Panic conditions are self-evident from the completed assertion."
)]
/// Get folding factors for the pre-result commitments
pub fn inner_product_multipliers(&self) -> &[S] {
assert!(self.completed());
self.inner_product_multipliers
}

#[allow(
clippy::missing_panics_doc,
reason = "The panic condition is evident due to the assertion ensuring completion."
)]
/// Get the evaluation of the folded pre-result MLE vectors used in a verifiable query's
/// bulletproof
pub fn folded_pcs_proof_evaluation(&self) -> S {
assert!(self.completed());
self.folded_pcs_proof_evaluation
}

/// Check that the verification builder is completely built up
fn completed(&self) -> bool {
self.bit_distributions.is_empty()
Expand Down
45 changes: 0 additions & 45 deletions crates/proof-of-sql/src/sql/proof/verification_builder_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ fn an_empty_sumcheck_polynomial_evaluates_to_zero() {
mle_evaluations,
&[][..],
&[][..],
&[][..],
Vec::new(),
Vec::new(),
);
assert_eq!(builder.sumcheck_evaluation(), Curve25519Scalar::zero());
assert_eq!(builder.inner_product_multipliers(), &[]);
}

#[test]
Expand All @@ -36,7 +34,6 @@ fn we_build_up_a_sumcheck_polynomial_evaluation_from_subpolynomial_evaluations()
mle_evaluations,
&[][..],
&subpolynomial_multipliers,
&[][..],
Vec::new(),
Vec::new(),
);
Expand All @@ -53,55 +50,13 @@ fn we_build_up_a_sumcheck_polynomial_evaluation_from_subpolynomial_evaluations()
assert_eq!(builder.sumcheck_evaluation(), expected_sumcheck_evaluation);
}

#[test]
fn we_build_up_the_folded_pcs_proof_commitment() {
let pcs_proof_evaluations = [
Curve25519Scalar::from(123u64),
Curve25519Scalar::from(456u64),
];
let mle_evaluations = SumcheckMleEvaluations {
num_sumcheck_variables: 1,
pcs_proof_evaluations: &pcs_proof_evaluations,
..Default::default()
};
let inner_product_multipliers = [
Curve25519Scalar::from(10u64),
Curve25519Scalar::from(100u64),
];
let mut builder = VerificationBuilder::new(
0,
mle_evaluations,
&[][..],
&[][..],
&inner_product_multipliers,
Vec::new(),
Vec::new(),
);
let eval = builder.consume_anchored_mle();
assert_eq!(eval, Curve25519Scalar::from(123u64));
let eval = builder.consume_intermediate_mle();
assert_eq!(eval, Curve25519Scalar::from(456u64));
assert_eq!(
builder.inner_product_multipliers(),
&[inner_product_multipliers[0], inner_product_multipliers[1]]
);
let expected_folded_pcs_proof_evaluation = inner_product_multipliers[0]
* Curve25519Scalar::from(123u64)
+ inner_product_multipliers[1] * Curve25519Scalar::from(456u64);
assert_eq!(
builder.folded_pcs_proof_evaluation(),
expected_folded_pcs_proof_evaluation
);
}

#[test]
fn we_can_consume_post_result_challenges_in_proof_builder() {
let mut builder = VerificationBuilder::new(
0,
SumcheckMleEvaluations::default(),
&[][..],
&[][..],
&[][..],
vec![
Curve25519Scalar::from(123),
Curve25519Scalar::from(456),
Expand Down
2 changes: 1 addition & 1 deletion crates/proof-of-sql/src/sql/proof_exprs/and_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl ProofExpr for AndExpr {
let rhs = self.rhs.verifier_evaluate(builder, accessor, one_eval)?;

// lhs_and_rhs
let lhs_and_rhs = builder.consume_intermediate_mle();
let lhs_and_rhs = builder.consume_mle_evaluation();

// subpolynomial: lhs_and_rhs - lhs * rhs
builder.produce_sumcheck_subpolynomial_evaluation(
Expand Down
Loading

0 comments on commit 6dbd61e

Please sign in to comment.