We talked about PLONK.
Plonk is a zk-SNARK that is based on the polynomial commitment scheme. It is a universal and scalable zk-SNARK that can be used for any NP language. It is a proof system that allows a prover to convince a verifier that a statement is true without revealing any information about the statement itself. With Plonk, you make use of arithmetization and a polynomial commitment scheme. For PCS you have several options:
PCS | Used in | Notes |
---|---|---|
KZG | "Vanilla" Plonk | Trusted Setup, small proof size |
IPA | Halo2 / Kimchi | Efficient recursion |
FRI | Boojum / Plonky2 / Plonky3 | No trusted setup, large proof size, can use small fields |
IPA stands for Inner-product Argument, and we can think of it as some kind of Pedersen commitment.
In FRI, the ability to use small fields enable us to implement faster provers, which is nice.
Proof Recursion / Aggregation: We should make a small note on this, now that we mention "Efficient recursion" in IPA. The idea here is that you can create a proof that you have verified a proof. In particular, you can use a different proof system to do this, i.e. use a Groth16 to prove that you have a valid STARK proof; and verify this final proof on Ethereum. This also allows for proof aggregation, where you can aggregate multiple proofs into a single proof.
Before Plonk, the most widely used system was R1CS where we work with the equation:
Here,
Imagine that you have a gate with 2 inputs
graph LR
g((" "))
a & b --> g
g --> c
Consider the table
Now, consider some selectors
This equation above is a "Basic Gate", and it allows you to capture certain computations.
If
If
With more clever selectors, you can implement custom gates. For example, you can introduce a term with selector like
This can help with some hard computations like elliptic curve additions, posedion hashes and foreign-field arithmetic. Moreover, custom gates allow one to use lookup gates. With a lookup gate, you can optimize a computation that is hard to arithmetize (e.g. SHA2 or AES) by simply storing a table of its inputs and outputs and then use that table to lookup a correct result.
Consider the basic gate again:
for
Similar to STARK from the week before, we will pick a domain of size
$a(g^i) = a_i$ $b(g^i) = b_i$ $c(g^i) = c_i$
We don't need to interpolate the selector polynomials because they are circuit-dependent, you can find them once you wrote the circuit independent of the inputs; they are "execution independent".
Now, define the polynomial
If the constraints are valid, then it must be that
Recall that vanishing polynomial is the product of roots over the domain, and when using roots of unity has a really nice form, shown below:
$$ Z(x) = \prod_{x_i \in D_i} (x - x_i) = x^n - 1 $$
For public inputs, we can add "dummy" gates where the input is
Again we are working over the basic gate equation, but the resulting polynomial is the public inputs polynomial:
For the dummy gates this results in the constraint:
The public input polynomial beyond the dummy gates should be equal to 0, i.e.
Note that the prover and verifier can compute this polynomial on their own sides, and they can use Lagrange basis polynomials for this:
where
The gate equations above capture the constraint within a gate alone, but not their connections!
graph LR
g1((" ")); g2((" "))
a1 & b1 --> g1
g1 --"c1"--> g2
b2 --> g2
g2 --> c2
In the diagram above for example,
The idea here is similar to "Memory Check" in CairoVM.
Fix some value
Consider
For example, the permutation
$g(\omega^1) = f(\omega^3)$ $g(\omega^2) = f(\omega^4)$ $g(\omega^3) = f(\omega^2)$ $g(\omega^4) = f(\omega^1)$
Verifier samples
Then, the polynomial
With this, the verifier can check for every
$L_1(a)(Z(a) - 1) = 0$ $Z(a)f'(a) = Z(\omega a)g'(a)$
The permutation trick here is better found in the Plonk paper.
Prover (having access to witness values
Sample
Here
Prover now commits to these polynomials to obtain
Now we will do the permutation argument. First, we sample
TODO: check paper for this
TODO: An addition blinding is added
TODO: !!!
We must convince the verifier that all these constraints hold, and show that the polynomials are correct. We will evaluate the polynomials at some random point
$\bar{a} = a(\zeta)$ $\bar{b} = b(\zeta)$ $\bar{c} = c(\zeta)$ $\bar{s_{\sigma_1}} = s_{\sigma_1}(\zeta)$ $\bar{s_{\sigma_2}} = s_{\sigma_2}(\zeta)$ $\bar{z}g = z(\zeta g)$
Prover sends
Sample a value
TODO: !!!
During the random linear combination, instead of a random sample per point, you can use a single random sample and its consecutive powers, which is slightly less secure but reduces communication.