Bulletproofs ZKP 允许证明者通过对数大小的证明来证明其知道某个内积。Bulletproofs 不需要可信设置(trusted setup)。
在前面的章节中,我们展示了如何在不泄露向量或内积的情况下证明对内积的知识,尽管其证明大小为 O(n),其中 n 是向量的长度。我们还展示了如何使用对数大小的数据来证明对内积的知识,但不具备零知识属性。
在本章中,我们将这些算法结合起来,以展示 Bulletproof ZK 算法。
(本文是 ZK Bulletproofs 系列的一部分。)
问题陈述
证明者和验证者就长度为 n 的两个椭圆曲线基向量 G 和 H,以及椭圆曲线点 Q 和 B 达成一致。所有这些点之间的离散对数关系都是未知的。
证明者拥有向量 a 和 b,其内积为 v。证明者将 a 和 b 承诺为 A,即 A=⟨a,G⟩+⟨b,H⟩+αB,其中 α 是盲化项(blinding term)。证明者承诺 V=⟨a,b⟩Q+γB。
证明者将 (A,V) 发送给验证者,旨在证明 A 是对 a 和 b 的承诺,且 V 是对它们内积的承诺。验证者不会获知具体的向量或内积。
证明的大小必须为 O(logn)。
Bulletproof ZK 算法
证明者生成随机标量 {α,β,γ,τ1,τ2} 和随机向量 {sL,sR} 并计算承诺:
ASV=⟨a,G⟩+⟨b,H⟩+αB=⟨sL,G⟩+⟨sR,H⟩+βB=vQ+γB
证明者准备(但不发送)向量多项式:
l(x)r(x)t(x)=a+sLx=b+sRx=⟨l(x),r(x)⟩=⟨a,b⟩+(⟨a,sR⟩+⟨b,sL⟩)x+(⟨sL,sR⟩)x2
A 是对向量多项式常数项的承诺,S 是对一次项的承诺,V 是对内积的承诺。
证明者为 t(x) 的系数创建承诺,如下所示:
T1T2=(⟨a,sR⟩+⟨b,sL⟩)Q+τ1B=⟨sL,sR⟩Q+τ2B
请注意,V 是对 t(x) 常数项系数的承诺,而 T1 和 T2 分别是对 t(x) 一次项和二次项系数的承诺。
证明者将 (A,S,V,T1,T2) 发送给验证者。
验证者回复随机值 u。
然后证明者在 u 处对多项式求值,并创建它们被正确求值的证明:
lurutuπlrπt=l(u)=a+sLu=r(u)=b+sRu=t(u)=v+(⟨a,sR⟩+⟨b,sL⟩)u+⟨sL,sR⟩u2=α+βu=γ+τ1u+τ2u2
在之前的方法中,证明者传输 (lu,ru,tu,πlr,πt) 以便验证者可以检查:
tuA+SutuQ=?⟨lu,ru⟩=?⟨lu,G⟩+⟨ru,H⟩+πlrB=?V+T1u+T2u2−πtB
但由于向量 lu 和 ru 的存在,其大小将是线性的。为了解决这个问题,证明者将 lu 和 ru 承诺为:
C=⟨lu,G⟩+⟨ru,H⟩
并发送 (C,tu,πlr,πt)。
我们可以将前两个验证者的检查重新排列如下:
tuA+Su−πlrB=?⟨lu,ru⟩=?⟨lu,G⟩+⟨ru,H⟩
观察发现,如果我们设 P=A+Su−πlrB,那么这与证明 P 是对基于基向量 G 和 H 的两个向量 lu 和 ru 的承诺,且 lu 和 ru 的内积为 tu 的问题陈述是相同的。因此,我们可以复用打开为 P 的承诺的对数大小的知识证明。
对于这个证明,我们不需要保密性,因为在前一个算法中 lu 和 ru 本来就是公开的。
现在验证者已经拥有所有必要的数据,证明者参与交互式证明,以证明 C 持有对 lu 和 ru 的承诺,并且它们的内积为 tu:
\texttt{prove_commitments_log}(C + t_uQ, \mathbf{G}, \mathbf{H}, Q, \mathbf{l}_u, \mathbf{r}_u)
该子程序将在无需发送 lu 和 ru 的情况下,证明 tu=?⟨lu,ru⟩ 和 C=?⟨lu,G⟩+⟨ru,H⟩。而且它仅发送对数大小的数据。注意,上一章的递归算法使用的是承诺 P=⟨a,G⟩+⟨b,H⟩+⟨a,b⟩Q,因此验证者需要自己添加“Q 部分”。现在验证者可以确信:
tuC=?⟨lu,ru⟩=?⟨lu,G⟩+⟨ru,H⟩
最后,验证者检查:
CtuQ=?A+Su−πlrB=?V+T1u+T2u2−πtB
回想一下,A 和 S 分别是对向量多项式 l(x) 和 r(x) 的常数项和一次项的承诺。第一个检查确保承诺为 C 的向量是这些多项式在 u 处的求值。
第二个检查是为了在已知系数承诺 V、T1 和 T2 的情况下,确保 t(u) 被正确求值。
通过 Fiat Shamir 变换实现非交互性
在实践中,此算法通过 Fiat Shamir Transform 实现非交互性。证明者无需向验证者索取随机数,而是通过连接到目前为止传输的所有数据并对其进行哈希处理来生成随机数。然后,验证者对数据重新进行哈希处理,以确保证明者正确生成了随机数。
至关重要的是,哈希必须包含之前所有的传输数据,否则该实现将出现 frozen heart vulnerability。
下一步
在实践中,具有实际意义的问题通常由多个内积组成。例如,一个秩一约束系统(Rank 1 Constraint System,R1CS):
La∘Ra=Oa
实际上是 3n 个内积(例如,将 a 乘以 L 的 n 行,对于 R 和 O 也是如此)和一个 Hadamard 乘积(Hadamard product)。因此,掌握一些将多个内积合并为单一内积的数学技巧将会非常方便,这样我们就无需发送 3n 个 Bulletproofs。我们将会在接下来关于随机线性组合(random linear combinations)的章节中学习如何实现这一点。
此外,一些有用的问题可以直接编码为内积,尤其是范围证明(range proof)或子集求和问题(subset sum problem)。在这些情况下,我们可以跳过将问题编码为算术电路的步骤,直接将其编码为内积。为了增加内积表示的灵活性,并为理解随机线性组合打下基础,我们将在下一章学习一些内积代数。
练习: 结合之前的练习来证明 A=⟨a,G⟩+⟨b,H⟩+αB,其中 a 和 b 是长度为 4 的向量。你的证明应该是既简洁又具备零知识属性的。为了简单起见,请创建一个交互式证明。练习请参考 此仓库。