Plonky2
Plonky2 is a recursive proving system combining TurboPLONK arithmetization with a FRIbased polynomial commitment scheme.
TurboPLONK Arithmetization
The PLONK arithmetization uses a global permutation argument to wire local constraints together. TurboPLONK introduces custom gates to PLONK, allowing for arbitrary local constraints to be defined.
Trace
The Plonky2 trace can be thought of as a matrix $M=F_{p}$, where each trace cell $M_{ij}$ ($i∈[0,n),j∈[0,m)$) is an element in the prime field $F_{p}$, with $p=2_{64}−2_{32}+1$.
Each row corresponds to the wires of one gate; and each column corresponds to a wire polynomial $w_{j}(X)$ such that
$w_{j}(ω_{i})=M_{ij},$
where $ω$ is a primitive $n_{th}$ root of unity in $F_{p}$.
Custom gates
In Plonky2, custom gates are represented as constraints on wire polynomials $w_{i}(X)$. For instance, an addition gate
$gate_{ADD}:X_{0}−(X_{1}+X_{2})=0$
may be represented as the polynomial constraint
$w_{0}(X)−(w_{1}(X)+w_{2}(X))=0.$
Note: Here, each $X_{i}$ variable is mapped to the $w_{i}(X)$ wire polynomial; in general, however, any arbitrary mapping is possible.
Gates are toggled on and off by preprocessed "filter" polynomials $f_{j}(X)$. For instance, the filter $f_{ADD}$ should enforce $gate_{ADD}$ only on relevant rows of the trace:
$f_{ADD}(ω_{i})={10 if thei_{th}row is an addition gate;otherwise. $
The filtered addition gate thus looks like $f_{ADD}⋅gate_{ADD}=0.$
In practice, a filter $f_{ADD}$ can be a composite of multiple binary filters. Plonky2 automates the construction of filter expressions for its custom gates, optimizing for an arrangement that minimizes constraint degree [see Section 3.1.1 of the Plonky2 paper].
Permutation argument
[Parts of this section have been adapted from the halo2 book.]
PLONK's permutation argument sets up routes between wires: i.e., it can constrain the value of one wire to equal that of another. In the below example, $w_{2}[0]$ is constrained to equal $w_{0}[1]$. We can write this as a permutation $σ(column, row)=(column_{′},row_{′})$ such that $σ(2,0)=(0,1)$.
$w_{0}w_{0}[0]w_{0}[1] w_{1}w_{1}[0]w_{1}[1] w_{2}w_{2}[0]w_{2}[1] gateG0G1 $
We will label each trace cell $w_{j}[i]$ using a unique field element $δ_{j}⋅ω_{i}∈F_{p}$. Then, we can represent $σ$ by a vector of $r$ polynomials $s_{j}(X)$ such that $s_{j}(ω_{i})=δ_{j_{′}}⋅ω_{i_{′}}$.
Now, given our permutation represented by $s_{0},…,s_{r−1}$ over $r$ routed wires $w_{0},…,w_{r−1}$, we want to ensure that this "grand product" evaluates to 1:
$≡ j=0∏r−1 i=0∏n−1 (w_{j}(ω_{i})+β⋅s_{j}(ω_{i})+γw_{j}(ω_{i})+β⋅δ_{j}⋅ω_{i}+γ )j=0∏r−1 i=0∏n−1 g_{j}(ω_{i})f_{j}(ω_{i}) =1, $
where $β,γ$ are random challenges.
Checking this "grand product" reduces to checking relations between coefficients of polynomials at "neighboring monomials". To see this, define a "running product" polynomial $Z_{P}$ such that $Z_{P}(ω_{0})=Z_{P}(ω_{n})=1$, and for $0≤i<n:$
$Z_{P}(ω_{i+1}) =k=0∏i j=0∏r−1 g_{j}(ω_{k})f_{j}(ω_{k}) =Z_{P}(ω_{i})j=0∏r−1 g_{j}(ω_{i})f_{j}(ω_{i}) . $
Then it is sufficient to enforce the constraints: $Z_{P}(ωX)⋅j=0∏r−1 g_{j}(X)−Z_{P}(X)⋅j=0∏r−1 f_{j}(X)=0,ℓ_{0}(X)⋅(1−Z_{P}(X))=0, (Z_{P}is correctly constructed)(starting conditionZ_{P}(ω_{0})=1) $
where $ℓ_{0}(X)=1$ when $X=ω_{0}$, and $0$ otherwise.
Note: To handle a large number $r$ of routed wires, Plonky2 splits the permutation product constraint into cumulative products [see Section 3.3 of the Plonky2 paper].
Combining constraints
The final polynomial that goes into FRI is a linearised form of a composite of the circuit's constraints. (See the Protocol section for details.)
The prover constructs the composite polynomial $p(X)$ from the wire commitments, permutation product commitments, and vanishing argument commitments, and evaluates it at a verifier challenge point $z$ to get a claimed evaluation $p(z)=y$.
The $final_poly(X)$ that goes into the FRI protocol is a linearized version of the composite $p(X)$:
$final_poly(X)=X−zp(X)−y .$
Notice that $final_poly(X)$ is a polynomial if and only if $p(z)=y$; in other words, if $p(z)=y$, then $final_poly(X)$ is not a polynomial and will fail the FRI protocol.
FRIbased polynomial commitment
FRI is an efficient protocol for proving proximity to a lowdegree polynomial. It proceeds in two phases: $COMMIT$ and $QUERY$. Plonky2 further includes a proofofwork $PoW$ phase.
The prover has a function $f_{(0)}:L_{(0)}→F$, where $F$ is a finite field, and the evaluation domain $L_{(0)}⊂F$ is a coset of a group contained in $F$.
Note: The size of the evaluation domain is much larger than the degree $d$. More precisely, $∣L_{(0)}∣=ρd $, where $ρ$ is the ReedSolomon code rate.
The prover claims that $f_{(0)}$ is an evaluation of a polynomial $p(X),g(p(X))<d$. In other words, they claim that $∀x∈L_{(0)},f_{(0)}(x)=p(x).$
COMMIT phase
To commit to $f_{(0)}(X)$, the prover begins by expressing it as a linear combination of two functions, each purportedly corresponding to a degree $2d $ polynomial:
$f_{(0)}(X)=g_{(0)}(X_{2})+X⋅h_{(0)}(X_{2}).$
Here, $g_{(0)}(X)$ and $h_{(0)}(X)$ correspond to the even and odd coefficients of $p(X)$, i.e. $f_{(0)}(X)=p(X)=p_{even}(X_{2})+X⋅p_{odd}(X_{2}).$ The intuition here is similar to that behind the arity2 FFT (Fast Fourier Transform). This algorithm can be generalised to other arities.
Suppose now that $f_{(0)}(X)$ is far from the degree$d$ polynomial. This means that a significant fraction of queries on $f_{(0)}(X)$ will not yield points on $p(X)$. The proximity gap result implies that, with high probability, any linear combination of $g_{(0)}(X)$ and $h_{(0)}(X)$ will be equally far from a degree$2d $ polynomial.
The prover now sends the verifier a commitment to $f_{(0)}$. Next, Plonky2 instantiates $Commit(f_{0})$ as the root of a Merkle tree whose leafs are the evaluations of $f_{(0)}$, and whose hash function is Poseidon in a sponge. Using $Commit(f_{0})$, the verifier derives a random challenge $α_{(0)}$. This is then used to construct a random linear combination of $g_{(0)}(X)$ and $h_{(0)}(X)$:
$f_{(1)}(X)=g_{(0)}(X)+α_{(0)}⋅h_{(0)}(X).$
Observe that our new function is half the degree: $g(f_{(1)}(X))=2d $.
Further, we can halve the size of our evaluation domain through a clever choice of $L_{(0)}$. We choose $L_{(0)}$ to be a finite field, such that $x∈L_{(0)}↔−x∈L_{(0)}.$ For a function on $x_{2}$, the symmetry $f(x_{2})=f((−x)_{2})$ means that half of the output values will be superfluous. In other words, we need only evaluate $f$ over half the domain:
$f_{(1)}(X)=g_{(0)}(X_{2})+α_{(0)}⋅h_{(0)}(X_{2}),f_{(1)}(−X)=g_{(0)}(X_{2})−α_{(0)}⋅h_{(0)}(X_{2}), $
where $x∈L_{(1)},∣L_{(1)}∣=2∣L_{(0)} $.
At each round $i$ in the $COMMIT$ phase, the verifier sends the prover a new random challenge $α_{i−1}$. Then the prover uses it to make a new function $f_{(i)}$ and merkle commitment $Commit(f_{i})$, halving the degree and evaluation domain size of the previous round's $f_{(i−1)}$. Finally, at $r=gd$ rounds, we are left with the constant function (degree 0) $f_{(r)}∈F$.
PoW phase
TODO
QUERY phase
The $QUERY$ phase consists of $ℓ$ rounds. In each round, the verifier makes $2r=2gd$ oracle queries to read the prover's $f_{(i)}$'s in select locations.
$1.Repeatℓtimes:a.Picks_{(0)}∈L_{(0)}uniformly at random.b.Fori=0 tor−1:i.Defines_{(i+1)}∈L_{(i+1)}bys_{(i+1)}=(s_{(i)})_{2}.ii.Make two queries,g_{(i)}(s_{(i+1)})andh_{(i)}(s_{(i+1)}).iii.Check thatf_{(i+1)}(X)=?g_{(i)}(s_{(i+1)})+α_{(i)}⋅h_{(i)}(s_{(i+1)}).iv.Check the Merkle proof at the leaf representings_{(i+1)}.c.If either of the checks fail,REJECT.2.ACCEPT. $
Protocol
$Provercommit to wire polynomials:W←Commit(w_{i}),i∈[0,m)compute permutation partial product and Z’scommit to permutation partial products and Z’s:Z←Commit(zs_partial_products)compute quotient polynomialt(X)commit tot(X):T←Commit(t)evaluate the wire commitments, partial product and Z’s commitments,and quotient poly commitment at opening locations{ζ,ζ⋅g}constructfinal_polycompute FRI proof forfinal_polyCOMMITphase: fold codewords in the commitment phasePoWphase: find proofofwork witnessQUERYphase W β,γ Z α T ζ opening evals α $
FRIbased recursion
The recursive verifier circuit is a subcircuit encoding the constraints needed to verify a FRI proof. About 75% of the recursive circuit is taken up by verifying Merkle proofs, i.e. Poseidon hashes.
The diagram below shows how the FRI proof of one instance can be submitted to a later recursive verifier as part of the next instance:
Starky
Starky shares Plonky2's FRIbased polynomial commitment scheme, but replaces TurboPLONK with the Algebraic Intermediate Representation ($AIR$), an arithmetization used in STARKs. $AIR$ is optimized for traces with repeating structure, where the same state transition function applies on all states in the trace. Here, each row in the matrix corresponds to a single state in the execution trace; and each column corresponds to a register.
The $AIR$ arithmetization is a special case of TurboPLONK arithmetization. This note explains their relationship in more detail.
Starky expresses the constraints of the computation using the following types of constraints:

Boundary constraints: these are applicable on only the first and last rows, and are often used to load the expected inputs and outputs of the computation. As in Plonky2, these are specified using preprocessed filters: $f_{first}(X)⋅constraint_{first}(X)f_{last}(X)⋅constraint_{last}(X) =0,=0, $ where $f_{first}$ only evaluates to $1$ on the first row, and $f_{last}$ only on the last.

Transition constraints: these define a valid transition from the current state to the next state of the execution trace. These are valid on all rows except the last.

Constraints that are valid on all rows.
Starky additionally allows for permutations between pairs of columns.