Reverie:优化的零知识证明系统
零知识证明曾仅是理论概念,如今已广泛应用于Zcash和Monero等区块链系统。然而,现有ZK证明在证明大小和性能间的权衡并不适用于所有场景——这些协议通常需要复杂的可信设置阶段,且为缩小证明尺寸而牺牲验证时间。Zcash使用的ZK-SNARK协议对复杂应用可能需要数天甚至数月才能完成。因此,为工程师提供另一种权衡方案至关重要。
在Trail of Bits实习期间,我实现了Reverie零知识证明系统:它优化验证效率且无需可信设置,代价是证明尺寸较大。但Reverie支持网络流式传输和增量验证,避免一次性加载大体积证明。该系统已以reverie-zk
包形式发布在crates.io。
本文将详解Reverie的底层ZK证明系统并提供性能基准。由于该证明系统采用安全多方计算(MPC)技术,我们将从MPC基础开始,逐步展示如何用MPC构建ZK证明。
MPC基础
多方计算协议允许多个参与方在互不公开输入的情况下联合计算函数。例如:
- 统计选票而不泄露投票内容
- 计算共享客户数而不公开客户数据库
- 在私有数据集上训练/评估机器学习模型
零知识证明与MPC存在概念相似性但关键差异在于:
- MPC支持对私有数据进行计算,而ZK证明仅能证明私有数据的属性
- MPC协议需交互进行(非交互版本为功能加密),要求参与方在线;ZK证明可交互或非交互
通过将MPC协议"编译"为零知识证明系统,我们发现这两个原语存在深刻关联:在ZK证明中验证函数输出总比用MPC计算函数更高效。该框架还能构建简洁高效的证明系统,包括后量子签名方案等应用。
密码学编译器
我们通过系列"密码学编译器"将任意MPC协议转换为非交互式零知识证明系统。编译器利用密码学工具从现有协议生成新协议,其优势在于通用性——任何满足特定属性的输入协议都能产生具备新属性保证的新协议。
IKOS编译器
给定能计算函数g(x)
的MPC协议,IKOS编译器可生成针对输入/输出对(w, o)
的ZK证明系统。证明者能向验证者证明其掌握秘密输入w
使得g(w)=o
(如证明已知SHA-256的输入w
能产生指定哈希o
而不泄露原像)。
高层级实现方式:
- 证明者本地运行
g(x)
的MPC协议,其中输入w
被分享给各参与方(例如三参与方场景中随机选择X,Y,Z满足X+Y+Z=w) - 使用MPC协议计算函数
f(X,Y,Z)=g(X+Y+Z)
- 为防止作弊,验证者要求证明者公开部分参与方的输入和通信记录以验证正确性
IKOS编译器需要:
- MPC协议
- 密码学承诺方案(承诺函数需满足:找不同消息产生相同承诺不可行;从给定消息辨别承诺不可行)
使用承诺方案后,MPC协议编译过程如下:
- 证明者"在脑中"模拟各参与方执行MPC协议,记录所有收发信息(称为"视图")
- 证明者提交每个参与方的视图承诺并发送给验证者
- 验证者要求公开部分视图(示例中为2个)
- 验证者检查公开视图间的一致性
为什么有效?
可靠性:如果证明者作弊,至少有一对视图承诺不一致。三参与方情况下作弊被捕获概率≥1/3。通过并行重复证明可指数级提高捕获概率。
零知识性:验证者仅获得两个参与方的消息和输入,由于承诺方案隐藏未公开视图且MPC协议保障输入隐私,验证者无法获悉未公开参与方的输入信息。
Fiat-Shamir编译器
Fiat-Shamir转换通过哈希函数消除交互式验证需求:
- 输入:公开硬币零知识证明系统 + 强哈希函数
- 输出:非交互式零知识证明
核心思想:用哈希函数代替验证者产生随机挑战。证明者哈希其消息(各参与方视图承诺),将摘要作为随机挑战(如解析为指定公开参与方的整数序列)。作弊证明者需反复计算哈希直到获得可作弊的挑战,但这相当于在交互协议中多次尝试,计算不可行。
Reverie实现
Reverie是KKW2018中描述的MPC-in-the-head证明系统的高效Rust实现,通过应用上述编译器到简单MPC协议构建。由于证明系统适用于任何环(如有限域、合数模整数或向量空间),Reverie设计兼顾速度与灵活性以支持任何环的计算。
Reverie设计具通用性和易扩展性,可轻松添加特征如环间转换和电路随机门。
优化措施
为提升性能,Reverie采用多项实现技巧:
- 位切片技术:由于底层MPC协议中各参与方并行执行相同简单操作,通过将参与方状态连续打包内存,用单指令操作所有参与方(传统64位寄存器或SIMD指令)
- 并行处理:证明系统需要多次重复实现"可靠性放大",每个重复可分配给独立线程实现线性性能提升
- 快速密码原语:采用Blake3和ChaCha12——当前最快的密码原语(密码哈希函数和伪随机函数)同时保持高安全余量
- 流式证明与验证:支持流式生成和验证证明,验证者可在证明生成传输过程中进行验证,实现完全异步操作
性能基准
测试SHA-256压缩函数验证速度,在32核AMD EPYC 7601上平均每秒处理20次SHA-256压缩:
SHA-256应用次数 | 证明生成时间 | AND门数量 | XOR门数量 | 证明大小 |
---|---|---|---|---|
100 | 4.76秒 | 2,227,200 | 9,397,400 | 22MB |
1000 | 50.39秒 | 22,272,000 | 93,974,000 | 220MB |
10000 | 482.97秒 | 222,720,000 | 939,740,000 | 2.2GB |
结论
Reverie是在主流SNARK范式外创建高性能零知识证明的第一步,能相对轻松地处理数亿个AND/XOR门。项目提供简易"伴侣程序"(在"companion"子目录中)便于使用。立即在Github和crates.io上尝试吧!