Figure 1: Range-check lookup
LookupElements
instance using the macro relation!
.
This macro creates an API for performing random linear combinations.
Under the hood, it creates two random values that can create a random linear combination of an arbitrary number of elements.
In our case, we only need to combine one value (value in ), which is why we pass in 1
to the macro.
Inside gen_logup_trace
, we create a LogupTraceGenerator
instance.
This is a helper class that allows us to create LogUp columns.
Every time we create a new column, we need to call new_col()
on the LogupTraceGenerator
instance.
You may notice that we are iterating over BaseColumn
in chunks of 16, or 1 << LOG_N_LANES
values.
This is because we are using the SimdBackend
, which runs 16 lanes simultaneously, so we need to preserve this structure.
The Packed
in PackedSecureField
means that it packs 16 values into a single value.
You may also notice that we are using a SecureField
instead of just the Field
.
This is because the random value we created in LookupElements
will be in the degree-4 extension field .
Interested readers can refer to the Mersenne Primes section for more details.
Once we set the fractions for each simd_row
, we need to call finalize_col()
to finalize the column.
This process modifies the LogUp columns from individual fractions to cumulative sums of the fractions as shown in Figure 2.
Figure 2: Finalizing each LogUp column
finalize_last()
on the LogupTraceGenerator
instance to finalize the LogUp columns, which will return the LogUp columns as well as the sum of the fractions in the LogUp columns.
TestEval
struct as in the previous sections, but the evaluate
function will look slightly different.
Instead of calling add_constraint
on the EvalAtRow
instance, we will call add_to_relation
, which recreates the fractions that we added in the LogUp columns using values in the range-check, lookup, and multiplicity columns.
Once we add the fractions as constraints, we call the finalize_logup_batched
function, which indicates how we want to batch the fractions.
In our case, we added 3 fractions but want to create batches where the last two fractions are batched together, so we pass in &vec![0, 1, 1]
.
claimed_sum
, which is the sum of the fractions in the LogUp columns, is 0.
And that’s it!
We have successfully created a static lookup for a range-check.