首先,zk-SNARK不能直接应用于任何计算问题;相反,您必须将问题转换为操作的正确“形式”。这种形式被称为“二次算术程序”(QAP),将函数的代码转换成这些代码本身就非常重要。与将函数代码转换为QAP的过程一起运行的还有另一个过程,这样,如果对代码有输入,就可以创建相应的解决方案(有时称为QAP的“见证”)。
首先第一步将所要求的等式转化为电路如上图。转化成电路的方法可以手动操作,也可以学习最近新出的XJsnark,其可以将你所需的代码转化为电路。
这样原始等式(以后称作等式F)就转化为4个式子如上图右侧。
R1CS是由三个向量(a, b, c)组成的序列,R1CS的解是一个向量s,其中s必须满足方程
s . a * s . b - s . c = 0(s.a表示内积运算,相应相应位置相乘再相加)
接下来需要进行的是如何将电路的4个式子变成以上图中的式子。
拿第一个式子举例:
我们假设此多项式的解表示为[1,x,y,y1,y2,y3],(未知数的顺序可以换)图中表示为s。
第一个多项式是:x*x-y1 = 0
对比s . a * s . b - s . c = 0可以得出:
s . a =x ----->a=[0,1,0,0,0,0]
s . b=x ------>b=[0,1,0,0,0,0]
s . c =y1 ------>c=[0,0,0,1,0,0]
其他三个式子同道理。
这里需要点明一下,回归到问题本身,我们想证明原多项式的解x,但是经过变换后,该解变成了向量s
我们在求完4个式子的R1CS后,这四个结果其实表示的意义是解向量s的约束,也就是说s必须满足这四个式子。
接下来进行最后一步将R1CS转化为QAP,这里用到了拉格朗日插值的方法。
首先介绍一下上图的意思:
上图是我们算的4个等式的R1CS转化后的a向量的值。我们把其组合为A矩阵,分别表示为A(1)……,
A(n)表示拉格朗插值后的值,例如:
看上图右边的A1(n)的y值取自A矩阵的第一列,A2(n)同理,算完6列后组成最终的A(n),如上图左边6个式子就是算完后A的结果。
接下来介绍为什么那么取点。
介绍一下拉格朗日插值:
*它的提出是对于某一个未知函数的一组观测或者实验数据,寻找一个多项式函数,使这个多项式函数能够过这些点。*
这两者的区别是 QAP 使用多项式来代替点积运算,他们所实现的逻辑完全相同。在介绍这种转化之前,我们需要学习拉格朗日差值公式,这个公式的作用是构造一个穿过指定点的多项式,Vitalik 的文章中用了很大的篇幅介绍这个公式的使用,在这里我直接给出拉格朗日插值公式:
好了,学会使用这个公式后可以继续我们的步骤了。现在我们要将四个长度为六的三向量组转化为六组多项式,每组多项式包括三个三阶多项式,我们在每个x点处来评估不同的约束,在这里,我们共有四个约束**,因此我们分别用多项式在 x = 1,2,3,4 处来评估这四个向量组。现在我们使用拉格朗日差值公式来将 R1CS 转化为 QAP 形式。**
我们先求出四个约束所对应的每个 a 向量的第一个值的多项式,也就是说使用拉格朗日插值定理求过点 (1,0), (2,0), (3,0), (4,0) 的多项式,类似的我们可以求出其余的四个约束所对应的每个向量的第i个值的多项式。
我们算完后一共有18个式子,将n=1带入18个式子后,可以恢复到第一个约束的三个向量(a,b,c),也就是说我们通过x=1 ,2,3,4 就可以恢复到相应的约束的三个向量。
这时再看一次这个图可能会清晰一些!!
这样的话我们就完成了QAP的转化。
稍微总结一下整个过程:
回归问题:我们用ZKSNARK来解决问题但是必须符合其数据的格式,也就是需要进行QAP的转化。(也就是使用浮点数计算则必须把整数先转化为浮点数的格式才可以)
数学是计算机的基础啊!!
最后一步发现原式子提取出一个Z(n),因为原来式子有1,2,3,4解,所以可以提取出Z(n),Z(n)是公开的,两者都知道,所以可以用以下方式进行简单验证: