- tags: blockchain
- date: 2022-09-04
- Zero Knowledge: 即0知识,不暴漏要证明的原始信息
- Succinct:证据信息比较短,方便验证
- Non-interactive:无交互的,prover只需要提供一个字符串即可。这点对于区块链应用非常重要,意味着可以把消息放在链上公开验证
- Arguments:证明过程的是计算完好的,即 prover 没发在合理的时间内伪造一个 proof 信息。跟计算完好对应的是理论完好,密码学上一般要求计算完好即可
- Of knowledge:保证证明者在不知晓密文的情况下构建出一个有效的零知识 proof 是不可能的
同态加法满足一下3个性质
- 对于大部分的 x,在给给定 E(x) 的情况下很难求解出 x
- 不同输入会得到不同的输出,if x ≠ y, then E(x) ≠ E(y)
- 如果某人知道 E(x) and E(y),则他可以计算出 E(x+y)
如果 A 有两个数字 x、y,他需要向 B 证明数字之和是 z,那么需要一下步骤:
- A 计算出 E(x), E(y) 并发送给 B
- B 通过A 发来的 E(x) E(y) 计算出 E(x+y)
- B 计算出 E(z) and assert E(z) == E(x+y)
基于椭圆曲线的算法 RSA、ECC 都支持同态加法运算,具体原理参考这个讲解:
https://www.bilibili.com/video/BV1BY411M74G
利用同态加法的特性,我们可以简单的把零知识证明推广到多项式中。假设 A 知道一个最高 d 次的多项式 P,而 B 想要知道对应的某个 s 的
- 对与 s 的每个指数,B计算出
$E(s^0),E(s^1),E(s^2)…E(s^d)$ 并发送给 A - A 知道所有多项式的系数,则
$E(P(s)) = \sum_{i=0}^d E(a_i) \cdot E(s^i)$
上面 A 计算出来的
- 当
$\alpha$ 很大的情况下,很难通过 a、b 推导出$\alpha$ 的值 - 满足加法和乘法的结合律,满足同态隐藏
- B 随机生成一个
$\alpha$ 对 (a,b),$\alpha$ 自己保存,(a,b) 发送给 A - A 选择一个
$\gamma$ 生成$(a’, b’) = (\gamma \cdot a, \gamma \cdot b)$ 回传给 B,则 B 可以验证$(a’, b’)$ 也是一个$\alpha$ 对,证明使用了乘法结合律:$b' = \gamma \cdot b = \gamma \cdot \alpha \cdot a = \alpha \cdot (\gamma \cdot a) = \alpha \cdot a'$ - B 校验
$(a’, b’)$ 也是一个$\alpha$ 对则能证明 A 知道$\gamma$ ,并且满足$a’=\gamma \cdot a$ 即证明了 A 知道 a 与 a’ 之间存在线性关系$\gamma$
上面 B 验证了 A 知道一个常数
结合前面多项式同态中不能确保 A 知道常数数组缺点可以改进一下,确保 B 能够验证 A 知道真正的多项式系数:
- 因为椭圆曲线符合同态特性,则令A, B 共同选择
$x \cdot g$ 作为$E(x)$ - B 计算
$s^0 \cdot g, s^1 \cdot g, ... s^d \cdot g$ 和$\alpha \cdot s^0 \cdot g, \alpha \cdot s^1 \cdot g, ... \alpha \cdot s^d \cdot g$ 发送给 A,实际上就是发送 各个$E(s^i)$ 的同时增加了$E(a \cdot s^i)$ 的数据;$(s^d \cdot g, \alpha s^d \cdot g)$ 是一$\alpha$ 对 - A 根据上面 B 发送的结果计算出
$a = P(s) \cdot g, b = \alpha \cdot P(s) \cdot g$ , 并且把 a, b 回传给 B - B 验证
$b=\alpha \cdot a$ , 即 (a, b) 是一个$\alpha$ 对即可证明 a 即是要求的$E(P(s))$
https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649
QAP 过程可以将任意计算关系转换成一个多项式证明。举个例子比如我们想证明我们知道一个数 x 使得
Computation → Arithmetic Circuit → R1CS → QAP
即把原来的高阶多项式关系转化为一阶关系,即加法和乘法。每个加法或乘法即使一个约束条件,我们称之为一个门电路,例如上面例子的约束关系转化为下面四个一阶约束:
- sym_1 = x * x
- y = sym_1 * x
- sym_2 = y + x
- ~out = sym_2 + 5 ( ~out = 35)
R1CS(Rand-1 Constraint System)是指由
那么针对第一个约束 sym_1 = x * x 我们可以得到向量组:
a = [ 0, 1, 0, 0, 0, 0 ]
b = [ 0, 1, 0, 0, 0, 0 ]
c = [ 0, 0, 0, 1, 0, 0 ]
a = [ 0, 1, 0, 0, 0, 0 ]
b = [ 0, 1, 0, 0, 0, 0 ]
c = [ 0, 0, 0, 1, 0, 0 ]
此时,对于向量 s,我们能确定它的第二个标量和第四个标量是2次幂关系,比如 [ 0, 3, 0, 9, 0, 0 ] 或者 [ 0, 7, 0, 49, 0, 0]
对于后面的 2、3、4 个约束条件我们可以表示为
a = [0, 0, 0, 1, 0, 0]
b = [0, 1, 0, 0, 0, 0]
c = [0, 0, 0, 0, 1, 0]
a = [0, 1, 0, 0, 1, 0] (y+x)
b = [1, 0, 0, 0, 0, 0] 对应常数 1
c = [0, 0, 0, 0, 0, 1]
a = [5, 0, 0, 0, 0, 1] 对应(sym_2 + 5)
b = [1, 0, 0, 0, 0, 0] 常数 1
c = [0, 0, 1, 0, 0, 0]
现在,我们假设 x = 3 根据第一个门,得到 sym_1 = 9,根据第二个门得到 y = 27,根据第三个门,得到 sym_2 = 30,根据第四个门得到 ~out = 35,所以 s = [ 1, 3, 35, 9, 27, 30 ]
-
此时我们针对 a,b,c 各自得到了 4 个约束条件:
A [0, 1, 0, 0, 0, 0] [0, 0, 0, 1, 0, 0] [0, 1, 0, 0, 1, 0] [5, 0, 0, 0, 0, 1] B [0, 1, 0, 0, 0, 0] [0, 1, 0, 0, 0, 0] [1, 0, 0, 0, 0, 0] [1, 0, 0, 0, 0, 0] C [0, 0, 0, 1, 0, 0] [0, 0, 0, 0, 1, 0] [0, 0, 0, 0, 0, 1] [0, 0, 1, 0, 0, 0]
使用多项式形式而不是内积(R1CS)来描述这些约束关系的方法即是 QAP。我们需要把 4 组长度为 6 的 3 个向量 转化为 6(因为系统中又6个符号) 组 3(因为系统中又4个约束条件,即4个点,通常多项式中d个点可以确定 d-1阶多项式) 阶多项式。在每个约束条件的 x 坐标处的值代表一个约束条件。满足4个约束我们可以分别确定 a 向量每个标量的约束多项式。
针对 A 的第一个标量,四个约束条件确定的 4个点(x, y) 分别是(1,0), (2,0), (3,0), ***(4,5),***那么这个问题就变成了求过以上四个点的 3 阶多项式的各个系数,这个多项式描述了 A 的第一个标量的约束。
求过 n 个点的多项式,可以使用 拉格朗日插值定理 https://en.wikipedia.org/wiki/Lagrange_polynomial 具体过程不再详述。至此我们得到了 A 向量第一个标量的约束多项式,可以记为一个 3 个元素的向量,由此推算,我们可以计算出 A、B、C 每个标量的约束多项式,V 神用 Python实现了计算过程:/~https://github.com/ethereum/research/tree/master/zksnark
-
这里直接给出计算结果
(1,0), (2,0), (3,0), (4,5) 的多项式,类似的我们可以求出其余的四个约束所对应的每个向量的第i个值的多项式。 这里,直接给出答案: A polynomials [-5.0, 9.166, -5.0, 0.833] [8.0, -11.333, 5.0, -0.666] [0.0, 0.0, 0.0, 0.0] [-6.0, 9.5, -4.0, 0.5] [4.0, -7.0, 3.5, -0.5] [-1.0, 1.833, -1.0, 0.166] B polynomials [3.0, -5.166, 2.5, -0.333] [-2.0, 5.166, -2.5, 0.333] [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] C polynomials [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] [-1.0, 1.833, -1.0, 0.166] [4.0, -4.333, 1.5, -0.166] [-6.0, 9.5, -4.0, 0.5] [4.0, -7.0, 3.5, -0.5]
这些是系数为升序的多项式排列,例如第一个多项式表达的是
-
我们将 x=1 带入这个 18 个多项式,可以得到结果:
A results at x=1 0 1 0 0 0 0 B results at x=1 0 1 0 0 0 0 C results at x=1 0 0 0 1 0 0
可以看到,结果就是我们第一个门电路的约束条件,同理后面 3 个门电路约束条件也是这样。
R1CS 中需要单独的检查每一个约束满足
这种情况下,如果得到的多项式在我们上面的4个约束门电路中么一个x坐标处的值都是0就意味着验证通过,否则如果有一个非0值,那么就意味着验证不通过。
事实上我们不计算多项式
事实上,如果一个约束系统确定之后,那么它的约束多项式 QAP 和 T 就确定了,这只需要在系统构建的时候运算一次,后面可以重复使用
-
我们使用上面 R1CS 里的 s 来验证我们得到的中间多项式
A . s = [43.0, -73.333, 38.5, -5.166] B . s = [-3.0, 10.333, -5.0, 0.666] C . s = [-41.0, 71.666, -24.5, 2.833] 其中: 43.0 = -5 * 1 + 8 * 3 + 0 * 35 - 6 * 9 + 4 * 27 - 1 * 30 -73.333 = 9.166 * 1 - 11.333 * 3 + 0 * 35 + 9.5 * 9 - 7 * 27 + 1.833 * 30 ... -3 = 3 * 1 - 2 * 3 + 0 * 35 + 0 * 9 + 0 * 27 + 0 * 30 ...
P = A . s * B . s - C . s = [-88.0, 592.666, -1063.777, 805.833, -294.777, 51.5, -3.444]
T = (x - 1) * (x - 2) * (x - 3) * (x - 4) = [24, -50, 35, -10, 1]
H = P / T = [-3.666, 17.055, -3.444] 没有余数,则验证通过
如果伪造 R1CS 的解 s,则带入上面的运算 h 将包含余数,不能通过验证
至此我们看到将任意一个运算约束关系转化成了证明满足某个多项式关系的问题。但是注意这里我们将原计算的4个约束关系转化成了一个多项式,相当于中间插入了很多没有意义的取值,这是是与元计算无关的点,也就是说多项式的验证与原计算的验证本质上不是一一等价的,但是验证了多项式也就验证了元计算。
我们定义
- A 按照 QAP 方式选出多项式 L、R、O、H
- B 随机选择取样点 s, 计算 E(T(s))
- A 计算出 E(L(s)), E(R(s)), E(O(s)), E(H(s)),根据 B 发过来的 E(s) E(s^2)…
- B 校验 E(L(s)*R(s)-O(s))=E(H(s)*T(s))
那么这里面仍有几个问题:
我们定义了
定义:
即只要 A 能证明 F 和
- B 选择
$\alpha$ ,并计算$E(\alpha \cdot F_i)$ 并发送给 A - A 计算
$E(\alpha F)$ 并回传给 B - B 计算 E(F) 并校验
$\alpha$ 对
如果如果需要验证的问题解 s 不多的情况下,B可以通过暴力穷举的方式倒推出原来的多项式,得到A得原始数据。例如我们已知A有两个正整数,要求盲验证这两个正整数的乘积是12,那么B完全可以穷举乘积是12的所有正整数组合,正向执行验证过程,与E(L(s)),E(R(s))和E(O(s))比对即可知道正确的答案是什么。那么我们的解决思路是引入一个随机偏量:
则:
其中
那么
开篇我们介绍了同态加法,但是各种对同态函数E的证明中需要在乘法上也具有同态特性。椭圆曲线很好的解决了这个问题。
还有一个非常关键的问题没有解决,即 B 需要生成验证点 s、
在预置数据的设置上,为了保证数据不被任何人掌握,依然采取了椭圆曲线非对称加密。选取多个人私钥各产生一个公钥,然后拼接在一起作为预置数据并计算各个 E(s) 等需要的值,之后每个人销毁自己的私钥。
- 设置预置数据 s,
$\alpha$ ,并计算$E_1(s^0),E_1(s^1),…,E_1(s^d);E_2(\alpha s^0),E_2(\alpha s^1),…,E_2(\alpha s^d)$ 并公示 - A 计算
$a = E_1(P(s)); b = E_2(\alpha P(s))$ - B 计算
$E(\alpha a) = Tate(E_1(a), E_2(\alpha)); E(b)=Tate(E_1(1), E_2(b))$ 然后验证他们是相同的。如果$E(\alpha a) = E(b)$ ,那么我们可以得到$\alpha a = b$ ,即 a、b 是一个$\alpha$ 对。