Some ideas behind PLONK

PLONK (opens new window) stands for Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge. But do not mind the incomprehensible words – PLONK is an incredibly useful cryptographic protocol.

Let’s say we are in the field FpF_p and in it, we have the multiplicative subgroup H={1,w,w2,...,wn1}.H = \{1, w, w^2, ..., w^{n-1}\}. We also have the polynomial ZH(x)Z_H(x), for which it holds:

ZH(x)=0forxHZ_H(x) = 0 \; \text{ for } \; x \in H

For example, we would like to prove that for each xH:x \in H:

a(x)b(x)+1=0a(x) b(x) + 1 = 0

That means:

(a(1)a(ω)...a(ωn1))(b(1)b(ω)...b(ωn1))+(11...1)=(00...0).\begin{pmatrix} a(1) \\ a(\omega) \\ ... \\ a(\omega^{n-1}) \end{pmatrix} \begin{pmatrix} b(1) \\ b(\omega) \\ ... \\ b(\omega^{n-1}) \end{pmatrix} + \begin{pmatrix} 1 \\ 1 \\ ... \\ 1 \end{pmatrix} = \begin{pmatrix} 0 \\ 0 \\ ... \\ 0 \end{pmatrix}.

Let’s denote:

h(x)=a(x)b(x)+1h(x) = a(x) b(x) + 1

The prover needs to prove:

h(x)=0forxHh(x) = 0 \; \text{ for } \; x \in H

To achieve this, the prover computes the polynomial hv(x)=h(x)ZH(x).h_v(x) = \frac{h(x)}{Z_H(x)}.

The prover then computes commitments [a(s)]1,[a(s)]_1, [b(s)]1,[b(s)]_1, and [hv(s)]1[h_v(s)]_1 to the polynomials a,b,andhva, b, \; \text{ and } \; h_v, respectively. The prover then proves that it knows the polynomials behind the commitments. It opens the polynomials at χ\chi (chosen by a verifier):

a¯=a(χ)\bar{a} = a(\chi)

b¯=b(χ)\bar{b} = b(\chi)

hv¯=hv(χ)\bar{h_v} = h_v(\chi)

That means the prover proves that a,bandhva, b \; \text{ and } \; h_v evaluate to a¯,b¯,andhv¯\bar{a}, \bar{b}, \text{and } \bar{h_v} at χ,\chi, respectively. The prover provides:

[ga(s)]1wherea(x)a(χ)=(xχ)ga(x)[g_a(s)]_1 \text{ where } a(x) - a(\chi) = (x-\chi)g_a(x)

[gb(s)]1whereb(x)b(χ)=(xχ)gb(x)[g_b(s)]_1 \text{ where } b(x) - b(\chi) = (x-\chi)g_b(x)

[ghv(s)]1wherehv(x)hv(χ)=(xχ)ghv(x)[g_{h_v}(s)]_1 \text{ where } h_v(x) - h_v(\chi) = (x-\chi)g_{h_v}(x)

The verifier checks:

e([a(s)a¯]1,[1]2)=e([ga(s)]1,[(sχ)]2)e([a(s) - \bar a]_1, [1]_2) = e([g_a(s)]_1, [(s - \chi)]_2)

e([b(s)b¯]1,[1]2)=e([gb(s)]1,[(sχ)]2)e([b(s) - \bar b]_1, [1]_2) = e([g_b(s)]_1, [(s - \chi)]_2)

e([hv(s)h¯v]1,[1]2)=e([ghv(s)]1,[(sχ)]2)e([h_v(s) - \bar h_v]_1, [1]_2) = e([g_{h_v}(s)]_1, [(s - \chi)]_2)

Note that the verifier computes hv¯\bar{h_v} as follows:

hv¯=a(χ)b(χ)+1ZH(χ)\bar{h_v} = \frac{a(\chi)b(\chi) + 1}{Z_H(\chi)}

Why is this secure?

This will be just a bit of hand-waving (I say this too many times).

Let’s say the attacker does not know a(x)a(x) and b(x)b(x) such that:

hv(x)ZH(x)=a(x)b(x)+1h_v(x) Z_H(x) = a(x)b(x) + 1

Note that the equation above ensures:

a(x)b(x)+1=0forxHa(x)b(x) + 1 = 0 \; \text{ for } \; x \in H

The attacker could easily take polynomials a(x),a(x), b(x)b(x) and define c(x)c(x) such that (considering ZH(χ)Z_H(\chi) as a constant):

c(x)ZH(χ)=a(x)b(x)+1c(x) Z_H(\chi) = a(x)b(x) + 1

However, the prover needs to commit to c(x)c(x) before knowing the challenge χ.\chi. That means that the prover cannot subsequently change the polynomial c(x).c(x). When committing to a(x),b(x),c(x),a(x), b(x), c(x), the value ZH(χ)Z_H(\chi) could be any element of Fp,F_p, and the probability of the prover guessing it is negligible.

Multi-opening

What if the prover needs to prove multiple relations?

Let’s say the prover would like to prove for xH:x \in H:

a(x)b(x)+1=0a(x) b(x) + 1 = 0

a(x)+b(x)=0a(x) + b(x) = 0

a(x)2b(x)+1=0.a(x)^2 - b(x) + 1 = 0.

Could opening a polynomial for each relation be avoided? Could one opening suffice?

It could and the reason, again, is probability.

Another challenge is needed for this, let’s say χ1.\chi_1.

Our new polynomial of interest is:

h(x)=(a(x)b(x)+1)+(a(x)+b(x))χ1+(a(x)2b(x)+1)χ12.h(x) = (a(x) b(x) + 1) + (a(x) + b(x)) \chi_1 + (a(x)^2 - b(x) + 1) \chi_1^2.

The steps are then the same as for the single opening, but note that the verifier computes hv¯\bar{h_v} as follows:

hv¯=(a(χ)b(χ)+1)+(a(χ)+b(χ))χ1+(a(χ)2b(χ)+1)χ12ZH(χ).\bar{h_v} = \frac{(a(\chi)b(\chi) + 1) + (a(\chi)+b(\chi))\chi_1 + (a(\chi)^2 - b(\chi) + 1)\chi_1^2}{Z_H(\chi)}.

Zero-knowledge

We didn’t care about zero-knowledge above - about disclosing nothing about a(x)a(x) and b(x)b(x) to the verifier.

To achieve zero-knowledge we need to add random multiples of ZH(x)Z_H(x) to the witness based polynomials (a(x)a(x) and b(x)b(x)), such as:

anew(x)=(b1x+b2)ZH(x)+a(x)a_{new}(x) = (b_1 x + b_2)Z_H(x) + a(x)

bnew(x)=(b3x+b4)ZH(x)+b(x).b_{new}(x) = (b_3 x + b_4)Z_H(x) + b(x).

where b1,b2,b3,andb4b_1, b_2, b_3, \text {and } b_4 are scalars chosen randomly from Fp.F_p.

Note that one very important PLONK idea is totally ignored here: the permutation argument.