Skip to content

Commit

Permalink
Refactor LagrangeKernelBoundaryConstraint
Browse files Browse the repository at this point in the history
  • Loading branch information
plafer committed Mar 12, 2024
1 parent d1bb2b7 commit a3377d9
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 89 deletions.
44 changes: 20 additions & 24 deletions air/src/air/boundary/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

use crate::{ConstraintDivisor, LagrangeKernelEvaluationFrame};
use crate::LagrangeKernelEvaluationFrame;

use super::{Assertion, ExtensionOf, FieldElement};
use math::{fft, polynom};
Expand Down Expand Up @@ -167,37 +167,23 @@ where
// ================================================================================================

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct LagrangeKernelBoundaryConstraint<F, E>
pub struct LagrangeKernelBoundaryConstraint<E>
where
F: FieldElement,
E: FieldElement<BaseField = F::BaseField> + ExtensionOf<F>,
E: FieldElement,
{
assertion_value: F,
assertion_value: E,
composition_coefficient: E,
divisor: ConstraintDivisor<F::BaseField>,
}

impl<F, E> LagrangeKernelBoundaryConstraint<F, E>
impl<E> LagrangeKernelBoundaryConstraint<E>
where
F: FieldElement,
E: FieldElement<BaseField = F::BaseField> + ExtensionOf<F>,
E: FieldElement,
{
/// Creates a new Lagrange kernel boundary constraint from the specified single assertion.
///
/// # Panics
/// Panics if the assertion is not a single assertion (i.e. `assertion.values` has more than 1
/// value)
pub fn new(
assertion: Assertion<F>,
composition_coefficient: E,
divisor: ConstraintDivisor<F::BaseField>,
) -> Self {
assert_eq!(assertion.values.len(), 1);

pub fn new(composition_coefficient: E, lagrange_kernel_rand_elements: &[E]) -> Self {
Self {
assertion_value: assertion.values[0],
assertion_value: Self::assertion_value(lagrange_kernel_rand_elements),
composition_coefficient,
divisor,
}
}

Expand All @@ -207,13 +193,23 @@ where
pub fn evaluate_at(&self, x: E, frame: &LagrangeKernelEvaluationFrame<E>) -> E {
let numerator = {
let trace_value = frame.inner()[0];
let constraint_evaluation = trace_value - E::from(self.assertion_value);
let constraint_evaluation = trace_value - self.assertion_value;

constraint_evaluation * self.composition_coefficient
};

let denominator = self.divisor.evaluate_at(x);
let denominator = x - E::ONE;

numerator / denominator
}

/// Computes the assertion value given the provided random elements.
pub fn assertion_value(lagrange_kernel_rand_elements: &[E]) -> E {
let mut assertion_value = E::ONE;
for &rand_ele in lagrange_kernel_rand_elements {
assertion_value *= E::ONE - rand_ele;
}

assertion_value
}
}
24 changes: 10 additions & 14 deletions air/src/air/boundary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ mod tests;
pub struct BoundaryConstraints<E: FieldElement> {
main_constraints: Vec<BoundaryConstraintGroup<E::BaseField, E>>,
aux_constraints: Vec<BoundaryConstraintGroup<E, E>>,
lagrange_kernel_constraint: Option<LagrangeKernelBoundaryConstraint<E, E>>,
lagrange_kernel_constraint: Option<LagrangeKernelBoundaryConstraint<E>>,
}

impl<E: FieldElement> BoundaryConstraints<E> {
Expand All @@ -58,9 +58,9 @@ impl<E: FieldElement> BoundaryConstraints<E> {
context: &AirContext<E::BaseField>,
main_assertions: Vec<Assertion<E::BaseField>>,
aux_assertions: Vec<Assertion<E>>,
lagrange_kernel_assertion: Option<Assertion<E>>,
composition_coefficients: &[E],
lagrange_kernel_boundary_coefficient: Option<E>,
lagrange_kernel_aux_rand_elements: &[E],
) -> Self {
// make sure the provided assertions are consistent with the specified context
assert_eq!(
Expand Down Expand Up @@ -125,17 +125,13 @@ impl<E: FieldElement> BoundaryConstraints<E> {
&mut twiddle_map,
);

let lagrange_kernel_constraint = lagrange_kernel_assertion.map(|assertion| {
let lagrange_kernel_boundary_coefficient = lagrange_kernel_boundary_coefficient
.expect("expected Lagrange boundary coefficient to be present");
let divisor = ConstraintDivisor::from_assertion(&assertion, trace_length);

LagrangeKernelBoundaryConstraint::new(
assertion,
lagrange_kernel_boundary_coefficient,
divisor,
)
});
let lagrange_kernel_constraint =
lagrange_kernel_boundary_coefficient.map(|lagrange_kernel_boundary_coefficient| {
LagrangeKernelBoundaryConstraint::new(
lagrange_kernel_boundary_coefficient,
lagrange_kernel_aux_rand_elements,
)
});

Self {
main_constraints,
Expand All @@ -159,7 +155,7 @@ impl<E: FieldElement> BoundaryConstraints<E> {
&self.aux_constraints
}

pub fn lagrange_kernel_constraint(&self) -> Option<&LagrangeKernelBoundaryConstraint<E, E>> {
pub fn lagrange_kernel_constraint(&self) -> Option<&LagrangeKernelBoundaryConstraint<E>> {
self.lagrange_kernel_constraint.as_ref()
}
}
Expand Down
30 changes: 7 additions & 23 deletions air/src/air/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,28 +309,6 @@ pub trait Air: Send + Sync {
&aux_rand_elements[0..num_rand_elements]
}

/// Evaluates and returns the Lagrange kernel boundary constraint.
fn get_lagrange_kernel_aux_assertion<E: FieldElement<BaseField = Self::BaseField>>(
&self,
aux_rand_elements: &AuxTraceRandElements<E>,
) -> Option<Assertion<E>> {
let lagrange_column_idx = self.context().lagrange_kernel_aux_column_idx()?;

let assertion_value = {
let r = aux_rand_elements.get_segment_elements(0);
let r_len = self.context().trace_len().ilog2();

let mut assertion_value = E::ONE;
for idx in 0..r_len {
assertion_value *= E::ONE - r[idx as usize];
}

assertion_value
};

Some(Assertion::single(lagrange_column_idx, 0, assertion_value))
}

/// Returns values for all periodic columns used in the computation.
///
/// These values will be used to compute column values at specific states of the computation
Expand Down Expand Up @@ -406,13 +384,19 @@ pub trait Air: Send + Sync {
boundary_composition_coefficients: &[E],
lagrange_kernel_boundary_coefficient: Option<E>,
) -> BoundaryConstraints<E> {
let lagrange_kernel_aux_rand_elements = if self.context().has_lagrange_kernel_aux_column() {
self.lagrange_kernel_rand_elements(aux_rand_elements.get_segment_elements(0))
} else {
&[]
};

BoundaryConstraints::new(
self.context(),
self.get_assertions(),
self.get_aux_assertions(aux_rand_elements),
self.get_lagrange_kernel_aux_assertion(aux_rand_elements),
boundary_composition_coefficients,
lagrange_kernel_boundary_coefficient,
lagrange_kernel_aux_rand_elements,
)
}

Expand Down
20 changes: 9 additions & 11 deletions prover/src/constraints/evaluator/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use super::{
};
use air::{
trace_aux_segment_has_only_lagrange_kernel_column, Air, AuxTraceRandElements,
ConstraintCompositionCoefficients, ConstraintDivisor, EvaluationFrame,
LagrangeKernelBoundaryConstraint, LagrangeKernelTransitionConstraints, TransitionConstraints,
ConstraintCompositionCoefficients, EvaluationFrame, LagrangeKernelBoundaryConstraint,
LagrangeKernelTransitionConstraints, TransitionConstraints,
};
use math::FieldElement;
use utils::{collections::*, iter_mut};
Expand Down Expand Up @@ -40,7 +40,7 @@ pub struct DefaultConstraintEvaluator<'a, A: Air, E: FieldElement<BaseField = A:
air: &'a A,
boundary_constraints: BoundaryConstraints<E>,
transition_constraints: TransitionConstraints<E>,
lagrange_kernel_boundary_constraint: Option<LagrangeKernelBoundaryConstraint<E, E>>,
lagrange_kernel_boundary_constraint: Option<LagrangeKernelBoundaryConstraint<E>>,
lagrange_kernel_transition_constraints: Option<LagrangeKernelTransitionConstraints<E>>,
aux_rand_elements: AuxTraceRandElements<E>,
periodic_values: PeriodicValueTable<E::BaseField>,
Expand Down Expand Up @@ -172,17 +172,15 @@ where
composition_coefficients.lagrange_kernel_boundary,
);

let lagrange_kernel_boundary_constraint =
air.get_lagrange_kernel_aux_assertion(&aux_rand_elements).map(|assertion| {
let lagrange_kernel_boundary_coefficient = composition_coefficients
.lagrange_kernel_boundary
.expect("expected Lagrange boundary coefficient to be present");
let divisor = ConstraintDivisor::from_assertion(&assertion, air.trace_length());
let lagrange_kernel_boundary_constraint = composition_coefficients
.lagrange_kernel_boundary
.map(|lagrange_kernel_boundary_coefficient| {
let lagrange_kernel_aux_rand_elements =
air.lagrange_kernel_rand_elements(aux_rand_elements.get_segment_elements(0));

LagrangeKernelBoundaryConstraint::new(
assertion,
lagrange_kernel_boundary_coefficient,
divisor,
lagrange_kernel_aux_rand_elements,
)
});

Expand Down
30 changes: 14 additions & 16 deletions prover/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use super::{matrix::MultiColumnIter, ColMatrix};
use air::{
trace_aux_segment_has_only_lagrange_kernel_column, Air, AuxTraceRandElements, EvaluationFrame,
TraceInfo,
LagrangeKernelBoundaryConstraint, TraceInfo,
};
use math::{polynom, FieldElement, StarkField};

Expand Down Expand Up @@ -155,21 +155,19 @@ pub trait Trace: Sized {
}

// then, check the Lagrange kernel assertion, if any
if let Some(assertion) = air.get_lagrange_kernel_aux_assertion(aux_rand_elements) {
let lagrange_kernel_col_idx = air
.context()
.lagrange_kernel_aux_column_idx()
.expect("Lagranged kernel column idx expected to be present");
assertion.apply(self.length(), |step, value| {
assert_eq!(
value,
aux_segments[0].get(lagrange_kernel_col_idx, step),
"trace does not satisfy assertion aux_trace({}, {}) == {}",
lagrange_kernel_col_idx,
step,
value
)
})
if let Some(lagrange_kernel_col_idx) = air.context().lagrange_kernel_aux_column_idx() {
let lagrange_kernel_aux_rand_elements =
air.lagrange_kernel_rand_elements(aux_rand_elements.get_segment_elements(0));

let boundary_constraint_assertion_value =
LagrangeKernelBoundaryConstraint::assertion_value(
lagrange_kernel_aux_rand_elements,
);

assert_eq!(
boundary_constraint_assertion_value,
aux_segments[0].get(lagrange_kernel_col_idx, 0)
);
}

// --- 2. make sure this trace satisfies all transition constraints -----------------------
Expand Down
2 changes: 1 addition & 1 deletion verifier/src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub fn evaluate_constraints<A: Air, E: FieldElement<BaseField = A::BaseField>>(
air.lagrange_kernel_rand_elements(aux_rand_elements.get_segment_elements(0));

result += lagrange_kernel_transition_constraints.evaluate_and_combine::<E>(
&lagrange_kernel_column_frame,
lagrange_kernel_column_frame,
lagrange_kernel_column_rand_elements,
x,
);
Expand Down

0 comments on commit a3377d9

Please sign in to comment.