Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Prover generic over the ConstraintCommitment type #343

Merged
merged 11 commits into from
Nov 24, 2024
80 changes: 0 additions & 80 deletions prover/src/constraints/commitment.rs

This file was deleted.

153 changes: 153 additions & 0 deletions prover/src/constraints/commitment/default.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

use alloc::vec::Vec;
use maybe_async::maybe_async;
use tracing::info_span;
use core::marker::PhantomData;

use air::{proof::Queries, PartitionOptions};
use crypto::{ElementHasher, VectorCommitment};
use math::FieldElement;

use crate::{CompositionPoly, CompositionPolyTrace, StarkDomain, DEFAULT_SEGMENT_WIDTH};

use super::{ConstraintCommitment, RowMatrix};

// CONSTRAINT COMMITMENT
// ================================================================================================

/// Constraint evaluation commitment.
///
/// The commitment consists of two components:
/// * Evaluations of composition polynomial columns over the LDE domain.
/// * Vector commitment where each vector element corresponds to the digest of a row in
/// the composition polynomial evaluation matrix.
pub struct DefaultConstraintCommitment<
E: FieldElement,
H: ElementHasher<BaseField = E::BaseField>,
V: VectorCommitment<H>,
> {
evaluations: RowMatrix<E>,
vector_commitment: V,
_h: PhantomData<H>,
}

impl<E, H, V> DefaultConstraintCommitment<E, H, V>
where
E: FieldElement,
H: ElementHasher<BaseField = E::BaseField>,
V: VectorCommitment<H>,
{
/// Creates a new constraint evaluation commitment from the provided composition polynomial
/// evaluations and the corresponding vector commitment.
pub fn new(
composition_poly_trace: CompositionPolyTrace<E>,
num_constraint_composition_columns: usize,
domain: &StarkDomain<E::BaseField>,
partition_options: PartitionOptions,
) -> (Self, CompositionPoly<E>) {

// extend the main execution trace and build a commitment to the extended trace
let (evaluations, commitment, composition_poly) =
build_constraint_commitment::<E, H, V>(composition_poly_trace, num_constraint_composition_columns, domain, partition_options);

assert_eq!(
evaluations.num_rows(),
commitment.domain_len(),
"number of rows in constraint evaluation matrix must be the same as the size \
of the vector commitment domain"
);

let commitment = Self {
evaluations,
vector_commitment: commitment,
_h: PhantomData,
};

(commitment, composition_poly)
}
}

impl<E, H, V> ConstraintCommitment<E> for DefaultConstraintCommitment<E, H, V>
where
E: FieldElement,
H: ElementHasher<BaseField = E::BaseField> + core::marker::Sync,
V: VectorCommitment<H> + core::marker::Sync,
{
type HashFn = H;
type VC = V;

/// Returns the commitment.
fn commitment(&self) -> H::Digest {
self.vector_commitment.commitment()
}

/// Returns constraint evaluations at the specified positions along with a batch opening proof
/// against the vector commitment.
fn query(self, positions: &[usize]) -> Queries {
// build batch opening proof to the leaves specified by positions
let opening_proof = self
.vector_commitment
.open_many(positions)
.expect("failed to generate a batch opening proof for constraint queries");

// determine a set of evaluations corresponding to each position
let mut evaluations = Vec::new();
for &position in positions {
let row = self.evaluations.row(position).to_vec();
evaluations.push(row);
}

Queries::new::<H, E, V>(opening_proof.1, evaluations)
}
}

