一个更优的零知识证明:Bulletproofs

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个更优的零知识证明:Bulletproofs相关的知识,希望对你有一定的参考价值。

参考技术A

在2015年我们宣布 机密交易(CT) 作为侧链 Elements Alpha 的主要特征。该特征用 Pedersen commitments 取代了交易金额,这种一种隐藏金额的加密工具,同时保留了任何人验证在特定交易内余额的能力。

CT面临的主要难题是让它交易变得非常大而且验证缓慢,因为它要求每个交易输出包含一个 rangeproof ,这是一种零知识证明,证明金额 太小而不会溢出 。普通数字签名小于100个字节,并且只需不到100微秒的时间就可以验证,而 rangeproofs 的大小是几千个字节,并需要几个毫秒才能验证。实际上, rangeproofs 是使用它们的任何交易中绝大部分的交易数据。

尽管我们的 rangeproofs ,基于 Borromean环形签名 ,在文献中是最快的和最小的,但对于我们需要的 范围大小(range sizes) 和无信任的环境下,它们仍然非常的大。

自从2015年来,我们一直都在努力提高 rangeproofs 的效率。在2017年初,Adam Back发现 rangeproofs 减小了24% ,不过验证速度并没有提高。在这段期间,我们曾向我们的朋友和同事,密码学家Dan Boneh和在斯坦福大学的BenediktBünz提到这个问题,他们对改善的空间都相当的有信心。

他们最终震惊了我们。

根据 Bootle等人 在2016年基于离散对数的零知识证明的空间效率方面的改进, Bulletproofs 是一种更加空间高效的零知识证明的形式。重要的是,为了我们的目的,这些证明还具有对提交值如 Pedersen commitments 公钥 的原生支持。这让我们可以在通用的零知识框架下实现诸如 rangeproofs 之类的功能,而不用在零知识中实现复杂的椭圆曲线算法。

更强健。 为了限制交易大小,我们老版本的 rangeproofs 限制输出范围大小为2^32。这限制了输出大约到43 BTC,不过这可以通过将证明的粒度从1聪减少到10聪或者100聪来增加,或者通过从零开始增加最小值来增加。这些调整是可能的,但是使用了显示的金额,限制了系统提供的隐私。

这些32位的 rangeproofs 大小大约为2.5 KiB。使用Adam的优化,它们将有2 KiB 的大小。使用 Bulletproofs ,它们应该是610字节。有了这么小的大小,我们可以将 范围(range) 加倍到64位,从而无需进行任何的非隐私调整。这样的话,就会将610字节增加到1220字节,是吗?不是,实际上,64位的 Bulletproof rangeproofs 仅仅只有674字节。

更小。 我们将 范围(range) 的大小增加了一倍,但证明的大小只增加了64个字节的原因是:它们以对数级增长。这是通过使用 Bootle等人在2016年论文中 的内部产品参数的变体来完成的。(Jonathan Bootle也帮助了Benedikt和Dan开发 Bulletproofs 。 )具体来说,论文中描述的对数大小的内部产品参数在 Bulletproofs 中进一步降低了,从6log(N)曲线点降到2log(N)。

相同的技巧可以将一个交易内多个 rangeproofs 整合到一个中,同样只会增加很少的字节数。2个 rangeproofs 的整合是738字节,4个则是802字节,8个是866字节。8个64位经典 rangeproofs 将会超过40000字节。

更快。 这种节省空间很大,但是我们对该技术的初步分析显示验证速度会比老版的 rangeproofs 慢。似乎验证一个64位的证明需要超过200个标量点乘法,每个都是繁重的50微秒事务,而老版的 rangeproofs 只需要128个标量点乘法。

但是经过进一步的分析后,我们可以组合很多乘法,将总数减少到147个。更重要的是,我们意识到,与老版的 rangeproofs 不同,这些乘法都是不依赖对方的,所以我们可以在一个批量中完成它们。作为 我们汇总签名工作 的一部分,我们知道如何快速批量相乘。 我和Pieter Wuille,Greg Maxwell,Jonas Nick,Peter Dettman在这个问题上花费了几个月的时间,最终将147个乘法的速度降低到每个只需15.5微秒,让 Bulletproof 的总验证时间降到2.3 ms,而老版的证明需要5.8 ms。

