Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Lagrange kernel constraints #247

Merged
merged 237 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
237 commits
Select commit Hold shift + click to select a range
9d6517f
add Air::lagrange_kernel
plafer Feb 15, 2024
1583e0a
LagrangeKernelMockAir scaffold
plafer Feb 15, 2024
3342acf
air: `TraceInfo` no longer uses `TraceLayout`
plafer Feb 15, 2024
23bdeb2
prover: propagate `TraceInfo` changes
plafer Feb 15, 2024
ebb1ced
examples: propagate change
plafer Feb 15, 2024
606a0ff
fix context serialization test
plafer Feb 15, 2024
1076a7d
revert `TraceTable` name changes
plafer Feb 15, 2024
44da0d4
test: `TraceInfo::to_elements()`
plafer Feb 15, 2024
520bb9b
remove `TraceLayout`
plafer Feb 15, 2024
6bc46ba
clippy
plafer Feb 15, 2024
0d41ad8
fix comment
plafer Feb 15, 2024
c7d888d
bytes_to_element_with_padding
plafer Feb 15, 2024
564da7c
use `vec![]` instead of `Vec::new()`
plafer Feb 15, 2024
c53ef5a
Merge branch 'plafer-merge-trace-info-layout' into plafer-lagrange-ke…
plafer Feb 15, 2024
a82bc0d
`TraceInfo`: knows about lagrange kernel column
plafer Feb 15, 2024
047353f
TraceInfo: lagrange kernel column index getter
plafer Feb 15, 2024
e372670
`AirContext`: if lagrange kernel is active, we don't need more constr…
plafer Feb 15, 2024
239b60d
`Air`: rename `lagrange_kernel_aux_column_idx`
plafer Feb 15, 2024
49f9b27
implement test prover
plafer Feb 15, 2024
04b878e
LagrangeMockTrace
plafer Feb 15, 2024
47e2acc
test_lagrange_kernel_air
plafer Feb 15, 2024
cdbb1e3
fix check in `AirContext`
plafer Feb 15, 2024
bbf8f30
`TraceInfo::aux_segment_has_only_lagrange_kernel_column`
plafer Feb 16, 2024
178f1ec
verify: check if lagrange kernel column is alone
plafer Feb 16, 2024
c809dfc
`DefaultConstraintEvaluator`: don't evaluate full if only lagrange ke…
plafer Feb 16, 2024
478d056
TraceOodFrame: add lagrange kernel constraint evaluations getter
plafer Feb 16, 2024
1c00435
verification: pass in lagrange kernel evaluations
plafer Feb 16, 2024
fc06c14
lagrange column idx: now fetch from `AirContext` instead of `Air`
plafer Feb 16, 2024
862af68
`Air::evaluate_lagrange_kernel_transition()`
plafer Feb 16, 2024
8ebdef4
LagrangeKernelTransitionConstraints
plafer Feb 16, 2024
450ecf1
ConstraintCompositionCoefficients: add the ones for lagrange kernel t…
plafer Feb 16, 2024
2d20d30
verifier: evaluate lagrange transition constraints
plafer Feb 16, 2024
4b2b8d5
verifier: evaluate lagrange kernel boundary constraint
plafer Feb 17, 2024
2f6bf50
rename lagrange air methods
plafer Feb 17, 2024
cca2ad6
implement `get_lagrange_kernel_aux_assertion`
plafer Feb 17, 2024
3e0122c
docstring: `TraceInfo::new_multi_segment`
plafer Feb 20, 2024
c31d18c
`get_trace_info()` -> `trace_info()`
plafer Feb 20, 2024
a0fdbfc
Rename Trace::get_info
plafer Feb 20, 2024
b27664b
fmt
plafer Feb 20, 2024
d85700a
Reintroduce `Trace::length`
plafer Feb 20, 2024
eef2453
Fix docstrings
plafer Feb 20, 2024
f854979
Use `Trace::length()`
plafer Feb 20, 2024
9cdd508
Reintroduce `Trace::{main,aux}_trace_width()`
plafer Feb 20, 2024
9d3296f
update docstrings
plafer Feb 20, 2024
81cde9d
reorg `StarkField` methods
plafer Feb 20, 2024
8359b00
Introduce `StarkField::from_byte_vec_with_padding`
plafer Feb 20, 2024
44b4961
Use `StarkField::from_byte_vec_with_padding`
plafer Feb 20, 2024
e5e762f
Merge branch 'plafer-merge-trace-info-layout' into plafer-lagrange-ke…
plafer Feb 20, 2024
2ac004c
docstring
plafer Feb 21, 2024
0f189b2
docstring fix
plafer Feb 21, 2024
8acf5c8
fix internal section separator
plafer Feb 21, 2024
b428665
add comment
plafer Feb 21, 2024
a40e0ee
Merge branch 'plafer-merge-trace-info-layout' into plafer-lagrange-ke…
plafer Feb 21, 2024
65bb928
TracePolyTable: know about lagrange kernel col
plafer Feb 21, 2024
6e94ccc
`TracePolyTable::get_ood_frame` now returns lagrange kernel frame
plafer Feb 21, 2024
a91e4b8
export LagrangeKernelTransitionConstraints
plafer Feb 21, 2024
e7d2511
Change `from_bytes_with_padding` signature
plafer Feb 21, 2024
98d3372
Merge branch 'plafer-merge-trace-info-layout' into plafer-lagrange-ke…
plafer Feb 21, 2024
2071fc4
Merge remote-tracking branch 'upstream/main' into plafer-merge-trace-…
plafer Feb 21, 2024
6a52469
Merge branch 'plafer-merge-trace-info-layout' into plafer-lagrange-ke…
plafer Feb 21, 2024
35ebd38
fix prover evaluator: call always `evaluate_fragment_full()` on non-e…
plafer Feb 21, 2024
2ab7732
export LagrangeKernelTransitionConstraints
plafer Feb 21, 2024
35742d6
rename fn
plafer Feb 21, 2024
5f945a5
fix typo
plafer Feb 21, 2024
5954c1b
Merge `TraceLayout` into `TraceInfo` (#245)
plafer Feb 21, 2024
ae05235
Merge branch 'plafer-merge-trace-info-layout' into plafer-lagrange-ke…
plafer Feb 21, 2024
8f35f80
update comment
plafer Feb 22, 2024
867fbce
`ConstraintEvaluationTable::combine()` returns the raw evaluations
plafer Feb 22, 2024
df07895
DefaultConstraintEvaluator: prepare for LagrangeKernelConstraints
plafer Feb 22, 2024
66dc757
`TraceLde`: add method to return lagrange kernel column frame
plafer Feb 22, 2024
6449619
`DefaultConstraintEvaluator`: evaluate Lagrange kernel transition con…
plafer Feb 22, 2024
849795a
var name
plafer Feb 22, 2024
a8a8062
`DefaultConstraintEvaluator`: add lagrange_kernel_boundary_constraint
plafer Feb 22, 2024
3efe11c
refactor names
plafer Feb 22, 2024
f0cabbf
eval boundary constraint prover
plafer Feb 23, 2024
ea9d524
remove assert
plafer Feb 23, 2024
68abe22
prover: pass in lagrange kernel boundary coefficient
plafer Feb 23, 2024
c3f0b60
`num_constraint_composition_columns`: hack to make test pass
plafer Feb 23, 2024
473184b
poly_table: fix vec access
plafer Feb 24, 2024
72d3c4e
`OodFrame`: Actually include Lagrange kernel frame
plafer Feb 24, 2024
fd61adc
make test more debuggable
plafer Feb 24, 2024
1790793
verifier: fix how public coin is reseeded after ood constraints
plafer Feb 24, 2024
afc4d4c
verifier: evaluate ood lagrange constraints after main/aux
plafer Feb 24, 2024
3e6d1ab
add question
plafer Feb 25, 2024
829e2e8
`get_ood_frame`: fix lagrange kernel frame
plafer Feb 25, 2024
d310a7f
fix comment
plafer Feb 25, 2024
4c24faf
var name change
plafer Feb 25, 2024
fb75bbd
fix transition constraint evaluations
plafer Feb 25, 2024
c3078b3
improve test: increment by one
plafer Feb 26, 2024
4e2927e
TraceLde: fix lagrange kernel column frame
plafer Feb 26, 2024
a22d6e3
fix Lagrange kernel frame
plafer Feb 26, 2024
05aa44e
Merge remote-tracking branch 'upstream/next' into plafer-lagrange-kernel
plafer Feb 27, 2024
b9e609c
export `LagrangeKernelEvaluationFrame`
plafer Feb 28, 2024
d3afb99
Use `LagrangeKernelEvaluationFrame`
plafer Feb 28, 2024
cbd8624
Use `LagrangeKernelEvaluationFrame` in Air
plafer Feb 28, 2024
9c8a6bd
use `Vec` for nostd
plafer Feb 28, 2024
0669c08
LagrangeKernelBoundaryConstraint
plafer Feb 28, 2024
9979f0e
verifier: use LagrangeKernelBoundaryConstraint
plafer Feb 28, 2024
7c5f0a7
prover: use `LagrangeKernelBoundaryConstraint`
plafer Feb 28, 2024
2570f56
fix vec no_std
plafer Feb 28, 2024
68a7e99
fix clippy
plafer Feb 28, 2024
dee9c05
use map instead of match
plafer Feb 29, 2024
b8b7afa
fix `AirContext::num_constraint_composition_columns`
plafer Feb 29, 2024
66d4f13
document `LagrangeKernelTransitionConstraints`
plafer Feb 29, 2024
c6e9fc1
write stubbed out `expect()` messages
plafer Feb 29, 2024
c685542
document and refactor
plafer Mar 1, 2024
b2688bb
Document `LagrangeKernelEvaluationFrame`
plafer Mar 1, 2024
f396410
Make `ParsedOodFrame` a struct
plafer Mar 1, 2024
32128d6
OodFrame docs
plafer Mar 1, 2024
98d16e0
Remove outdated TODO
plafer Mar 1, 2024
7b8fd82
prover trace validation: Lagrange kernel assertion
plafer Mar 1, 2024
1e2a9df
`trace::evaluate()`: check lagrange kernel constraints
plafer Mar 2, 2024
7afc04b
cleanup
plafer Mar 2, 2024
1daa63a
`TraceInfo` serialization test
plafer Mar 2, 2024
589f959
refactor `TraceInfo`
plafer Mar 3, 2024
d92a94d
Make which random elements to use for lagrange kernel column explicit
plafer Mar 3, 2024
eb13b3e
remove "all"
plafer Mar 7, 2024
3b116df
reword comment
plafer Mar 7, 2024
ae53ec5
add period
plafer Mar 7, 2024
396aa1f
reword comment
plafer Mar 7, 2024
8ecd0d9
fix rows -> columns
plafer Mar 7, 2024
dd29e3a
comment: add period
plafer Mar 7, 2024
4fc1832
fix comment
plafer Mar 7, 2024
29e22f7
comment: add period
plafer Mar 7, 2024
a19c041
grammar fix
plafer Mar 7, 2024
5ee7352
capitalize
plafer Mar 7, 2024
1096a49
fix comment
plafer Mar 7, 2024
9193897
capitalize
plafer Mar 7, 2024
8544e17
fix comment width
plafer Mar 7, 2024
880f5ef
TraceInfo: remove aux_segment_has_only_lagrange_kernel_column()
plafer Mar 12, 2024
2ed8c7e
Make `AirContext` hold the lagrange kernel column idx
plafer Mar 12, 2024
9aa7bc5
Move `TraceInfo::has_lagrange_kernel_aux_column()` to `AirContext`
plafer Mar 12, 2024
37a322b
move lagrange column idx to `AirContext`
plafer Mar 12, 2024
922be9e
log2 -> ilog2
plafer Mar 12, 2024
dbe5326
`row()` -> `get()`
plafer Mar 12, 2024
8897f5e
z -> x
plafer Mar 12, 2024
27301b6
Prover: use `LagrangeKernelTransitionConstraints::evaluate_and_combin…
plafer Mar 12, 2024
881cf16
verifier: use `evaluate_and_combine()`
plafer Mar 12, 2024
d1bb2b7
Remove `Air::get_lagrange_kernel_transition_constraints`
plafer Mar 12, 2024
a3377d9
Refactor `LagrangeKernelBoundaryConstraint`
plafer Mar 12, 2024
454c60b
Remove `ood` prefix
plafer Mar 12, 2024
3e9062e
z -> x
plafer Mar 12, 2024
cc4ef88
row() -> get()
plafer Mar 12, 2024
a4b8065
Remove `trace_aux_segment_has_only_lagrange_kernel_column`
plafer Mar 13, 2024
3a4c457
remove use of `exp_vartime`
plafer Mar 13, 2024
ef5dc1d
`lagrange_kernel_frame` renaming
plafer Mar 13, 2024
45783ec
read_lagrange_kernel_frame_into
plafer Mar 13, 2024
51deff8
optimize prover performance for Lagrange boundary constraint evaluation
plafer Mar 13, 2024
360dde1
LagrangeKernelTransitionConstraints::evaluate_numerators
plafer Mar 13, 2024
80f8141
remove assertion
plafer Mar 13, 2024
cb64e2d
remove `Air::lagrange_kernel_rand_elements`
plafer Mar 13, 2024
4a513ec
Introduce LagrangeConstraintsCompositionCoefficients
plafer Mar 14, 2024
589fc8a
LagrangeTrace benchmark
plafer Mar 14, 2024
3c9c5ea
benchmark air and prover
plafer Mar 14, 2024
cb7ecb3
write benchmark
plafer Mar 14, 2024
8b9f24d
ref var
plafer Mar 15, 2024
22eb9a6
lagrange transition constraint evaluation optimization
plafer Mar 15, 2024
a03bb25
don't compute repeating denominators
plafer Mar 15, 2024
e68ffa1
only evaluate lagrange frame once
plafer Mar 15, 2024
d80ac67
reorganize function
plafer Mar 15, 2024
60ec574
make `evaluate_numerators` private
plafer Mar 15, 2024
bab3c66
LagrangeConstraintsBatchEvaluator
plafer Mar 15, 2024
0de21f3
cleanup LagrangeConstraintsBatchEvaluator
plafer Mar 15, 2024
89728fd
docstring LagrangeKernelTransitionConstraints
plafer Mar 15, 2024
e570495
document LagrangeConstraintsBatchEvaluator
plafer Mar 15, 2024
f13d602
clippy
plafer Mar 15, 2024
40a3b06
Merge branch 'main' into plafer-lagrange-kernel
plafer Mar 18, 2024
05efd34
move `LagrangeKernelTransitionConstraints` to `air/lagrange`
plafer Mar 18, 2024
c60448f
Move `LagrangeKernelBoundaryConstraint` to `air/lagrange`
plafer Mar 18, 2024
3acdefd
move `LagrangeKernelEvaluationFrame`
plafer Mar 18, 2024
3a7ddfe
introduce lagrange/{boundary, transition} modules
plafer Mar 18, 2024
1b68cac
Remove Lagrange kernel boundary constraint from `BoundaryConstraints`
plafer Mar 18, 2024
bcf7304
move `Option` in wrapping structs
plafer Mar 18, 2024
41cae6c
`LagrangeConstraintsBatchEvaluator`: store Lagrange rand elements
plafer Mar 18, 2024
aacb8e5
`LagrangeKernelConstraintsBatchEvaluator` naming
plafer Mar 18, 2024
5b679a1
constraints/evaluator/lagrange mod
plafer Mar 18, 2024
57c71df
Introduce `LagrangeKernelConstraints`
plafer Mar 18, 2024
b61353a
fix benchmark trace lengths
plafer Mar 18, 2024
7b65565
write complex test
plafer Mar 18, 2024
b3c7688
fix test/bench
plafer Mar 18, 2024
628b83e
Merge remote-tracking branch 'upstream/next' into plafer-lagrange-kernel
plafer Mar 18, 2024
e45ef8c
Add `LagrangeKernelTransitionConstraints::len()`
plafer Mar 18, 2024
a4aecfd
Introduce `LagrangeKernelTransitionConstraintsDivisor`
plafer Mar 18, 2024
f15faf1
evaluate_lagrange_kernel_constraints_2
plafer Mar 19, 2024
f1f726f
fix index precomputes
plafer Mar 19, 2024
35c9413
use `Vec::with_capacity`
plafer Mar 19, 2024
8cfa8ad
cleanup
plafer Mar 19, 2024
9132ffe
cleanup evaluate_lagrange_kernel_constraints
plafer Mar 19, 2024
1cd4c9e
document vector capacity
plafer Mar 19, 2024
9ba472d
remove TODO
plafer Mar 19, 2024
bfb381f
remove unecessary `A` generic param
plafer Mar 19, 2024
12e9280
clippy
plafer Mar 19, 2024
64cca23
frame: don't instantiante new one on each iteration
plafer Mar 19, 2024
9ea6c2d
remove useless constructor
plafer Mar 19, 2024
28bbea3
update comment
plafer Mar 19, 2024
911fe48
update comment
plafer Mar 19, 2024
5db85fa
wrap comment
plafer Mar 19, 2024
628bca7
fix docs
plafer Mar 19, 2024
a6d9491
format doc
plafer Mar 19, 2024
0404920
var name
plafer Mar 19, 2024
f7c70bc
remove `as usize`
plafer Mar 19, 2024
989b88e
var name
plafer Mar 19, 2024
7611aa9
var name
plafer Mar 19, 2024
29796b9
TransitionDivisorEvaluator
plafer Mar 19, 2024
7a8b23a
domain_idx: modulo domain size
plafer Mar 19, 2024
1e80a09
fix divisor
plafer Mar 19, 2024
e80df1e
remove dead code
plafer Mar 19, 2024
ca27645
docstring
plafer Mar 19, 2024
2da7312
fmt
plafer Mar 19, 2024
ce5227c
docstring `evaluate_at()`
plafer Mar 20, 2024
aa6ce84
comment line wrap
plafer Mar 20, 2024
3032660
use `air.get_lagrange_kernel_constraints()`
plafer Mar 20, 2024
0eb5c3c
remove useless check
plafer Mar 20, 2024
8c5758a
add lagrange col idx to LagrangeKernelConstraints
plafer Mar 20, 2024
7c74d89
`evaluate_lagrange_kernel_constraints` no longer returns a `Vec`
plafer Mar 20, 2024
f47e107
optimize `TransitionDivisorEvaluator::new()`
plafer Mar 20, 2024
d96c220
boundary_denominator_evals: use `uninit_vector()`
plafer Mar 21, 2024
9a190d4
from_lagrange_kernel_column_poly: use uninit_vector
plafer Mar 21, 2024
63aa20d
Revert "boundary_denominator_evals: use `uninit_vector()`"
plafer Mar 21, 2024
b5cf5e1
Revert "from_lagrange_kernel_column_poly: use uninit_vector"
plafer Mar 21, 2024
844eed9
var name
plafer Mar 25, 2024
2637eb2
update comment and varname
plafer Mar 25, 2024
2816de5
document `evaluate_lagrange_kernel_constraints`
plafer Mar 25, 2024
52efde0
Remove `context` argument from `LagrangeKernelConstraints`
plafer Mar 25, 2024
40ba874
Remove redundant check
plafer Mar 25, 2024
2c168c7
docstring
plafer Mar 25, 2024
f76ebf8
change naming to `evaluate_constraints`
plafer Mar 25, 2024
59e1f2b
`OodFrameTraceStates`: rename to `current_row` and `next_row`
plafer Mar 25, 2024
212265f
remove comment
plafer Mar 25, 2024
b109af9
///
plafer Mar 25, 2024
5953864
comment: "a constraint composition polynomial"
plafer Mar 25, 2024
526c7e9
Var name in `ConstraintDivisor::from_transition()`
plafer Mar 25, 2024
21a7960
comment
plafer Mar 25, 2024
203b762
comment
plafer Mar 25, 2024
4f84821
comment formatting
plafer Mar 25, 2024
acdd130
fix typo
plafer Mar 25, 2024
8097e57
use (1 << i) instead of 2.pow
plafer Mar 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion air/src/air/boundary/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use math::{fft, polynom};

// BOUNDARY CONSTRAINT
// ================================================================================================

/// The numerator portion of a boundary constraint.
///
/// A boundary constraint is described by a rational function $\frac{f(x) - b(x)}{z(x)}$, where:
Expand Down Expand Up @@ -45,8 +46,9 @@ where
F: FieldElement,
E: FieldElement<BaseField = F::BaseField> + ExtensionOf<F>,
{
// CONSTRUCTOR
// CONSTRUCTORS
// --------------------------------------------------------------------------------------------

/// Creates a new boundary constraint from the specified assertion.
pub(super) fn new(
assertion: Assertion<F>,
Expand Down
8 changes: 8 additions & 0 deletions air/src/air/coefficients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,16 @@ impl<E: FieldElement> Default for AuxTraceRandElements<E> {
pub struct ConstraintCompositionCoefficients<E: FieldElement> {
pub transition: Vec<E>,
pub boundary: Vec<E>,
pub lagrange: Option<LagrangeConstraintsCompositionCoefficients<E>>,
}

/// Stores the constraint composition coefficients for the Lagrange kernel transition and boundary
/// constraints.
#[derive(Debug, Clone)]
pub struct LagrangeConstraintsCompositionCoefficients<E: FieldElement> {
pub transition: Vec<E>,
pub boundary: E,
}
// DEEP COMPOSITION COEFFICIENTS
// ================================================================================================
/// Coefficients used in construction of DEEP composition polynomial.
Expand Down
76 changes: 52 additions & 24 deletions air/src/air/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct AirContext<B: StarkField> {
pub(super) aux_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
pub(super) num_main_assertions: usize,
pub(super) num_aux_assertions: usize,
pub(super) lagrange_kernel_aux_column_idx: Option<usize>,
pub(super) ce_blowup_factor: usize,
pub(super) trace_domain_generator: B,
pub(super) lde_domain_generator: B,
Expand Down Expand Up @@ -59,6 +60,7 @@ impl<B: StarkField> AirContext<B> {
Vec::new(),
num_assertions,
0,
None,
options,
)
}
Expand Down Expand Up @@ -91,6 +93,7 @@ impl<B: StarkField> AirContext<B> {
aux_transition_constraint_degrees: Vec<TransitionConstraintDegree>,
num_main_assertions: usize,
num_aux_assertions: usize,
lagrange_kernel_aux_column_idx: Option<usize>,
options: ProofOptions,
) -> Self {
assert!(
Expand All @@ -103,7 +106,7 @@ impl<B: StarkField> AirContext<B> {
assert!(
!aux_transition_constraint_degrees.is_empty(),
"at least one transition constraint degree must be specified for auxiliary trace segments"
);
);
assert!(
num_aux_assertions > 0,
"at least one assertion must be specified against auxiliary trace segments"
Expand All @@ -119,6 +122,11 @@ impl<B: StarkField> AirContext<B> {
);
}

// validate Lagrange kernel aux column, if any
if let Some(lagrange_kernel_aux_column_idx) = lagrange_kernel_aux_column_idx {
assert!(lagrange_kernel_aux_column_idx < trace_info.get_aux_segment_width(0), "Lagrange kernel column index out of bounds: index={}, but only {} columns in segment", lagrange_kernel_aux_column_idx, trace_info.get_aux_segment_width(0));
}

// determine minimum blowup factor needed to evaluate transition constraints by taking
// the blowup factor of the highest degree constraint
let mut ce_blowup_factor = 0;
Expand Down Expand Up @@ -151,6 +159,7 @@ impl<B: StarkField> AirContext<B> {
aux_transition_constraint_degrees,
num_main_assertions,
num_aux_assertions,
lagrange_kernel_aux_column_idx,
ce_blowup_factor,
trace_domain_generator: B::get_root_of_unity(trace_length.ilog2()),
lde_domain_generator: B::get_root_of_unity(lde_domain_size.ilog2()),
Expand All @@ -161,9 +170,14 @@ impl<B: StarkField> AirContext<B> {
// PUBLIC ACCESSORS
// --------------------------------------------------------------------------------------------

/// Returns the trace info for an instance of a computation.
pub fn trace_info(&self) -> &TraceInfo {
&self.trace_info
}

/// Returns length of the execution trace for an instance of a computation.
///
// This is guaranteed to be a power of two greater than or equal to 8.
/// This is guaranteed to be a power of two greater than or equal to 8.
pub fn trace_len(&self) -> usize {
self.trace_info.length()
}
Expand All @@ -189,12 +203,13 @@ impl<B: StarkField> AirContext<B> {
self.trace_info.length() * self.options.blowup_factor()
}

/// Returns the number of transition constraints for a computation.
/// Returns the number of transition constraints for a computation, excluding the Lagrange
/// kernel transition constraints, which are managed separately.
///
/// The number of transition constraints is defined by the total number of transition
/// constraint degree descriptors (for both the main and the auxiliary trace constraints).
/// This number is used to determine how many transition constraint coefficients need to be
/// generated for merging transition constraints into a composition polynomial.
/// The number of transition constraints is defined by the total number of transition constraint
/// degree descriptors (for both the main and the auxiliary trace constraints). This number is
/// used to determine how many transition constraint coefficients need to be generated for
/// merging transition constraints into a constraint composition polynomial.
pub fn num_transition_constraints(&self) -> usize {
self.main_transition_constraint_degrees.len() + self.aux_transition_constraint_degrees.len()
}
Expand All @@ -209,7 +224,18 @@ impl<B: StarkField> AirContext<B> {
self.aux_transition_constraint_degrees.len()
}

/// Returns the total number of assertions defined for a computation.
/// Returns the index of the auxiliary column which implements the Lagrange kernel, if any
pub fn lagrange_kernel_aux_column_idx(&self) -> Option<usize> {
self.lagrange_kernel_aux_column_idx
}

/// Returns true if the auxiliary trace segment contains a Lagrange kernel column
pub fn has_lagrange_kernel_aux_column(&self) -> bool {
self.lagrange_kernel_aux_column_idx().is_some()
}

/// Returns the total number of assertions defined for a computation, excluding the Lagrange
/// kernel assertion, which is managed separately.
///
/// The number of assertions consists of the assertions placed against the main segment of an
/// execution trace as well as assertions placed against all auxiliary trace segments.
Expand All @@ -230,24 +256,26 @@ impl<B: StarkField> AirContext<B> {
/// Returns the number of columns needed to store the constraint composition polynomial.
///
/// This is the maximum of:
/// 1. The maximum evaluation degree over all transition constraints minus the degree
/// of the transition constraint divisor divided by trace length.
/// 1. The maximum evaluation degree over all transition constraints minus the degree of the
/// transition constraint divisor divided by trace length.
/// 2. `1`, because the constraint composition polynomial requires at least one column.
///
/// Since the degree of a constraint `C(x)` can be well approximated by
/// `[constraint.base + constraint.cycles.len()] * [trace_length - 1]` the degree of the
/// constraint composition polynomial can be approximated by:
/// `([constraint.base + constraint.cycles.len()] * [trace_length - 1] - [trace_length - n])`
/// where `constraint` is the constraint attaining the maximum and `n` is the number of
/// exemption points.
/// In the case `n = 1`, the expression simplifies to:
/// `[constraint.base + constraint.cycles.len() - 1] * [trace_length - 1]`
/// Thus, if each column is of length `trace_length`, we would need
/// `[constraint.base + constraint.cycles.len() - 1]` columns to store the coefficients of
/// the constraint composition polynomial.
/// This means that if the highest constraint degree is equal to `5`, the constraint
/// composition polynomial will require four columns and if the highest constraint degree is
/// equal to `7`, it will require six columns to store.
/// Since the degree of a constraint `C(x)` can be computed as `[constraint.base +
/// constraint.cycles.len()] * [trace_length - 1]` the degree of the constraint composition
/// polynomial can be computed as: `([constraint.base + constraint.cycles.len()] * [trace_length
/// - 1] - [trace_length - n])` where `constraint` is the constraint attaining the maximum and
/// `n` is the number of exemption points. In the case `n = 1`, the expression simplifies to:
/// `[constraint.base + constraint.cycles.len() - 1] * [trace_length - 1]` Thus, if each column
/// is of length `trace_length`, we would need `[constraint.base + constraint.cycles.len() - 1]`
/// columns to store the coefficients of the constraint composition polynomial. This means that
/// if the highest constraint degree is equal to `5`, the constraint composition polynomial will
/// require four columns and if the highest constraint degree is equal to `7`, it will require
/// six columns to store.
///
/// Note that the Lagrange kernel constraints require only 1 column, since the degree of the
/// numerator is `trace_len - 1` for all transition constraints (i.e. the base degree is 1).
/// Hence, no matter what the degree of the divisor is for each, the degree of the fraction will
/// be at most `trace_len - 1`.
pub fn num_constraint_composition_columns(&self) -> usize {
let mut highest_constraint_degree = 0_usize;
for degree in self
Expand Down
28 changes: 14 additions & 14 deletions air/src/air/divisor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,24 @@ impl<B: StarkField> ConstraintDivisor<B> {
///
/// For transition constraints, the divisor polynomial $z(x)$ is always the same:
///
/// $$
/// z(x) = \frac{x^n - 1}{ \prod_{i=1}^k (x - g^{n-i})}
/// $$
/// $$ z(x) = \frac{x^n - 1}{ \prod_{i=1}^k (x - g^{n-i})} $$
///
/// where, $n$ is the length of the execution trace, $g$ is the generator of the trace
/// domain, and $k$ is the number of exemption points. The default value for $k$ is $1$.
/// where, $n$ is the length of the execution trace, $g$ is the generator of the trace domain,
/// and $k$ is the number of exemption points. The default value for $k$ is $1$.
///
/// The above divisor specifies that transition constraints must hold on all steps of the
/// execution trace except for the last $k$ steps.
pub fn from_transition(trace_length: usize, num_exemptions: usize) -> Self {
assert!(
num_exemptions > 0,
"invalid number of transition exemptions: must be greater than zero"
);
irakliyk marked this conversation as resolved.
Show resolved Hide resolved
let exemptions = (trace_length - num_exemptions..trace_length)
.map(|step| get_trace_domain_value_at::<B>(trace_length, step))
/// constraint enforcement domain except for the last $k$ steps. The constraint enforcement
/// domain is the entire trace in the case of transition constraints, but only a subset of the
/// trace for Lagrange kernel transition constraints.
pub fn from_transition(
constraint_enforcement_domain_size: usize,
num_exemptions: usize,
) -> Self {
let exemptions = (constraint_enforcement_domain_size - num_exemptions
..constraint_enforcement_domain_size)
.map(|step| get_trace_domain_value_at::<B>(constraint_enforcement_domain_size, step))
.collect();
Self::new(vec![(trace_length, B::ONE)], exemptions)
Self::new(vec![(constraint_enforcement_domain_size, B::ONE)], exemptions)
}

/// Builds a divisor for a boundary constraint described by the assertion.
Expand Down
63 changes: 63 additions & 0 deletions air/src/air/lagrange/boundary.rs
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
}
}
80 changes: 80 additions & 0 deletions air/src/air/lagrange/frame.rs
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> {
plafer marked this conversation as resolved.
Show resolved Hide resolved
&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()
}
}
Loading
Loading