The PSE's zkEVM circuits have a variety of helpful 'gadgets' for various functionalities.
One of these is the LTChip
gadget, which is used for checking, given inputs lhs
and rhs
, whether lhs < rhs
holds true. It can be used as a helper as a part of various larger circuits, something like this:
Here, LTConfig
is the configuration for the gadget as defined in the zkevm-circuits. But how does it look like and work under the hood and what limitations does it possess?
LTConfig
The default LTConfig
is defined in the following manner:
What this means is that the configuration looks something like this:
lt | diff[0] | diff[1] | diff [2] | … | diff[N_BYTES-1] | u8 |
---|---|---|---|---|---|---|
1 | 0xff |
0xff |
0xff |
… | 0xff |
The column contains a lookup table u8
which can be used to perform a range check on the value of each byte, 1 advice column for the lt
status (1 if lhs<rhs
and 0 otherwise) and the 2N_BYTES advice columns for the difference.
diff[0], diff[1], diff[2] .... diff[N_BYTES-1]
denote the respective bytes of the difference of the LHS and RHS.
Remember the range
field in the LTConfig
struct? This will come into play now. range
is defined as NUM_BYTES*8
(basically the decimal range in which the LHS and RHS will lie)
This difference is calculated using the following high level logic:
What this logic does is that it prevents overflow by adding range
in case lhs<rhs
and this comes in handy when constraining the circuit as well.
Now, we constrain the "larger" circuit with the following conditions:
Check the fact that, given inputs lhs
and rhs
to the circuit, lhs - rhs - difference + (range*lt) == 0
The lt
value is a boolean.
We use this gadget in Summa, and the main issue here is that this 'horizontal' approach results in a huge number of advice columns.
Specifically, for our use case, N_BYTES = 31
and hence this results in 31 advice columns for difference in the LTChip
alone. We need to reduce this to 3.