Cross-Table Lookups

The various STARK tables carry out independent operations, but on shared values. We need to check that the shared values are identical in all the STARKs that require them. This is where cross-table lookups (CTLs) come in handy.

Suppose STARK requires an operation -- say -- that is carried out by another STARK . Then writes the input and output of in its own table, and provides the inputs to . also writes the inputs and outputs in its rows, and the table's constraints check that is carried out correctly. We then need to ensure that the inputs and outputs are the same in and .

In other words, we need to ensure that the rows -- reduced to the input and output columns -- of calling are permutations of the rows of that carry out . Our CTL protocol is based on logUp and is similar to our range-checks.

To prove this, the first step is to only select the rows of interest in and , and filter out the rest. Let be the filter for and the filter for . and are constrained to be in . (resp. ) whenever the row at hand carries out in (resp. in ), and 0 otherwise. Let also be two random challenges.

The idea is to create subtables and of and respectively, such that and for all their rows. The columns in the subtables are limited to the ones whose values must be identical (the inputs and outputs of in our example).

Note that for design and constraint reasons, filters are limited to (at most) degree 2 combinations of columns.

Let be the columns in an be the columns in .

The prover defines a "running sum" for such that:

The second equation "selects" the terms of interest thanks to and filters out the rest.

Similarly, the prover constructs a running sum for . Note that is computed "upside down": we start with and the final sum is in .

On top of the constraints to check that the running sums were correctly constructed, the verifier checks that . This ensures that the columns in and the columns in are permutations of each other.

In other words, the CTL argument is a logUp lookup argument where is the looking table, is the looked table, and (all the multiplicities are 1). For more details about logUp, see the next section.

To sum up, for each STARK , the prover:

  1. constructs a running sum for each table looking into (called looking sums here),

  2. constructs a running sum for (called looked sum here),

  3. sends the final value for each running sum and to the verifier,

  4. sends a commitment to and to the verifier.

Then, for each STARK , the verifier:

  1. computes the sum ,

  2. checks that ,

  3. checks that each and was correctly constructed.