Skip to content

Commit

Permalink
Merge branch 'logup-gkr' into al-gkr-backend-for-logup-gkr-support-pe…
Browse files Browse the repository at this point in the history
…riodic
  • Loading branch information
Al-Kindi-0 committed Aug 30, 2024
2 parents 0f7e2e0 + aef404d commit 8bad002
Show file tree
Hide file tree
Showing 41 changed files with 333 additions and 313 deletions.
53 changes: 31 additions & 22 deletions air/src/air/aux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,26 @@ 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<E: FieldElement> {
rand_elements: Vec<E>,
gkr: Option<GkrData<E>>,
}

impl<E: FieldElement> AuxRandElements<E> {
/// Creates a new [`AuxRandElements`], where the auxiliary trace doesn't contain a Lagrange
/// kernel column.
pub fn new(rand_elements: Vec<E>) -> 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<E>, gkr: GkrData<E>) -> Self {
Self { rand_elements, gkr: Some(gkr) }
pub fn new(rand_elements: Vec<E>, gkr: Option<GkrData<E>>) -> 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
Expand All @@ -51,21 +46,35 @@ impl<E: FieldElement> AuxRandElements<E> {
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<GkrData<E>> {
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<E: FieldElement> {
pub lagrange_kernel_eval_point: LagrangeKernelRandElements<E>,
Expand Down
10 changes: 5 additions & 5 deletions air/src/air/boundary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ impl<E: FieldElement> BoundaryConstraints<E> {
/// 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<E::BaseField>,
pub fn new<P>(
context: &AirContext<E::BaseField, P>,
main_assertions: Vec<Assertion<E::BaseField>>,
aux_assertions: Vec<Assertion<E>>,
composition_coefficients: &[E],
Expand Down Expand Up @@ -88,7 +88,7 @@ impl<E: FieldElement> BoundaryConstraints<E> {
);

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;
Expand Down Expand Up @@ -151,9 +151,9 @@ impl<E: FieldElement> BoundaryConstraints<E> {

/// 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<F, E>(
fn group_constraints<F, E, P>(
assertions: Vec<Assertion<F>>,
context: &AirContext<F::BaseField>,
context: &AirContext<F::BaseField, P>,
composition_coefficients: &[E],
inv_g: F::BaseField,
twiddle_map: &mut BTreeMap<usize, Vec<F::BaseField>>,
Expand Down
23 changes: 18 additions & 5 deletions air/src/air/coefficients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<E: FieldElement> {
pub transition: Vec<E>,
Expand Down Expand Up @@ -84,8 +91,9 @@ pub struct LagrangeConstraintsCompositionCoefficients<E: FieldElement> {
/// 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)}
Expand All @@ -100,8 +108,13 @@ pub struct LagrangeConstraintsCompositionCoefficients<E: FieldElement> {
/// 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<E: FieldElement> {
/// Trace polynomial composition coefficients $\alpha_i$.
Expand All @@ -110,6 +123,6 @@ pub struct DeepCompositionCoefficients<E: FieldElement> {
pub constraints: Vec<E>,
/// Lagrange kernel trace polynomial composition coefficient $\gamma$.
pub lagrange: Option<E>,
/// TODO
/// S-column trace polynomial composition coefficient.
pub s_col: Option<E>,
}
21 changes: 16 additions & 5 deletions air/src/air/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<B: StarkField> {
pub struct AirContext<B: StarkField, P> {
pub(super) options: ProofOptions,
pub(super) trace_info: TraceInfo,
pub(super) pub_inputs: P,
pub(super) main_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
pub(super) aux_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
pub(super) num_main_assertions: usize,
Expand All @@ -28,7 +29,7 @@ pub struct AirContext<B: StarkField> {
pub(super) logup_gkr: bool,
}

impl<B: StarkField> AirContext<B> {
impl<B: StarkField, P> AirContext<B, P> {
// CONSTRUCTORS
// --------------------------------------------------------------------------------------------
/// Returns a new instance of [AirContext] instantiated for computations which require a single
Expand All @@ -48,6 +49,7 @@ impl<B: StarkField> AirContext<B> {
/// * `trace_info` describes a multi-segment execution trace.
pub fn new(
trace_info: TraceInfo,
pub_inputs: P,
transition_constraint_degrees: Vec<TransitionConstraintDegree>,
num_assertions: usize,
options: ProofOptions,
Expand All @@ -58,6 +60,7 @@ impl<B: StarkField> AirContext<B> {
);
Self::new_multi_segment(
trace_info,
pub_inputs,
transition_constraint_degrees,
Vec::new(),
num_assertions,
Expand Down Expand Up @@ -90,6 +93,7 @@ impl<B: StarkField> AirContext<B> {
/// of the specified transition constraints.
pub fn new_multi_segment(
trace_info: TraceInfo,
pub_inputs: P,
main_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
aux_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
num_main_assertions: usize,
Expand All @@ -102,7 +106,7 @@ impl<B: StarkField> AirContext<B> {
);
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"
Expand Down Expand Up @@ -150,6 +154,7 @@ impl<B: StarkField> AirContext<B> {
AirContext {
options,
trace_info,
pub_inputs,
main_transition_constraint_degrees,
aux_transition_constraint_degrees,
num_main_assertions,
Expand All @@ -164,6 +169,7 @@ impl<B: StarkField> AirContext<B> {

pub fn with_logup_gkr(
trace_info: TraceInfo,
pub_inputs: P,
main_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
aux_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
num_main_assertions: usize,
Expand All @@ -172,6 +178,7 @@ impl<B: StarkField> AirContext<B> {
) -> Self {
let mut air_context = Self::new_multi_segment(
trace_info,
pub_inputs,
main_transition_constraint_degrees,
aux_transition_constraint_degrees,
num_main_assertions,
Expand Down Expand Up @@ -218,6 +225,10 @@ impl<B: StarkField> AirContext<B> {
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.
///
Expand All @@ -241,15 +252,15 @@ impl<B: StarkField> AirContext<B> {

/// Returns the index of the auxiliary column which implements the Lagrange kernel, if any
pub fn lagrange_kernel_aux_column_idx(&self) -> Option<usize> {
if self.uses_logup_gkr() {
if self.logup_gkr_enabled() {
Some(self.trace_info().aux_segment_width() - 1)
} else {
None
}
}

/// Returns true if LogUp-GKR is enabled.
pub fn uses_logup_gkr(&self) -> bool {
pub fn logup_gkr_enabled(&self) -> bool {
self.logup_gkr
}

Expand Down
28 changes: 21 additions & 7 deletions air/src/air/logup_gkr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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].
///
Expand Down Expand Up @@ -104,12 +105,25 @@ pub trait LogUpGkrEvaluator: Clone + Sync {
}

#[derive(Clone, Default)]
pub struct DummyLogUpGkrEval<B: StarkField, P: Clone + Send + Sync + ToElements<B>> {
pub(crate) struct PhantomLogUpGkrEval<B: StarkField, P: Clone + Send + Sync + ToElements<B>> {
_field: PhantomData<B>,
_public_inputs: PhantomData<P>,
}

impl<B, P> LogUpGkrEvaluator for DummyLogUpGkrEval<B, P>
impl<B, P> PhantomLogUpGkrEval<B, P>
where
B: StarkField,
P: Clone + Send + Sync + ToElements<B>,
{
pub fn new() -> Self {
Self {
_field: PhantomData,
_public_inputs: PhantomData,
}
}
}

impl<B, P> LogUpGkrEvaluator for PhantomLogUpGkrEval<B, P>
where
B: StarkField,
P: Clone + Send + Sync + ToElements<B>,
Expand Down Expand Up @@ -164,12 +178,12 @@ where

#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord)]
pub enum LogUpGkrOracle<B: StarkField> {
// 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<B>),
}

Expand Down
Loading

0 comments on commit 8bad002

Please sign in to comment.