前一段时间,介绍了零知识证明的入门知识,通过QSP问题证明来验证另外一个NP问题的解。最近在看QAP问题相关的文章和资料,这篇文章分享一下QAP问题的理解。
0 背景介绍
QSP/QAP问题的思想都是出自2012年一篇论文:Quadratic Span Programs and Succinct NIZKs without PCPs。论文的下载地址:https://eprint.iacr.org/2012/215.pdf。

这篇论文提出了使用QSP/QAP问题,而不使用PCP方式,实现零知识证明。
1 术语介绍
SP - Span Program ,采用多项式形式实现计算的验证。
QSP - Quadratic Span Program,QSP问题,实现基于布尔电路的NP问题的证明和验证。
QAP - Quadratic Arithmetic Program,QAP问题,实现基于算术电路的NP问题的证明和验证,相对于QSP,QAP有更好的普适性。
PCP - Probabilistically Checkable Proof ,在QSP和QAP理论之前,学术界主要通过PCP理论实现计算验证。PCP是一种基于交互的,随机抽查的计算验证系统。
NIZK - Non-Interactive Zero-Knowledge,统称,无交互零知识验证系统。NIZK需要满足三个条件:1/ 完备性(Completeness),对于正确的解,肯定存在相应证明。 2/可靠性 (Soundness) ,对于错误的解,能通过验证的概率极低。3/ 零知识。
SNARG - Succinct Non-interactive ARGuments,简洁的无须交互的证明过程。
SNARK - Succinct Non-interactive ARgumentss of Knowledge,相比SNARG,SNARK多了Knowledge,也就是说,SNARK不光能证明计算过程,还能确认证明者“拥有”计算需要的Knowledge(只要证明者能给出证明就证明证明者拥有相应的解)。
zkSNARK - zero-knowledge SNARK,在SNARK的基础上,证明和验证双方除了能验证计算外,验证者对其他信息一无所知。
Statement - 对于QSP/QAP而言,某个计算电路的输入。Statement对证明者和验证者都是公开的。
Witness - Witness只有证明者知道。可以理解成,某个计算电路的输出(output)。
2 QAP问题和算术电路
QAP的定义和QSP的定义有些相似(毕竟都是一个思想理论的两种形式)。论文中给出了QAP的一般定义和强定义。QAP的强定义如下:
QAP问题是这样一个NP问题:给定一系列的多项式,以及给定一个目标多项式,找出多项式的组合能整除目标多项式。输入为n位的QAP问题定义如下:
- 给定多个多项式:v0,...,vm,w0,...,wm,y0,...,ym
- 目标多项式:t
- 映射函数:f:{(i,j)∣1≤i≤n,j∈0,1}→{1,...m} (确定输入对应的序号)
给定一个证据u(由Statement,Witness以及中间门电路的输出组成),满足如下条件,即可验证u是QAP问题的解:
- (v0(x)+∑k=1mak⋅vk(x))⋅(w0(x)+∑k=1mbk⋅wk(x))−(y0(x)+∑k=1mck⋅yk(x))能整除t(x)
对一个证据u,多项式之间的系数(a1,...,am,和b1,...,bm,以及c1,...,cm 相等)。
算术电路可以简单看成由如下的三种门组成:加门,系数乘法门以及通用乘法门(减法可以转化为加法,除法可以转化为乘法)。Vitalik在2016年写过的QAP介绍,深入浅出的解释NP问题的算术电路生成和QAP问题的转化。推荐大家都读一读。
https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649
以Vitalik文章中的例子为例,算术逻辑(x3+x+5)对应的电路如下图所示:

3 算术问题转化为QAP问题
把一个算术电路转化为QAP问题的过程,其实就是将电路中的每个门描述限定的过程,也就是所谓的R1CS (Rank-1 constraint system)。
3.1 算术电路拍平
算术电路拍平,就是用一组向量定义算术电路中的所有的变量(包括一个常量变量)。比如2中所示的电路,拍平之后的向量表示为[one,x,out,sym_1,y,sym_2],其中one代表常量变量,x代表输入,out代表输出,其他是中间门电路的输出。
假设一个合理的电路向量值为s−[s0,s1,s2,s3,s4,s5]。
3.2 门描述
对于每个电路中的门进行描述,说清输入以及输出,采用s⋅a∗s⋅b−s⋅c=0的形式,其中a,b,c都是和电路向量长度一致的向量值。s⋅a,s⋅b,s⋅c都是点乘。这种形式表达的是“乘法门”。可以简单的理解,a,b,c和s的点乘就是“挑选”向量中的变量,查看挑选出的变量是否满足A∗B=C。
各个门对应的a,b,c的向量值如下:
门1 (查看x∗x是否等于sym_1):
a=[0,1,0,0,0,0]
b=[0,1,0,0,0,0]
c=[0,0,0,1,0,0]
门2 (查看sym_1∗x是否等于y):
a=[0,0,0,1,0,0]
b=[0,1,0,0,0,0]
c=[0,0,0,0,1,0]
门3 (查看(x+y)∗1是否等于sym_2):
a=[0,1,0,0,1,0]
b=[1,0,0,0,0,0]
c=[0,0,0,0,0,1]
门4 (查看(5x+sym_2)∗1是否等于out):
a=[5,0,0,0,0,1]
b=[1,0,0,0,0,0]
c=[0,0,1,0,0,0]
3.3 多项式表达
在门电路描述的基础上,将所有的门电路,转化为多项式表达。将a,b,c中的每个系数,看成一个多项式的结果(以a为例):a=[f0(x),f1(x),f2(x),f3(x),f4(x),f5(x)]。
针对门1/门2/门3/门4,f0(x),f1(x),f2(x),f3(x),f4(x),f5(x)的取值不同。比如说,门1的a的f0(x)为0。门2的a的f0(x)为0。门3的a的f0(x)为0。门4的a的f0(x)为5。
设定门1对应的x为1,门2对应的x为2,门3对应的x为3,门4对应的x为4的话(这些值可以任意指定),会得到如下的等式:
f0(1)=0,f0(2)=0,f0(3)=0,f0(4)=5
在获知一系列的输入和输出的前提下,可以通过拉格朗日定理,获取多项式表达式。小伙伴可以通过如下的工具计算多项式:http://skisickness.com/2010/04/28/。


