Zero-Knowledge Proofs

Introduction to SNARK

Interactive proofs are complete and (statistically) sound, while interactive arguments are sound w.r.t computationally bounded prover (computational soundness).

Definition (SNARK).
A succinct (preprocessing) non-interactive argument of knowledge (SNARK) is a triple of algorithms (S,P,V)(S, P, V):
  • Setup S(C;r)=(pp,vp)S(C;r)=(pp,vp): Generates public parameters (pp,vp)(pp, vp) for the prover and verifier respectively, given a circuit CC.
  • Prove P(pp,x,w)=πP(pp, x, w)=\pi: Produces a short proof π\pi, where len(π)=sublinear(w)\mathsf{len}(\pi) = \mathsf{sublinear}(|w|)
  • Verify V(vp,x,π)V(vp, x, \pi): Fast to verify, with verification time: time(V)=Oλ(x,sublinear(C))\mathsf{time}(V) = O_{\lambda}(|x|, \mathsf{sublinear}(|C|)),

that satisfy:

  • Completeness: For all x,wx,w such that C(x,w)=0C(x,w)=0,Pr[πP(pp,x,w):V(vp,x,π)=1]=1\mathbf{Pr}\left[\pi \leftarrow P(pp, x, w): V(vp, x, \pi) = 1\right] = 1.
  • Knowledge Soundness: If VV accepts, then PP “knows” a witness ww such that C(x,w)=0C(x,w)=0.

If the algorithms satisfy:

  • Zero-Knowledge: The (C,pp,vp,x,π)(C,pp,vp,x,\pi) “reveals nothing new” about the witness ww.

then the scheme is called a zk-SNARK.

Strong SNARK: all sublinear terms are log(C)\log(|C|).

So in SNARK, prover can not simply send a ww, for ww might be long (wC|w|\leq |C|) and it may be hard to verify C(x,w)=0C(x,w)=0.

Observe that SS is randomized for setup phase. If rr is revealed to PP, it can prove false statements. This is because while vpvp is visible from PP, it can hide some key structures invisible from PP without knowing the random rr.

The pre-processing has different types:

  • transparent setup: S(C)S(C) uses no random bit.
  • trusted but universal setup: S=(Sinit,Sindex)S=(S_{\text{init}}, S_{\text{index}}), Sinit(r)=gpS_{\text{init}}(r)=gp generates global parameters with secret rr, Sindex(gp,C)=(pp,vp)S_{\text{index}}(gp,C)=(pp,vp) is deterministic.
  • trusted setup per circuit: S(C;r)S(C;r) uses random bits for every circuit CC.

Argument of Knowledge

Here we use trusted but universal setup.

Definition (Adaptive Knowledge Soundness). A preprocessing NARK (S,P,V)(S, P, V) is (adaptively) knowledge sound for a circuit CC if for every polynomial-time adversary A=(A0,A1)A = (A_0, A_1) such that:
gpSinit(1λ;r),(C,x,st)A0(gp),(pp,vp)Sindex(C),πA1(pp,x,st)\begin{aligned} & gp \leftarrow S_{\text{init}}(1^\lambda;r), \\ & (C, x, \text{st}) \leftarrow A_0(gp), \\ & (pp, vp) \leftarrow S_{\text{index}}(C), \\ & \pi \leftarrow A_1(pp, x, \text{st}) \end{aligned}

and

Pr[V(vp,x,π)=accept]>1/106(non-negligible w.r.t. λ)\Pr[V(vp, x, \pi) = \text{accept}] > 1/10^6 \quad (\text{non-negligible w.r.t. } \lambda)

there exists an efficient extractor EE (that uses AA) such that:

gpSinit(1λ;r),(C,x,st)A0(gp),wEA(gp,C,x)\begin{aligned} & gp \leftarrow S_{\text{init}}(1^\lambda;r), \\ & (C, x, \text{st}) \leftarrow A_0(gp), \\ & w \leftarrow E^A(gp, C, x) \end{aligned}

and

Pr[C(x,w)=0]>1/106ϵ(for a negligible ε w.r.t. λ).\Pr[C(x, w) = 0] > 1/10^6 - \epsilon \quad (\text{for a negligible } \varepsilon\text{ w.r.t. } \lambda).

Adversary chooses (C,x)(C, x) after seeing gpgp (adaptive), then produces a proof π\pi. If AA produces an accepting proof with non-negligible probability, then EE can extract a valid witness ww with essentially the same probability (up to negligible ε\varepsilon).

After intro, we proceed to constructing a SNARK, which uses 2 building blocks, one is functional commitment scheme, and the other is interactive oracle proof. The former is a cryptographic object and the latter is an information-theoretical object.

Building Blocks 1: functional commitment scheme

Definition (Commitment Scheme). A commitment scheme consists of
  • setup(1λ)gp\mathsf{setup}(1^\lambda)\to gp, outputs public parameters gpgp
  • commit(gp,f,r)com\mathsf{commit}(gp, f, r)\to \mathsf{com}, commitment to fFf \in \mathcal{F} with rRr \in \mathcal{R} randomly chosen
  • open(com,f,r)\mathsf{open}(\mathsf{com}, f, r): if com=commit(gp,f,r)\mathsf{com} = \mathsf{commit}(gp, f, r), then open(com,f,r)=1\mathsf{open}(\mathsf{com}, f, r) = 1; otherwise open(com,f,r)=0\mathsf{open}(\mathsf{com}, f, r) = 0

satisfying hiding and binding properties:

  • Binding: for all PPT adversary A\mathcal{A}
Pr[gpsetup(1λ)(comf,f0,r0,f1,r1)A(gp):(f0,r0)(f1,r1)  comf=Commit(gp,f0,r0)  comf=Commit(gp,f1,r1)]negl(λ)\Pr\left[ \begin{array}{l} gp \leftarrow \mathsf{setup}(1^\lambda) \\ (\mathsf{com}_f, f_0, r_0, f_1, r_1) \leftarrow \mathcal{A}(gp) \end{array} : \begin{array}{l} (f_0, r_0) \neq (f_1, r_1) \\ \wedge \; \mathsf{com}_f = \mathsf{Commit}(gp, f_0, r_0) \\ \wedge \; \mathsf{com}_f = \mathsf{Commit}(gp, f_1, r_1) \end{array} \right] \le \mathsf{negl}(\lambda)
  • Hiding: for all PPT adversary A=(A1,A2)\mathcal{A}=(\mathcal{A}_1,\mathcal{A}_2):
Pr[gpSetup(1λ)(f0,f1,st)A1(gp)b{0,1},  rRcomfCommit(gp,fb,r)bA2(st,comf):b=b]12negl(λ)\left| \Pr\left[ \begin{array}{l} gp \leftarrow \mathsf{Setup}(1^\lambda) \\ (f_0, f_1, st) \leftarrow \mathcal{A}_1(gp) \\ b \leftarrow \{0,1\}, \; r \leftarrow \mathcal{R} \\ com_f \leftarrow \mathsf{Commit}(gp, f_b, r) \\ b' \leftarrow \mathcal{A}_2(st, com_f) \end{array} : b' = b \right] - \frac{1}{2} \right| \le \mathsf{negl}(\lambda)

also defined as computational indistinguishability.

Note: the rr in the open algorithm is the same as that in the commit algorithm.

After sender’s commitment, the sender should also send (x,r)(x,r) for the receiver to verify. For example, if I want to play paper-scissors-rock with a friend remotely: first we determine our choices; then we send the commitments to each other; finally we send the choice and the random bits used and verify the commitments sent by one another.

To hide the message along the interaction (also, to make the proof short instead of (x,r)(x,r)), we define functional commitment scheme.

Definition (Functional Commitment Scheme). A functional commitment scheme for F={f:XY}\mathcal{F}=\{f:X\mapsto Y\}:
  • setup(1λ)gp\mathsf{setup}(1^\lambda)\to gp, outputs public parameters gpgp
  • commit(gp,f,r)comf\mathsf{commit}(gp, f, r)\to \mathsf{com}_f , commitment to fFf \in \mathcal{F} with rRr \in \mathcal{R}, which is a binding (and hiding for zk-SNARK) commitment scheme for F\mathcal{F}
  • eval(P,V)\mathsf{eval}(P, V): for a given comf\mathsf{com}_f and all xXx \in X:
open(gp,f,x,r)short proof π and value yY\mathsf{open}(gp, f, x, r) \to \text{short proof } \pi\text{ and value }y\in Y
verify(gp,comf,x,y,π)accept/reject\mathsf{verify}(gp, \mathsf{com}_f, x, y, \pi) \to \text{accept/reject}