在速度上已经不仅增加了一倍,而且由于我们的批量乘法随着你提供的点越多速度越快,所以整合的性能数字就更加令人印象深刻。8个64位 Bulletproofs 的整合可以在11.5 ms内验证完,而对于老版的证明需要46.8 ms,速度超过了4倍。

不过它能变得更好。 Bulletproofs 支持非常高效的批量验证形式。在我们需要完成的147次乘法中,其中130次在每个 Bulletproof 中使用相同的点,这意味着在批量验证期间,这130次乘法是可以组合的,剩下只有17次是新的乘法。实际上,这种小成本仅仅以对数级增加:对于2个 范围(ranges) 的整合,每个额外的证明需要19个额外的点,而4个 范围(ranges) 的整合,每个证明需要21个点。

注意我们引入了两个相似但是独立的概念:整合(aggregation)是指证明程序将多个 rangeproofs 组合成1个;而批量处理(batching)是指验证程序同时检测多个单独的证明。

这意味着两个64位的 rangeproofs 可以在2.7 ms内完成验证,或者每个 范围(range) 1.4 ms。500个 rangeproofs 可以在130 ms内完成验证,或者每个 范围(range) 0.26 ms,这比老版的证明提高了23倍。不过由于整合,它还可以变的更加可观。500个8个一整合的 rangeproofs (一共是4000个 范围(ranges) )可以在305 ms内验证完,或者每个范围 76 微秒,比老版的 rangeproofs 提高了75倍。

随着日益高效的标量点乘法不再是主导效应,这种影响最终会围绕64个证明的整合最大化。在这一点上,我们可以以每个 范围(range) 46微秒来批量验证,速度提高了125倍。作为参考,椭圆曲线数字签名算法(ECDSA)签名大约需要55微秒,所以在这种级别的整合下, rangeproofs 甚至不是交易验证的主要部分。当然,我们不太可能在区块链上看见64个输出交易,不过这种速度在非区块链环境中(如 Provisions
)是可能的。

这种验证同样也是节约内存的,验证单个 rangeproof 需要 100 KiB,随着大小而增加减。

Bulletproofs rangeproofs 更加的通用。它们可以被用来在零知识中证明任意的陈述。它们与 SNARKs 或 STARKs 相当,不过它们原生支持椭圆曲线(EC)公钥和 Pedersen commitments (因此通常不需要在程序中实现EC算法)。此外,与SNARK不同的是, Bulletproofs 在无信任环境的标准猜想下拥有完整的128位安全性。与STARK不同,它们在典型的计算机硬件上足以快速证明和验证合理大小的问题。

作为一个具体的例子,考虑SHA2压缩功能的一次运行。我们的证明程序需要少于 30 MiB的内存和大约21秒来证明SHA2原像的知识。验证需要大约23 MiB的内存和75 ms,但是我们可以用大约每个证明5 ms和13.4 KiB批量验证额外的证明。

我们的证明程序比SNARK更节省内存:在相同的系统中,SHA2的一个SNARK证明只需要4秒但是要75 MiB内存。验证时,每个电路需要大量的一次性预计算(需要被证明的陈述),然后只需要3-5 ms和很少的内存就可以验证。这些数字不会随着电路的增加而增加,所以对于超过几千门的电路,即使与我们的批量验证相比,SNARK也明显是赢家。不幸的是,这是以可信赖的环境和新的加密猜想为代价的。

在证明程序和验证程序上, Bulletproofs 仍有很大的优化空间。

验证任意陈述句的能力——不管是 Bulletproofs ,SNARKs或者STARKs,都有很多的应用。它可以用于实现普通的数字签名,包括(可追踪的)环形签名和阈值签名,对于大型环来说,在验证时间和证明大小方面它都比传统方案要高效。它的使用不限于此,它还可以用来可靠的销售数独问题,可以用于多方计算,即使有秘密数据的情况下还是可以证明每方都是诚实行事。(特别是在MuSig这样的多重签名方案中,这允许使用确定性的随机数生成,而不需要签名者维护状态或容易受到随机重用攻击。)它还可以用来证明哈希原像(preimages)。

