,
+ pub fn new(
+ context: &AirContext,
main_assertions: Vec>,
aux_assertions: Vec>,
composition_coefficients: &[E],
@@ -88,7 +88,7 @@ impl BoundaryConstraints {
);
let trace_length = context.trace_info.length();
- let main_trace_width = context.trace_info.main_trace_width();
+ let main_trace_width = context.trace_info.main_segment_width();
let aux_trace_width = context.trace_info.aux_segment_width();
// make sure the assertions are valid in the context of their respective trace segments;
@@ -151,9 +151,9 @@ impl BoundaryConstraints {
/// Translates the provided assertions into boundary constraints, groups the constraints by their
/// divisor, and sorts the resulting groups by the degree adjustment factor.
-fn group_constraints(
+fn group_constraints(
assertions: Vec>,
- context: &AirContext,
+ context: &AirContext,
composition_coefficients: &[E],
inv_g: F::BaseField,
twiddle_map: &mut BTreeMap>,
diff --git a/air/src/air/coefficients.rs b/air/src/air/coefficients.rs
index b82b2ac6b..ed6c3fa99 100644
--- a/air/src/air/coefficients.rs
+++ b/air/src/air/coefficients.rs
@@ -27,11 +27,19 @@ use math::FieldElement;
///
/// The coefficients are separated into two lists: one for transition constraints and another one
/// for boundary constraints. This separation is done for convenience only.
+///
+/// In addition to the above, and when LogUp-GKR is enabled, there are two extra sets of
+/// constraint composition coefficients that are used, namely for:
+///
+/// 1. Lagrange kernel constraints, which include both transition and boundary constraints.
+/// 2. S-column constraint, which is used in implementing the cohomological sum-check argument
+/// of https://eprint.iacr.org/2021/930
#[derive(Debug, Clone)]
pub struct ConstraintCompositionCoefficients {
pub transition: Vec,
pub boundary: Vec,
pub lagrange: Option>,
+ pub s_col: Option,
}
/// Stores the constraint composition coefficients for the Lagrange kernel transition and boundary
@@ -83,8 +91,9 @@ pub struct LagrangeConstraintsCompositionCoefficients {
/// negligible increase in soundness error. The formula for the updated error can be found in
/// Theorem 8 of https://eprint.iacr.org/2022/1216.
///
-/// In the case when the trace polynomials contain a trace polynomial corresponding to a Lagrange
-/// kernel column, the above expression of $Y(x)$ includes the additional term given by
+/// In the case when LogUp-GKR is enabled, the trace polynomials contain an additional trace
+/// polynomial corresponding to a Lagrange kernel column and the above expression of $Y(x)$
+/// includes the additional term given by
///
/// $$
/// \gamma \cdot \frac{T_l(x) - p_S(x)}{Z_S(x)}
@@ -99,8 +108,13 @@ pub struct LagrangeConstraintsCompositionCoefficients {
/// 4. $p_S(X)$ is the polynomial of minimal degree interpolating the set ${(a, T_l(a)): a \in S}$.
/// 5. $Z_S(X)$ is the polynomial of minimal degree vanishing over the set $S$.
///
-/// Note that, if a Lagrange kernel trace polynomial is present, then $\rho^{+}$ from above should
-/// be updated to be $\rho^{+} := \frac{\kappa + log_2(\nu) + 1}{\nu}$.
+/// Note that when LogUp-GKR is enabled, we also have to take into account an additional column,
+/// called s-column throughout, used in implementing the univariate IOP for multi-linear evaluation.
+/// This means that we need and additional random value, in addition to $\gamma$ above, when
+/// LogUp-GKR is enabled.
+///
+/// Note that, when LogUp-GKR is enabled, $\rho^{+}$ from above should be updated to be
+/// $\rho^{+} := \frac{\kappa + log_2(\nu) + 1}{\nu}$.
#[derive(Debug, Clone)]
pub struct DeepCompositionCoefficients {
/// Trace polynomial composition coefficients $\alpha_i$.
@@ -109,4 +123,6 @@ pub struct DeepCompositionCoefficients {
pub constraints: Vec,
/// Lagrange kernel trace polynomial composition coefficient $\gamma$.
pub lagrange: Option,
+ /// S-column trace polynomial composition coefficient.
+ pub s_col: Option,
}
diff --git a/air/src/air/context.rs b/air/src/air/context.rs
index 183f575fc..c36173ca3 100644
--- a/air/src/air/context.rs
+++ b/air/src/air/context.rs
@@ -14,21 +14,22 @@ use crate::{air::TransitionConstraintDegree, ProofOptions, TraceInfo};
// ================================================================================================
/// STARK parameters and trace properties for a specific execution of a computation.
#[derive(Clone, PartialEq, Eq)]
-pub struct AirContext {
+pub struct AirContext {
pub(super) options: ProofOptions,
pub(super) trace_info: TraceInfo,
+ pub(super) pub_inputs: P,
pub(super) main_transition_constraint_degrees: Vec,
pub(super) aux_transition_constraint_degrees: Vec,
pub(super) num_main_assertions: usize,
pub(super) num_aux_assertions: usize,
- pub(super) lagrange_kernel_aux_column_idx: Option,
pub(super) ce_blowup_factor: usize,
pub(super) trace_domain_generator: B,
pub(super) lde_domain_generator: B,
pub(super) num_transition_exemptions: usize,
+ pub(super) logup_gkr: bool,
}
-impl AirContext {
+impl AirContext {
// CONSTRUCTORS
// --------------------------------------------------------------------------------------------
/// Returns a new instance of [AirContext] instantiated for computations which require a single
@@ -48,6 +49,7 @@ impl AirContext {
/// * `trace_info` describes a multi-segment execution trace.
pub fn new(
trace_info: TraceInfo,
+ pub_inputs: P,
transition_constraint_degrees: Vec,
num_assertions: usize,
options: ProofOptions,
@@ -58,11 +60,11 @@ impl AirContext {
);
Self::new_multi_segment(
trace_info,
+ pub_inputs,
transition_constraint_degrees,
Vec::new(),
num_assertions,
0,
- None,
options,
)
}
@@ -91,11 +93,11 @@ impl AirContext {
/// of the specified transition constraints.
pub fn new_multi_segment(
trace_info: TraceInfo,
+ pub_inputs: P,
main_transition_constraint_degrees: Vec,
aux_transition_constraint_degrees: Vec,
num_main_assertions: usize,
num_aux_assertions: usize,
- lagrange_kernel_aux_column_idx: Option,
options: ProofOptions,
) -> Self {
assert!(
@@ -104,11 +106,11 @@ impl AirContext {
);
assert!(num_main_assertions > 0, "at least one assertion must be specified");
- if trace_info.is_multi_segment() {
+ if trace_info.is_multi_segment() && !trace_info.logup_gkr_enabled() {
assert!(
- !aux_transition_constraint_degrees.is_empty(),
- "at least one transition constraint degree must be specified for the auxiliary trace segment"
- );
+ !aux_transition_constraint_degrees.is_empty(),
+ "at least one transition constraint degree must be specified for the auxiliary trace segment"
+ );
assert!(
num_aux_assertions > 0,
"at least one assertion must be specified against the auxiliary trace segment"
@@ -124,15 +126,6 @@ impl AirContext {
);
}
- // validate Lagrange kernel aux column, if any
- if let Some(lagrange_kernel_aux_column_idx) = lagrange_kernel_aux_column_idx {
- assert!(
- lagrange_kernel_aux_column_idx == trace_info.get_aux_segment_width() - 1,
- "Lagrange kernel column should be the last column of the auxiliary trace: index={}, but aux trace width is {}",
- lagrange_kernel_aux_column_idx, trace_info.get_aux_segment_width()
- );
- }
-
// determine minimum blowup factor needed to evaluate transition constraints by taking
// the blowup factor of the highest degree constraint
let mut ce_blowup_factor = 0;
@@ -161,18 +154,41 @@ impl AirContext {
AirContext {
options,
trace_info,
+ pub_inputs,
main_transition_constraint_degrees,
aux_transition_constraint_degrees,
num_main_assertions,
num_aux_assertions,
- lagrange_kernel_aux_column_idx,
ce_blowup_factor,
trace_domain_generator: B::get_root_of_unity(trace_length.ilog2()),
lde_domain_generator: B::get_root_of_unity(lde_domain_size.ilog2()),
num_transition_exemptions: 1,
+ logup_gkr: false,
}
}
+ pub fn with_logup_gkr(
+ trace_info: TraceInfo,
+ pub_inputs: P,
+ main_transition_constraint_degrees: Vec,
+ aux_transition_constraint_degrees: Vec,
+ num_main_assertions: usize,
+ num_aux_assertions: usize,
+ options: ProofOptions,
+ ) -> Self {
+ let mut air_context = Self::new_multi_segment(
+ trace_info,
+ pub_inputs,
+ main_transition_constraint_degrees,
+ aux_transition_constraint_degrees,
+ num_main_assertions,
+ num_aux_assertions,
+ options,
+ );
+ air_context.logup_gkr = true;
+ air_context
+ }
+
// PUBLIC ACCESSORS
// --------------------------------------------------------------------------------------------
@@ -209,6 +225,10 @@ impl AirContext {
self.trace_info.length() * self.options.blowup_factor()
}
+ pub fn public_inputs(&self) -> &P {
+ &self.pub_inputs
+ }
+
/// Returns the number of transition constraints for a computation, excluding the Lagrange
/// kernel transition constraints, which are managed separately.
///
@@ -232,12 +252,16 @@ impl AirContext {
/// Returns the index of the auxiliary column which implements the Lagrange kernel, if any
pub fn lagrange_kernel_aux_column_idx(&self) -> Option {
- self.lagrange_kernel_aux_column_idx
+ if self.logup_gkr_enabled() {
+ Some(self.trace_info().aux_segment_width() - 1)
+ } else {
+ None
+ }
}
- /// Returns true if the auxiliary trace segment contains a Lagrange kernel column
- pub fn has_lagrange_kernel_aux_column(&self) -> bool {
- self.lagrange_kernel_aux_column_idx().is_some()
+ /// Returns true if LogUp-GKR is enabled.
+ pub fn logup_gkr_enabled(&self) -> bool {
+ self.logup_gkr
}
/// Returns the total number of assertions defined for a computation, excluding the Lagrange
diff --git a/air/src/air/logup_gkr.rs b/air/src/air/logup_gkr.rs
index 98054c938..0438064d9 100644
--- a/air/src/air/logup_gkr.rs
+++ b/air/src/air/logup_gkr.rs
@@ -4,10 +4,12 @@
// LICENSE file in the root directory of this source tree.
use alloc::vec::Vec;
+use core::marker::PhantomData;
+use crypto::{ElementHasher, RandomCoin};
use math::{ExtensionOf, FieldElement, StarkField, ToElements};
-use super::EvaluationFrame;
+use super::{EvaluationFrame, GkrData, LagrangeKernelRandElements};
/// A trait containing the necessary information in order to run the LogUp-GKR protocol of [1].
///
@@ -25,7 +27,7 @@ pub trait LogUpGkrEvaluator: Clone + Sync {
/// Gets a list of all oracles involved in LogUp-GKR; this is intended to be used in construction of
/// MLEs.
- fn get_oracles(&self) -> Vec>;
+ fn get_oracles(&self) -> &[LogUpGkrOracle];
/// Returns the number of random values needed to evaluate a query.
fn get_num_rand_values(&self) -> usize;
@@ -79,11 +81,122 @@ pub trait LogUpGkrEvaluator: Clone + Sync {
{
E::ZERO
}
+
+ /// Generates the data needed for running the univariate IOP for multi-linear evaluation of [1].
+ ///
+ /// This mainly generates the batching randomness used to batch a number of multi-linear
+ /// evaluation claims and includes some additional data that is needed for building/verifying
+ /// the univariate IOP for multi-linear evaluation of [1].
+ ///
+ /// This is the $\lambda$ randomness in section 5.2 in [1] but using different random values for
+ /// each term instead of powers of a single random element.
+ ///
+ /// [1]: https://eprint.iacr.org/2023/1284
+ fn generate_univariate_iop_for_multi_linear_opening_data(
+ &self,
+ openings: Vec,
+ eval_point: Vec,
+ public_coin: &mut impl RandomCoin,
+ ) -> GkrData
+ where
+ E: FieldElement,
+ H: ElementHasher,
+ {
+ public_coin.reseed(H::hash_elements(&openings));
+
+ let mut batching_randomness = Vec::with_capacity(openings.len() - 1);
+ for _ in 0..openings.len() - 1 {
+ batching_randomness.push(public_coin.draw().expect("failed to generate randomness"))
+ }
+
+ GkrData::new(
+ LagrangeKernelRandElements::new(eval_point),
+ batching_randomness,
+ openings,
+ self.get_oracles().to_vec(),
+ )
+ }
+}
+
+#[derive(Clone, Default)]
+pub(crate) struct PhantomLogUpGkrEval> {
+ _field: PhantomData,
+ _public_inputs: PhantomData,
+}
+
+impl PhantomLogUpGkrEval
+where
+ B: StarkField,
+ P: Clone + Send + Sync + ToElements,
+{
+ pub fn new() -> Self {
+ Self {
+ _field: PhantomData,
+ _public_inputs: PhantomData,
+ }
+ }
+}
+
+impl LogUpGkrEvaluator for PhantomLogUpGkrEval
+where
+ B: StarkField,
+ P: Clone + Send + Sync + ToElements,
+{
+ type BaseField = B;
+
+ type PublicInputs = P;
+
+ fn get_oracles(&self) -> &[LogUpGkrOracle] {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
+
+ fn get_num_rand_values(&self) -> usize {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
+
+ fn get_num_fractions(&self) -> usize {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
+
+ fn max_degree(&self) -> usize {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
+
+ fn build_query(&self, _frame: &EvaluationFrame, _periodic_values: &[E], _query: &mut [E])
+ where
+ E: FieldElement,
+ {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
+
+ fn evaluate_query(
+ &self,
+ _query: &[F],
+ _rand_values: &[E],
+ _numerator: &mut [E],
+ _denominator: &mut [E],
+ ) where
+ F: FieldElement,
+ E: FieldElement + ExtensionOf,
+ {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
+
+ fn compute_claim(&self, _inputs: &Self::PublicInputs, _rand_values: &[E]) -> E
+ where
+ E: FieldElement,
+ {
+ panic!("LogUpGkrEvaluator method called but LogUp-GKR is not implemented")
+ }
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum LogUpGkrOracle {
+ /// A column with a given index in the main trace segment.
CurrentRow(usize),
+ /// A column with a given index in the main trace segment but shifted upwards.
NextRow(usize),
+ /// A virtual periodic column defined by its values in a given cycle. Note that the cycle length
+ /// must be a power of 2.
PeriodicValue(Vec),
}
diff --git a/air/src/air/mod.rs b/air/src/air/mod.rs
index 07f38cce1..5dcee0717 100644
--- a/air/src/air/mod.rs
+++ b/air/src/air/mod.rs
@@ -6,12 +6,13 @@
use alloc::{collections::BTreeMap, vec::Vec};
use crypto::{RandomCoin, RandomCoinError};
+use logup_gkr::PhantomLogUpGkrEval;
use math::{fft, ExtensibleField, ExtensionOf, FieldElement, StarkField, ToElements};
use crate::ProofOptions;
mod aux;
-pub use aux::{AuxRandElements, GkrRandElements, GkrVerifier};
+pub use aux::{AuxRandElements, GkrData};
mod trace_info;
pub use trace_info::TraceInfo;
@@ -45,7 +46,6 @@ pub use coefficients::{
mod divisor;
pub use divisor::ConstraintDivisor;
-use utils::{Deserializable, Serializable};
#[cfg(test)]
mod tests;
@@ -195,13 +195,7 @@ pub trait Air: Send + Sync {
/// A type defining shape of public inputs for the computation described by this protocol.
/// This could be any type as long as it can be serialized into a sequence of field elements.
- type PublicInputs: ToElements + Send;
-
- /// An GKR proof object. If not needed, set to `()`.
- type GkrProof: Serializable + Deserializable + Send;
-
- /// A verifier for verifying GKR proofs. If not needed, set to `()`.
- type GkrVerifier: GkrVerifier;
+ type PublicInputs: ToElements + Clone + Send + Sync;
// REQUIRED METHODS
// --------------------------------------------------------------------------------------------
@@ -217,7 +211,7 @@ pub trait Air: Send + Sync {
fn new(trace_info: TraceInfo, pub_inputs: Self::PublicInputs, options: ProofOptions) -> Self;
/// Returns context for this instance of the computation.
- fn context(&self) -> &AirContext;
+ fn context(&self) -> &AirContext;
/// Evaluates transition constraints over the specified evaluation frame.
///
@@ -306,16 +300,15 @@ pub trait Air: Send + Sync {
Vec::new()
}
- // AUXILIARY PROOF VERIFIER
+ // LOGUP-GKR EVALUATOR
// --------------------------------------------------------------------------------------------
- /// Returns the [`GkrVerifier`] to be used to verify the GKR proof.
- ///
- /// Leave unimplemented if the `Air` doesn't use a GKR proof.
- fn get_gkr_proof_verifier>(
+ /// Returns the object needed for the LogUp-GKR argument.
+ fn get_logup_gkr_evaluator(
&self,
- ) -> Self::GkrVerifier {
- unimplemented!("`get_auxiliary_proof_verifier()` must be implemented when the proof contains a GKR proof");
+ ) -> impl LogUpGkrEvaluator
+ {
+ PhantomLogUpGkrEval::new()
}
// PROVIDED METHODS
@@ -345,13 +338,16 @@ pub trait Air: Send + Sync {
lagrange_composition_coefficients: LagrangeConstraintsCompositionCoefficients,
lagrange_kernel_rand_elements: &LagrangeKernelRandElements,
) -> Option> {
- self.context().lagrange_kernel_aux_column_idx().map(|col_idx| {
- LagrangeKernelConstraints::new(
+ if self.context().logup_gkr_enabled() {
+ let col_idx = self.context().trace_info().aux_segment_width() - 1;
+ Some(LagrangeKernelConstraints::new(
lagrange_composition_coefficients,
lagrange_kernel_rand_elements,
col_idx,
- )
- })
+ ))
+ } else {
+ None
+ }
}
/// Returns values for all periodic columns used in the computation.
@@ -548,7 +544,7 @@ pub trait Air: Send + Sync {
b_coefficients.push(public_coin.draw()?);
}
- let lagrange = if self.context().has_lagrange_kernel_aux_column() {
+ let lagrange = if self.context().logup_gkr_enabled() {
let mut lagrange_kernel_t_coefficients = Vec::new();
for _ in 0..self.context().trace_len().ilog2() {
lagrange_kernel_t_coefficients.push(public_coin.draw()?);
@@ -564,10 +560,17 @@ pub trait Air: Send + Sync {
None
};
+ let s_col = if self.context().logup_gkr_enabled() {
+ Some(public_coin.draw()?)
+ } else {
+ None
+ };
+
Ok(ConstraintCompositionCoefficients {
transition: t_coefficients,
boundary: b_coefficients,
lagrange,
+ s_col,
})
}
@@ -591,7 +594,13 @@ pub trait Air: Send + Sync {
c_coefficients.push(public_coin.draw()?);
}
- let lagrange_cc = if self.context().has_lagrange_kernel_aux_column() {
+ let lagrange_cc = if self.context().logup_gkr_enabled() {
+ Some(public_coin.draw()?)
+ } else {
+ None
+ };
+
+ let s_col = if self.context().logup_gkr_enabled() {
Some(public_coin.draw()?)
} else {
None
@@ -601,6 +610,7 @@ pub trait Air: Send + Sync {
trace: t_coefficients,
constraints: c_coefficients,
lagrange: lagrange_cc,
+ s_col,
})
}
}
diff --git a/air/src/air/tests.rs b/air/src/air/tests.rs
index e0063ed3b..5e9871ca5 100644
--- a/air/src/air/tests.rs
+++ b/air/src/air/tests.rs
@@ -9,8 +9,8 @@ use crypto::{hashers::Blake3_256, DefaultRandomCoin, RandomCoin};
use math::{fields::f64::BaseElement, get_power_series, polynom, FieldElement, StarkField};
use super::{
- Air, AirContext, Assertion, EvaluationFrame, ProofOptions, TraceInfo,
- TransitionConstraintDegree,
+ logup_gkr::PhantomLogUpGkrEval, Air, AirContext, Assertion, EvaluationFrame, ProofOptions,
+ TraceInfo, TransitionConstraintDegree,
};
use crate::FieldExtension;
@@ -192,7 +192,7 @@ fn get_boundary_constraints() {
// ================================================================================================
struct MockAir {
- context: AirContext,
+ context: AirContext,
assertions: Vec>,
periodic_columns: Vec>,
}
@@ -225,8 +225,7 @@ impl MockAir {
impl Air for MockAir {
type BaseField = BaseElement;
type PublicInputs = ();
- type GkrProof = ();
- type GkrVerifier = ();
+ //type LogUpGkrEvaluator = DummyLogUpGkrEval;
fn new(trace_info: TraceInfo, _pub_inputs: (), _options: ProofOptions) -> Self {
let num_assertions = trace_info.meta()[0] as usize;
@@ -238,7 +237,7 @@ impl Air for MockAir {
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
@@ -257,6 +256,13 @@ impl Air for MockAir {
_result: &mut [E],
) {
}
+
+ fn get_logup_gkr_evaluator(
+ &self,
+ ) -> impl super::LogUpGkrEvaluator
+ {
+ PhantomLogUpGkrEval::default()
+ }
}
// UTILITY FUNCTIONS
@@ -266,11 +272,11 @@ pub fn build_context(
trace_length: usize,
trace_width: usize,
num_assertions: usize,
-) -> AirContext {
+) -> AirContext {
let options = ProofOptions::new(32, 8, 0, FieldExtension::None, 4, 31);
let t_degrees = vec![TransitionConstraintDegree::new(2)];
let trace_info = TraceInfo::new(trace_width, trace_length);
- AirContext::new(trace_info, t_degrees, num_assertions, options)
+ AirContext::new(trace_info, (), t_degrees, num_assertions, options)
}
pub fn build_prng() -> DefaultRandomCoin> {
diff --git a/air/src/air/trace_info.rs b/air/src/air/trace_info.rs
index 99ff4aa6d..44aa0a7ea 100644
--- a/air/src/air/trace_info.rs
+++ b/air/src/air/trace_info.rs
@@ -27,6 +27,7 @@ pub struct TraceInfo {
num_aux_segment_rands: usize,
trace_length: usize,
trace_meta: Vec,
+ logup_gkr: bool,
}
impl TraceInfo {
@@ -65,7 +66,7 @@ impl TraceInfo {
/// * Length of `meta` is greater than 65535;
pub fn with_meta(width: usize, length: usize, meta: Vec) -> Self {
assert!(width > 0, "trace width must be greater than 0");
- Self::new_multi_segment(width, 0, 0, length, meta)
+ Self::new_multi_segment(width, 0, 0, length, meta, false)
}
/// Creates a new [TraceInfo] with main and auxiliary segments.
@@ -90,6 +91,7 @@ impl TraceInfo {
num_aux_segment_rands: usize,
trace_length: usize,
trace_meta: Vec,
+ logup_gkr: bool,
) -> Self {
assert!(
trace_length >= Self::MIN_TRACE_LENGTH,
@@ -138,6 +140,7 @@ impl TraceInfo {
num_aux_segment_rands,
trace_length,
trace_meta,
+ logup_gkr,
}
}
@@ -146,9 +149,13 @@ impl TraceInfo {
/// Returns the total number of columns in an execution trace.
///
+ /// When LogUp-GKR is enabled, we also account for two extra columns, in the auxiliary segment,
+ /// which are needed for implementing the univariate IOP for multi-linear evaluation in
+ /// https://eprint.iacr.org/2023/1284.
+ ///
/// This is guaranteed to be between 1 and 255.
pub fn width(&self) -> usize {
- self.main_segment_width + self.aux_segment_width
+ self.main_segment_width + self.aux_segment_width + 2 * self.logup_gkr as usize
}
/// Returns execution trace length.
@@ -171,13 +178,13 @@ impl TraceInfo {
/// Returns the number of columns in the main segment of an execution trace.
///
/// This is guaranteed to be between 1 and 255.
- pub fn main_trace_width(&self) -> usize {
+ pub fn main_segment_width(&self) -> usize {
self.main_segment_width
}
/// Returns the number of columns in the auxiliary segment of an execution trace.
pub fn aux_segment_width(&self) -> usize {
- self.aux_segment_width
+ self.aux_segment_width + 2 * self.logup_gkr as usize
}
/// Returns the total number of segments in an execution trace.
@@ -198,9 +205,9 @@ impl TraceInfo {
}
}
- /// Returns the number of columns in the auxiliary trace segment.
- pub fn get_aux_segment_width(&self) -> usize {
- self.aux_segment_width
+ /// Returns a boolean indicating whether LogUp-GKR is enabled.
+ pub fn logup_gkr_enabled(&self) -> bool {
+ self.logup_gkr
}
/// Returns the number of random elements needed to build all auxiliary columns, except for the
@@ -264,6 +271,9 @@ impl Serializable for TraceInfo {
// store trace meta
target.write_u16(self.trace_meta.len() as u16);
target.write_bytes(&self.trace_meta);
+
+ // write bool indicating if LogUp-GKR is used
+ target.write_bool(self.logup_gkr);
}
}
@@ -326,12 +336,16 @@ impl Deserializable for TraceInfo {
vec![]
};
+ // read `logup_gkr`
+ let logup_gkr = source.read_bool()?;
+
Ok(Self::new_multi_segment(
main_segment_width,
aux_segment_width,
num_aux_segment_rands,
trace_length,
trace_meta,
+ logup_gkr,
))
}
}
@@ -387,6 +401,7 @@ mod tests {
aux_rands,
trace_length as usize,
trace_meta,
+ false,
);
assert_eq!(expected, info.to_elements());
diff --git a/air/src/air/transition/mod.rs b/air/src/air/transition/mod.rs
index 60e641817..d29cbbb8b 100644
--- a/air/src/air/transition/mod.rs
+++ b/air/src/air/transition/mod.rs
@@ -46,7 +46,7 @@ impl TransitionConstraints {
/// # Panics
/// Panics if the number of transition constraints in the context does not match the number of
/// provided composition coefficients.
- pub fn new(context: &AirContext, composition_coefficients: &[E]) -> Self {
+ pub fn new(context: &AirContext, composition_coefficients: &[E]) -> Self {
assert_eq!(
context.num_transition_constraints(),
composition_coefficients.len(),
diff --git a/air/src/lib.rs b/air/src/lib.rs
index aaede0bda..2993306b9 100644
--- a/air/src/lib.rs
+++ b/air/src/lib.rs
@@ -44,7 +44,7 @@ mod air;
pub use air::{
Air, AirContext, Assertion, AuxRandElements, BoundaryConstraint, BoundaryConstraintGroup,
BoundaryConstraints, ConstraintCompositionCoefficients, ConstraintDivisor,
- DeepCompositionCoefficients, EvaluationFrame, GkrRandElements, GkrVerifier,
+ DeepCompositionCoefficients, EvaluationFrame, GkrData,
LagrangeConstraintsCompositionCoefficients, LagrangeKernelBoundaryConstraint,
LagrangeKernelConstraints, LagrangeKernelEvaluationFrame, LagrangeKernelRandElements,
LagrangeKernelTransitionConstraints, LogUpGkrEvaluator, LogUpGkrOracle, TraceInfo,
diff --git a/air/src/proof/context.rs b/air/src/proof/context.rs
index 83c2beece..73152709a 100644
--- a/air/src/proof/context.rs
+++ b/air/src/proof/context.rs
@@ -190,6 +190,7 @@ mod tests {
aux_rands,
trace_length,
vec![],
+ false,
);
let mut expected = trace_info.to_elements();
@@ -213,8 +214,14 @@ mod tests {
fri_folding_factor as usize,
fri_remainder_max_degree as usize,
);
- let trace_info =
- TraceInfo::new_multi_segment(main_width, aux_width, aux_rands, trace_length, vec![]);
+ let trace_info = TraceInfo::new_multi_segment(
+ main_width,
+ aux_width,
+ aux_rands,
+ trace_length,
+ vec![],
+ false,
+ );
let context = Context::new::(trace_info, options);
assert_eq!(expected, context.to_elements());
}
diff --git a/air/src/proof/ood_frame.rs b/air/src/proof/ood_frame.rs
index d4b3f14ec..feab1b260 100644
--- a/air/src/proof/ood_frame.rs
+++ b/air/src/proof/ood_frame.rs
@@ -229,6 +229,8 @@ impl Deserializable for OodFrame {
// OOD FRAME TRACE STATES
// ================================================================================================
+/// Stores trace evaluations at an OOD point.
+///
/// Stores the trace evaluations at `z` and `gz`, where `z` is a random Field element in
/// `current_row` and `next_row`, respectively. If the Air contains a Lagrange kernel auxiliary
/// column, then that column interpolated polynomial will be evaluated at `z`, `gz`, `g^2 z`, ...
diff --git a/crypto/src/merkle/concurrent.rs b/crypto/src/merkle/concurrent.rs
index 637bd51b5..7a3ba077f 100644
--- a/crypto/src/merkle/concurrent.rs
+++ b/crypto/src/merkle/concurrent.rs
@@ -18,9 +18,10 @@ pub const MIN_CONCURRENT_LEAVES: usize = 1024;
// PUBLIC FUNCTIONS
// ================================================================================================
-/// Builds all internal nodes of the Merkle using all available threads and stores the
-/// results in a single vector such that root of the tree is at position 1, nodes immediately
-/// under the root is at positions 2 and 3 etc.
+/// Builds all internal nodes of the Merkle tree.
+///
+/// This uses all available threads and stores the results in a single vector such that root of
+/// the tree is at position 1, nodes immediately under the root is at positions 2 and 3 etc.
pub fn build_merkle_nodes(leaves: &[H::Digest]) -> Vec {
let n = leaves.len() / 2;
diff --git a/examples/src/fibonacci/fib2/air.rs b/examples/src/fibonacci/fib2/air.rs
index 9e5d75a48..4019ddcae 100644
--- a/examples/src/fibonacci/fib2/air.rs
+++ b/examples/src/fibonacci/fib2/air.rs
@@ -14,15 +14,13 @@ use crate::utils::are_equal;
// ================================================================================================
pub struct FibAir {
- context: AirContext,
+ context: AirContext,
result: BaseElement,
}
impl Air for FibAir {
type BaseField = BaseElement;
type PublicInputs = BaseElement;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -30,12 +28,12 @@ impl Air for FibAir {
let degrees = vec![TransitionConstraintDegree::new(1), TransitionConstraintDegree::new(1)];
assert_eq!(TRACE_WIDTH, trace_info.width());
FibAir {
- context: AirContext::new(trace_info, degrees, 3, options),
+ context: AirContext::new(trace_info, pub_inputs, degrees, 3, options),
result: pub_inputs,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/fibonacci/fib8/air.rs b/examples/src/fibonacci/fib8/air.rs
index 4d7aef9ba..17edc7970 100644
--- a/examples/src/fibonacci/fib8/air.rs
+++ b/examples/src/fibonacci/fib8/air.rs
@@ -15,15 +15,13 @@ use crate::utils::are_equal;
// ================================================================================================
pub struct Fib8Air {
- context: AirContext,
+ context: AirContext,
result: BaseElement,
}
impl Air for Fib8Air {
type BaseField = BaseElement;
type PublicInputs = BaseElement;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -31,12 +29,12 @@ impl Air for Fib8Air {
let degrees = vec![TransitionConstraintDegree::new(1), TransitionConstraintDegree::new(1)];
assert_eq!(TRACE_WIDTH, trace_info.width());
Fib8Air {
- context: AirContext::new(trace_info, degrees, 3, options),
+ context: AirContext::new(trace_info, pub_inputs, degrees, 3, options),
result: pub_inputs,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/fibonacci/fib_small/air.rs b/examples/src/fibonacci/fib_small/air.rs
index 66580c872..b48eb734b 100644
--- a/examples/src/fibonacci/fib_small/air.rs
+++ b/examples/src/fibonacci/fib_small/air.rs
@@ -14,15 +14,13 @@ use crate::utils::are_equal;
// ================================================================================================
pub struct FibSmall {
- context: AirContext,
+ context: AirContext,
result: BaseElement,
}
impl Air for FibSmall {
type BaseField = BaseElement;
type PublicInputs = BaseElement;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -30,12 +28,12 @@ impl Air for FibSmall {
let degrees = vec![TransitionConstraintDegree::new(1), TransitionConstraintDegree::new(1)];
assert_eq!(TRACE_WIDTH, trace_info.width());
FibSmall {
- context: AirContext::new(trace_info, degrees, 3, options),
+ context: AirContext::new(trace_info, pub_inputs, degrees, 3, options),
result: pub_inputs,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/fibonacci/mulfib2/air.rs b/examples/src/fibonacci/mulfib2/air.rs
index 3190d2e41..501adf6af 100644
--- a/examples/src/fibonacci/mulfib2/air.rs
+++ b/examples/src/fibonacci/mulfib2/air.rs
@@ -16,15 +16,13 @@ use crate::utils::are_equal;
// ================================================================================================
pub struct MulFib2Air {
- context: AirContext,
+ context: AirContext,
result: BaseElement,
}
impl Air for MulFib2Air {
type BaseField = BaseElement;
type PublicInputs = BaseElement;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -32,12 +30,12 @@ impl Air for MulFib2Air {
let degrees = vec![TransitionConstraintDegree::new(2), TransitionConstraintDegree::new(2)];
assert_eq!(TRACE_WIDTH, trace_info.width());
MulFib2Air {
- context: AirContext::new(trace_info, degrees, 3, options),
+ context: AirContext::new(trace_info, pub_inputs, degrees, 3, options),
result: pub_inputs,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/fibonacci/mulfib8/air.rs b/examples/src/fibonacci/mulfib8/air.rs
index bbbe1dea0..c76f4f091 100644
--- a/examples/src/fibonacci/mulfib8/air.rs
+++ b/examples/src/fibonacci/mulfib8/air.rs
@@ -16,15 +16,13 @@ use crate::utils::are_equal;
// ================================================================================================
pub struct MulFib8Air {
- context: AirContext,
+ context: AirContext,
result: BaseElement,
}
impl Air for MulFib8Air {
type BaseField = BaseElement;
type PublicInputs = BaseElement;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -41,12 +39,12 @@ impl Air for MulFib8Air {
];
assert_eq!(TRACE_WIDTH, trace_info.width());
MulFib8Air {
- context: AirContext::new(trace_info, degrees, 3, options),
+ context: AirContext::new(trace_info, pub_inputs, degrees, 3, options),
result: pub_inputs,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/lamport/aggregate/air.rs b/examples/src/lamport/aggregate/air.rs
index 29b6e2372..57708fd74 100644
--- a/examples/src/lamport/aggregate/air.rs
+++ b/examples/src/lamport/aggregate/air.rs
@@ -38,7 +38,7 @@ impl ToElements for PublicInputs {
}
pub struct LamportAggregateAir {
- context: AirContext,
+ context: AirContext,
pub_keys: Vec<[BaseElement; 2]>,
messages: Vec<[BaseElement; 2]>,
}
@@ -46,8 +46,6 @@ pub struct LamportAggregateAir {
impl Air for LamportAggregateAir {
type BaseField = BaseElement;
type PublicInputs = PublicInputs;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -88,13 +86,13 @@ impl Air for LamportAggregateAir {
];
assert_eq!(TRACE_WIDTH, trace_info.width());
LamportAggregateAir {
- context: AirContext::new(trace_info, degrees, 22, options),
+ context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 22, options),
pub_keys: pub_inputs.pub_keys,
messages: pub_inputs.messages,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/lamport/threshold/air.rs b/examples/src/lamport/threshold/air.rs
index 41983c743..b68a2a24d 100644
--- a/examples/src/lamport/threshold/air.rs
+++ b/examples/src/lamport/threshold/air.rs
@@ -22,7 +22,7 @@ const TWO: BaseElement = BaseElement::new(2);
// THRESHOLD LAMPORT PLUS SIGNATURE AIR
// ================================================================================================
-#[derive(Clone)]
+#[derive(Clone, Default)]
pub struct PublicInputs {
pub pub_key_root: [BaseElement; 2],
pub num_pub_keys: usize,
@@ -41,7 +41,7 @@ impl ToElements for PublicInputs {
}
pub struct LamportThresholdAir {
- context: AirContext,
+ context: AirContext,
pub_key_root: [BaseElement; 2],
num_pub_keys: usize,
num_signatures: usize,
@@ -51,8 +51,6 @@ pub struct LamportThresholdAir {
impl Air for LamportThresholdAir {
type BaseField = BaseElement;
type PublicInputs = PublicInputs;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -99,7 +97,7 @@ impl Air for LamportThresholdAir {
];
assert_eq!(TRACE_WIDTH, trace_info.width());
LamportThresholdAir {
- context: AirContext::new(trace_info, degrees, 26, options),
+ context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 26, options),
pub_key_root: pub_inputs.pub_key_root,
num_pub_keys: pub_inputs.num_pub_keys,
num_signatures: pub_inputs.num_signatures,
@@ -244,7 +242,7 @@ impl Air for LamportThresholdAir {
result
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
}
diff --git a/examples/src/merkle/air.rs b/examples/src/merkle/air.rs
index e0c8b177c..5d38397ff 100644
--- a/examples/src/merkle/air.rs
+++ b/examples/src/merkle/air.rs
@@ -14,6 +14,7 @@ use crate::utils::{are_equal, is_binary, is_zero, not, EvaluationResult};
// MERKLE PATH VERIFICATION AIR
// ================================================================================================
+#[derive(Clone)]
pub struct PublicInputs {
pub tree_root: [BaseElement; 2],
}
@@ -25,15 +26,13 @@ impl ToElements for PublicInputs {
}
pub struct MerkleAir {
- context: AirContext,
+ context: AirContext,
tree_root: [BaseElement; 2],
}
impl Air for MerkleAir {
type BaseField = BaseElement;
type PublicInputs = PublicInputs;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -49,12 +48,12 @@ impl Air for MerkleAir {
];
assert_eq!(TRACE_WIDTH, trace_info.width());
MerkleAir {
- context: AirContext::new(trace_info, degrees, 4, options),
+ context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 4, options),
tree_root: pub_inputs.tree_root,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/rescue/air.rs b/examples/src/rescue/air.rs
index a9d3d5ebb..09bf9c450 100644
--- a/examples/src/rescue/air.rs
+++ b/examples/src/rescue/air.rs
@@ -37,6 +37,7 @@ const CYCLE_MASK: [BaseElement; CYCLE_LENGTH] = [
// RESCUE AIR
// ================================================================================================
+#[derive(Clone)]
pub struct PublicInputs {
pub seed: [BaseElement; 2],
pub result: [BaseElement; 2],
@@ -51,7 +52,7 @@ impl ToElements for PublicInputs {
}
pub struct RescueAir {
- context: AirContext,
+ context: AirContext,
seed: [BaseElement; 2],
result: [BaseElement; 2],
}
@@ -59,8 +60,6 @@ pub struct RescueAir {
impl Air for RescueAir {
type BaseField = BaseElement;
type PublicInputs = PublicInputs;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -73,13 +72,13 @@ impl Air for RescueAir {
];
assert_eq!(TRACE_WIDTH, trace_info.width());
RescueAir {
- context: AirContext::new(trace_info, degrees, 4, options),
+ context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 4, options),
seed: pub_inputs.seed,
result: pub_inputs.result,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/rescue_raps/air.rs b/examples/src/rescue_raps/air.rs
index 6fb5321b1..694e189bc 100644
--- a/examples/src/rescue_raps/air.rs
+++ b/examples/src/rescue_raps/air.rs
@@ -41,6 +41,7 @@ const CYCLE_MASK: [BaseElement; CYCLE_LENGTH] = [
// RESCUE AIR
// ================================================================================================
+#[derive(Clone)]
pub struct PublicInputs {
pub result: [[BaseElement; 2]; 2],
}
@@ -52,15 +53,13 @@ impl ToElements for PublicInputs {
}
pub struct RescueRapsAir {
- context: AirContext,
+ context: AirContext,
result: [[BaseElement; 2]; 2],
}
impl Air for RescueRapsAir {
type BaseField = BaseElement;
type PublicInputs = PublicInputs;
- type GkrProof = ();
- type GkrVerifier = ();
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------
@@ -76,18 +75,18 @@ impl Air for RescueRapsAir {
RescueRapsAir {
context: AirContext::new_multi_segment(
trace_info,
+ pub_inputs.clone(),
main_degrees,
aux_degrees,
8,
2,
- None,
options,
),
result: pub_inputs.result,
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
diff --git a/examples/src/rescue_raps/custom_trace_table.rs b/examples/src/rescue_raps/custom_trace_table.rs
index 063d509a4..f6f9d075b 100644
--- a/examples/src/rescue_raps/custom_trace_table.rs
+++ b/examples/src/rescue_raps/custom_trace_table.rs
@@ -89,7 +89,7 @@ impl RapTraceTable {
let columns = unsafe { (0..width).map(|_| uninit_vector(length)).collect() };
Self {
- info: TraceInfo::new_multi_segment(width, 3, 3, length, meta),
+ info: TraceInfo::new_multi_segment(width, 3, 3, length, meta, false),
trace: ColMatrix::new(columns),
}
}
@@ -113,7 +113,7 @@ impl RapTraceTable {
I: Fn(&mut [B]),
U: Fn(usize, &mut [B]),
{
- let mut state = vec![B::ZERO; self.info.main_trace_width()];
+ let mut state = vec![B::ZERO; self.info.main_segment_width()];
init(&mut state);
self.update_row(0, &state);
@@ -133,7 +133,7 @@ impl RapTraceTable {
/// Returns the number of columns in this execution trace.
pub fn width(&self) -> usize {
- self.info.main_trace_width()
+ self.info.main_segment_width()
}
/// Returns value of the cell in the specified column at the specified row of this trace.
diff --git a/examples/src/rescue_raps/prover.rs b/examples/src/rescue_raps/prover.rs
index 7adee9bbb..6e50f1572 100644
--- a/examples/src/rescue_raps/prover.rs
+++ b/examples/src/rescue_raps/prover.rs
@@ -139,16 +139,11 @@ where
DefaultConstraintEvaluator::new(air, aux_rand_elements, composition_coefficients)
}
- fn build_aux_trace(
- &self,
- trace: &Self::Trace,
- aux_rand_elements: &AuxRandElements,
- ) -> ColMatrix
+ fn build_aux_trace(&self, trace: &Self::Trace, aux_rand_elements: &[E]) -> ColMatrix
where
E: FieldElement,
{
let main_trace = trace.main_segment();
- let rand_elements = aux_rand_elements.rand_elements();
let mut current_row = unsafe { uninit_vector(main_trace.num_cols()) };
let mut next_row = unsafe { uninit_vector(main_trace.num_cols()) };
@@ -157,10 +152,10 @@ where
// Columns storing the copied values for the permutation argument are not necessary, but
// help understanding the construction of RAPs and are kept for illustrative purposes.
- aux_columns[0][0] =
- rand_elements[0] * current_row[0].into() + rand_elements[1] * current_row[1].into();
- aux_columns[1][0] =
- rand_elements[0] * current_row[4].into() + rand_elements[1] * current_row[5].into();
+ aux_columns[0][0] = aux_rand_elements[0] * current_row[0].into()
+ + aux_rand_elements[1] * current_row[1].into();
+ aux_columns[1][0] = aux_rand_elements[0] * current_row[4].into()
+ + aux_rand_elements[1] * current_row[5].into();
// Permutation argument column
aux_columns[2][0] = E::ONE;
@@ -172,14 +167,16 @@ where
main_trace.read_row_into(index, &mut current_row);
main_trace.read_row_into(index + 1, &mut next_row);
- aux_columns[0][index] = rand_elements[0] * (next_row[0] - current_row[0]).into()
- + rand_elements[1] * (next_row[1] - current_row[1]).into();
- aux_columns[1][index] = rand_elements[0] * (next_row[4] - current_row[4]).into()
- + rand_elements[1] * (next_row[5] - current_row[5]).into();
+ aux_columns[0][index] = aux_rand_elements[0]
+ * (next_row[0] - current_row[0]).into()
+ + aux_rand_elements[1] * (next_row[1] - current_row[1]).into();
+ aux_columns[1][index] = aux_rand_elements[0]
+ * (next_row[4] - current_row[4]).into()
+ + aux_rand_elements[1] * (next_row[5] - current_row[5]).into();
}
- let num = aux_columns[0][index - 1] + rand_elements[2];
- let denom = aux_columns[1][index - 1] + rand_elements[2];
+ let num = aux_columns[0][index - 1] + aux_rand_elements[2];
+ let denom = aux_columns[1][index - 1] + aux_rand_elements[2];
aux_columns[2][index] = aux_columns[2][index - 1] * num * denom.inv();
}
diff --git a/examples/src/utils/rescue.rs b/examples/src/utils/rescue.rs
index e09cb094e..be297fcf3 100644
--- a/examples/src/utils/rescue.rs
+++ b/examples/src/utils/rescue.rs
@@ -21,6 +21,8 @@ pub const RATE_WIDTH: usize = 4;
/// Two elements (32-bytes) are returned as digest.
const DIGEST_SIZE: usize = 2;
+/// Number of rounds used in Rescue.
+///
/// The number of rounds is set to 7 to provide 128-bit security level with 40% security margin;
/// computed using algorithm 7 from
/// security margin here differs from Rescue Prime specification which suggests 50% security
diff --git a/examples/src/vdf/exempt/air.rs b/examples/src/vdf/exempt/air.rs
index 9254e4e0a..015778459 100644
--- a/examples/src/vdf/exempt/air.rs
+++ b/examples/src/vdf/exempt/air.rs
@@ -29,7 +29,7 @@ impl ToElements for VdfInputs {
// ================================================================================================
pub struct VdfAir {
- context: AirContext,
+ context: AirContext,
seed: BaseElement,
result: BaseElement,
}
@@ -37,16 +37,14 @@ pub struct VdfAir {
impl Air for VdfAir {
type BaseField = BaseElement;
type PublicInputs = VdfInputs;
- type GkrProof = ();
- type GkrVerifier = ();
fn new(trace_info: TraceInfo, pub_inputs: VdfInputs, options: ProofOptions) -> Self {
let degrees = vec![TransitionConstraintDegree::new(3)];
assert_eq!(TRACE_WIDTH, trace_info.width());
// make sure the last two rows are excluded from transition constraints as we populate
// values in the last row with garbage
- let context =
- AirContext::new(trace_info, degrees, 2, options).set_num_transition_exemptions(2);
+ let context = AirContext::new(trace_info, pub_inputs.clone(), degrees, 2, options)
+ .set_num_transition_exemptions(2);
Self {
context,
seed: pub_inputs.seed,
@@ -76,7 +74,7 @@ impl Air for VdfAir {
]
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
}
diff --git a/examples/src/vdf/regular/air.rs b/examples/src/vdf/regular/air.rs
index b434c1478..bec2ccb3c 100644
--- a/examples/src/vdf/regular/air.rs
+++ b/examples/src/vdf/regular/air.rs
@@ -29,7 +29,7 @@ impl ToElements for VdfInputs {
// ================================================================================================
pub struct VdfAir {
- context: AirContext,
+ context: AirContext,
seed: BaseElement,
result: BaseElement,
}
@@ -37,14 +37,12 @@ pub struct VdfAir {
impl Air for VdfAir {
type BaseField = BaseElement;
type PublicInputs = VdfInputs;
- type GkrProof = ();
- type GkrVerifier = ();
fn new(trace_info: TraceInfo, pub_inputs: VdfInputs, options: ProofOptions) -> Self {
let degrees = vec![TransitionConstraintDegree::new(3)];
assert_eq!(TRACE_WIDTH, trace_info.width());
Self {
- context: AirContext::new(trace_info, degrees, 2, options),
+ context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 2, options),
seed: pub_inputs.seed,
result: pub_inputs.result,
}
@@ -67,7 +65,7 @@ impl Air for VdfAir {
vec![Assertion::single(0, 0, self.seed), Assertion::single(0, last_step, self.result)]
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
}
diff --git a/math/src/field/f64/mod.rs b/math/src/field/f64/mod.rs
index 119676076..64c637c0a 100644
--- a/math/src/field/f64/mod.rs
+++ b/math/src/field/f64/mod.rs
@@ -3,9 +3,10 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
-//! An implementation of a 64-bit STARK-friendly prime field with modulus $2^{64} - 2^{32} + 1$
-//! using Montgomery representation.
-//! Our implementation follows and is constant-time.
+//! An implementation of a 64-bit STARK-friendly prime field with modulus $2^{64} - 2^{32} + 1$.
+//!
+//! Our implementation uses Montgomery representation and follows
+//! and is constant-time.
//!
//! This field supports very fast modular arithmetic and has a number of other attractive
//! properties, including:
diff --git a/prover/Cargo.toml b/prover/Cargo.toml
index 36272766f..6fef7f90f 100644
--- a/prover/Cargo.toml
+++ b/prover/Cargo.toml
@@ -35,6 +35,8 @@ crypto = { version = "0.9", path = "../crypto", package = "winter-crypto", defau
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 = { path = "../utils/maybe_async" , package = "winter-maybe-async" }
+sumcheck = { version = "0.1", path = "../sumcheck", package = "winter-sumcheck", default-features = false }
+thiserror = { version = "1.0", git = "https://github.com/bitwalker/thiserror", branch = "no-std", default-features = false }
tracing = { version = "0.1", default-features = false, features = ["attributes"]}
utils = { version = "0.9", path = "../utils/core", package = "winter-utils", default-features = false }
diff --git a/prover/benches/lagrange_kernel.rs b/prover/benches/lagrange_kernel.rs
index 7ee8ab3c3..348554806 100644
--- a/prover/benches/lagrange_kernel.rs
+++ b/prover/benches/lagrange_kernel.rs
@@ -7,15 +7,14 @@ use std::time::Duration;
use air::{
Air, AirContext, Assertion, AuxRandElements, ConstraintCompositionCoefficients,
- EvaluationFrame, FieldExtension, GkrRandElements, LagrangeKernelRandElements, ProofOptions,
- TraceInfo, TransitionConstraintDegree,
+ EvaluationFrame, FieldExtension, ProofOptions, TraceInfo, TransitionConstraintDegree,
};
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
-use crypto::{hashers::Blake3_256, DefaultRandomCoin, MerkleTree, RandomCoin};
+use crypto::{hashers::Blake3_256, DefaultRandomCoin, MerkleTree};
use math::{fields::f64::BaseElement, ExtensionOf, FieldElement};
use winter_prover::{
- matrix::ColMatrix, DefaultConstraintEvaluator, DefaultTraceLde, Prover, ProverGkrProof,
- StarkDomain, Trace, TracePolyTable,
+ matrix::ColMatrix, DefaultConstraintEvaluator, DefaultTraceLde, Prover, StarkDomain, Trace,
+ TracePolyTable,
};
const TRACE_LENS: [usize; 2] = [2_usize.pow(16), 2_usize.pow(20)];
@@ -61,7 +60,7 @@ impl LagrangeTrace {
Self {
main_trace: ColMatrix::new(vec![main_trace_col]),
- info: TraceInfo::new_multi_segment(1, aux_segment_width, 0, trace_len, vec![]),
+ info: TraceInfo::new_multi_segment(1, aux_segment_width, 0, trace_len, vec![], false),
}
}
@@ -94,31 +93,28 @@ impl Trace for LagrangeTrace {
// =================================================================================================
struct LagrangeKernelAir {
- context: AirContext,
+ context: AirContext,
}
impl Air for LagrangeKernelAir {
type BaseField = BaseElement;
- type GkrProof = ();
- type GkrVerifier = ();
-
type PublicInputs = ();
fn new(trace_info: TraceInfo, _pub_inputs: Self::PublicInputs, options: ProofOptions) -> Self {
Self {
context: AirContext::new_multi_segment(
trace_info,
+ _pub_inputs,
vec![TransitionConstraintDegree::new(1)],
vec![TransitionConstraintDegree::new(1)],
1,
1,
- Some(0),
options,
),
}
}
- fn context(&self) -> &AirContext {
+ fn context(&self) -> &AirContext {
&self.context
}
@@ -221,42 +217,14 @@ impl Prover for LagrangeProver {
DefaultConstraintEvaluator::new(air, aux_rand_elements, composition_coefficients)
}
- fn generate_gkr_proof(
- &self,
- main_trace: &Self::Trace,
- public_coin: &mut Self::RandomCoin,
- ) -> (ProverGkrProof, GkrRandElements)
- where
- E: FieldElement,
- {
- let main_trace = main_trace.main_segment();
- let lagrange_kernel_rand_elements = {
- let log_trace_len = main_trace.num_rows().ilog2() as usize;
- let mut rand_elements = Vec::with_capacity(log_trace_len);
- for _ in 0..log_trace_len {
- rand_elements.push(public_coin.draw().unwrap());
- }
-
- LagrangeKernelRandElements::new(rand_elements)
- };
-
- ((), GkrRandElements::new(lagrange_kernel_rand_elements, Vec::new()))
- }
-
- fn build_aux_trace(
- &self,
- main_trace: &Self::Trace,
- aux_rand_elements: &AuxRandElements,
- ) -> ColMatrix
+ fn build_aux_trace(&self, main_trace: &Self::Trace, aux_rand_elements: &[E]) -> ColMatrix
where
E: FieldElement,
{
let main_trace = main_trace.main_segment();
let mut columns = Vec::new();
- let lagrange_kernel_rand_elements = aux_rand_elements
- .lagrange()
- .expect("expected lagrange kernel random elements to be present.");
+ let lagrange_kernel_rand_elements = aux_rand_elements;
// first build the Lagrange kernel column
{
diff --git a/prover/src/constraints/evaluator/default.rs b/prover/src/constraints/evaluator/default.rs
index 8f96c7dcd..ea02b41d4 100644
--- a/prover/src/constraints/evaluator/default.rs
+++ b/prover/src/constraints/evaluator/default.rs
@@ -158,7 +158,7 @@ where
&composition_coefficients.boundary,
);
- let lagrange_constraints_evaluator = if air.context().has_lagrange_kernel_aux_column() {
+ let lagrange_constraints_evaluator = if air.context().logup_gkr_enabled() {
let aux_rand_elements =
aux_rand_elements.as_ref().expect("expected aux rand elements to be present");
let lagrange_rand_elements = aux_rand_elements
@@ -198,7 +198,7 @@ where
fragment: &mut EvaluationTableFragment