satisfying

  • Completeness: If fFf \in \mathcal{F} and xXx \in X with f(x)=yf(x)=y, then Pr[V(gp,comf,x,y,π)=accept]=1\Pr[V(gp, \mathsf{com}_f, x, y, \pi) = \mathsf{accept}] = 1.
  • Knowledge Soundness: (setup    commit,open,verify)(\mathsf{setup}\;\|\;\mathsf{commit}, \mathsf{open}, \mathsf{verify}) is knowledge sound.

The interaction within eval(P,V)\mathsf{eval}(P,V) is actually a SNARK for the relation (circuit)

{(gp,comf,x,y):(f,r),f(x)=y,fF,comf=commit(gp,f,r)}\{(gp,\mathsf{com}_f,x,y): \exists (f,r),f(x)=y, f\in\mathcal{F},\mathsf{com}_f=\mathsf{commit}(gp, f, r)\}

whose witness is essentially (f,r)(f,r). The proof π\pi actually proves that fFf\in\mathcal{F}, f(x)=yf(x)=y and comf\mathsf{com}_f is a commitment to ff.

The definition above essentially illustrates an interactive process. It is like the verifier “queries” the oracle ff at xx with an additional cost of verifying.

ProverVerifierr$R,comfcommit(gp,f,r)comfx  x$Xyf(x),πopen(gp,f,x,y,r)y,π  verify(gp,comf,x,y,π)accept/reject\begin{align*} &\text{Prover}&&&\text{Verifier}\\ &r\xleftarrow{\$}R,\mathsf{com}_f\leftarrow\mathsf{commit}(gp, f, r)&\xrightarrow{\mathsf{com}_f}&&\\ &&\xleftarrow{x}&\;&x\xleftarrow{\$} X\\ &y\leftarrow f(x),\pi\leftarrow\mathsf{open}(gp, f, x, y, r)&\xrightarrow{y,\pi}&\;&\mathsf{verify}(gp, \mathsf{com}_f, x, y, \pi) \to \text{accept/reject} \end{align*}

With the scheme above we commit to a function. The F\mathcal{F} vary from many different function classes.

  • Polynomial commitments: F=Fd[X]\mathcal{F} = \mathbb{F}^{\leq d}[X]
  • Multilinear commitments: F=F1[X1,,Xn]\mathcal{F} = \mathbb{F}^{\leq 1}[X_1, \ldots, X_n], where the degree is defined the maximum degree of the polynomial in every variable (1\leq1 means multilinear)
  • Vector commitments: F={fu:[n]F:f(i)=ui,uFn}\mathcal{F} = \{f_u: [n] \to \mathbb{F}:f(i) = u_i,u\in\mathbb{F}^n\}
  • Inner product commitments: F={fu:FnF:fu(v)=u,v,uFn}\mathcal{F} = \{f_{u}: \mathbb{F}^n \to \mathbb{F}:f_{u}(v) = \langle u,v\rangle, u\in\mathbb{F}^n\}

Building Blocks 2: F\mathcal{F}-Interactive Oracle Proof

IOP is a proof system that proves the prover knows ww such that C(x,w)=0C(x,w)=0. The verifier uses oracles of fFf\in\mathcal{F}, which is later replaced by functional commitments to construct a SNARK; here we use oracles.

Definition (F\mathcal{F}-IOP): An F\mathcal{F}-IOP is a proof system that proves w,  C(x,w)=0\exists w,\;C(x,w)=0 and consists of
  • setup(1λ)pp,vp=(Oraclefs,,Oraclef0)\mathsf{setup}(1^\lambda)\to pp,vp=(\mathsf{Oracle}_{f_{-s}},\dots,\mathsf{Oracle}_{f_{0}})
  • At round i[t]i\in[t], prover PP sends Oraclefi\mathsf{Oracle}_{f_i} where fif_i is based on the interaction history from view of PP; verifier sends ri$Rr_i\xleftarrow{\$} R unless i=ti=t.
  • verifyOraclefs,,Oracleft(vp,x,r1,,rt1)\mathsf{verify}^{\mathsf{Oracle}_{f_{-s}},\dots,\mathsf{Oracle}_{f_t}}(vp,x,r_1,\dots,r_{t-1}) uses (fi)i=st(f_i)_{i=-s}^t as oracles and output the result.

which satisfies

  • Completeness: If w,  C(x,w)=0\exists w,\;C(x,w)=0, then the verifier is bound to accept
  • Knowledge Soundness: if we use comf\mathsf{com}_f’s for Oraclef\mathsf{Oracle}_f’s, the extractor can use (fi)i=st(f_{i})_{i=-s}^t to compute ww because the functional commitment scheme is knowledge sound (functional commitment scheme is actually a SNARK).
  • (Optional) Zero-Knowledge

Polynomial IOP for Circuit SAT

In this lecture we are going to construct a poly-IOP for circuit satisfiability. CC is an arithmetic circuit with size SS. The prover wants to prove that it knows the solution ww to C(w)=yC(w)=y.

First, we label every gate of CC with a bit string of length logS\log S. Thus the computation of C(w)=yC(w)=y can be expressed in a form of function T:{0,1}logSFT:\{0,1\}^{\log S}\mapsto\mathbb{F}, which maps the label of some gate to the output of the gate with its output (notice that T(root)=yT(\text{root})=y). Let h:FlogSFh:\mathbb{F}^{\log S}\mapsto\mathbb{F} be the unique multilinear extension of TT, satisfying h(x)=T(x)h(x)=T(x) for all x{0,1}logSx \in \{0,1\}^{\log S} (the uniqueness is trivial by dynamic programming).

Why shall we extend the function TT to a multilinear polynomial hh? The necessity is shown in the part of the sum-check protocol.

Here VV should have verified the hh and TT are the same on {0,1}logS\{0,1\}^{\log S}. However VV only has the commitment of hh, so VV verifies this by another approach shown below.

We use labels to denote gates, and define the polynomial gh:F3logSFg_h:\mathbb{F}^{3\log S}\mapsto\mathbb{F} as follows:

gh(a,b,c)={h(a)+h(b)h(c),if c is an add gate with input a,b,h(a)h(b)h(c),if c is an mult gate with input a,b,0,otherwise.g_h(a,b,c)=\begin{cases} h(a)+h(b)-h(c), & \text{if }c\text{ is an add gate with input }a,b, \\ h(a)h(b)-h(c), & \text{if }c\text{ is an mult gate with input }a,b,\\ 0,& \text{otherwise}. \end{cases}

which satisfies:

T is a correct assignment     (a,b,c){0,1}3logS,  gh(a,b,c)=0  (in F).T\text{ is a correct assignment }\iff \forall (a,b,c)\in\{0,1\}^{3\log S},\;g_h(a,b,c)=0\;(\text{in }\mathbb{F}).

We shall modify a little in ghg_h: we embed the result gh(a,b,c)g_h(a,b,c) into Z\mathbb{Z}. So the condition above is equivalent to x{0,1}3logSg~h(x)=0\sum_{x\in\{0,1\}^{3\log S}} \tilde{g}_h(x)=0 where g~h:F3logSZ\tilde{g}_h:\mathbb{F}^{3\log S}\mapsto\mathbb{Z} has the same values as ghg_h on all inputs. Then PP and VV interact to let VV believe that the sum is 00. If the sum is 00, VV believes that PP knows the correct TT.

Here comes the usage of the sum-check protocol.

Sum-Check Protocol

The goal of the protocol is to check the answer CC provided by prover satisfies:

C=x{0,1}ng(x)C=\sum_{x\in\{0,1\}^n}g(x)

where gg is an nn-variate polynomial over the field F\mathbb{F} and the sum is computed in Z\mathbb{Z} (i.e. add them up without taking the modulo).

In setup phase, PP sends the commitment of gg to VV. Then they interact for nn rounds, and in the end VV checks the final claim by querying the oracle of gg for one time at a random point.

ProverVerifierstart: “I know s0=x{0,1}ng(x)” s0round 1:“Please verify the last step to compute s0s1(X1) verify s1(0)+s1(1)=s0 and the next goal is to verify s1(X1)=x{0,1}n1g(X1,x)r1“If indeed, then for most rF,s1(r)=x{0,1}n1g(r,x). So I send a random r1.”round 2:“I will proof s1(r1)=x{0,1}n1g(r1,x), please verify...” s2(X2)  ......round n: “I will proof sn1(rn1)=x{0,1}g(r1,,rn1,x), please verify...” sn(Xn)   verify sn(0)+sn(1)=sn1(rn1) and the next goal is to verify sn(Xn)=g(r1,,rn1,Xn)  rn$F, obtaining sn(rn). Then query the oracle of g at (ri)i=1n. Accept iff g(r1,,rn)=sn(rn).\begin{align*} &\text{Prover}&&&\text{Verifier}\\ \text{start}:&\text{ ``I know }s_0=\sum_{x\in\{0,1\}^n}g(x)\text{'' }&\xrightarrow{s_0}&&\\ \text{round 1}:&\text{``Please verify the last step to compute }s_0\text{''}&\xrightarrow{s_1(X_1)}&&\text{ verify }s_1(0)+s_1(1)=s_0\text{ and the next goal is to verify }s_1(X_1)=\sum_{x\in\{0,1\}^{n-1}}g(X_1,x)\\ &&\xleftarrow{r_1}&&\text{``If indeed, then for most }r\in\mathbb{F},s_1(r)=\sum_{x\in\{0,1\}^{n-1}}g(r,x)\text{. So I send a random $r_1$.''}\\ \text{round 2}:&\text{``I will proof }s_1(r_1)=\sum_{x\in\{0,1\}^{n-1}}g(r_1,x)\text{, please verify...'' }&\xrightarrow{s_2(X_2)}&\;&...\\ &&...&&\\ \text{round }n:&\text{ ``I will proof }s_{n-1}(r_{n-1})=\sum_{x\in\{0,1\}}g(r_1,\dots,r_{n-1},x)\text{, please verify...'' }&\xrightarrow{s_{n}(X_{n})}&\;&\text{ verify }s_n(0)+s_n(1)=s_{n-1}(r_{n-1})\text{ and the next goal is to verify }s_{n}(X_n)=g(r_1,\dots,r_{n-1},X_{n})\\ &&&\;&r_n\xleftarrow{\$}\mathbb{F},\text{ obtaining }s_n(r_n).\text{ Then query the oracle of }g\text{ at }(r_i)_{i=1}^n.\text{ Accept iff }g(r_1,\dots,r_n)=s_n(r_n). \end{align*}

The probability that a cheating prover can make the verifier accept a false claim is at most ndeg(g)F\frac{n\deg(g)}{|\mathbb{F}|} (by Schwartz-Zippel lemma, deg\deg is the maximum degree in total, regardless of different variables). So we can make the soundness error negligible by choosing a large enough field.

Note that every polynomial from PP is sent in its coefficients. Let d=deg(g)d=\deg(g) and it takes TgT_g time to verify/evaluate any g(x)g(x), we have

TV=O(nd+Tg),TP=O(2ndTg)T_V=O(nd+T_g),T_P=O(2^ndT_g)

and the proof length is O(nd)O(nd) .

For dense polynomial gg , the time to evaluate its multilinear extension g~\tilde g on point xx is at most O(2n)O(2^n) . Thus our prover has quadratic time. The [Libra] puts forwards a linear time sum-check prover.

This sum-check protocol is also used in the proof that IP=PSPACE\mathbf{IP}=\mathbf{PSPACE}. Define the decisional counting problem of 3CNF as:

(#SAT)D:={φ,k:k=b1,,bn{0,1}φ(b1,,bn)}(\#\mathsf{SAT})_D:=\left\{\langle\varphi,k\rangle:k=\sum_{b_1,\dots,b_n\in\{0,1\}}\varphi(b_1,\dots,b_n)\right\}

so by translating the boolean formula into a multilinear polynomial, with the sum-check protocol we have (#SAT)DIP(\#\mathsf{SAT})_D\in\mathbf{IP}.

Suppose we have a TQBF\mathsf{TQBF} formula ψ=x1x2Qxn.φ(x1,x2,,xn)\psi=\forall x_1\exists x_2\dots Qx_n.\varphi(x_1,x_2,\dots,x_n) , if we directly make \forall into multiplication and \exists into addition, the degree will skyrocket. Define for a pF[X1,,Xn]p\in\mathbb{F}[X_1,\dots,X_n],

Lip:=(1Xi)pi0+Xipi1F[X1,Xn],Aip:=pi0pi1F[X1Xi1,Xi+1,,Xn],Eip:=1(1pi0)(1pi1)F[X1Xi1,Xi+1,,Xn],\begin{align*} &\mathsf{L}_ip:=(1-X_i)p^{i\leftarrow0}+X_ip^{i\leftarrow1}\in\mathbb{F}[X_1\dots,X_n],\\ &\mathsf{A}_ip:=p^{i\leftarrow0}p^{i\leftarrow1}\in\mathbb{F}[X_1\dots X_{i-1},X_{i+1},\dots,X_n],\\ &\mathsf{E}_ip:=1-(1-p^{i\leftarrow0})(1-p^{i\leftarrow1})\in\mathbb{F}[X_1\dots X_{i-1},X_{i+1},\dots,X_n], \end{align*}

these polynomials are all in F[X1,Xn]\mathbb{F}[X_1\dots,X_n].

In analogy to the sum-check protocol, we can also define Xip:=pi0+pi1F[X1Xi1,Xi+1,,Xn]\mathsf{X}_ip:=p^{i\leftarrow0}+p^{i\leftarrow1}\in\mathbb{F}[X_1\dots X_{i-1},X_{i+1},\dots,X_n].

The idea is to linearize the polynomial after each multiplication. So the formula is described by the polynomial

A1L1E2L1L2A3L1L2L3QnL1L2Lnpφ=1\mathsf{A}_1\mathsf{L}_1\mathsf{E}_2\mathsf{L}_1\mathsf{L}_2\mathsf{A}_3\mathsf{L}_1\mathsf{L}_2\mathsf{L}_3\dots\mathsf{Q}_n\mathsf{L}_1\mathsf{L}_2\dots\mathsf{L}_np_{\varphi}=1

then the prover and verifier go through a O(n2)O(n^2) interaction to establish the protocol. Thus TQBFIP\mathsf{TQBF}\in\mathbf{IP} and IP=PSPACE\mathbf{IP}=\mathbf{PSPACE}.

PLONK IOP

Based on the lecture 4, we can encode a circuit problem into a polynomial. The sum-check protocol uses multi-variable polynomials with a large proof size (linear to nlogCn\sim\log |C| even if we send commitments of polynomials instead of coefficients). PLONK is also used for circuit SAT with a different encoding, which uses univariate polynomials and has a proof size independent of nn.

Small gadgets to build PLONK IOP

Let Ω=ωFp\Omega=\langle\omega\rangle\subset\mathbb{F}_p be a multiplicative subgroup of size kφ(p)k\mid\varphi(p). And we want to provide protocols to prove that a committed polynomial ff has some properties on Ω\Omega. The properties of given f,gFp[X]f,g\in\mathbb{F}_p[X] include:

  • Zeroness: f(x)=0f(x)=0 for all xΩx\in\Omega
  • Sum/Product over Ω\Omega: xΩ(f(x)g(x))=0\sum_{x\in\Omega}\left(f(x)-g(x)\right)=0 or xΩf(x)g(x)=1\prod_{x\in\Omega}\frac{f(x)}{g(x)}=1
  • Permutation: (f(ωi))i=0k1(f(\omega^i))_{i=0}^{k-1} is a permutation of (g(ωi))i=0k1(g(\omega^i))_{i=0}^{k-1} . Warning: it is not enough to check xΩf(x)g(x)=1\prod_{x\in\Omega}\frac{f(x)}{g(x)}=1 ! The soundness relies on the random challenge by the verifier.
  • Prescribed permutation: f(y)=g(W(y))f(y)=g(W(y)) for some known permutation W:ΩΩW:\Omega\to\Omega

Encoding a circuit into a polynomial

We again take C(x,w)C(x,w) as the circuit satisfiability problem. Let d=3C+x+wd=3|C|+|x|+|w|, and label each gate with a integer. And we have the dd-th root ω\omega, which satisfies ωd=1\omega^d=1.

Setup phase outputs polynomial SS and permutation WW. The prover wants to prove that it knows ww such that C(x,w)=0C(x,w)=0, so it interpolates a polynomial TFpd[X]T\in\mathbb{F}_p^{\leq d}[X] such that

  • T(ωj)=T(\omega^{-j})= the value of the jj-th input
  • T(ω3i),T(ω3i+1),T(ω3i+2)T(\omega^{3i}),T(\omega^{3i+1}),T(\omega^{3i+2}) are the left-input/right-input/output of the ii-th gate, i=0,1,,C1i=0,1,\dots,|C|-1

using FFT in time O(dlogd)O(d\log d).

Then the prover proves the following:

  • The inputs are correct: T(ωj)=xjT(\omega^{-j})=x_j for j=0,1,,x1j=0,1,\dots,|x|-1
  • The math operations are correct: Use a public S(ω3i)=1S(\omega^{3i})=1 iff ii-th gate is multiplicative; then, prove for all y{ω3i:i<C}y\in\{\omega^{3i}:i<|C|\},
S(y)T(y)T(yω)+(1S(y))(T(y)+T(yω))T(yω2)=0.S(y)\cdot T(y)\cdot T(y\omega)+(1-S(y))\cdot(T(y)+T(y\omega))-T(y\omega^{2})=0.
  • Wiring is correct: Use a public WW to rotate the wires that share the same value; then, prove T(y)=T(W(y))T(y)=T(W(y)) for all y{ωi:i<d}y\in\{\omega^{i}:i<d\}
  • The output is 00 : T(ω3C1)=0T(\omega^{3|C|-1})=0

using the gadgets mentioned above.

Polynomial commitment based on discrete-log and pairing

KZG: pairing

We have GG as a group of prime order pp with generator gg. We have a bilinear map e:G×GGTe:G\times G\to G_T where GGTCpG\cong G_T\cong C_p are pp-order cyclic groups. We use F=Fpd[X]\mathcal{F}=\mathbb{F}_p^{\leq d}[X], and the public parameters gpgp are generated as

(g,gτ,gτ2,,gτd)setup(λ,F;τ)(g,g^\tau,g^{\tau^2},\dots,g^{\tau^d})\leftarrow\mathsf{setup}(\lambda,\mathcal{F};\tau)

where τ\tau is a random element in Fp\mathbb{F}_p; after computing, abort the random τ\tau. To commit to a polynomial f(X)=i=0dfiXif(X)=\sum_{i=0}^d f_iX^i, we compute

i=0d(gτi)ficommit(gp,f).\prod_{i=0}^d (g^{\tau^i})^{f_i}\leftarrow\mathsf{commit}(gp, f).

In the evaluation phase, with input uu, the prover sends vv and a proof π\pi for the verifier to verify f(u)=vf(u)=v using π\pi. The idea is if f(u)=vf(u)=v, then f(X)vf(X)-v is divisible by XuX-u. Let q(X)=(f(X)v)/(Xu)q(X)=(f(X)-v)/(X-u), then the proof is written as π=gq(τ)\pi=g^{q(\tau)} and (v,π)open(gp,f,u)(v,\pi)\leftarrow\mathsf{open}(gp,f,u). The verifier checks if e(gτu,π)=e(comfgv,g)e\left(g^{\tau-u},\pi\right)=e\left(\frac{\mathsf{com}_f}{g^{v}}, g\right). The verifier knows gτug^{\tau-u} because it knows gτg^\tau from the global parameter and it can compute gug^u from uu.

Time: commit O(d)O(d) group exponentiations, open (including computing qq) O(d)O(d) group exponentiations and O(d)O(d) group multiplications, verify O(1)O(1) pairings. Size: proof and commitment are both O(1)O(1) group elements.

The completeness is trivial. For soundness, if the prover outputs another (v,π)(v',\pi') such that f(u)vf(u)\not=v' and e(gτu,π)=e(comfgv,g)e\left(g^{\tau-u},\pi'\right)=e\left(\frac{\mathsf{com}_f}{g^{v'}}, g\right), then we have (denote δ=f(u)v\delta=f(u)-v'):

e(comfgv,g)=e(gf(τ)f(u)+δ,g)=e(gq(τ)+δτu,gτu)=e(gτu,π)e\left(\frac{\mathsf{com}_f}{g^{v'}}, g\right)=e\left(g^{f(\tau)-f(u)+\delta}, g^{}\right)=e\left(g^{q(\tau)+\frac{\delta}{\tau-u}}, g^{\tau-u}\right)=e\left(g^{\tau-u},\pi'\right)

so as a result

e(g,g)δτu=e(g,π)e(g,g)q(τ)e\left(g, g\right)^{\frac{\delta}{\tau-u}}=\frac{e\left(g,\pi'\right)}{e\left(g, g\right)^{q(\tau)}}

where the operations on the exponent are in Fp\mathbb{F}_p which corresponds to the multiplication in the groups GG and GTG_T. This is the qq-Strong Bilinear Diffie-Hellman** assumption, which says that it is hard to compute e(g,g)1τue(g,g)^{\frac{1}{\tau-u}} given (p,G,g,GT,e)(p,G,g,G_T,e) and gp=(g,gτ,,gτd)gp=(g,g^\tau,\dots,g^{\tau^d}).

Knowledge Soundness

The plain KZG is not knowledge soundness without assumptions like KoE or GGM. We will discuss the assumptions in the PCP-based SNARK.

Zero-Knowledge-ness

The plain KZG is not zk since the commit algorithm is deterministic. For example, you can use gf(τ)g^{f(\tau)} to test if ff is a zero polynomial. Here, we denote the protocol modified to zk in the graph below.

Setup: sample τ,η$Fp and compute gp(g,gτ,,gτd,gη); then delete τ,η.ProverVerifierr$Fp,comf=gf(τ)+rηcommit(gp,f;r)comfr$Fp,vf(u),π=(gq(τ)+rη,grr(τu))open(gp,f,u,r;r)uFp  v,π  e(π1,gτu)e(π2,gη)=?e(comfgv,g)\begin{align*} &\text{Setup: sample }\tau,\eta\xleftarrow{\$}\mathbb{F}_p\text{ and compute }gp←(g,g^{\tau},\dots,g^{\tau^d},g^\eta);\text{ then delete }\tau,\eta.\\ &\text{Prover}&&&\text{Verifier}\\ &r\xleftarrow{\$}\mathbb{F}_p,\mathsf{com}_f=g^{f(\tau)+r\eta}\leftarrow\mathsf{commit}(gp, f; r)&\xrightarrow{\mathsf{com}_f}&&\\ &r'\xleftarrow{\$}\mathbb{F}_p,v\leftarrow f(u),\pi=\left(g^{q(\tau)+r'\eta},g^{r-r'(\tau-u)}\right)\leftarrow\mathsf{open}(gp, f, u, r;r')&\xleftarrow{u\in\mathbb{F}_p}&\;&\\ &&\xrightarrow{v,\pi}&\;&e\left(\pi_1,g^{\tau-u}\right)e\left(\pi_2,g^{\eta}\right) \stackrel{?}{=} e\left(\frac{\mathsf{com}_f}{g^{v}}, g\right) \end{align*}

The polynomial is hidden by the random rr'.

Variants of KZG

  • For multivariate poly: f(x1,,xk)f(u1,,uk)=i[k](xiui)qi(x1,,xk)f(x_1,\dots,x_k)-f(u_1,\dots,u_k)=\sum_{i\in[k]}(x_i-u_i)q_i(x_1,\dots,x_k) . Prover computes and sends πi=gqi(τ1,,τn)\pi_i=g^{q_i(\tau_1,\dots,\tau_n)} . Prover time is O(km)O(km) group exponentials where m2km\leq 2^k is the number of terms of ff . [Chopin] claims to reduce the prover time to m+O(m)m+O(\sqrt{m}) MSMs (compute jgjaj\prod_j g_j^{a_j} ).
  • For batch query on u1,,umu_1,\dots,u_m: f(x)h(x)=q(x)i[m](xui)f(x)-h(x)=q(x)\prod_{i\in[m]}(x-u_i) where h(x)h(x) is the extrapolation of (ui,f(ui))(u_i,f(u_i))’s.
  • For multi-party, each party has a private number for setup, and the public parameters are (for example, 2-party) gp=(g,gst,,g(st)d)gp=\left(g,g^{st},\dots,g^{(st)^d}\right). The parameters can be generated party after party, since g(st)i=(gsi)tig^{(st)^i}=\left(g^{s^i}\right)^{t^i}.

And it is worth noting that PLONK uses univariate KZG and plonk IOP, while vSQL uses multivariate KZG and sum-check protocol.

Bulletproofs: discrete-log

KZG requires trusted setup. Here we present Bulletproofs which has transparent setup. The goal of the prover is to convince the verifier that f(u)=vf(u)=v where f=i=0d+1fixiFp[X]f=\sum_{i=0}^{d+1}f_ix^i\in\mathbb{F}_p[X]. The setup phase is just a random gp=(gp0,0,,gp0,d)Ggp=(gp_{0,0},\dots,gp_{0,d})\in G and we assume d+1=2kd+1=2^k is some exponential of 22. Then the prover and verifier go through a interaction shown below:

ProverVerifiercomf=i=02k1gp0,ificommit(gp,f)comf,vround 1:  f=f0fL+u2k1fR,L=i=02k11gp0,i+2k1f0,i,R=i=2k12k1gp0,i2k1f0,i,vL=fL(u),vR=fR(u)L,R,vL,vR  “I verify f0(u)=v ”: v=?vL+vRu2k1f1rfL+fRgp1,rgp1(gp0,ir1gp0,i+2k1)i[0,2k1),r$Fp[X],v1rvL+vR,comf1LrRr1comfround 2:  f1fL+u2k2fR,L=i=02k21gp1,i+2k2f1,i,R=i=2k22k11gp1,i2k2f1,i,vL=fL(u),vR=fR(u)L,R,vL,vR“ I verify f1(u)=v1”: v1=?vL+vRu2k2.........round k:  fk1fL+ufR,L=gpk1,1fk1,0,R=gpk1,0fk1,1,vL=fL(u),vR=fR(u)L,R,vL,vR  “I verify fk1(u)=vk1 ”: vk1=?vL+vRufkFprfL+fRgpk,rgpk(gpk1,0r1gpk1,1),r$Fp[X],vkrvL+vR,comfkLrRr1comfk1final :  “ I verify fk=vk as a constant polynomial ”: comfk=?gpkvk\begin{align*} &\text{Prover} & & &\text{Verifier}\\ &\mathsf{com}_f=\prod_{i=0}^{2^k-1}gp_{0,i}^{f_i}\leftarrow\mathsf{commit}(gp, f) &\xrightarrow{\mathsf{com}_f,v} & &\\ \text{round }1:\; &f=f_0\rightarrow f_L+u^{2^{k-1}}f_R,L=\prod_{i=0}^{2^{k-1}-1}gp_{0,i+2^{k-1}}^{f_{0,i}},R=\prod_{i=2^{k-1}}^{2^k-1}gp_{0,i-2^{k-1}}^{f_{0,i}},v_L=f_L(u),v_R=f_R(u) &\xrightarrow{L,R,v_L,v_R} & &\;\text{``I verify } f_0(u)=v \text{ '': }v\stackrel{?}{=}v_L+v_Ru^{2^{k-1}}\\ &f_1\leftarrow rf_L+f_R &\xleftarrow{gp_1,r} & &gp_1\leftarrow (gp_{0,i}^{r^{-1}}gp_{0,i+2^{k-1}})_{i\in[0,2^{k-1})},r\xleftarrow{\$}\mathbb{F}_p[X],v_1\leftarrow rv_L+v_R,\mathsf{com}_{f_1}\leftarrow L^rR^{r^{-1}}\mathsf{com}_f\\ \text{round }2:\; &f_1\rightarrow f_L+u^{2^{k-2}}f_R,L=\prod_{i=0}^{2^{k-2}-1}gp_{1,i+2^{k-2}}^{f_{1,i}},R=\prod_{i=2^{k-2}}^{2^{k-1}-1}gp_{1,i-2^{k-2}}^{f_{1,i}},v_L=f_L(u),v_R=f_R(u) &\xrightarrow{L,R,v_L,v_R} & &\text{`` I verify } f_1(u)=v_1 \text{'': }v_1\stackrel{?}{=}v_L+v_Ru^{2^{k-2}}\\ &... &... & &...\\ \text{round }k:\; &f_{k-1}\rightarrow f_L+uf_R,L=gp_{k-1,1}^{f_{k-1,0}},R=gp_{k-1,0}^{f_{k-1,1}},v_L=f_L(u),v_R=f_R(u) &\xrightarrow{L,R,v_L,v_R} & &\;\text{``I verify } f_{k-1}(u)=v_{k-1} \text{ '': }v_{k-1}\stackrel{?}{=}v_L+v_Ru\\ &f_k\in\mathbb{F}_p\leftarrow rf_L+f_R &\xleftarrow{gp_k,r} & &gp_k\leftarrow (gp_{k-1,0}^{r^{-1}}gp_{k-1,1}),r\xleftarrow{\$}\mathbb{F}_p[X],v_k\leftarrow rv_L+v_R,\mathsf{com}_{f_k}\leftarrow L^rR^{r^{-1}}\mathsf{com}_{f_{k-1}}\\ \text{final }:\; & & & &\text{`` I verify } f_{k}=v_{k} \text{ as a constant polynomial '': }\mathsf{com}_{f_k}\stackrel{?}{=}gp_{k}^{v_k}\\ \end{align*}

The rr’s at every round is sampled randomly and independently. Then we apply Fiat-Shamir to the protocol. The gpgp’s should be computed by the verifier to prevent backdoor in parameters.

Time analysis

  • Setup: O(d)O(d) sampling
  • Commit: O(d)O(d) group exponentiations
  • Prover: O(d)O(d) group exponentiations
  • Verifier: O(d)O(d) group exponentiations

The proof size is O(logd)O(\log d) group elements, and the commitment size is O(1)O(1) group elements (this is the first commitment comf\mathsf{com}_f. Other commitments are computed by the verifier).

Soundness analysis.

Statistical soundness: we assume the prover does not know the correct vv. The final fkf_k is a multilinear polynomial of all the random rr’s, say fk=gf(r1,,rk)f_k=g_f(r_1,\dots,r_{k}) and the function gfg_f is deterministic. Note that every ff corresponds to a unique gfg_f.

So, conditioned on the prover does not know the correct vv but send a vvv^*\not=v instead, we can say v=f(u)v^*=f^*(u) for some fff^*\not=f. Thus by the Schwartz-Zippel lemma, we have

Prr1,,rkFp[fkvk=g(r1,,rk)g(r1,,rk)=0|vv]kp\mathbf{Pr}_{r_1,\dots,r_k\sim \mathbb{F}_p}\left[f^*_k-v_k=g^*(r_1,\dots,r_k)-g(r_1,\dots,r_k)=0\middle|v^*\not=v\right]\leq\frac{k}{p}

Since vkFpv_k\in\mathbb{F}_p, fk=vkf^*_k=v_k if and only if comfk=gpkvk\mathsf{com}_{f_k}=gp_{k}^{v_k}, so the soundness error is at most kp=logdp\frac{k}{p}=\frac{\log d}{p}.

Polynomial commitment based on linear codes

The motivations to develop code-based commitment scheme are:

  • post-quantum secure
  • no group exponentiations (only hash, addition and multiplication)
  • small global parameters

but the new commitment scheme has larger proof sizes; additionally, without the algebraic structure, it is not homomorphic and harder to aggregate.

The goal of the prover is to prove f(u)=vf(u)=v where fFp[X]f\in\mathbb{F}_p[X] is a degree-d1d-1 polynomial. The value f(u)f(u) equals a quadratic form

f(u)=[1uud1][f0,0f0,d1f1,0f1,d1fd1,0fd1,d1][1udu(d1)d]f(u)= \begin{bmatrix}1&u&\dots&u^{\sqrt{d}-1}\end{bmatrix} \begin{bmatrix}f_{0,0}&\cdots&f_{0,\sqrt{d}-1}\\f_{1,0}&\cdots&f_{1,\sqrt{d}-1}\\\vdots&\ddots&\vdots\\f_{\sqrt{d}-1,0}&\cdots&f_{\sqrt{d}-1,\sqrt{d}-1}\end{bmatrix} \begin{bmatrix}1\\ u^{\sqrt{d}}\\ \vdots\\ u^{(\sqrt{d}-1)\sqrt{d}}\end{bmatrix}

because f(u)=uTFu=i=0d1j=0d1fi,juid+jf(u)=\mathbf{u}^T\mathbf{F}\mathbf{u}'=\sum_{i=0}^{\sqrt{d}-1}\sum_{j=0}^{\sqrt{d}-1} f_{i,j}u^{i\sqrt{d}+j}.

Setup phase samples a random hash function. Then in commit phase, the prover encode each row of F\mathbf{F} with a [n,d][n,\sqrt{d}] linear code (this encoding is a public algorithm, e.g. Reed-Solomon code), represented by a matrix CFpd×n\mathbf{C}\in\mathbb{F}_p^{\sqrt{d}\times n}. The result is a matrix of d×n\sqrt{d}\times n:

P=[f0Cf1Cfd1C].\mathbf{P}=\begin{bmatrix}\mathbf{f}_0\mathbf{C}\\\mathbf{f}_1\mathbf{C}\\\vdots\\\mathbf{f}_{\sqrt{d}-1}\mathbf{C}\end{bmatrix}.

After encoding, use Merkle tree to generate the commitment with the hash function in the global parameters. The leaf nodes are the nn columns of the matrix P\mathbf{P}. The root hash is the commitment of the function.

Then the prover and verifier go through the following interaction to verify f(u)=xf(u)=x:

ProverVerifierrr$FpdwrTF  (originally we send encoded version rTP, this is for optimization)w  wwC is indeed a codewords  s$FpGenerate Merkle proof π that the s-th column of P equals to vFpdπ,v  verify the proof π, and verify rTv=ws, then repeat sampling s multiple timeswuTFw  wwC is indeed a codewords  s$FpGenerate Merkle proof π that the s-th column of P equals to vFpdπ,v  verify the proof π, and verify rTv=ws, then repeat sampling s multiple times  wu=?x\begin{align*} &\text{Prover}&&&\text{Verifier}\\ & &\xleftarrow{\mathbf{r}} & &\mathbf{r}\xleftarrow{\$}\mathbb{F}_p^{\sqrt{d}}\\ &\mathbf{w}\leftarrow\mathbf{r}^T\mathbf{F}\;(\text{originally we send encoded version }\mathbf{r}^T\mathbf{P}\text{, this is for optimization}) &\xrightarrow{\mathbf{w}} &\; &\mathbf{w}\leftarrow\mathbf{w}\mathbf{C}\text{ is indeed a codeword}\\ & &\xleftarrow{s} &\; &s\xleftarrow{\$}\mathbb{F}_p\\ &\text{Generate Merkle proof }\pi\text{ that the }s\text{-th column of }\mathbf{P}\text{ equals to }\mathbf{v}\in\mathbb{F}_p^{\sqrt{d}} &\xrightarrow{\pi,\mathbf{v}} &\; &\text{verify the proof }\pi\text{, and verify }\mathbf{r}^T\mathbf{v}=\mathbf{w}_s\text{, then repeat sampling }s\text{ multiple times}\\ &\mathbf{w}'\leftarrow\mathbf{u}^T\mathbf{F} &\xrightarrow{\mathbf{w}'} &\; &\mathbf{w}'\leftarrow\mathbf{w}'\mathbf{C}\text{ is indeed a codeword}\\ & &\xleftarrow{s} &\; &s\xleftarrow{\$}\mathbb{F}_p\\ &\text{Generate Merkle proof }\pi\text{ that the }s\text{-th column of }\mathbf{P}\text{ equals to }\mathbf{v}\in\mathbb{F}_p^{\sqrt{d}} &\xrightarrow{\pi,\mathbf{v}} &\; &\text{verify the proof }\pi\text{, and verify }\mathbf{r}^T\mathbf{v}=\mathbf{w}'_s\text{, then repeat sampling }s\text{ multiple times}\\ & & &\; &\mathbf{w}'\mathbf{u}'\stackrel{?}{=}x \end{align*}

Analysis of the protocol is as follows:

  • Keygen: O(1)O(1), transparent
  • Commit:
    • Encoding: O(dlogd)O(d \log d) field multiplications using Reed-Solomon code, O(d)O(d) using linear-time encodable code
    • Merkle tree: O(d)O(d) hashes, O(1)O(1) commitment size
  • Prover time: O(d)O(d) field multiplications
  • Proof size: O(d)O(\sqrt{d})
  • Verifier time: O(d)O(\sqrt{d})

Fast Reed-Solomon IOPP

Intro: Merkle trees for univariate poly-commitment

An intuitive attempt is to commit to a vector of evaluations of a given polynomial fFpd[X]f\in\mathbb{F}_p^{\leq d}[X]. The leaves of the tree are {f(x):xFp}\{f(x):x\in\mathbb{F}_p\} and the tree hashes every neighboring 22 nodes to form a new layer. When VV requires f(r)f(r), the prover sends the hash values along the path up to the root.

The Merkle tree for commitment requires O(pd)O(pd) field multiplication (using Qin-Horner method) to commit, and the proof size is O(logp)O(\log p) hash values. The verifier takes O(logp)O(\log p) hashes. The setup only generates a hash function, so it is transparent.

There are 2 problems:

  • The field may be very large; and the time is linear to the max degree.
  • The verifier cannot know if ff has degree at most dd.

Fix the Problem 1

FRI commitment uses a multiplicative subset of Fp\mathbb{F}_p: Ω={ωi:ωn=1,i=0,1,,n1}\Omega=\{\omega^i:\omega^n=1,i=0,1,\dots,n-1\}, for example, {1,3,9,27,1,3,9,27}\{1,3,9,27,-1,-3,-9,-27\} in F41\mathbb{F}_{41}. The leaves of the Merkle tree will be the values f(ωi)f(\omega^i).

We call the rate ρ=dn\rho=\frac{d}{n} the FRI blowup factor.

Fix the Problem 2

ProverVerifierf0=f,degf0k1,Ω0={1,ω,,ωn1},n=ρ1kcom0=MerkleCommit(f0Ω0)round 1:  f0(X)=f0,e(X2)+Xf0,o(X2)r1r1$Fpf1(Z)=f0,e(Z)+r1f0,o(Z),degf1k21,Ω1={x2:xΩ0}com1=MerkleCommit(f1Ω1)round 2:  f1(X)=f1,e(X2)+Xf1,o(X2)r2r2$Fpf2(Z)=f1,e(Z)+r2f1,o(Z),degf2k41,Ω2={x2:xΩ1}com2=MerkleCommit(f2Ω2)......round log2k:  ft1(X)=ft1,e(X2)+Xft1,o(X2)rtrt$Fpft(Z)=ft1,e(Z)+rtft1,o(Z),degft=0,Ωt={x2log2k:xΩ0}comt=ftΩt verify that ftΩt is a constant vectorquery :  对于每个 jq,打开从第 t=log2k 层到第 0 层的路径:πt,jqMerkleOpen(comt,jq){jq}q=1s随机选择 j1,,js[0,Ωt1]πt1,jq+,πt1,jqMerkleOpen(comt1,对应的两个索引)...所有打开值+路径验证每条路径的一致性;同时,对于第 t 层: ft(ωtjq) 是常数对于第 i 层: 检查fi+1(z)=?ri+1+x2xfi(x)+ri+1x2xfi(x)其中 z=x2,x=ωij,ωi 是第 i 层的生成元\begin{align*} &\text{Prover} & & &\text{Verifier}\\ &f_0=f,\deg f_0\leq k-1,\Omega_0=\{1,\omega,\dots,\omega^{n-1}\},n=\rho^{-1}k &\xrightarrow{\mathsf{com}_0=\mathsf{MerkleCommit}(f_0|_{\Omega_0})} & &\\ \text{round }1:\; &f_0(X)=f_{0,e}(X^2)+Xf_{0,o}(X^2) &\xleftarrow{r_1} & &r_1\xleftarrow{\$}\mathbb{F}_p\\ &f_1(Z)=f_{0,e}(Z)+r_1f_{0,o}(Z),\deg f_1\leq\frac{k}{2}-1,\Omega_1=\{x^2:x\in\Omega_0\} &\xrightarrow{\mathsf{com}_1=\mathsf{MerkleCommit}(f_1|_{\Omega_1})} & &\\ \text{round }2:\; &f_1(X)=f_{1,e}(X^2)+Xf_{1,o}(X^2) &\xleftarrow{r_2} & &r_2\xleftarrow{\$}\mathbb{F}_p\\ &f_2(Z)=f_{1,e}(Z)+r_2f_{1,o}(Z),\deg f_2\leq\frac{k}{4}-1,\Omega_2=\{x^2:x\in\Omega_1\} &\xrightarrow{\mathsf{com}_2=\mathsf{MerkleCommit}(f_2|_{\Omega_2})} & &\\ &... & & &...\\ \text{round }\log_2k:\; &f_{t-1}(X)=f_{t-1,e}(X^2)+Xf_{t-1,o}(X^2) &\xleftarrow{r_t} & &r_t\xleftarrow{\$}\mathbb{F}_p\\ &f_t(Z)=f_{t-1,e}(Z)+r_tf_{t-1,o}(Z),\deg f_t=0,\Omega_t=\{x^{2^{\log_2k}}:x\in\Omega_0\} &\xrightarrow{\mathsf{com}_t=f_t|_{\Omega_t}\ } & &\text{verify that }f_t|_{\Omega_t}\text{ is a constant vector}\\ \text{query }:\; &\text{对于每个 }j_q,\text{打开从第 }t=\log_2k\text{ 层到第 }0\text{ 层的路径:}\pi_{t,j_q}\leftarrow\text{MerkleOpen}(\mathsf{com}_t,j_q)&\xleftarrow{\{j_q\}_{q=1}^s} & &\text{随机选择 }j_1,\dots,j_s\in[0,|\Omega_t|-1]\\ &\\ &\pi_{t-1,j_q^+},\pi_{t-1,j_q^-}\leftarrow\text{MerkleOpen}(\mathsf{com}_{t-1},\text{对应的两个索引})\\ &... &\xrightarrow{\text{所有打开值}+\text{路径}} & &\text{验证每条路径的一致性;同时,}\\ &&&& \text{对于第 }t\text{ 层: }f_t(\omega_t^{j_q})\text{ 是常数}\\ &&&& \text{对于第 }i\text{ 层: 检查}f_{i+1}(z)\stackrel{?}{=}\frac{r_{i+1}+x}{2x}f_i(x)+\frac{r_{i+1}-x}{-2x}f_i(-x)\\ &&&& \text{其中 }z=x^2,x=\omega_i^{j},\omega_i\text{ 是第 }i\text{ 层的生成元}\\ \end{align*}

Remark.

  • It is easy from fiΩif_i|_{\Omega_i} to fi+1Ωi+1f_{i+1}|_{\Omega_{i+1}}. This is because fi+1(x2)=fi,e(x2)+ri+1fi,o(x2)=fi(x)+fi(x)2+ri+1fi(x)fi(x)2xf_{i+1}(x^2)=f_{i,e}(x^2)+r_{i+1}f_{i,o}(x^2)=\frac{f_i(x)+f_i(-x)}{2}+r_{i+1}\frac{f_i(x)-f_i(-x)}{2x}. Also, the verifying process relies on this equation.
  • To analysis the soundness, we introduce the relative Hamming distance HamΩ(f,g)={xΩ:f(x)g(x)}Ω\mathsf{Ham}_{\Omega}(f,g)=\frac{|\{x\in\Omega:f(x)\not=g(x)\}|}{|\Omega|} and δ=minhFpk1[X](HamΩ(f,h))\delta=\min_{h\in\mathbb{F}_p^{\leq k-1}[X]}\left(\mathsf{Ham}_{\Omega}(f,h)\right), which is the distance on Ω\Omega of ff to the closest degree-(k1)(k-1) polynomial.
  • We consider ff such that δ1ρ\delta\leq 1-\sqrt{\rho}, which is to say, the ff is far from any degree-(k1)(k-1) polynomial.
  • A cheating prover has a high (>k1> k-1) degree polynomial ff. In case the prover is accepted, either it folds incorrectly, or it folds correctly and is lucky to have those rir_i’s that reduce the degree to 00 eventually. In the first case, the accept probability is (1δ)t\left(1-\delta\right)^t; in the second case, the accept probability is at most kp\frac{k}{p}. As a result, to reach an accept probability 2λ2^{-\lambda} (λ\lambda is the security parameter), ss should be Ω(λlogρ1)\Omega\left(\frac{\lambda}{\log\rho^{-1}}\right).

(The security proof is problematic.)

Polynomial commitment from FRI

The FRI introduces another two problems:

  • Prover has only committed to evaluations on a subset ΩFp\Omega\subset\mathbb{F}_p.
  • Verifier only knows that ff is close to a low-degree polynomial (in the sense of Hamming distance), but not necessarily a low-degree polynomial.

There is an attack to the first problem: the prover can commit to a polynomial gg that agrees with ff on TΩT\subset\Omega with much lower degree (T=k|T|=k). Then δ<1ρ<1ρ\delta<1-\rho<1-\sqrt{\rho} and the soundness is broken.

Then to confirm that f(r)=vf(r)=v where fFpd[X]f\in\mathbb{F}_p^{\leq d}[X], the prover applies FRI on the polynomial (f(x)v)/(xr)(f(x)-v)/(x-r), which has degree at most d1d-1.

Fiat-Shamir transform

Definition. (Interactive Security) A poly-commitment scheme runs at λ\lambda bits of interactive security if and only if: assume PP cannot find a collision of the hash function in the global parameters, then for every PP^*, the probability that PP^* can make the verifier accept a false claim is at most 2λ2^{-\lambda}.

To find out if a challenge is lucky, the prover should interact with the verifier at least 2λ2^\lambda times in average. It is unlikely that VV continues to interact after rejecting the same prover so many rounds. So following is the

Definition. (Non-interactive security) A poly-commitment scheme runs at λ\lambda bits of non-interactive security if and only if: for every PP^* willing to compute 2k2^k hashs, the probability that PP^* can make the verifier accept a false claim is at most 2kλ2^{k-\lambda}.

In this scheme, a lying PP can propose the grinding attack silently, without interacting. This definition is weaker than the interactive security, i.e., if a prover breaks the interactive security of one interactive protocol, then it can also break the non-interactive security of the Fiat-Shamir transform of that protocol.

We show that Fiat-Shamir transform may be insecure. Consider a protocol of the empty language. In this protocol, PP sends a nonce, and then VV sends a random bit rr, and accepts iff r=1r=1. The VV accepts iff every round it accepts, so the soundness error is 2λ2^{-\lambda} with λ\lambda rounds. However, the Fiat-Shamir transform of this protocol is insecure, since the prover can grind for a nonce 2 times per round in average, in order to find a nonce that leads to r=1r=1 for every round. The cost is 2λ2\lambda in average, which is much smaller than 2λ2^\lambda and the protocol does not satisfy the non-interactive security.

Applying Fiat-Shamir to a many-round interactive protocol can lead to a huge loss in security, whereby the resulting non-interactive protocol is totally insecure. So we need “round-by-round” soundness to describe the security of an interactive protocol, which means that for every prover in every round, if the prover is not “lucky” enough to make the verifier accept, then the probability that the prover can make the verifier accept in the next round is at most 2λ2^{-\lambda}.

The sum-check protocol is round-by-round sound, so its Fiat-Shamir transform is secure.

Linear PCP-based SNARK

Here is another paradigm for SNARKs: a cryptographic tool and a linear PCP builds a SNARK system. Before IOP and PCS paradigm was put forward, the main paradigm is PCP, e.g. Kilian’92 and Micali’00 is PCP+Merkle tree; IKO’07 is linear PCP; GGPR’13 uses QAP as linear PCP.

Quadratic Arithmetic Program (QAP)

QAP is another method to encode a circuit into a polynomial. Recall that in the first IOP for circuit SAT, we label each gate with a bitstring, and the satisfying value is encoded into a multilinear polynomial on the hypercube (interpolated to Fpn\mathbb{F}_p^n). In PLONK, we label each wire with an integer, and the satisfying value is encoded into a univariate polynomial on the roots of unity.

QAP labels all the input and output of all multiplicative gates. We label each gate with integers in [n][n] and each wire (except output wires of additive gate) with integers in [m][m]. The value of wire ii is cic_i. Then we define li(x)l_i(x) by li(ωj)=1,ωn=1l_i(\omega^j)=1,\omega^n=1, iff cic_i is the left input of the gate jj; and the same as ri(x)r_i(x), oi(x)o_i(x) for the right input and output.

Note that we say ii is the left input of gate jj also if ii passes several additive gates before it is the left input of gate jj. Then we have: the value on the circuit is proper iff

V(x)=i[n](xωi)  |  L(x)R(x)O(x)\left.V(x)=\prod_{i\in[n]}(x-\omega^i)\;\middle|\;L(x)R(x)-O(x)\right.

where

Lc(x)=i[m]cili(x),Rc(x)=i[m]ciri(x),Oc(x)=i[m]cioi(x)L_{\mathbf{c}}(x)=\sum_{i\in[m]}c_il_i(x),R_{\mathbf{c}}(x)=\sum_{i\in[m]}c_ir_i(x),O_{\mathbf{c}}(x)=\sum_{i\in[m]}c_io_i(x)

exactly encodes the left-input, right-input and output of gate jj with Lc(ωj)L_{\mathbf{c}}(\omega^j), Rc(ωj)R_{\mathbf{c}}(\omega^j), and Oc(ωj)O_{\mathbf{c}}(\omega^j).

Thus, the statement that PP knows ww such that C(x,w)=0C(x,w)=0 holds iff PP knows a vector c\mathbf{c} such that Lc(x)Rc(x)Oc(x)=q(x)i[n](xωi)=q(x)V(x)L_{\mathbf{c}}(x)R_{\mathbf{c}}(x)-O_{\mathbf{c}}(x)=q(x)\prod_{i\in[n]}(x-\omega^i)=q(x)V(x).

Constructing SNARK: [PGHR13] and [Groth16]

The global parameter is gp=((gτi)i[n],(gli(τ))i[m],(gri(τ))i[m],(goi(τ))i[m],gq(τ))gp=\left(\left(g^{\tau^i}\right)_{i\in[n]},\left(g^{l_i(\tau)}\right)_{i\in[m]},\left(g^{r_i(\tau)}\right)_{i\in[m]},\left(g^{o_i(\tau)}\right)_{i\in[m]},g^{q(\tau)}\right) where τ\tau is a random element (later deleted) in Fp\mathbb{F}_p.

With KZG in our hands, we reach to a simple protocol: The prover can compute πl=gLc(τ)\pi_l=g^{L_{\mathbf{c}}(\tau)}, πr=gRc(τ)\pi_r=g^{R_{\mathbf{c}}(\tau)}, πo=gOc(τ)\pi_o=g^{O_{\mathbf{c}}(\tau)}, and π=gq(τ)\pi=g^{q(\tau)} by homomorphically combining the global parameters. The verifier checks if e(πl,πr)=e(πo,g)e(π,gV(τ))e(\pi_l,\pi_r)=e(\pi_o,g) e(\pi,g^{V(\tau)}).

However, the protocol is far from the real protocol.

Problem 1: How to make sure that πl\pi_l is computed from gli(τ)g^{l_i(\tau)}?

KoE Assumption. We use gp=(gli(τ),gαli(τ))i[m]gp=(g^{l_i(\tau)},g^{\alpha l_i(\tau)})^{i\in[m]}. If the prover can compute π1=gicili(τ)\pi_1=g^{\sum_ic_il_i(\tau)} and π2=gαicili(τ)\pi_2=g^{\alpha \sum_ic_il_i(\tau)} without knowing α\alpha, then there is an extractor that can extract cic_i’s from the prover. The Pinocchio [PGHR13] uses KoE assumption.

GGM Assumption. Any prover can only compute linear combinations of gli(τ)g^{l_i(\tau)}’s, i.e., if the prover can compute π=gicili(τ)\pi=g^{\sum_ic_il_i(\tau)}, then it must know every cic_i. [Groth16] uses GGM assumption.

Problem 2: How to make sure every π\pi share the same cic_i’s?

We use another random β\beta for setup (also deleted after setup). We add gβ(li(τ)+ri(τ)+oi(τ))g^{\beta(l_i(\tau)+r_i(\tau)+o_i(\tau))} and gβg^{\beta} to the global parameters.

Problem 3: How to handle the public input and the expected output?

Recall that all the wires except the output of add gates are labelled. So the input wire and output wire (if not labelled, add a multiply 11 gate) are labelled with IioI_{io} . The idea is to split LcL_{\mathbf{c}} apart, and let verifier compute iIiocili(x)\sum_{i\in I_{io}}c_il_i(x).

Analysis

  • Setup: O(n)O(n) group exps, since there is a unique jj that makes li(ωj)=1l_i(\omega^j)=1 , if we label different wires with a same output gate with different labels.
  • Prover: O(nlogn)O(n\log n) for NTT. The prover computes the values of polynomial qq on the unity set ω\langle\omega\rangle and uses NTT to get its coefficients. Only with coefficients can the prover compute gq(τ)g^{q(\tau)} . Also, O(n)O(n) group exps.
  • Proof size: O(1)O(1)
  • Verifier: O(1)O(1) for pairing, O(Iio)O(|I_{io}|) group exps.

Recursive SNARKs

Recall if the circuit size is nn:

  • Pinocchio and Groth16: prover time O(nlogn)O(n\log n) and proof size O(1)O(1)
  • PLONK-KZG: prover time O(nlogn)O(n\log n) (every gadgets the prover should compute NTT) and proof size O(1)O(1)
  • FRI-based: prover time and proof size O(log2n)O(\log^2 n)

How can we achieve the better one in both prover time and proof size? The recursive proof provides a “proof of proof”. Let the inner system be (S,P,V)(S,P,V) , which proves that the prover knows the ww such that C(x,w)=1C(x,w)=1 . Suppose that the prover and verifier PP and VV is fast but the proof π\pi is long, the idea is to construct another proof system (S,P,V)(S^\prime,P^\prime,V^\prime) proving that the prover knows the π\pi such that V(vp,x,π)=1V(vp,x,\pi)=1 . This outer system has slower prover, but since the verifier VV is fast, the circuit of VV is much smaller than that of the original CC . So the outer prover PP^\prime is not so slow, as we expected.

A simple argument shows that if (S,P,V)(S,P,V) and (S,P,V)(S^\prime,P^\prime,V^\prime) are both knowledge sound, then the integrated proof system is also knowledge sound. The idea of proof is to regard the extractor EE^\prime as a malicious prover of (S,P,V)(S,P,V) . The probability gap is the sum of those of the original prove systems, thus negligible.

Application 1: incrementally verifiable computation

Suppose that a computation FF is applied to initial state s0s_0 recursively, each round takes an input wiw_i . The prover wants to prove that it knows the wiw_i ’s such that each computation step is correct. The verifier wants to verify that after nn steps, the state s0s_0 eventually becomes sns_n . (TODO)

Application 2: streaming proof generation

Suppose there is a bunch of transactions to be proved. We need not wait the transactions all to take place; rather, we generate proofs on every arrival of batches. For example if the batch size is 11 , first π1\pi_1 proves the prover knows w1w_1 that C(x1,w1)=0C(x_1,w_1)=0 ; then π2\pi_2 proves that the prover knows w2w_2 such that C(x2,w2)=0C(x_2,w_2)=0 . Then a proof is generated to prove that the prover knows π1,π2,\pi_1,\pi_2,\dots such that the verifier accepts them all.

Construction: alternating groups

Recall in KZG, the public parameter is a tuple (p,G,q,g,e)(p,G,q,g,e) , where GG is a group of order pp with gg its generator. And in this section, we regard the verifier algorithm as a circuit, so we had better embed GG into some vector space over Fq\mathbb{F}_q .

Definition (Algebraic Groups). Group GFqG\leq\mathbb{F}_q^\ell is an algebraic group if and only if
  • there are polynomials f1,,fFq[X]f_1,\dots,f_\ell\in\mathbb{F}_q[X^\ell] such that for all a,bGa,b\in G , a+b=(f1(a,b),,f(a,b))a+b=\left(f_1(a,b),\dots,f_\ell(a,b)\right) ;
  • there is an efficient algorithm testing if a=ba=b .

Can we make G=p|G|=p a subgroup of Fp\mathbb{F}_p^\ell ? No, because the discrete log is trivial in such groups. Take Smart Attack in the anomalous curve for an example.

The idea is to construct a group chain that: G1=p|G_1|=p , G1<FqG_1<\mathbb{F}_q^\ell ; G2=q|G_2|=q , G2<FrG_2<\mathbb{F}_r^\ell . The original circuit CC is over Fp\mathbb{F}_p . The KZG PCS will help us understand this recursive SNARK, because in that scheme, an exponentiation embeds every elements in Fp\mathbb{F}_p into G1<FqG_1<\mathbb{F}_q^\ell . Now that VV is a circuit over Fq\mathbb{F}_q , the proof that the prover PP^\prime knows a proof π1\pi_1 involves group arithmetic on Fq\mathbb{F}_q . Since G2G_2 has order qq , then PP^\prime sends a proof in G2G_2 .

However it is inefficient to have two pairing groups. For one pairing group and another non-pairing group, we can use KZG for one and bulletproofs for the other. The Halo is based on two non-pairing groups, i.e. elliptic group E(Fp)E(\mathbb{F}_p) and E(Fq)E(\mathbb{F}_q) of the elliptic curve y2=x3+5y^2=x^3+5 . Details https://eprint.iacr.org/2019/1021.pdf

Construction: folding

Another idea is homomorphic commitment, which we can compute a commitment of an addition simply by adding the commitments. We use this to prove two circuits at once (generate one proof for the two circuits) . More precisely, all circuits can be written in R1CS form (Az)(Bz)=Dz(Az)\circ(Bz)=Dz . An idea to prove two instance z1=(x1,w1),z2=(x2,w2)z_1 = (x_1, w_1),z_2 = (x_2, w_2) of the same R1CS at one time is to randomly choose an rr and prove for some R1CS, the combination z1+rz2z_1+rz_2 is feasible. However, we cannot have (Az1+rAz2)(Bz1+rBz2)=D(z1+rz2)(Az_1+rAz_2)\circ(Bz_1+rBz_2)=D(z_1+rz_2) if z1,z2z_1,z_2 are feasible inputs. Thus we turn to modify the definition and put forward Relaxed R1CS.

HW

  • ❎ Knowledge soundness is a meaningful notion when a prover claims that there are no satisfying assignments to a system of constraints
  • ❎ Knowledge soundness is a meaningful notion for the sumcheck protocol
  • ✅ Knowledge soundness (as defined in lecture 2) implies soundness
  • ❎ Non-interactive implies publicly verifiable
  • ❎ Vector commitments are as expressive as polynomial commitments
  • ✅ Polynomial extensions are distance amplifying encodings
  • ✅ Multivariate polynomial encoding reduces the total degree by an exponential factor compared to univariate polynomial encoding
  • ✅ The verifier in the sum-check protocol is oblivious to the polynomial g whose evaluations are being summed until the last step
  • ❎ The uniqueness of multilinear extensions is crucial for the soundness of the sumcheck protocol
  • ❎ The claim f(x) = g(x) for all k-bit inputs, where f and g are low degree polynomials over a large field, can be reduced to the following sumcheck claim: _{x ^k} (f(x)-g(x)) = 0
  • ❎ The polynomial IOP for SAT (from lecture 4) can be transformed into a SNARK with verifier complexity independent of circuit size
  • ✅ The polynomial IOP for SAT (from lecture 4) has optimal prover complexity
  • ✅ Extending the polynomial IOP for SAT in the natural way to support gates with n inputs will result in a sumcheck protocol over (n+1) * logS variables

verkle trees