pub fn plain_lookup<FS, const LOG_MAX_MULTIPLICITY: usize>(
builder: &mut ConstraintSystemBuilder<'_>,
table: OracleId,
lookup_values: OracleId,
lookup_values_count: usize,
) -> Result<(), Error>
Expand description
Checks values in lookup_values
to be in table
.
§Introduction
This is a gadget for performing a “lookup”, wherein a set of values are claimed by the prover to be a subset of a set of values known to the verifier.
We call the set of values known to the verifier as the “table”, and we call the set of values held by the prover as the “lookup values.”
We represent these sets using oracles table
and lookup_values
as lists of values.
This gadget performs the lookup by verifying that every value in the oracle lookup_vales
appears somewhere in the oracle table
.
§Parameters
builder
: a mutable reference to theConstraintSystemBuilder
.table
: an oracle holding the table of valid lookup values.lookup_values
: an oracle holding the values to be looked up.lookup_values_count
: only the firstlookup_values_count
values inlookup_values
will be looked up.
§How this Works
We create a single channel for this lookup.
We let the prover push all values in lookup_values
, that is all values to be looked up, into the channel.
We also must pull valid table values (i.e. values that appear in table
) from the channel if the channel is to balance.
By ensuring that only valid table values get pulled from the channel, and observing the channel to balance, we ensure that only valid table values get pushed (by the prover) into the channel.
Therefore our construction is sound.
In order for the construction to be complete, allowing an honest prover to pass, we must pull each
table value from the channel with exactly the same multiplicity (duplicate count) that the prover pushed that table value into the channel.
To do so, we allow the prover to commit information on the multiplicity of each table value.
The prover counts the multiplicity of each table value, and creates a bit column for each of the LOG_MAX_MULTIPLICITY bits in the bit-decomposition of the multiplicities. Then we flush the table values LOG_MAX_MULTIPLICITY times, each time using a different bit column as the ‘selector’ oracle to select which values in the table actually get pushed into the channel flushed. When flushing the table with the i’th bit column as the selector, we flush with multiplicity 1 << i.