STARKs protocol

In this section we describe precisely the STARKs protocol used in Lambdaworks.

We begin with some additional considerations and notation for most of the relevant objects and values to refer to them later on.

Grinding

This is a technique to increase the soundness of the protocol by adding proof of work. It works as follows. At some fixed point in the protocol, the prover needs to find a string nonce such that H(H(prefix || state || grinding_factor) || nonce) has grinding_factor number of zeros to the left, where H is a hash function, prefix is the bit-string 0x0123456789abcded and state is the state of the transcript. Here x || y denotes the concatenation of the bit-strings x and y.

Transcript

The Fiat-Shamir heuristic is used to make the protocol noninteractive. We assume there is a transcript object to which values can be added and from which challenges can be sampled.

General notation

  • denotes a finite field.
  • Given a vector and a function , denote by the vector . Here denotes the underlying set of .
  • A polynomial induces a function for every subset of , where .
  • Let be two polynomials. A function can be induced from them for every subset disjoint from the set of roots of , defined by . We abuse notation and denote by .

Definitions

We assume the prover has already obtained the trace of the execution of the program. This is a matrix with entries in a finite field . We assume the number of rows of is for some in .

Values known by the prover and verifier prior to the interactions

These values are determined the program, the specifications of the AIR being used and the security parameters chosen.

  • is the number of columns of the trace matrix .
  • the number of RAP challenges.
  • is the number of extended columns of the trace matrix in the (optional) second round of RAP.
  • is the total number of columns: .
  • denote the transition constraint polynomials for . We are assuming these are of degree at most 2.
  • denote the transition constraint zerofiers for .
  • is the blowup factor.
  • is the grinding factor.
  • is number of FRI queries.
  • We assume there is a fixed hash function from to binary strings. We also assume all Merkle trees are constructed using this hash function.

Values computed by the prover

These values are computed by the prover from the execution trace and are sent to the verifier along with the proof.

  • is the number of rows of the trace matrix after RAP.
  • a primitive -th root of unity.
  • .
  • An element . This is called the coset factor.
  • Boundary constraints polynomials for .
  • Boundary constraint zerofiers for ..

Derived values

Both prover and verifier compute the following.

  • The interpolation domain: the vector .
  • The Low Degree Extension . Recall is the blowup factor.

Notation of important operations

Vector commitment scheme

Given a vector . The operation returns the root of the Merkle tree that has the hash of the elements of as leaves.

For , the operation returns the pair , where is the authentication path to the Merkle tree root.

The operation returns Accept or Reject depending on whether the -th element of is . It checks whether the authentication path is compatible with , and the Merkle tree root .

In our cases the sets will be of the form for some elements . It will be convenient to use the following abuse of notation. We will write to mean . Similarly, we will write instead of . Note that this is only notation and is only checking that the is the -th element of the commited vector.

Batch

As we mentioned in the protocol overview. When committing to multiple vectors , where one can build a single Merkle tree. Its -th leaf is the concatenation of all the -th coordinates of all vectors, that is, . The commitment to this batch of vectors is the root of this Merkle tree.

Protocol

Prover

Round 0: Transcript initialization

  • Start a new transcript.
  • (Strong Fiat Shamir) Add to it all the public values.

Round 1: Arithmetization and commitment of the execution trace

Round 1.1: Commit main trace
  • For each column of the execution trace matrix , interpolate its values at the domain and obtain polynomials such that .
  • Compute for all (Batch commitment optimization applies here).
  • Add to the transcript in increasing order.
Round 1.2: Commit extended trace
  • Sample random values in from the transcript.
  • Use to build following the specifications of the RAP process.
  • For each column of the matrix , interpolate its values at the domain and obtain polynomials such that .
  • Compute for all (Batch commitment optimization applies here).
  • Add to the transcript in increasing order for all .

Round 2: Construction of composition polynomial

  • Sample in from the transcript.
  • Sample in from the transcript.
  • Compute .
  • Compute .
  • Compute the composition polynomial
  • Decompose as
  • Compute commitments and (Batch commitment optimization applies here).
  • Add and to the transcript.

Round 3: Evaluation of polynomials at

  • Sample from the transcript until obtaining .
  • Compute , , and and for all .
  • Add , , and and for all to the transcript.

Round 4: Run batch open protocol

  • Sample , , and , in from the transcript.
  • Compute as
Round 4.1.k: FRI commit phase
  • Let .
  • For do the following:
    • Sample from the transcript.
    • Decompose into even and odd parts, that is, .
    • Define .
    • If :
      • Let . Define , where .
      • Let .
      • Add to the transcript.
  • is a constant polynomial and therefore . Add to the transcript.
