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

Swapped maybe-async for maybe-async-await #283

Merged
merged 6 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions air/src/air/assertions/mod.rs
irakliyk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ const NO_STRIDE: usize = 0;
/// An assertion is always placed against a single column of an execution trace, but can cover
/// multiple steps and multiple values. Specifically, there are three kinds of assertions:
///
/// 1. **Single** assertion - which requires that a value in a single cell of an execution trace
/// is equal to the specified value.
/// 2. **Periodic** assertion - which requires that values in multiple cells of a single column
/// are equal to the specified value. The cells must be evenly spaced at intervals with lengths
/// equal to powers of two. For example, we can specify that values in a column must be equal
/// to 0 at steps 0, 8, 16, 24, 32 etc. Steps can also start at some offset - e.g., 1, 9, 17,
/// 25, 33 is also a valid sequence of steps.
/// 3. **Sequence** assertion - which requires that multiple cells in a single column are equal
/// to the values from the provided list. The cells must be evenly spaced at intervals with
/// lengths equal to powers of two. For example, we can specify that values in a column must
/// be equal to a sequence 1, 2, 3, 4 at steps 0, 8, 16, 24. That is, value at step 0 should be
/// equal to 1, value at step 8 should be equal to 2 etc.
/// 1. **Single** assertion - which requires that a value in a single cell of an execution trace
/// is equal to the specified value.
/// 2. **Periodic** assertion - which requires that values in multiple cells of a single column
/// are equal to the specified value. The cells must be evenly spaced at intervals with lengths
/// equal to powers of two. For example, we can specify that values in a column must be equal
/// to 0 at steps 0, 8, 16, 24, 32 etc. Steps can also start at some offset - e.g., 1, 9, 17,
/// 25, 33 is also a valid sequence of steps.
/// 3. **Sequence** assertion - which requires that multiple cells in a single column are equal
/// to the values from the provided list. The cells must be evenly spaced at intervals with
/// lengths equal to powers of two. For example, we can specify that values in a column must
/// be equal to a sequence 1, 2, 3, 4 at steps 0, 8, 16, 24. That is, value at step 0 should be
/// equal to 1, value at step 8 should be equal to 2 etc.
///
/// Note that single and periodic assertions are succinct. That is, a verifier can evaluate them
/// very efficiently. However, sequence assertions have liner complexity in the number of
Expand Down
23 changes: 11 additions & 12 deletions air/src/air/context.rs
irakliyk marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,19 @@ impl<B: StarkField> AirContext<B> {
///
/// This is the maximum of:
/// 1. The maximum evaluation degree over all transition constraints minus the degree of the
/// transition constraint divisor divided by trace length.
/// transition constraint divisor divided by trace length.
/// 2. `1`, because the constraint composition polynomial requires at least one column.
///
/// Since the degree of a constraint `C(x)` can be computed as `[constraint.base +
/// constraint.cycles.len()] * [trace_length - 1]` the degree of the constraint composition
/// polynomial can be computed as: `([constraint.base + constraint.cycles.len()] * [trace_length
/// - 1] - [trace_length - n])` where `constraint` is the constraint attaining the maximum and
/// `n` is the number of exemption points. In the case `n = 1`, the expression simplifies to:
/// `[constraint.base + constraint.cycles.len() - 1] * [trace_length - 1]` Thus, if each column
/// is of length `trace_length`, we would need `[constraint.base + constraint.cycles.len() - 1]`
/// columns to store the coefficients of the constraint composition polynomial. This means that
/// if the highest constraint degree is equal to `5`, the constraint composition polynomial will
/// require four columns and if the highest constraint degree is equal to `7`, it will require
/// six columns to store.
/// Since the degree of a constraint `C(x)` can be computed as `[constraint.base +
/// constraint.cycles.len()] * [trace_length - 1]` the degree of the constraint composition
/// polynomial can be computed as: `([constraint.base + constraint.cycles.len()] * [trace_length
/// - 1] - [trace_length - n])` where `constraint` is the constraint attaining the maximum and
/// `n` is the number of exemption points. In the case `n = 1`, the expression simplifies to:
/// `[constraint.base + constraint.cycles.len() - 1] * [trace_length - 1]` Thus, if each column
/// is of length `trace_length`, we would need `[constraint.base + constraint.cycles.len() - 1]`
/// columns to store the coefficients of the constraint composition polynomial. This means that
/// if the highest constraint degree is equal to `5`, the constraint composition polynomial will
/// require four columns and if the highest constraint degree is equal to `7`, it will require six columns to store.
///
/// Note that the Lagrange kernel constraints require only 1 column, since the degree of the
/// numerator is `trace_len - 1` for all transition constraints (i.e. the base degree is 1).
Expand Down
5 changes: 2 additions & 3 deletions prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,17 @@ name = "lagrange_kernel"
harness = false

[features]
async = ["async-trait", "maybe_async/async"]
async = ["maybe_async/async"]
concurrent = ["crypto/concurrent", "math/concurrent", "fri/concurrent", "utils/concurrent", "std"]
default = ["std"]
std = ["air/std", "crypto/std", "fri/std", "math/std", "utils/std"]

[dependencies]
air = { version = "0.9", path = "../air", package = "winter-air", default-features = false }
async-trait = { version = "0.1.80", optional = true }
crypto = { version = "0.9", path = "../crypto", package = "winter-crypto", default-features = false }
fri = { version = "0.9", path = '../fri', package = "winter-fri", default-features = false }
math = { version = "0.9", path = "../math", package = "winter-math", default-features = false }
maybe_async = { version = "0.9", path = "../utils/maybe_async", package = "winter-maybe-async"}
maybe_async = { path = "../utils/maybe_async" , package = "winter-maybe-async" }
tracing = { version = "0.1", default-features = false, features = ["attributes"]}
utils = { version = "0.9", path = "../utils/core", package = "winter-utils", default-features = false }

Expand Down
71 changes: 38 additions & 33 deletions prover/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@
#[macro_use]
extern crate alloc;

#[cfg(feature = "async")]
use alloc::boxed::Box;

use air::AuxRandElements;
pub use air::{
proof, proof::Proof, Air, AirContext, Assertion, BoundaryConstraint, BoundaryConstraintGroup,
Expand All @@ -61,7 +58,7 @@ use math::{
fields::{CubeExtension, QuadExtension},
ExtensibleField, FieldElement, StarkField, ToElements,
};
use maybe_async::maybe_async;
use maybe_async::{maybe_async, maybe_await};
use tracing::{event, info_span, instrument, Level};
pub use utils::{
iterators, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
Expand Down Expand Up @@ -129,7 +126,6 @@ pub type ProverGkrProof<P> = <<P as Prover>::Air as Air>::GkrProof;
/// of these types are provided with the prover). For example, providing custom implementations
/// of [TraceLde] and/or [ConstraintEvaluator] can be beneficial when some steps of proof
/// generation can be delegated to non-CPU hardware (e.g., GPUs).
#[maybe_async]
pub trait Prover {
/// Base field for the computation described by this prover.
type BaseField: StarkField + ExtensibleField<2> + ExtensibleField<3>;
Expand Down Expand Up @@ -177,7 +173,8 @@ pub trait Prover {
///
/// Returns a tuple containing a [TracePolyTable] with the trace polynomials for the main trace
/// and a new [TraceLde] instance from which the LDE and trace commitments can be obtained.
async fn new_trace_lde<E>(
#[maybe_async]
fn new_trace_lde<E>(
&self,
trace_info: &TraceInfo,
main_trace: &ColMatrix<Self::BaseField>,
Expand All @@ -188,7 +185,8 @@ pub trait Prover {

/// Returns a new constraint evaluator which can be used to evaluate transition and boundary
/// constraints over the extended execution trace.
async fn new_evaluator<'a, E>(
#[maybe_async]
fn new_evaluator<'a, E>(
&self,
air: &'a Self::Air,
aux_rand_elements: Option<AuxRandElements<E>>,
Expand All @@ -202,7 +200,8 @@ pub trait Prover {

/// Builds the GKR proof. If the [`Air`] doesn't use a GKR proof, leave unimplemented.
#[allow(unused_variables)]
async fn generate_gkr_proof<E>(
#[maybe_async]
fn generate_gkr_proof<E>(
&self,
main_trace: &Self::Trace,
public_coin: &mut Self::RandomCoin,
Expand All @@ -215,7 +214,8 @@ pub trait Prover {

/// Builds and returns the auxiliary trace.
#[allow(unused_variables)]
async fn build_aux_trace<E>(
#[maybe_async]
fn build_aux_trace<E>(
&self,
main_trace: &Self::Trace,
aux_rand_elements: &AuxRandElements<E>,
Expand All @@ -234,7 +234,8 @@ pub trait Prover {
/// public inputs. It may also contain a GKR proof, further documented in [`Proof`].
/// Public inputs must match the value returned from
/// [Self::get_pub_inputs()](Prover::get_pub_inputs) for the provided trace.
async fn prove(&self, trace: Self::Trace) -> Result<Proof, ProverError>
#[maybe_async]
fn prove(&self, trace: Self::Trace) -> Result<Proof, ProverError>
where
<Self::Air as Air>::PublicInputs: Send,
<Self::Air as Air>::GkrProof: Send,
Expand All @@ -243,18 +244,18 @@ pub trait Prover {
// of static dispatch for selecting two generic parameter: extension field and hash
// function.
match self.options().field_extension() {
FieldExtension::None => self.generate_proof::<Self::BaseField>(trace).await,
FieldExtension::None => maybe_await!(self.generate_proof::<Self::BaseField>(trace)),
FieldExtension::Quadratic => {
if !<QuadExtension<Self::BaseField>>::is_supported() {
return Err(ProverError::UnsupportedFieldExtension(2));
}
self.generate_proof::<QuadExtension<Self::BaseField>>(trace).await
maybe_await!(self.generate_proof::<QuadExtension<Self::BaseField>>(trace))
},
FieldExtension::Cubic => {
if !<CubeExtension<Self::BaseField>>::is_supported() {
return Err(ProverError::UnsupportedFieldExtension(3));
}
self.generate_proof::<CubeExtension<Self::BaseField>>(trace).await
maybe_await!(self.generate_proof::<CubeExtension<Self::BaseField>>(trace))
},
}
}
Expand All @@ -266,7 +267,8 @@ pub trait Prover {
/// execution `trace` is valid against this prover's AIR.
/// TODO: make this function un-callable externally?
#[doc(hidden)]
async fn generate_proof<E>(&self, trace: Self::Trace) -> Result<Proof, ProverError>
#[maybe_async]
fn generate_proof<E>(&self, trace: Self::Trace) -> Result<Proof, ProverError>
where
E: FieldElement<BaseField = Self::BaseField>,
<Self::Air as Air>::PublicInputs: Send,
Expand Down Expand Up @@ -303,15 +305,15 @@ pub trait Prover {

// commit to the main trace segment
let (mut trace_lde, mut trace_polys) =
self.commit_to_main_trace_segment(&trace, &domain, &mut channel).await;
maybe_await!(self.commit_to_main_trace_segment(&trace, &domain, &mut channel));

// build the auxiliary trace segment, and append the resulting segments to trace commitment
// and trace polynomial table structs
let aux_trace_with_metadata = if air.trace_info().is_multi_segment() {
let (gkr_proof, lagrange_rand_elements) =
if air.context().has_lagrange_kernel_aux_column() {
let (gkr_proof, lagrange_rand_elements) =
self.generate_gkr_proof(&trace, channel.public_coin()).await;
maybe_await!(self.generate_gkr_proof(&trace, channel.public_coin()));

(Some(gkr_proof), Some(lagrange_rand_elements))
} else {
Expand All @@ -326,7 +328,7 @@ pub trait Prover {
AuxRandElements::new_with_lagrange(rand_elements, lagrange_rand_elements)
};

let aux_trace = self.build_aux_trace(&trace, &aux_rand_elements).await;
let aux_trace = maybe_await!(self.build_aux_trace(&trace, &aux_rand_elements));

// commit to the auxiliary trace segment
let aux_segment_polys = {
Expand Down Expand Up @@ -373,16 +375,17 @@ pub trait Prover {
// compute random linear combinations of these evaluations using coefficients drawn from
// the channel
let ce_domain_size = air.ce_domain_size();
let composition_poly_trace = self
.new_evaluator(&air, aux_rand_elements, channel.get_constraint_composition_coeffs())
.await
.evaluate(&trace_lde, &domain);
let composition_poly_trace = maybe_await!(self.new_evaluator(
&air,
aux_rand_elements,
channel.get_constraint_composition_coeffs()
))
.evaluate(&trace_lde, &domain);
assert_eq!(composition_poly_trace.num_rows(), ce_domain_size);

// 3 ----- commit to constraint evaluations -----------------------------------------------
let (constraint_commitment, composition_poly) = self
.commit_to_constraint_evaluations(&air, composition_poly_trace, &domain, &mut channel)
.await;
let (constraint_commitment, composition_poly) = maybe_await!(self
.commit_to_constraint_evaluations(&air, composition_poly_trace, &domain, &mut channel));

// 4 ----- build DEEP composition polynomial ----------------------------------------------
let deep_composition_poly = {
Expand Down Expand Up @@ -509,7 +512,8 @@ pub trait Prover {
///
/// The commitment is computed by hashing each row in the evaluation matrix, and then building
/// a Merkle tree from the resulting hashes.
async fn build_constraint_commitment<E>(
#[maybe_async]
fn build_constraint_commitment<E>(
&self,
composition_poly_trace: CompositionPolyTrace<E>,
num_constraint_composition_columns: usize,
Expand Down Expand Up @@ -556,18 +560,19 @@ pub trait Prover {

#[doc(hidden)]
#[instrument(skip_all)]
async fn commit_to_main_trace_segment<E>(
#[maybe_async]
fn commit_to_main_trace_segment<E>(
&self,
trace: &Self::Trace,
domain: &StarkDomain<Self::BaseField>,
channel: &mut ProverChannel<Self::Air, E, Self::HashFn, Self::RandomCoin>,
channel: &mut ProverChannel<'_, Self::Air, E, Self::HashFn, Self::RandomCoin>,
) -> (Self::TraceLde<E>, TracePolyTable<E>)
where
E: FieldElement<BaseField = Self::BaseField>,
{
// extend the main execution trace and build a Merkle tree from the extended trace
let (trace_lde, trace_polys) =
self.new_trace_lde(trace.info(), trace.main_segment(), domain).await;
maybe_await!(self.new_trace_lde(trace.info(), trace.main_segment(), domain));

// get the commitment to the main trace segment LDE
let main_trace_root = trace_lde.get_main_trace_commitment();
Expand All @@ -581,25 +586,25 @@ pub trait Prover {

#[doc(hidden)]
#[instrument(skip_all)]
async fn commit_to_constraint_evaluations<E>(
#[maybe_async]
fn commit_to_constraint_evaluations<E>(
&self,
air: &Self::Air,
composition_poly_trace: CompositionPolyTrace<E>,
domain: &StarkDomain<Self::BaseField>,
channel: &mut ProverChannel<Self::Air, E, Self::HashFn, Self::RandomCoin>,
channel: &mut ProverChannel<'_, Self::Air, E, Self::HashFn, Self::RandomCoin>,
) -> (ConstraintCommitment<E, Self::HashFn>, CompositionPoly<E>)
where
E: FieldElement<BaseField = Self::BaseField>,
{
// first, build a commitment to the evaluations of the constraint composition polynomial
// columns
let (constraint_commitment, composition_poly) = self
let (constraint_commitment, composition_poly) = maybe_await!(self
.build_constraint_commitment::<E>(
composition_poly_trace,
air.context().num_constraint_composition_columns(),
domain,
)
.await;
));

// then, commit to the evaluations of constraints by writing the root of the constraint
// Merkle tree into the channel
Expand Down
18 changes: 7 additions & 11 deletions utils/maybe_async/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
[package]
name = "winter-maybe-async"
version = "0.9.0"
version = "0.10.0"
description = "sync/async macro for winterfell"
authors = ["winterfell contributors"]
readme = "README.md"
license = "MIT"
repository = "https://github.com/facebook/winterfell"
documentation = "https://docs.rs/winter-maybe-async/0.9.0"
documentation = "https://docs.rs/winter-maybe-async/0.10.0"
keywords = ["async"]
edition = "2021"
rust-version = "1.75"
rust-version = "1.78"

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "2.0", features = ["full", "visit-mut"] }

[dev-dependencies]
async-trait = "0.1"

[features]
async = []

[dependencies]
quote = "1"
syn = { version = "2", features = ["full"] }
Loading