后一种应用,哈希原像,是特别有趣的,因为它可以用来创建零知识Merkle证明,包含在大规模集合(有数百万甚至数十亿元素)的高效证明。我们将在未来的文章中探讨这一点。

我们很感谢Bootle等人开发的内部产品参数,它引导了我们。同样也感谢Benedikt Bünz和Dan Boneh,我们的合著者,他们做了大量的创造性工作。感谢Sean Bowe和Daira Hopwood为优化算术电路而做的研究。

翻译作者: 许莉
原文地址: Bulletproofs Faster Rangeproofs and Much More

基于 MPC 的零知识证明协议

参考文献:

  1. Jawurek, M., F. Kerschbaum, and C. Orlandi. 2013. “Zero-knowledge using garbled circuits: how to prove non-algebraic statements efficiently”. In: ACM CCS 13: 20th Conference on Computer and Communications Security. Ed. by A.-R. Sadeghi, V. D. Gligor, and M. Yung. ACM Press. 955–966.
  2. Evans D, Kolesnikov V, Rosulek M. A pragmatic introduction to secure multi-party computation[J]. Foundations and Trends® in Privacy and Security, 2018, 2(2-3): 70-246.
  3. 应用密码学:协议、算法与C源程序(机工社大黑皮)

ZKP

零知识证明协议的基本定义在这篇文章

交互式

最近看到了另一种描述 ZKP 的表述:

  1. Verifier拥有一个困难问题实例 H 1 H_1 H1,Prover声明自己拥有 H 1 H_1 H1的解法 S 1 S_1 S1
  2. Prover利用 1 1 1个随机数 r r r,将这个难题实例 H 1 H_1 H1,转变为另一个同构的难题实例 H 2 H_2 H2。同时,依据 S 1 S_1 S1 r r r,得到对应的解法 S 2 S_2 S2
  3. Prover对解法 S 2 S_2 S2做承诺,然后将难题 H 2 H_2 H2和承诺值 c c c都发送给Verifier
  4. Verifier随机要求Prover给出如下两个声明之一的Proof:
    1. 要求Prover证明两个难题同构, H 1 ≅ H 2 H_1 \\cong H_2 H1H2
    2. 要求Prover公开 S 2 S_2 S2,并证明 S 2 S_2 S2 H 2 H_2 H2的正确解法
  5. Prover给出所要求的Proof,Verifier验证它
  6. 两者反复执行 n n n次 step 1 ~ step 5,直到Verifier相信Prover确实拥有 S 1 S_1 S1(一般而言, n = 10 n=10 n=10就很好了)

完备性:诚实的Prover拥有 S 1 S_1 S1,他总是可以给出 step 4 中所要求的两种Proof,因此Verifier最终会相信他。

可靠性:一个恶意的Prover,他没有 S 1 S_1 S1,为了通过 step 4 的验证,他不得不猜测Verifier的选择。如果猜测Verifier会执行 step 4.1,那么敌手就在 step 2 中选择一个 H 2 ≅ H 1 H_2 \\cong H_1 H2H1,同时他不拥有对应的 S 2 S_2 S2。如果猜测Verifier会执行 step 4.2,那么敌手就在 step 2 中随机生成一个难题 H 2 ′ H_2' H2以及对应的解法 S 2 ′ S_2' S2,但同时他无法证明 H 1 ≅ H 2 ′ H_1 \\cong H_2' H1H2

零知识性:一个恶意的Verifier,他无法让第三方Alice相信上述 Proof 的有效性。假设敌手用一个摄像机记录协议的每一步,即使视频中显示Prover总是给出了正确的 Proof,Alice也总是可以质疑:每当Prover猜对了,Verifier就保留视频;每当Prover猜错了,Verifier就删除视频。人们无法区分真实记录(in the real world)和伪造记录(in the ideal world)!