也就是说,a的f0(x)=−5+9.167x+−5x2+0.833x3。同样的方式,可以算其他参数的f0(x),f1(x),f2(x),f3(x),f4(x),f5(x)。再把这些多项式代入s⋅a∗s⋅b−s⋅c=0,在正确的s向量值的情况下,1/2/3/4能让等式成立,也就是说,多项式s⋅a∗s⋅b−s⋅c能整除(x−1)(x−2)(x−3)(x−4)。这样,一个算术电路就转化为了QAP问题。
4 QAP问题的zkSNARK证明
QAP问题的zkSNARK证明过程和QSP有点类似。skSNARK证明过程分为两部分:a) setup阶段 b)证明阶段。QAP问题就是给定一系列的多项式v0,...,vm,w0,...,wm,y0,...,ym以及目标多项式t,证明存在一个证据u。这些多项式中的最高阶为d。
4.1 setup和CRS
CRS - Common Reference String,也就是预先setup的公开信息。在选定s和α的情况下,发布如下信息:
-
s和α的计算结果
E(s0),E(s1),...,E(sd)
E(αs0),E(αs1),...,E(αsd)
-
多项式的α对的计算结果
E(t(s)),E(αt(s))
E(v0(s)),...E(vm(s)),E(αv0(s)),...,E(αvm(s))
E(w0(s)),...E(wm(s)),E(αw0(s)),...,E(αwm(s))
E(y0(s)),...E(ym(s)),E(αy0(s)),...,E(αym(s))
-
多项式的βv,βw,βy,γ 参数的计算结果
E(γ),E(βvγ),E(βwγ),E(βyγ)
E(βvv1(s)),...,E(βvvm(s))
E(βww1(s)),...,E(βwwm(s))
E(βyy1(s)),...,E(βyym(s))
E(βvt(s)),E(βwt(s)),E(βyt(s))
4.2 证明者提供证据
在QAP的映射函数中,1,...,m中有些数字没有映射到,也就是除了输入之外的序号。这些没有映射到的序号(中间门电路和输出)组成Ifree,并定义(k为未映射到的序号):
vfree(x)=k∑akvk(x)
证明者需提供的证据如下
- Vfree:=E(vfree(s)), W:=E(w(s)), Y:=E(y(s)), H:=E(h(s)),
- Vfree′:=E(αvfree(s)),W′:=E(αw(s)),Y′:=E(αy(s)),H′:=E(αh(s)),
- P:=E(βvvfree(s)+βww(s)+βyy(s))
Vfree/Vfree′,W/W′,Y/Y′,H/H′是α对,用以验证vfree,w,y,h是否是多项式形式。t是已知,公开的,毋需验证。P用来确保vfree(s),w(s)和y(s)的计算采用一致的参数。
4.3 验证者验证
在QAP的映射函数中,1,...,m中所有映射到的序号(输入序号)作为组成系数组成的二项式定义为(和vfree互补):
vin(x)=k∑akvk(x)
验证者需要验证如下的等式是否成立:
- e(Vfree′,g)=e(Vfree,gα),e(W′,E(1))=e(W,E(α)),e(Y′,E(1))=e(Y,E(α)),e(H′,E(1))=e(H,E(α))
- e(E(γ),P)=e(E(βvγ),Vfree)e(E(βwγ),W)e(E(βyγ),Y)
- e(E(v0(s))E(vin(s))Vfree,E(w0(s))W)=e(H,E(t(s)))e(y0(s)Y,E(1))
第一个(系列)等式验证Vfree/Vfree′,W/W′,Y/Y′,H/H′是否是α对。
第二个等式验证Vfree,W,Y的计算采用一致的参数。因为vfree,w,y都是二项式,它们的和也同样是一个多项式,所以采用γ 参数进行确认。证明过程如下:
e(E(γ),P)=e(E(γ),E(βvvfree(s)+βww(s)+βyy(s)))=e(g,g)γ(βvvfree(s)+βww(s)+βyy(s))
e(E(βvγ),Vfree)e(E(βwγ),W)e(E(βyγ),Y)=e(E(βvγ),E(vfree(s)))e(E(βwγ),E(w(s)))e(E(βyγ),E(y(s)))
=e(g,g)(βvγ)vfree(s)e(g,g)(βwγ)w(s)e(g,g)(βyγ)y(s)=e(g,g)γ(βvvfree(s)+βww(s)+βyy(s))
第三个等式验证v(s)w(s)−y(s)=h(s)t(s),其中v0(s)+vin(s)+vfree(s)=v(s)。
简单的说,逻辑是确认v,w,y,h是多项式,并且v,w,y采用同样的参数,满足v(s)w(s)−y(s)=h(s)t(s)。
到目前为止,整个QAP的zkSNARK的证明过程逻辑已见雏形。
4.4 δ 偏移
为了进一步“隐藏” Vfree,W,Y,额外需要采用两个偏移: δfree,δw和δy。 vfree(s)/w(s)/y(s)/h(s)进行如下的变形,验证者用同样的逻辑验证。
vfree(s)→vfree(s)+δfreet(s)
w(s)→w(s)+δwt(s)
y(s)→y(s)+δyt(s)
h(s)→h(s)+δfree(w0(s)+w(s))+δw(v0(s)+vin(s)+vfree(s))+(δfreeδw)t(s)−δy
总结:QAP和QSP问题类似。QSP问题主要用于布尔电路计算表达,QAP问题主要用于算术电路计算表达。将一个算术电路计算转化为QAP问题的过程,其实就是对电路中每个门电路进行描述限制的过程。通过朗格朗日定理,实现算术电路的多项式表达。QAP问题的zkSNARK的证明验证过程和QSP非常相似。
