diff --git a/air/src/air/aux.rs b/air/src/air/aux.rs index 7c64e36d7..7dc9c4f48 100644 --- a/air/src/air/aux.rs +++ b/air/src/air/aux.rs @@ -9,12 +9,14 @@ use math::FieldElement; use super::{lagrange::LagrangeKernelRandElements, LogUpGkrOracle}; -/// Holds the randomly generated elements necessary to build the auxiliary trace. +/// Holds the randomly generated elements used in defining the auxiliary segment of the trace. /// -/// Specifically, [`AuxRandElements`] currently supports 3 types of random elements: -/// - the ones needed to build the Lagrange kernel column (when using GKR to accelerate LogUp), -/// - the ones needed to build the "s" auxiliary column (when using GKR to accelerate LogUp), -/// - the ones needed to build all the other auxiliary columns +/// Specifically, [`AuxRandElements`] currently supports 2 types of random elements: +/// - the ones needed to build all the auxiliary columns except for the ones associated +/// to LogUp-GKR. +/// - the ones needed to build the "s" and Lagrange kernel auxiliary columns (when using GKR to +/// accelerate LogUp). These also include additional information needed to evaluate constraints +/// one these two columns. #[derive(Debug, Clone)] pub struct AuxRandElements { rand_elements: Vec, @@ -22,18 +24,11 @@ pub struct AuxRandElements { } impl AuxRandElements { - /// Creates a new [`AuxRandElements`], where the auxiliary trace doesn't contain a Lagrange - /// kernel column. - pub fn new(rand_elements: Vec) -> Self { - Self { rand_elements, gkr: None } - } - - /// Creates a new [`AuxRandElements`], where the auxiliary trace contains columns needed when + /// Creates a new [`AuxRandElements`], where the auxiliary segment may contain columns needed when /// using GKR to accelerate LogUp (i.e. a Lagrange kernel column and the "s" column). - pub fn new_with_gkr(rand_elements: Vec, gkr: GkrData) -> Self { - Self { rand_elements, gkr: Some(gkr) } + pub fn new(rand_elements: Vec, gkr: Option>) -> Self { + Self { rand_elements, gkr } } - /// Returns the random elements needed to build all columns other than the two GKR-related ones. pub fn rand_elements(&self) -> &[E] { &self.rand_elements @@ -51,21 +46,35 @@ impl AuxRandElements { self.gkr.as_ref().map(|gkr| gkr.openings_combining_randomness.as_ref()) } + /// Returns a collection of data necessary for implementing the univariate IOP for multi-linear + /// evaluations of [1] when LogUp-GKR is enabled, else returns a `None`. + /// + /// [1]: https://eprint.iacr.org/2023/1284 pub fn gkr_data(&self) -> Option> { self.gkr.clone() } } -/// Holds all the random elements needed when using GKR to accelerate LogUp. +/// Holds all the data needed when using LogUp-GKR in order to build and verify the correctness of +/// two extra auxiliary columns required for running the univariate IOP for multi-linear +/// evaluations of [1]. /// -/// This consists of two sets of random values: -/// 1. The Lagrange kernel random elements (expanded on in [`LagrangeKernelRandElements`]), and +/// This consists of: +/// 1. The Lagrange kernel random elements (expanded on in [`LagrangeKernelRandElements`]). These +/// make up the evaluation point of the multi-linear extension polynomials underlying the oracles +/// in point 4 below. /// 2. The "openings combining randomness". +/// 3. The openings of the multi-linear extension polynomials of the main trace columns involved +/// in LogUp. +/// 4. A description of the each of the oracles involved in LogUp. +/// +/// After verifying the LogUp-GKR circuit, the verifier is left with unproven claims provided +/// by the prover about the evaluations of the MLEs of the main trace columns at the evaluation +/// point defining the Lagrange kernel. Those claims are (linearly) batched into one using the +/// openings combining randomness and checked against the batched oracles using univariate IOP +/// for multi-linear evaluations of [1]. /// -/// After the verifying the LogUp-GKR circuit, the verifier is left with unproven claims provided -/// nondeterministically by the prover about the evaluations of the MLE of the main trace columns at -/// the Lagrange kernel random elements. Those claims are (linearly) combined into one using the -/// openings combining randomness. +/// [1]: https://eprint.iacr.org/2023/1284 #[derive(Clone, Debug)] pub struct GkrData { pub lagrange_kernel_eval_point: LagrangeKernelRandElements, diff --git a/air/src/air/boundary/mod.rs b/air/src/air/boundary/mod.rs index 7f92c80ab..2c15ac5a3 100644 --- a/air/src/air/boundary/mod.rs +++ b/air/src/air/boundary/mod.rs @@ -58,8 +58,8 @@ impl BoundaryConstraints { /// coefficients. /// * The specified assertions are not valid in the context of the computation (e.g., assertion /// column index is out of bounds). - pub fn new( - context: &AirContext, + 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 37ecf1657..ed6c3fa99 100644 --- a/air/src/air/coefficients.rs +++ b/air/src/air/coefficients.rs @@ -27,6 +27,13 @@ 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, @@ -84,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)} @@ -100,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$. @@ -110,6 +123,6 @@ pub struct DeepCompositionCoefficients { pub constraints: Vec, /// Lagrange kernel trace polynomial composition coefficient $\gamma$. pub lagrange: Option, - /// TODO + /// 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 bd6275a03..c36173ca3 100644 --- a/air/src/air/context.rs +++ b/air/src/air/context.rs @@ -14,9 +14,10 @@ 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, @@ -28,7 +29,7 @@ pub struct AirContext { 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,6 +60,7 @@ impl AirContext { ); Self::new_multi_segment( trace_info, + pub_inputs, transition_constraint_degrees, Vec::new(), num_assertions, @@ -90,6 +93,7 @@ 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, @@ -102,7 +106,7 @@ impl AirContext { ); assert!(num_main_assertions > 0, "at least one assertion must be specified"); - if trace_info.is_multi_segment() && !trace_info.is_with_logup_gkr() { + 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" @@ -150,6 +154,7 @@ impl AirContext { AirContext { options, trace_info, + pub_inputs, main_transition_constraint_degrees, aux_transition_constraint_degrees, num_main_assertions, @@ -164,6 +169,7 @@ impl AirContext { 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, @@ -172,6 +178,7 @@ impl AirContext { ) -> Self { let mut air_context = Self::new_multi_segment( trace_info, + pub_inputs, main_transition_constraint_degrees, aux_transition_constraint_degrees, num_main_assertions, @@ -218,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. /// @@ -241,7 +252,7 @@ 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 { - if self.uses_logup_gkr() { + if self.logup_gkr_enabled() { Some(self.trace_info().aux_segment_width() - 1) } else { None @@ -249,7 +260,7 @@ impl AirContext { } /// Returns true if LogUp-GKR is enabled. - pub fn uses_logup_gkr(&self) -> bool { + pub fn logup_gkr_enabled(&self) -> bool { self.logup_gkr } diff --git a/air/src/air/logup_gkr.rs b/air/src/air/logup_gkr.rs index f28f06c69..08b2890f3 100644 --- a/air/src/air/logup_gkr.rs +++ b/air/src/air/logup_gkr.rs @@ -6,9 +6,10 @@ 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]. /// @@ -104,12 +105,25 @@ pub trait LogUpGkrEvaluator: Clone + Sync { } #[derive(Clone, Default)] -pub struct DummyLogUpGkrEval> { +pub(crate) struct PhantomLogUpGkrEval> { _field: PhantomData, _public_inputs: PhantomData