#[maybe_async]
fn build_constraint_commitment<E, H, V>(
composition_poly_trace: CompositionPolyTrace<E>,
num_constraint_composition_columns: usize,
domain: &StarkDomain<E::BaseField>,
partition_options: PartitionOptions,
) -> (RowMatrix<E>, V, CompositionPoly<E>)
where
E: FieldElement,
H: ElementHasher<BaseField = E::BaseField>,
V: VectorCommitment<H>,
{
// first, build constraint composition polynomial from its trace as follows:
// - interpolate the trace into a polynomial in coefficient form
// - "break" the polynomial into a set of column polynomials each of degree equal to
// trace_length - 1
let composition_poly = info_span!(
"build_composition_poly_columns",
num_columns = num_constraint_composition_columns
)
.in_scope(|| {
CompositionPoly::new(composition_poly_trace, domain, num_constraint_composition_columns)
});
assert_eq!(composition_poly.num_columns(), num_constraint_composition_columns);
assert_eq!(composition_poly.column_degree(), domain.trace_length() - 1);

// then, evaluate composition polynomial columns over the LDE domain
let domain_size = domain.lde_domain_size();
let composed_evaluations = info_span!("evaluate_composition_poly_columns").in_scope(|| {
RowMatrix::evaluate_polys_over::<DEFAULT_SEGMENT_WIDTH>(composition_poly.data(), domain)
});
assert_eq!(composed_evaluations.num_cols(), num_constraint_composition_columns);
assert_eq!(composed_evaluations.num_rows(), domain_size);

// finally, build constraint evaluation commitment
let commitment = info_span!(
"compute_constraint_evaluation_commitment",
log_domain_size = domain_size.ilog2()
)
.in_scope(|| {
composed_evaluations
.commit_to_rows::<H, V>(partition_options)
});

(composed_evaluations, commitment, composition_poly)
}
38 changes: 38 additions & 0 deletions prover/src/constraints/commitment/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

use air::proof::Queries;
use crypto::{ElementHasher, Hasher, VectorCommitment};
use math::FieldElement;

use super::RowMatrix;

mod default;
pub use default::DefaultConstraintCommitment;


// CONSTRAINT COMMITMENT
// ================================================================================================

