-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Lagrange kernel constraints (#247)
- Loading branch information
Showing
39 changed files
with
1,900 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use math::FieldElement; | ||
|
||
use crate::LagrangeKernelEvaluationFrame; | ||
|
||
#[derive(Debug, Clone, Eq, PartialEq)] | ||
pub struct LagrangeKernelBoundaryConstraint<E> | ||
where | ||
E: FieldElement, | ||
{ | ||
assertion_value: E, | ||
composition_coefficient: E, | ||
} | ||
|
||
impl<E> LagrangeKernelBoundaryConstraint<E> | ||
where | ||
E: FieldElement, | ||
{ | ||
/// Creates a new Lagrange kernel boundary constraint. | ||
pub fn new(composition_coefficient: E, lagrange_kernel_rand_elements: &[E]) -> Self { | ||
Self { | ||
assertion_value: Self::assertion_value(lagrange_kernel_rand_elements), | ||
composition_coefficient, | ||
} | ||
} | ||
|
||
/// Returns the evaluation of the boundary constraint at `x`, multiplied by the composition | ||
/// coefficient. | ||
/// | ||
/// `frame` is the evaluation frame of the Lagrange kernel column `c`, starting at `c(x)` | ||
pub fn evaluate_at(&self, x: E, frame: &LagrangeKernelEvaluationFrame<E>) -> E { | ||
let numerator = self.evaluate_numerator_at(frame); | ||
let denominator = self.evaluate_denominator_at(x); | ||
|
||
numerator / denominator | ||
} | ||
|
||
/// Returns the evaluation of the boundary constraint numerator, multiplied by the composition | ||
/// coefficient. | ||
/// | ||
/// `frame` is the evaluation frame of the Lagrange kernel column `c`, starting at `c(x)` for | ||
/// some `x` | ||
pub fn evaluate_numerator_at(&self, frame: &LagrangeKernelEvaluationFrame<E>) -> E { | ||
let trace_value = frame.inner()[0]; | ||
let constraint_evaluation = trace_value - self.assertion_value; | ||
|
||
constraint_evaluation * self.composition_coefficient | ||
} | ||
|
||
/// Returns the evaluation of the boundary constraint denominator at point `x`. | ||
pub fn evaluate_denominator_at(&self, x: E) -> E { | ||
x - E::ONE | ||
} | ||
|
||
/// 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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use alloc::vec::Vec; | ||
use math::{polynom, FieldElement, StarkField}; | ||
|
||
/// The evaluation frame for the Lagrange kernel. | ||
/// | ||
/// The Lagrange kernel's evaluation frame is different from [`crate::EvaluationFrame`]. | ||
/// Specifically, | ||
/// - it only contains evaluations from the Lagrange kernel column compared to all columns in the | ||
/// case of [`crate::EvaluationFrame`]) | ||
/// - The column is evaluated at points `x`, `gx`, `g^2 x`, ..., `g^(2^(v-1)) x`, where `x` is an | ||
/// arbitrary point, and `g` is the trace domain generator | ||
#[derive(Debug, Clone)] | ||
pub struct LagrangeKernelEvaluationFrame<E: FieldElement> { | ||
frame: Vec<E>, | ||
} | ||
|
||
impl<E: FieldElement> LagrangeKernelEvaluationFrame<E> { | ||
// CONSTRUCTORS | ||
// -------------------------------------------------------------------------------------------- | ||
|
||
/// Constructs a Lagrange kernel evaluation frame from the raw column polynomial evaluations. | ||
pub fn new(frame: Vec<E>) -> Self { | ||
Self { frame } | ||
} | ||
|
||
/// Constructs an empty Lagrange kernel evaluation frame from the raw column polynomial | ||
/// evaluations. The frame can subsequently be filled using [`Self::frame_mut`]. | ||
pub fn new_empty() -> Self { | ||
Self { frame: Vec::new() } | ||
} | ||
|
||
/// Constructs the frame from the Lagrange kernel column trace polynomial coefficients for an | ||
/// evaluation point. | ||
pub fn from_lagrange_kernel_column_poly(lagrange_kernel_col_poly: &[E], z: E) -> Self { | ||
let log_trace_len = lagrange_kernel_col_poly.len().ilog2(); | ||
let g = E::from(E::BaseField::get_root_of_unity(log_trace_len)); | ||
|
||
let mut frame = Vec::with_capacity(log_trace_len as usize + 1); | ||
|
||
// push c(x) | ||
frame.push(polynom::eval(lagrange_kernel_col_poly, z)); | ||
|
||
// push c(z * g), c(z * g^2), c(z * g^4), ..., c(z * g^(2^(v-1))) | ||
let mut g_exp = g; | ||
for _ in 0..log_trace_len { | ||
let x = g_exp * z; | ||
let lagrange_poly_at_x = polynom::eval(lagrange_kernel_col_poly, x); | ||
|
||
frame.push(lagrange_poly_at_x); | ||
|
||
// takes on the values `g`, `g^2`, `g^4`, `g^8`, ... | ||
g_exp *= g_exp; | ||
} | ||
|
||
Self { frame } | ||
} | ||
|
||
// MUTATORS | ||
// -------------------------------------------------------------------------------------------- | ||
|
||
/// Returns a mutable reference to the inner frame. | ||
pub fn frame_mut(&mut self) -> &mut Vec<E> { | ||
&mut self.frame | ||
} | ||
|
||
// ACCESSORS | ||
// -------------------------------------------------------------------------------------------- | ||
|
||
/// Returns a reference to the inner frame. | ||
pub fn inner(&self) -> &[E] { | ||
&self.frame | ||
} | ||
|
||
/// Returns the number of rows in the frame. | ||
/// | ||
/// This is equal to `log(trace_length) + 1`. | ||
pub fn num_rows(&self) -> usize { | ||
self.frame.len() | ||
} | ||
} |
Oops, something went wrong.