技术深度解析
Scroll的Halo2实现在通用性与性能之间取得了精妙平衡,堪称教科书级案例。其核心是PLONKish架构,这一术语描述了一类源自原始PLONK(基于拉格朗日基的通用非交互式知识论证排列)协议的证明系统。关键创新在于将电路分离为多个列和门,其中每个门都可以是一个自定义多项式约束。
架构分解:
- 自定义门: 与固定门系统(例如早期的Groth16)不同,PLONKish允许开发者定义任意多项式恒等式。例如,以太坊的`ADD`操作码可以作为一个单一自定义门实现,检查`a + b = c`模2^256,而无需将其分解为众多小门。这极大地减少了约束数量。
- 查找表: Halo2支持查找参数(基于Caulk协议),能够高效进行范围检查和表驱动操作。Scroll将其用于`SHA3`或`BALANCE`等操作码,这些操作的正确输出可以预先计算并通过查找获得,而无需在电路中重新计算。
- 多线程证明生成: 该库使用Rust编写,并利用Rayon并行化繁重的多项式算术(NTT、MSM)。基准测试显示,在多达32个核心上可实现近乎线性的扩展,这对于证明包含数千笔交易的区块至关重要。
- 内存优化: Scroll采用了一种称为“分块证明”的技术——将大型电路分割成较小的片段,独立证明后再聚合。这避免了单体式PLONK证明器常见的O(n^2)内存爆炸问题。
性能数据(来自Scroll内部基准测试):
| 指标 | Scroll Halo2 (zkEVM) | 通用Halo2 (未优化) | Groth16 (固定电路) |
|---|---|---|---|
| 每秒约束数(证明) | 120万 | 40万 | 250万 |
| 证明大小 | 2.5 KB | 2.5 KB | 200字节 |
| 证明时间(1万笔交易区块) | 8分钟 | 25分钟 | 不适用(需要可信设置) |
| 内存使用(峰值) | 6 GB | 18 GB | 4 GB |
| 所需设置 | 无(透明) | 无 | 可信设置(有毒废料) |
数据要点: Scroll的优化使得证明吞吐量相比通用Halo2实现提升了3倍,同时将内存控制在合理范围内。代价是与Groth16相比证明体积更大,但对于公共区块链而言,消除可信设置是一项重大的运营优势。
相关开源仓库:
- `scroll-tech/halo2` — 核心库。目前约1200颗星。包含PLONKish后端、查找参数实现和序列化工具。
- `scroll-tech/zkevm-circuits` — 基于Halo2构建的EVM电路定义。每个操作码的自定义门都位于此处。对于任何构建EVM兼容ZK电路的人来说,都值得研究。
关键参与者与案例研究
Scroll团队: 该项目由Sandy Peng、Haichen Shen和Ye Zhang联合创立——他们均拥有深厚的分布式系统和密码学背景。Ye Zhang曾为Zcash协议做出贡献,并发表过关于递归证明组合的研究。团队决定基于Halo2(而非Groth16或Plonk)构建是战略性的:Halo2的透明设置和灵活性使其成为复杂且不断演进的zkEVM的唯一可行选择。
竞争格局:
| 项目 | ZK系统 | 证明器性能 | EVM兼容性 | 可信设置 |
|---|---|---|---|---|
| Scroll | Halo2 (PLONKish) | 高(已优化) | 完全 | 否 |
| zkSync Era | Boojum (自定义PLONK) | 非常高 | 完全 | 否 |
| Polygon zkEVM | PIL (自定义) | 中高 | 完全 | 否 |
| StarkNet | STARK | 低(但无双线性配对) | 部分(Cairo VM) | 否 |
| Aztec | PLONK (自定义) | 中 | 否(隐私) | 否 |
数据要点: Scroll的Halo2处于一个竞争甜蜜点——它提供完全的EVM兼容性和强劲性能,但并非最快的证明器。zkSync的Boojum声称在类似工作负载下证明速度快2倍,但使用了更僵化的电路模型。选择Halo2为Scroll未来的升级(例如添加新操作码或预编译)提供了更多灵活性,而无需重新设计整个系统。
案例研究:超越区块链的可验证计算
Scroll的Halo2已被Succinct Labs用于其SP1 zkVM,该zkVM旨在证明任意Rust程序。通过利用Scroll优化的查找表,Succinct将简单Merkle树验证的证明时间从30秒缩短至5秒以下。这展示了该库在以太坊L2之外的实用性。
行业影响与市场动态
一个生产级、开源的Halo2实现的发布产生了若干涟漪效应:
1. 降低ZK开发门槛: 在Scroll的工作之前,构建自定义ZK电路需要深厚的密码学专业知识和数月的工程投入。现在,开发者可以fork `scroll-te