/// Constraint evaluation commitment.
///
/// The commitment consists of two components:
/// * Evaluations of composition polynomial columns over the LDE domain.
/// * Vector commitment where each vector element corresponds to the digest of a row in
/// the composition polynomial evaluation matrix.
pub trait ConstraintCommitment<E: FieldElement> {
/// The hash function used for hashing the rows of trace segment LDEs.
type HashFn: ElementHasher<BaseField = E::BaseField>;

/// The vector commitment scheme used for commiting to the trace.
type VC: VectorCommitment<Self::HashFn>;

/// Returns the commitment.
fn commitment(&self) -> <Self::HashFn as Hasher>::Digest;

/// Returns constraint evaluations at the specified positions along with a batch opening proof
/// against the vector commitment.
fn query(self, positions: &[usize]) -> Queries;
}
2 changes: 1 addition & 1 deletion prover/src/constraints/composition_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<E: FieldElement> CompositionPolyTrace<E> {
/// For example, if the composition polynomial has degree 2N - 1, where N is the trace length,
/// it will be stored as two columns of size N (each of degree N - 1).
pub struct CompositionPoly<E: FieldElement> {
data: ColMatrix<E>,
pub data: ColMatrix<E>,
gswirski marked this conversation as resolved.
Show resolved Hide resolved
}

impl<E: FieldElement> CompositionPoly<E> {
Expand Down
2 changes: 1 addition & 1 deletion prover/src/constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ mod evaluation_table;
pub use evaluation_table::{ConstraintEvaluationTable, EvaluationTableFragment};

mod commitment;
pub use commitment::ConstraintCommitment;
pub use commitment::{ConstraintCommitment, DefaultConstraintCommitment};
54 changes: 12 additions & 42 deletions prover/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@
//! also depends on the capabilities of the machine used to generate the proofs (i.e. on number
//! of CPU cores and memory bandwidth).

#![no_std]

#[macro_use]
extern crate alloc;

Expand Down Expand Up @@ -73,7 +71,7 @@ use matrix::{ColMatrix, RowMatrix};
mod constraints;
pub use constraints::{
CompositionPoly, CompositionPolyTrace, ConstraintCommitment, ConstraintEvaluator,
DefaultConstraintEvaluator,
DefaultConstraintEvaluator, DefaultConstraintCommitment,
};

mod composer;
Expand Down Expand Up @@ -150,6 +148,12 @@ pub trait Prover {
where
E: FieldElement<BaseField = Self::BaseField>;

/// Trace low-degree extension for building the LDEs of trace segments and their commitments.
type ConstraintCommitment<E>: ConstraintCommitment<E, HashFn = Self::HashFn, VC = Self::VC>
where
E: FieldElement<BaseField = Self::BaseField>;
irakliyk marked this conversation as resolved.
Show resolved Hide resolved


/// Constraints evaluator used to evaluate AIR constraints over the extended execution trace.
type ConstraintEvaluator<'a, E>: ConstraintEvaluator<E, Air = Self::Air>
where
Expand Down Expand Up @@ -524,45 +528,10 @@ pub trait Prover {
composition_poly_trace: CompositionPolyTrace<E>,
num_constraint_composition_columns: usize,
domain: &StarkDomain<Self::BaseField>,
) -> (ConstraintCommitment<E, Self::HashFn, Self::VC>, CompositionPoly<E>)
partition_options: PartitionOptions,
) -> (Self::ConstraintCommitment<E>, CompositionPoly<E>)
where
E: FieldElement<BaseField = Self::BaseField>,
{
// first, build constraint composition polynomial from its trace as follows:
// - interpolate the trace into a polynomial in coefficient form
// - "break" the polynomial into a set of column polynomials each of degree equal to
// trace_length - 1
let composition_poly = info_span!(
"build_composition_poly_columns",
num_columns = num_constraint_composition_columns
)
.in_scope(|| {
CompositionPoly::new(composition_poly_trace, domain, num_constraint_composition_columns)
});
assert_eq!(composition_poly.num_columns(), num_constraint_composition_columns);
assert_eq!(composition_poly.column_degree(), domain.trace_length() - 1);

// then, evaluate composition polynomial columns over the LDE domain
let domain_size = domain.lde_domain_size();
let composed_evaluations = info_span!("evaluate_composition_poly_columns").in_scope(|| {
RowMatrix::evaluate_polys_over::<DEFAULT_SEGMENT_WIDTH>(composition_poly.data(), domain)
});
assert_eq!(composed_evaluations.num_cols(), num_constraint_composition_columns);
assert_eq!(composed_evaluations.num_rows(), domain_size);

// finally, build constraint evaluation commitment
let constraint_commitment = info_span!(
"compute_constraint_evaluation_commitment",
log_domain_size = domain_size.ilog2()
)
.in_scope(|| {
let commitment = composed_evaluations
.commit_to_rows::<Self::HashFn, Self::VC>(self.options().partition_options());
ConstraintCommitment::new(composed_evaluations, commitment)
});

(constraint_commitment, composition_poly)
}
E: FieldElement<BaseField = Self::BaseField>;
irakliyk marked this conversation as resolved.
Show resolved Hide resolved

#[doc(hidden)]
#[instrument(skip_all)]
Expand Down Expand Up @@ -603,7 +572,7 @@ pub trait Prover {
composition_poly_trace: CompositionPolyTrace<E>,
domain: &StarkDomain<Self::BaseField>,
channel: &mut ProverChannel<'_, Self::Air, E, Self::HashFn, Self::RandomCoin, Self::VC>,
) -> (ConstraintCommitment<E, Self::HashFn, Self::VC>, CompositionPoly<E>)
) -> (Self::ConstraintCommitment<E>, CompositionPoly<E>)
where
E: FieldElement<BaseField = Self::BaseField>,
{
Expand All @@ -614,6 +583,7 @@ pub trait Prover {
composition_poly_trace,
air.context().num_constraint_composition_columns(),
domain,
self.options().partition_options()
));

// then, commit to the evaluations of constraints by writing the commitment string of
Expand Down
Loading
Loading