Round 4.2: Grinding
  • Let be the internal state of the transcript.
  • Compute such that has leading zeroes.
  • Add to the transcript.
Round 4.3: FRI query phase
  • For do the following:
    • Sample random index from the transcript and let .
    • Compute and for all .
    • Compute and .
    • Compute and .
    • Compute and for all .

Build proof

  • Send the proof to the verifier:

Verifier

From the point of view of the verifier, the proof they receive is a bunch of values that may or may not be what they claim to be. To make this explicit, we avoid denoting values like as such, because that implicitly assumes that the value was obtained after evaluating a polynomial at . And that's something the verifier can't assume. We use the following convention.

  • Bold capital letters refer to commitments. For example is the claimed commitment .
  • Greek letters with superscripts refer to claimed function evaluations. For example is the claimed evaluation and is the claimed evaluation of . Note that field elements in superscripts never indicate powers. They are just notation.
  • Gothic letters refer to authentication paths. For example is the authentication path of a opening of .
  • Recall that every opening is a pair , where is the claimed value at index and is the authentication path. So for example, is denoted as from the verifier's end.

Input

This is the proof using the notation described above. The elements appear in the same exact order as they are in the Prover section, serving also as a complete reference of the meaning of each value.

Step 1: Replay interactions and recover challenges

  • Start a transcript
  • (Strong Fiat Shamir) Add all public values to the transcript.
  • Add to the transcript for all .
  • Sample random values from the transcript.
  • Add to the transcript for .
  • Sample and in from the transcript.
  • Sample and in from the transcript.
  • Add and to the transcript.
  • Sample from the transcript.
  • Add , , and to the transcript.
  • Sample , , and from the transcript.
  • For do the following:
    • Sample
    • If : add to the transcript
  • Add to the transcript.
  • Add to the transcript.
  • For :
    • Sample random index from the transcript and let .

Verify grinding:

Check that has leading zeroes.

Step 2: Verify claimed composition polynomial

  • Compute
  • Compute
  • Compute
  • Verify

Step 3: Verify FRI

  • Reconstruct the deep composition polynomial values at and . That is, define
  • For all :
    • For all :
      • Check that and are Accept.
      • Solve the following system of equations on the variables
      • If , check that equals
      • If , check that equals .

Step 4: Verify trace and composition polynomials openings

  • For do the following:
    • Check that the following are all Accept:
      • for all .
      • .
      • .
      • for all .
      • .
      • .

Notes on Optimizations and variants

Sampling of challenges variant

To build the composition the prover samples challenges and for and . A variant of this is sampling a single challenge and defining and as powers of . That is, define for and for .

The same variant applies for the challenges for used to build the deep composition polynomial. In this case the variant samples a single challenge and defines , for all , and .

Batch inversion

Inversions of finite field elements are slow. There is a very well known trick to batch invert many elements at once replacing inversions by multiplications. See here for the algorithm.

FFT

One of the most computationally intensive operations performed is polynomial division. These can be optimized by utilizing Fast Fourier Transform (FFT) to divide each field element in Lagrange form.

Ruffini's rule

In specific scenarios, such as dividing by a polynomial of the form , for example when building the deep composition polynomial, Ruffini's rule can be employed to further enhance performance.

Bit-reversal ordering of Merkle tree leaves

As one can see from inspecting the protocol, there are multiple times where, for a polynomial , the prover sends both openings and . This implies, a priori, sending two authentication paths. Domains can be indexed using bit-reverse ordering to reduce this to a single authentication path for both openings, as follows.

The natural way of building a Merkle tree to commit to a vector , is assigning the value to leaf . If this is the case, the value is at position and the value is at position . This is because equals for the value used in the protocol.

Instead of this naive approach, a better solution is to assign the value to leaf , where is the bit-reversal permutation. This is the permutation that maps to the index whose binary representation (padded to bits), is the binary representation of but in reverse order. For example, if and , then its binary representation is , which reversed is . Therefore . In the same way and . Check out the wikipedia article. With this ordering of the leaves, if is even, element is at index and is at index . Which means that a single authentication path serves to validate both points simultaneously.

Redundant values in the proof

The prover opens the polynomials of the FRI layers at and for all . Later on, the verifier uses each of those pairs to reconstruct one of the values of the next layer, namely . So there's no need to add the value to the proof, as the verifier reconstructs them. The prover only needs to send the authentication paths for them.

The protocol is only modified at Step 3 of the verifier as follows. Checking that is skipped. After computing , the verifier uses it to check that is Accept, which proves that is actually , and continues to the next iteration of the loop.