, } -impl LogUpGkrEvaluator for DummyLogUpGkrEval +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, @@ -164,12 +178,12 @@ where #[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord)] pub enum LogUpGkrOracle { - // a column with a given index in the main trace segment + /// 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 + /// 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. + /// 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 f913be5de..431b901f1 100644 --- a/air/src/air/mod.rs +++ b/air/src/air/mod.rs @@ -6,6 +6,7 @@ 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; @@ -194,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 object needed for LogUp-GKR, when enabled. - type LogUpGkrEvaluator: LogUpGkrEvaluator< - BaseField = Self::BaseField, - PublicInputs = Self::PublicInputs, - >; + type PublicInputs: ToElements + Clone + Send + Sync; // REQUIRED METHODS // -------------------------------------------------------------------------------------------- @@ -216,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. /// @@ -309,10 +304,11 @@ pub trait Air: Send + Sync { // -------------------------------------------------------------------------------------------- /// Returns the object needed for the LogUp-GKR argument. - fn get_logup_gkr_evaluator>( + fn get_logup_gkr_evaluator( &self, - ) -> Self::LogUpGkrEvaluator { - unimplemented!("`get_logup_gkr_evaluator()` must be implemented when LogUp-GKR is enabled"); + ) -> impl LogUpGkrEvaluator + { + PhantomLogUpGkrEval::new() } // PROVIDED METHODS @@ -342,7 +338,7 @@ pub trait Air: Send + Sync { lagrange_composition_coefficients: LagrangeConstraintsCompositionCoefficients, lagrange_kernel_rand_elements: &LagrangeKernelRandElements, ) -> Option> { - if self.context().uses_logup_gkr() { + if self.context().logup_gkr_enabled() { let col_idx = self.context().trace_info().aux_segment_width() - 1; Some(LagrangeKernelConstraints::new( lagrange_composition_coefficients, @@ -548,7 +544,7 @@ pub trait Air: Send + Sync { b_coefficients.push(public_coin.draw()?); } - let lagrange = if self.context().uses_logup_gkr() { + 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,7 +560,7 @@ pub trait Air: Send + Sync { None }; - let s_col = if self.context().uses_logup_gkr() { + let s_col = if self.context().logup_gkr_enabled() { Some(public_coin.draw()?) } else { None @@ -598,13 +594,13 @@ pub trait Air: Send + Sync { c_coefficients.push(public_coin.draw()?); } - let lagrange_cc = if self.context().uses_logup_gkr() { + let lagrange_cc = if self.context().logup_gkr_enabled() { Some(public_coin.draw()?) } else { None }; - let s_col = if self.context().uses_logup_gkr() { + let s_col = if self.context().logup_gkr_enabled() { Some(public_coin.draw()?) } else { None diff --git a/air/src/air/tests.rs b/air/src/air/tests.rs index 2475e0698..2400cb883 100644 --- a/air/src/air/tests.rs +++ b/air/src/air/tests.rs @@ -9,7 +9,7 @@ use crypto::{hashers::Blake3_256, DefaultRandomCoin, RandomCoin}; use math::{fields::f64::BaseElement, get_power_series, polynom, FieldElement, StarkField}; use super::{ - logup_gkr::DummyLogUpGkrEval, Air, AirContext, Assertion, EvaluationFrame, ProofOptions, + 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,7 +225,6 @@ impl MockAir { impl Air for MockAir { type BaseField = BaseElement; type PublicInputs = (); - type LogUpGkrEvaluator = DummyLogUpGkrEval; fn new(trace_info: TraceInfo, _pub_inputs: (), _options: ProofOptions) -> Self { let num_assertions = trace_info.meta()[0] as usize; @@ -237,7 +236,7 @@ impl Air for MockAir { } } - fn context(&self) -> &AirContext { + fn context(&self) -> &AirContext { &self.context } @@ -256,6 +255,13 @@ impl Air for MockAir { _result: &mut [E], ) { } + + fn get_logup_gkr_evaluator( + &self, + ) -> impl super::LogUpGkrEvaluator + { + PhantomLogUpGkrEval::default() + } } // UTILITY FUNCTIONS @@ -265,11 +271,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 150b55be4..44aa0a7ea 100644 --- a/air/src/air/trace_info.rs +++ b/air/src/air/trace_info.rs @@ -149,6 +149,10 @@ 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 + 2 * self.logup_gkr as usize @@ -174,7 +178,7 @@ 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 } @@ -201,7 +205,8 @@ impl TraceInfo { } } - pub fn is_with_logup_gkr(&self) -> bool { + /// Returns a boolean indicating whether LogUp-GKR is enabled. + pub fn logup_gkr_enabled(&self) -> bool { self.logup_gkr } 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 9188ca4df..39ef44d18 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, DummyLogUpGkrEval, EvaluationFrame, GkrData, + DeepCompositionCoefficients, EvaluationFrame, GkrData, LagrangeConstraintsCompositionCoefficients, LagrangeKernelBoundaryConstraint, LagrangeKernelConstraints, LagrangeKernelEvaluationFrame, LagrangeKernelRandElements, LagrangeKernelTransitionConstraints, LogUpGkrEvaluator, LogUpGkrOracle, PeriodicTable, 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 639e2e421..4019ddcae 100644 --- a/examples/src/fibonacci/fib2/air.rs +++ b/examples/src/fibonacci/fib2/air.rs @@ -14,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -29,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 df8c8065d..17edc7970 100644 --- a/examples/src/fibonacci/fib8/air.rs +++ b/examples/src/fibonacci/fib8/air.rs @@ -15,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -30,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 59b9a435a..b48eb734b 100644 --- a/examples/src/fibonacci/fib_small/air.rs +++ b/examples/src/fibonacci/fib_small/air.rs @@ -14,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -29,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 20d7c81f2..501adf6af 100644 --- a/examples/src/fibonacci/mulfib2/air.rs +++ b/examples/src/fibonacci/mulfib2/air.rs @@ -16,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -31,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 e849f2029..c76f4f091 100644 --- a/examples/src/fibonacci/mulfib8/air.rs +++ b/examples/src/fibonacci/mulfib8/air.rs @@ -16,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -40,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 9fc6ab3ad..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,7 +46,6 @@ pub struct LamportAggregateAir { impl Air for LamportAggregateAir { type BaseField = BaseElement; type PublicInputs = PublicInputs; - type LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -87,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 dbd18531f..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,7 +51,6 @@ pub struct LamportThresholdAir { impl Air for LamportThresholdAir { type BaseField = BaseElement; type PublicInputs = PublicInputs; - type LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -98,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, @@ -243,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 459d3522f..5d38397ff 100644 --- a/examples/src/merkle/air.rs +++ b/examples/src/merkle/air.rs @@ -26,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // 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 f6fa6ec06..09bf9c450 100644 --- a/examples/src/rescue/air.rs +++ b/examples/src/rescue/air.rs @@ -52,7 +52,7 @@ impl ToElements for PublicInputs { } pub struct RescueAir { - context: AirContext, + context: AirContext, seed: [BaseElement; 2], result: [BaseElement; 2], } @@ -60,7 +60,6 @@ pub struct RescueAir { impl Air for RescueAir { type BaseField = BaseElement; type PublicInputs = PublicInputs; - type LogUpGkrEvaluator = air::DummyLogUpGkrEval; // 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 00bf8ff8c..694e189bc 100644 --- a/examples/src/rescue_raps/air.rs +++ b/examples/src/rescue_raps/air.rs @@ -53,14 +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 LogUpGkrEvaluator = air::DummyLogUpGkrEval; // CONSTRUCTOR // -------------------------------------------------------------------------------------------- @@ -76,6 +75,7 @@ impl Air for RescueRapsAir { RescueRapsAir { context: AirContext::new_multi_segment( trace_info, + pub_inputs.clone(), main_degrees, aux_degrees, 8, @@ -86,7 +86,7 @@ impl Air for RescueRapsAir { } } - 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 7f324f497..f6f9d075b 100644 --- a/examples/src/rescue_raps/custom_trace_table.rs +++ b/examples/src/rescue_raps/custom_trace_table.rs @@ -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 e6082955f..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,15 +37,14 @@ pub struct VdfAir { impl Air for VdfAir { type BaseField = BaseElement; type PublicInputs = VdfInputs; - type LogUpGkrEvaluator = air::DummyLogUpGkrEval; 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, @@ -75,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 335dde279..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,13 +37,12 @@ pub struct VdfAir { impl Air for VdfAir { type BaseField = BaseElement; type PublicInputs = VdfInputs; - type LogUpGkrEvaluator = air::DummyLogUpGkrEval; 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, } @@ -66,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/benches/lagrange_kernel.rs b/prover/benches/lagrange_kernel.rs index 6c06b98dc..348554806 100644 --- a/prover/benches/lagrange_kernel.rs +++ b/prover/benches/lagrange_kernel.rs @@ -7,8 +7,7 @@ use std::time::Duration; use air::{ Air, AirContext, Assertion, AuxRandElements, ConstraintCompositionCoefficients, - DummyLogUpGkrEval, EvaluationFrame, FieldExtension, ProofOptions, TraceInfo, - TransitionConstraintDegree, + EvaluationFrame, FieldExtension, ProofOptions, TraceInfo, TransitionConstraintDegree, }; use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use crypto::{hashers::Blake3_256, DefaultRandomCoin, MerkleTree}; @@ -94,18 +93,18 @@ impl Trace for LagrangeTrace { // ================================================================================================= struct LagrangeKernelAir { - context: AirContext, + context: AirContext, } impl Air for LagrangeKernelAir { type BaseField = BaseElement; - type LogUpGkrEvaluator = DummyLogUpGkrEval; 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, @@ -115,7 +114,7 @@ impl Air for LagrangeKernelAir { } } - fn context(&self) -> &AirContext { + fn context(&self) -> &AirContext { &self.context } @@ -218,20 +217,14 @@ impl Prover for LagrangeProver { DefaultConstraintEvaluator::new(air, aux_rand_elements, composition_coefficients) } - 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 df646b674..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().uses_logup_gkr() { + 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, ) { // initialize buffers to hold trace values and evaluation results at each step; - let mut main_frame = EvaluationFrame::new(trace.trace_info().main_trace_width()); + let mut main_frame = EvaluationFrame::new(trace.trace_info().main_segment_width()); let mut evaluations = vec![E::ZERO; fragment.num_columns()]; let mut t_evaluations = vec![E::BaseField::ZERO; self.num_main_transition_constraints()]; @@ -249,7 +249,7 @@ where fragment: &mut EvaluationTableFragment, ) { // initialize buffers to hold trace values and evaluation results at each step - let mut main_frame = EvaluationFrame::new(trace.trace_info().main_trace_width()); + let mut main_frame = EvaluationFrame::new(trace.trace_info().main_segment_width()); let mut aux_frame = EvaluationFrame::new(trace.trace_info().aux_segment_width()); let mut tm_evaluations = vec![E::BaseField::ZERO; self.num_main_transition_constraints()]; let mut ta_evaluations = vec![E::ZERO; self.num_aux_transition_constraints()]; diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 3703c183b..fe58e85f3 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -48,7 +48,7 @@ pub use air::{ EvaluationFrame, FieldExtension, LagrangeKernelRandElements, ProofOptions, TraceInfo, TransitionConstraintDegree, }; -use air::{AuxRandElements, LogUpGkrEvaluator}; +use air::{AuxRandElements, GkrData, LogUpGkrEvaluator}; pub use crypto; use crypto::{ElementHasher, RandomCoin, VectorCommitment}; use fri::FriProver; @@ -58,6 +58,7 @@ use math::{ fields::{CubeExtension, QuadExtension}, ExtensibleField, FieldElement, StarkField, ToElements, }; +use sumcheck::FinalOpeningClaim; use tracing::{event, info_span, instrument, Level}; pub use utils::{ iterators, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, @@ -87,7 +88,7 @@ pub use trace::{ }; mod logup_gkr; -use logup_gkr::{build_lagrange_column, build_s_column, generate_gkr_randomness, prove_gkr}; +use logup_gkr::{build_lagrange_column, build_s_column, prove_gkr}; mod channel; use channel::ProverChannel; @@ -204,26 +205,7 @@ pub trait Prover { /// Builds and returns the auxiliary trace. #[allow(unused_variables)] #[maybe_async] - fn build_aux_trace( - &self, - main_trace: &Self::Trace, - aux_rand_elements: &AuxRandElements, - ) -> ColMatrix - where - E: FieldElement, - { - unimplemented!("`Prover::build_aux_trace` needs to be implemented when the trace has an auxiliary segment.") - } - - /// Builds and returns the auxiliary trace. - #[allow(unused_variables)] - #[maybe_async] - fn build_aux_trace_wrapper( - &self, - air: &Self::Air, - 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, { @@ -329,34 +311,40 @@ pub trait Prover { // 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, aux_rand_elements) = if air.context().uses_logup_gkr() { + // build the auxiliary segment without the LogUp-GKR related part + let aux_rand_elements = air + .get_aux_rand_elements(channel.public_coin()) + .expect("failed to draw random elements for the auxiliary trace segment"); + let mut aux_trace = maybe_await!(self.build_aux_trace(&trace, &aux_rand_elements)); + + // build the LogUp-GKR related section of the auxiliary segment, if any. This will also + // build an object containing randomness and data related to the LogUp-GKR section of + // the auxiliary trace segment. + let (gkr_proof, gkr_rand_elements) = if air.context().logup_gkr_enabled() { let gkr_proof = - prove_gkr(&trace, &air.get_logup_gkr_evaluator::(), channel.public_coin()) + prove_gkr(&trace, &air.get_logup_gkr_evaluator(), channel.public_coin()) .map_err(|_| ProverError::FailedToGenerateGkrProof)?; - let gkr_rand_elements = generate_gkr_randomness( - gkr_proof.get_final_opening_claim(), - air.get_logup_gkr_evaluator::().get_oracles(), - channel.public_coin(), - ); + let FinalOpeningClaim { eval_point, openings } = + gkr_proof.get_final_opening_claim(); - let rand_elements = air - .get_aux_rand_elements(channel.public_coin()) - .expect("failed to draw random elements for the auxiliary trace segment"); + let gkr_data = air + .get_logup_gkr_evaluator() + .generate_univariate_iop_for_multi_linear_opening_data( + openings, + eval_point, + channel.public_coin(), + ); - let aux_rand_elements = - AuxRandElements::new_with_gkr(rand_elements, gkr_rand_elements); + // add the extra columns required for LogUp-GKR + maybe_await!(build_logup_gkr_columns(&air, &trace, &mut aux_trace, &gkr_data)); - (Some(gkr_proof), aux_rand_elements) + (Some(gkr_proof), Some(gkr_data)) } else { - let rand_elements = air - .get_aux_rand_elements(channel.public_coin()) - .expect("failed to draw random elements for the auxiliary trace segment"); - - (None, AuxRandElements::new(rand_elements)) + (None, None) }; - let aux_trace = - maybe_await!(self.build_aux_trace_wrapper(&air, &trace, &aux_rand_elements)); + // build the set of all random values associated to the auxiliary segment + let aux_rand_elements = AuxRandElements::new(aux_rand_elements, gkr_rand_elements); // commit to the auxiliary trace segment let aux_segment_polys = { @@ -638,3 +626,26 @@ pub trait Prover { (constraint_commitment, composition_poly) } } + +/// Builds and appends to the auxiliary segment two additional columns needed for implementing +/// the univariate IOP for multi-linear evaluation of Section 5 in [1]. +/// +/// [1]: https://eprint.iacr.org/2023/1284 +#[maybe_async] +fn build_logup_gkr_columns( + air: &A, + main_trace: &T, + aux_trace: &mut ColMatrix, + gkr_data: &GkrData, +) where + E: FieldElement, + A: Air, + T: Trace, +{ + let evaluator = air.get_logup_gkr_evaluator(); + let lagrange_col = build_lagrange_column(&gkr_data.lagrange_kernel_eval_point); + let s_col = build_s_column(main_trace, gkr_data, &evaluator, &lagrange_col); + + aux_trace.merge_column(s_col); + aux_trace.merge_column(lagrange_col); +} diff --git a/prover/src/logup_gkr/mod.rs b/prover/src/logup_gkr/mod.rs index 4ce5f5d73..56174bf1f 100644 --- a/prover/src/logup_gkr/mod.rs +++ b/prover/src/logup_gkr/mod.rs @@ -1,12 +1,9 @@ use alloc::vec::Vec; use core::ops::Add; -use air::{ - EvaluationFrame, GkrData, LagrangeKernelRandElements, LogUpGkrEvaluator, LogUpGkrOracle, -}; -use crypto::{ElementHasher, RandomCoin}; +use air::{EvaluationFrame, GkrData, LogUpGkrEvaluator}; use math::FieldElement; -use sumcheck::{EqFunction, FinalOpeningClaim, MultiLinearPoly, SumCheckProverError}; +use sumcheck::{EqFunction, MultiLinearPoly, SumCheckProverError}; use utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; use crate::Trace; @@ -350,41 +347,6 @@ where ) } -// UNIVARIATE IOP FOR MULTI-LINEAR EVALUATION -// =============================================================================================== - -/// Generates the batching randomness used to batch a number of multi-linear evaluation claims. -/// -/// 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 -pub fn generate_gkr_randomness< - E: FieldElement, - C: RandomCoin, - H: ElementHasher, ->( - final_opening_claim: FinalOpeningClaim, - oracles: &[LogUpGkrOracle], - public_coin: &mut C, -) -> GkrData { - let FinalOpeningClaim { eval_point, openings } = final_opening_claim; - - 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, - oracles.to_vec(), - ) -} - /// Builds the auxiliary trace column for the univariate sum-check argument. /// /// Following Section 5.2 in [1] and using the inner product representation of multi-linear queries, @@ -401,7 +363,7 @@ pub fn generate_gkr_randomness< /// [1]: https://eprint.iacr.org/2023/1284 pub fn build_s_column( main_trace: &impl Trace, - gkr_data: GkrData, + gkr_data: &GkrData, evaluator: &impl LogUpGkrEvaluator, lagrange_kernel_col: &[E], ) -> Vec { diff --git a/prover/src/tests/mod.rs b/prover/src/tests/mod.rs index f88afcde1..7c1b66b9f 100644 --- a/prover/src/tests/mod.rs +++ b/prover/src/tests/mod.rs @@ -34,7 +34,7 @@ pub fn build_fib_trace(length: usize) -> TraceTable { // ================================================================================================ pub struct MockAir { - context: AirContext, + context: AirContext, assertions: Vec>, periodic_columns: Vec>, } @@ -75,7 +75,6 @@ impl MockAir { impl Air for MockAir { type BaseField = BaseElement; type PublicInputs = (); - type LogUpGkrEvaluator = DummyLogUpGkrEval; fn new(trace_info: TraceInfo, _pub_inputs: (), _options: ProofOptions) -> Self { let context = build_context(trace_info, 8, 1); @@ -86,7 +85,7 @@ impl Air for MockAir { } } - fn context(&self) -> &AirContext { + fn context(&self) -> &AirContext { &self.context } @@ -114,8 +113,8 @@ fn build_context( trace_info: TraceInfo, blowup_factor: usize, num_assertions: usize, -) -> AirContext { +) -> AirContext { let options = ProofOptions::new(32, blowup_factor, 0, FieldExtension::None, 4, 31); let t_degrees = vec![TransitionConstraintDegree::new(2)]; - AirContext::new(trace_info, t_degrees, num_assertions, options) + AirContext::new(trace_info, (), t_degrees, num_assertions, options) } diff --git a/prover/src/trace/mod.rs b/prover/src/trace/mod.rs index 00fd57b0b..8d7c999bf 100644 --- a/prover/src/trace/mod.rs +++ b/prover/src/trace/mod.rs @@ -80,7 +80,7 @@ pub trait Trace: Sized { /// Returns the number of columns in the main segment of this trace. fn main_trace_width(&self) -> usize { - self.info().main_trace_width() + self.info().main_segment_width() } /// Returns the number of columns in the auxiliary trace segment. @@ -99,10 +99,10 @@ pub trait Trace: Sized { // make sure the width align; if they don't something went terribly wrong assert_eq!( self.main_trace_width(), - air.trace_info().main_trace_width(), + air.trace_info().main_segment_width(), "inconsistent trace width: expected {}, but was {}", self.main_trace_width(), - air.trace_info().main_trace_width(), + air.trace_info().main_segment_width(), ); // --- 1. make sure the assertions are valid ---------------------------------------------- diff --git a/prover/src/trace/trace_table.rs b/prover/src/trace/trace_table.rs index dfbd6fe72..0d26c73a0 100644 --- a/prover/src/trace/trace_table.rs +++ b/prover/src/trace/trace_table.rs @@ -166,7 +166,7 @@ impl TraceTable { I: FnOnce(&mut [B]), U: FnMut(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); @@ -255,7 +255,7 @@ impl TraceTable { /// 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 the entire trace column at the specified index. diff --git a/sumcheck/src/verifier/mod.rs b/sumcheck/src/verifier/mod.rs index ba33ec9aa..6a708b255 100644 --- a/sumcheck/src/verifier/mod.rs +++ b/sumcheck/src/verifier/mod.rs @@ -52,6 +52,8 @@ pub fn verify_sum_check_intermediate_layers< Ok(openings_claim.clone()) } +/// Sum-check verifier for the input layer. +/// /// Verifies the final sum-check proof i.e., the one for the input layer, including the final check, /// and returns a [`FinalOpeningClaim`] to the STARK verifier in order to verify the correctness of /// the openings. diff --git a/verifier/src/channel.rs b/verifier/src/channel.rs index f0f949c47..5fefe991d 100644 --- a/verifier/src/channel.rs +++ b/verifier/src/channel.rs @@ -13,6 +13,8 @@ use air::{ use crypto::{ElementHasher, VectorCommitment}; use fri::VerifierChannel as FriVerifierChannel; use math::{FieldElement, StarkField}; +use sumcheck::GkrCircuitProof; +use utils::Deserializable; use crate::VerifierError; @@ -81,7 +83,7 @@ where let constraint_frame_width = air.context().num_constraint_composition_columns(); let num_trace_segments = air.trace_info().num_segments(); - let main_trace_width = air.trace_info().main_trace_width(); + let main_trace_width = air.trace_info().main_segment_width(); let aux_trace_width = air.trace_info().aux_segment_width(); let lde_domain_size = air.lde_domain_size(); let fri_options = air.options().to_fri_options(); @@ -172,9 +174,12 @@ where self.pow_nonce } - /// Returns the serialized GKR proof, if any. - pub fn read_gkr_proof(&self) -> Option<&Vec> { - self.gkr_proof.as_ref() + /// Returns the GKR proof, if any. + pub fn read_gkr_proof(&self) -> Result, VerifierError> { + GkrCircuitProof::read_from_bytes( + self.gkr_proof.as_ref().expect("Expected a GKR proof but there was none"), + ) + .map_err(|err| VerifierError::ProofDeserializationError(err.to_string())) } /// Returns trace states at the specified positions of the LDE domain. This also checks if @@ -313,7 +318,7 @@ where ); // parse main trace segment queries - let main_segment_width = air.trace_info().main_trace_width(); + let main_segment_width = air.trace_info().main_segment_width(); let main_segment_queries = queries.remove(0); let (main_segment_query_proofs, main_segment_states) = main_segment_queries .parse::(air.lde_domain_size(), num_queries, main_segment_width) diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index 0f0d0fc0a..f21cfc227 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -38,7 +38,7 @@ pub use air::{ ConstraintCompositionCoefficients, ConstraintDivisor, DeepCompositionCoefficients, EvaluationFrame, FieldExtension, ProofOptions, TraceInfo, TransitionConstraintDegree, }; -use air::{AuxRandElements, GkrData, LagrangeKernelRandElements, LogUpGkrEvaluator}; +use air::{AuxRandElements, LogUpGkrEvaluator}; pub use crypto; use crypto::{ElementHasher, Hasher, RandomCoin, VectorCommitment}; use fri::FriVerifier; @@ -47,7 +47,7 @@ use math::{ fields::{CubeExtension, QuadExtension}, FieldElement, ToElements, }; -use sumcheck::{FinalOpeningClaim, GkrCircuitProof}; +use sumcheck::FinalOpeningClaim; pub use utils::{ ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, SliceReader, }; @@ -62,7 +62,7 @@ mod composer; use composer::DeepComposer; mod logup_gkr; -use logup_gkr::{verify_logup_gkr, VerifierError as GkrVerifierError}; +use logup_gkr::verify_gkr; mod errors; pub use errors::VerifierError; @@ -179,34 +179,40 @@ where // process auxiliary trace segments (if any), to build a set of random elements for each segment let aux_trace_rand_elements = if air.trace_info().is_multi_segment() { - if air.context().uses_logup_gkr() { - let gkr_proof = { - let gkr_proof_serialized = - channel.read_gkr_proof().expect("Expected a GKR proof but there was none"); - - GkrCircuitProof::read_from_bytes(gkr_proof_serialized) - .map_err(|err| VerifierError::ProofDeserializationError(err.to_string()))? - }; - - let gkr_rand_elements = - verify_gkr(gkr_proof, &air.get_logup_gkr_evaluator::(), &mut public_coin) - .map_err(|err| VerifierError::GkrProofVerificationFailed(err.to_string()))?; + // build the set of random elements related to the auxiliary segment without the LogUp-GKR + // related ones. + let trace_rand_elements = air + .get_aux_rand_elements(&mut public_coin) + .expect("failed to generate the random elements needed to build the auxiliary trace"); + + // if LogUp-GKR is enabled, verify the attached proof and build an object which includes + // randomness and data related to LogUp-GKR + if air.context().logup_gkr_enabled() { + let gkr_proof = channel.read_gkr_proof()?; + let logup_gkr_evaluator = air.get_logup_gkr_evaluator(); + + let FinalOpeningClaim { eval_point, openings } = verify_gkr::( + air.context().public_inputs(), + &gkr_proof, + &logup_gkr_evaluator, + &mut public_coin, + ) + .map_err(|err| VerifierError::GkrProofVerificationFailed(err.to_string()))?; - let rand_elements = air.get_aux_rand_elements(&mut public_coin).expect( - "failed to generate the random elements needed to build the auxiliary trace", - ); + let gkr_data = logup_gkr_evaluator + .generate_univariate_iop_for_multi_linear_opening_data( + openings, + eval_point, + &mut public_coin, + ); public_coin.reseed(trace_commitments[AUX_TRACE_IDX]); - Some(AuxRandElements::new_with_gkr(rand_elements, gkr_rand_elements)) + Some(AuxRandElements::new(trace_rand_elements, Some(gkr_data))) } else { - let rand_elements = air.get_aux_rand_elements(&mut public_coin).expect( - "failed to generate the random elements needed to build the auxiliary trace", - ); - public_coin.reseed(trace_commitments[AUX_TRACE_IDX]); - Some(AuxRandElements::new(rand_elements)) + Some(AuxRandElements::new(trace_rand_elements, None)) } } else { None diff --git a/verifier/src/logup_gkr/mod.rs b/verifier/src/logup_gkr/mod.rs index dcc1529ed..4ff9334fc 100644 --- a/verifier/src/logup_gkr/mod.rs +++ b/verifier/src/logup_gkr/mod.rs @@ -1,6 +1,6 @@ use alloc::vec::Vec; -use air::LogUpGkrEvaluator; +use air::{Air, LogUpGkrEvaluator}; use crypto::{ElementHasher, RandomCoin}; use math::FieldElement; use sumcheck::{ @@ -9,7 +9,8 @@ use sumcheck::{ }; /// Verifies the validity of a GKR proof for a LogUp-GKR relation. -pub fn verify_logup_gkr< +pub fn verify_gkr< + A: Air, E: FieldElement, C: RandomCoin, H: ElementHasher, @@ -38,6 +39,7 @@ pub fn verify_logup_gkr< } // check that the output matches the expected `claim` + let claim = evaluator.compute_claim(pub_inputs, &logup_randomness); if (p0 * q1 + p1 * q0) / (q0 * q1) != claim { return Err(VerifierError::MismatchingCircuitOutput); } @@ -86,7 +88,7 @@ pub fn verify_logup_gkr< verify_sum_check_input_layer( evaluator, final_layer_proof, - log_up_randomness, + logup_randomness, &evaluation_point, reduced_claim, transcript, diff --git a/winterfell/src/lib.rs b/winterfell/src/lib.rs index 770b62090..c3da2fb6a 100644 --- a/winterfell/src/lib.rs +++ b/winterfell/src/lib.rs @@ -150,12 +150,13 @@ //! ```no_run //! use winterfell::{ //! math::{fields::f128::BaseElement, FieldElement, ToElements}, -//! Air, AirContext, Assertion, GkrVerifier, EvaluationFrame, +//! Air, AirContext, Assertion, EvaluationFrame, //! ProofOptions, TraceInfo, TransitionConstraintDegree, //! crypto::{hashers::Blake3_256, DefaultRandomCoin, MerkleTree}, //! }; //! //! // Public inputs for our computation will consist of the starting value and the end result. +//! #[derive(Clone)] //! pub struct PublicInputs { //! start: BaseElement, //! result: BaseElement, @@ -172,7 +173,7 @@ //! // the computation's context which we'll build in the constructor. The context is used //! // internally by the Winterfell prover/verifier when interpreting this AIR. //! pub struct WorkAir { -//! context: AirContext, +//! context: AirContext, //! start: BaseElement, //! result: BaseElement, //! } @@ -182,8 +183,6 @@ //! // the public inputs must look like. //! type BaseField = BaseElement; //! type PublicInputs = PublicInputs; -//! type GkrProof = (); -//! type GkrVerifier = (); //! //! // Here, we'll construct a new instance of our computation which is defined by 3 //! // parameters: starting value, number of steps, and the end result. Another way to @@ -206,7 +205,7 @@ //! let num_assertions = 2; //! //! WorkAir { -//! context: AirContext::new(trace_info, degrees, num_assertions, options), +//! context: AirContext::new(trace_info, pub_inputs.clone(), degrees, num_assertions, options), //! start: pub_inputs.start, //! result: pub_inputs.result, //! } @@ -246,7 +245,7 @@ //! //! // This is just boilerplate which is used by the Winterfell prover/verifier to retrieve //! // the context of the computation. -//! fn context(&self) -> &AirContext { +//! fn context(&self) -> &AirContext { //! &self.context //! } //! } @@ -269,6 +268,7 @@ //! # EvaluationFrame, TraceInfo, TransitionConstraintDegree, //! # }; //! # +//! # #[derive(Clone)] //! # pub struct PublicInputs { //! # start: BaseElement, //! # result: BaseElement, @@ -281,7 +281,7 @@ //! # } //! # //! # pub struct WorkAir { -//! # context: AirContext, +//! # context: AirContext, //! # start: BaseElement, //! # result: BaseElement, //! # } @@ -289,14 +289,12 @@ //! # impl Air for WorkAir { //! # type BaseField = BaseElement; //! # type PublicInputs = PublicInputs; -//! # type GkrProof = (); -//! # type GkrVerifier = (); //! # //! # fn new(trace_info: TraceInfo, pub_inputs: PublicInputs, options: ProofOptions) -> Self { //! # assert_eq!(1, trace_info.width()); //! # let degrees = vec![TransitionConstraintDegree::new(3)]; //! # WorkAir { -//! # context: AirContext::new(trace_info, degrees, 2, options), +//! # context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 2, options), //! # start: pub_inputs.start, //! # result: pub_inputs.result, //! # } @@ -321,7 +319,7 @@ //! # ] //! # } //! # -//! # fn context(&self) -> &AirContext { +//! # fn context(&self) -> &AirContext { //! # &self.context //! # } //! # } @@ -418,7 +416,7 @@ //! # trace //! # } //! # -//! # +//! # #[derive(Clone)] //! # pub struct PublicInputs { //! # start: BaseElement, //! # result: BaseElement, @@ -431,7 +429,7 @@ //! # } //! # //! # pub struct WorkAir { -//! # context: AirContext, +//! # context: AirContext, //! # start: BaseElement, //! # result: BaseElement, //! # } @@ -439,14 +437,12 @@ //! # impl Air for WorkAir { //! # type BaseField = BaseElement; //! # type PublicInputs = PublicInputs; -//! # type GkrProof = (); -//! # type GkrVerifier = (); //! # //! # fn new(trace_info: TraceInfo, pub_inputs: PublicInputs, options: ProofOptions) -> Self { //! # assert_eq!(1, trace_info.width()); //! # let degrees = vec![TransitionConstraintDegree::new(3)]; //! # WorkAir { -//! # context: AirContext::new(trace_info, degrees, 2, options), +//! # context: AirContext::new(trace_info, pub_inputs.clone(), degrees, 2, options), //! # start: pub_inputs.start, //! # result: pub_inputs.result, //! # } @@ -471,7 +467,7 @@ //! # ] //! # } //! # -//! # fn context(&self) -> &AirContext { +//! # fn context(&self) -> &AirContext { //! # &self.context //! # } //! # } @@ -594,7 +590,7 @@ #[cfg(test)] extern crate std; -pub use air::AuxRandElements; +pub use air::{AuxRandElements, LogUpGkrEvaluator}; pub use prover::{ crypto, iterators, math, matrix, Air, AirContext, Assertion, AuxTraceWithMetadata, BoundaryConstraint, BoundaryConstraintGroup, CompositionPolyTrace, diff --git a/winterfell/src/tests/logup_gkr_simple.rs b/winterfell/src/tests/logup_gkr_simple.rs index 778040bfc..d180da2b5 100644 --- a/winterfell/src/tests/logup_gkr_simple.rs +++ b/winterfell/src/tests/logup_gkr_simple.rs @@ -105,7 +105,7 @@ impl Trace for LogUpGkrSimple { // ================================================================================================= struct LogUpGkrSimpleAir { - context: AirContext, + context: AirContext, } impl Air for LogUpGkrSimpleAir { @@ -117,6 +117,7 @@ impl Air for LogUpGkrSimpleAir { Self { context: AirContext::with_logup_gkr( trace_info, + _pub_inputs, vec![TransitionConstraintDegree::new(1)], vec![], 1, @@ -126,7 +127,7 @@ impl Air for LogUpGkrSimpleAir { } } - fn context(&self) -> &AirContext { + fn context(&self) -> &AirContext { &self.context } @@ -168,20 +169,21 @@ impl Air for LogUpGkrSimpleAir { vec![] } - fn get_logup_gkr_evaluator>( + fn get_logup_gkr_evaluator( &self, - ) -> Self::LogUpGkrEvaluator { + ) -> impl LogUpGkrEvaluator + { PlainLogUpGkrEval::new() } } #[derive(Clone, Default)] -pub struct PlainLogUpGkrEval { +pub struct PlainLogUpGkrEval { oracles: Vec>, _field: PhantomData, } -impl PlainLogUpGkrEval { +impl PlainLogUpGkrEval { pub fn new() -> Self { let committed_0 = LogUpGkrOracle::CurrentRow(0); let committed_1 = LogUpGkrOracle::CurrentRow(1); @@ -312,11 +314,7 @@ impl Prover for LogUpGkrSimpleProver { DefaultConstraintEvaluator::new(air, aux_rand_elements, composition_coefficients) } - 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, {