人们已经证明:

  1. 任何 NP 命题都包含一个 ZKP
  2. 任何数学证明都能转化为一个 ZKP
  3. 能使用交互式证明完成的任何事,也能用交互式 ZKP 完成

非交互式

上述的Alice不相信的原因是,她没有介入 ZKP 的交互。为了Prover为了让任何人相信他的Proof,他需要一个非交互式的ZKP。每当Prover发布Proof后,任何人都可以验证这个Proof是否有效(身份认证协议、签名协议)。

利用 Hash 函数 H H H代替了 Verifier:

  1. Prover声明自己拥有一个困难问题实例 H H H的解法 S S S
  2. Prover利用 n n n个随机数 r i \\r_i\\ ri,将这个难题实例 H H H,转变为随机的 n n n个同构的难题实例 H i \\H_i\\ Hi。同时,依据 S S S r i \\r_i\\ ri,得到对应的解法 S i \\S_i\\ Si
  3. Prover对解法 S i \\S_i\\ Si做承诺,然后将难题 H i \\H_i\\ Hi和承诺值 c i \\c_i\\ ci都公开
  4. Prover计算 b = H ( c i ) b = H(\\c_i\\) b=H(ci),截取前 n n n比特 b = b [ 1 : n ] b=b[1:n] b=b[1:n],然后依据 b [ i ] ∈ 0 , 1 b[i] \\in \\0,1\\ b[i]0,1给出如下两个声明之一的Proof:
    1. b [ i ] = 0 b[i]=0 b[i]=0,Prover证明两个难题同构, H ≅ H i H \\cong H_i HHi
    2. b [ i ] = 1 b[i]=1 b[i]=1,Prover公开 S i S_i Si,并证明 S i S_i Si H i H_i Hi的正确解法
  5. Prover公布 step 4 中的 n n n个Proof,任何人都可以验证它:先根据 c i \\c_i\\ ci计算出 b b b,然后依次检查第 i i i个Proof是否是关于 b [ i ] b[i] b[i]声明的合法证明。

这儿的 H H H扮演了无偏随机比特发生器的角色。如果恶意Prover不拥有 S S S,那么他最多只能给出 step 4 中的某一个Proof,而不能同时都给出Proof,因此为了欺骗,他必须能够预测 H H H的输出。

当然,是Prover(而非Verifier)来挑选的 b b b,因此敌手完全可以随机猜测 b b b的前 n n n位,然后尝试不同的 S i \\S_i\\ Si组合,直到全部猜对 n n n个比特。此时,敌手就可以给出一个合法的 Proof 了。为了抵挡敌手的穷举攻击,我们需要将 n n n设置的比较大,例如 64 , 128 64,128 64,128

JKO(2013)

ZKP 可以作为一种特殊的 malicious secure computation,根据声明 y y y构造电路 C ( ⋅ , y ) C(\\cdot,y) C(,y) C ( x , y ) = 1    ⟺    ( x , y ) ∈ R C(x,y)=1 \\iff (x,y) \\in R C(x,y)=1(x,y)R),其中作为Prover的一方输入证据 x x x,作为Verifier的一方什么也不输入,最后电路结果 C ( x , y ) C(x,y) C(x,y)输出给Prover。

很明显,利用任意的 cut-and-choose-based 2PC protocol,总是可以实现上述的恶意敌手安全的两方计算。但是,直接使用 C&C 技术的 2PC 协议,对应的混淆电路过于巨大。

Jawurek, Kerschbaum 和 Orlandi 观察到:由于 Verifier 没有输入,因此如果让他来生成 GC,那么这个 GC 可以同时用来 checking 和 evaluation:翻转角色,我们让 Verifier 生成一个主流的零知识证明开发库

安全多方计算之五:零知识证明(从入门到入土。。)

基于 MPC 的零知识证明协议

区块链与密码学第10-3讲:零知识证明概念

基于Sigma protocol实现的零知识证明protocol集锦

官方信息:星际文件系统已成为最大的零知识证明网络