2个版本
0.4.1 | 2024年1月18日 |
---|---|
0.4.0 | 2023年12月4日 |
#896 in 密码学
每月下载量281
在 10 个crate中使用 (直接使用2个)
680KB
13K SLoC
halo2-lib
这个仓库旨在为使用Halo 2证明堆栈编写零知识证明电路提供基本原语。要讨论或合作,请加入我们的Telegram社区 Telegram。
入门
有关零知识证明(ZK)的简要介绍,请参阅此 文档。
Halo 2是用Rust编写的,因此您需要安装 Rust才能使用此库
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
克隆此仓库,并在 halo2-lib
目录中开始。
git clone https://github.com/axiom-crypto/halo2-lib.git
cd halo2-lib
halo2-base
这个crate提供了一种使用我们的简单垂直门编写Halo 2电路的附加API。它还提供了使用此API构建的基本函数。提供的方法可以在GateInstructions
和 RangeInstructions
中找到。后者是需要使用查找表进行范围检查的操作。
要运行一些基本测试,请运行以下命令
cargo test -- --nocapture test_gates
cargo test -- --nocapture test_range
(Rust测试默认不显示stdout,因此我们使用 --nocapture
启用实时stdout。) 这些测试使用 MockProver
检查电路是否正确约束,但它并不模拟真正的生产证明设置。
对于在生产证明设置中运行的原生字段乘法和内积的基准测试,请运行以下命令
cargo bench --bench mul
cargo bench --bench inner_product
这些基准测试使用 criterion
包来运行 create_proof
10 次,以进行统计分析。注意基准电路在每个电路中执行超过一个乘法/内积。
halo2-ecc
此包使用 halo2-base
来提供一个椭圆曲线密码学原语库。特别是,我们支持在比证明系统中使用的标量字段更大的基字段上的椭圆曲线(例如,当使用 Halo 2 并与 KZG 后端一起使用 bn254 时,为 F_r
)。
特性
如果您是 Rust 新手,我们建议忽略本节并使用默认特性。默认特性包括:"jemallocator","halo2-axiom","display"。您可以通过关闭 "display" 来获得非常小的性能提升,在这种情况下,不会计算和打印关于电路的某些统计信息。
始终开启 "halo2-axiom" 或 "halo2-pse" 特性中的 一个。
- "halo2-axiom" 特性使用我们的
halo2_proofs
,这是 PSE one 的一个分支,我们对证明速度进行了轻微优化。 - "halo2-pse" 特性使用 Privacy Scaling Explorations 的
halo2_proofs
,这是最稳定且审查者最多的。
我们保证由这两个分支生成的证明是相同的。
内存分配器
"jemallocator" 特性使用 jemallocator 包进行内存分配。您可以将其关闭以使用系统分配器。或者使用 "mimalloc" 特性来使用 mimalloc 包。我们发现这些分配器的性能在很大程度上取决于您正在运行的机器。
模块
bigint
:为 ZK 提供优化的大整数算术支持。fields
:为素数域算术提供常用函数,针对比证明系统中使用的标量字段更大的素数域进行了优化。fp2
:在某些二次扩展域上的域运算。fp12
:在某些度数为12
的扩展域上的域运算(针对 BN254 和 BLS12-381 进行设计)。
ecc
:椭圆曲线密码学原语库,目前适用于与fields
模块兼容的基字段上的短 Weierstrass 曲线(特别是允许域扩展)。- 椭圆曲线加法和倍乘。
- 标量乘法和多标量乘法(MSM,multiexp)。实现是 ZK 优化的,在适当的情况下使用窗口方法和 Pippenger 算法。
- ECDSA 签名验证。
secp256k1
:为 secp256k1 曲线专门化的ecc
模块。test_secp256k1_ecdsa
和bench_secp256k1_ecdsa
展示了如何为 secp256k1 实现 ECDSA 签名验证。(更多细节见下文。)
bn254
:为 BN254 曲线专门化的ecc
模块。final_exp
和pairing
模块一起实现了 BN254 在 ZK 中的最优 Ate 对。实现已针对 BN 曲线的特定情况进行优化,但可以轻松地适应 BLS 曲线(即将推出!)。
使用 MockProver
进行测试
不要在没有任何过滤器的情况下运行 cargo test
。其中一些测试实际上是基准测试,将需要很长时间才能运行。
设置
所有测试应在 halo2-lib/halo2-ecc
目录下运行。一些测试从特定目录读取文件,因此如果您在 halo2-lib
根目录下,它们将无法运行。
以下基准测试中,您可以将位于 halo2-ecc
目录下的 params
文件夹与之前生成的通用可信设置文件进行符号链接。否则,基准测试将生成新的随机设置并将它们保存在 params
目录中。 警告:这些可信设置是使用一个 已知 的随机种子生成的,因此它们不安全。它们不应在生产环境中使用。有关适合生产的可信设置,请参阅KZG可信设置。
测试可以像在之前的部分中一样运行。可用的命令有
cargo test -- --nocapture test_fp
cargo test -- --nocapture test_fp12
cargo test -- --nocapture test_ecc
cargo test -- --nocapture test_secp256k1_ecdsa
cargo test -- --nocapture test_ec_add # for BN254
cargo test -- --nocapture test_fixed_base_msm # for BN254
cargo test -- --nocapture test_msm # for BN254
cargo test -- --nocapture test_pairing # for BN254
可配置电路
使用 halo2-base
编写的电路的一个特殊功能是,任何此类电路都可以配置为具有不同的行数与列数,同时保持单元格总数大致相同。不同的配置适用于不同的环境。例如,行数比列数多总是会导致链上验证的gas成本更低,但通常会以证明速度较慢为代价。为了有一个粗略的心理模型,请参阅成本建模。
在上述一些测试中,电路配置是从文件中读取的。您可以通过更改文件中的数字来更改配置。如果某些数字太小,测试将因为构建电路的单元格不足而崩溃。如果您输入了过大的数字,测试将显示有关最佳数字的建议。在未来版本中,我们将使电路能够自动配置。
以下基准配置文件还给出了可以放入测试配置文件中的可能配置列表。
测试配置文件的位置(相对于 halo2-ecc
目录)
测试 | 配置文件 |
---|---|
test_secp256k1_ecdsa |
src/secp256k1/configs/ecdsa_circuit.config |
test_ec_add |
src/bn254/configs/ec_add_circuit.config |
test_fixed_base_msm |
src/bn254/configs/fixed_msm_circuit.config |
test_msm |
src/bn254/configs/msm_circuit.config |
test_pairing |
src/bn254/configs/pairing_circuit.config |
基准测试
我们有一些实际上是使用生产Halo2证明器的基准测试。如上文所述,每个电路都有不同的配置,导致证明时间差异很大。以下基准测试将针对一系列可能的配置进行基准测试。结果保存在 results
目录下的文件中。我们目前提供的配置列表,应该为给定电路度 k
提供最优配置(然而您可以通过与stdout建议进行核对,看它们是否真的是最优的!)。
我们以 --release
模式运行基准测试,以获得最大速度。
命令
可用的基准测试命令有
cargo test --release -- --nocapture bench_secp256k1_ecdsa
cargo test --release -- --nocapture bench_ec_add
cargo test --release -- --nocapture bench_fixed_base_msm
cargo test --release -- --nocapture bench_msm
cargo test --release -- --nocapture bench_pairing
配置文件和结果文件的位置(相对于 halo2-ecc
目录)是
基准测试 | 配置文件 | 结果文件 |
---|---|---|
bench_secp256k1_ecdsa |
src/secp256k1/configs/bench_ecdsa.config |
src/secp256k1/results/ecdsa_bench.csv |
bench_ec_add |
src/bn254/configs/bench_ec_add.config |
src/bn254/results/ec_add_bench.csv |
bench_fixed_base_msm |
src/bn254/configs/bench_fixed_msm.config |
src/bn254/results/fixed_msm_bench.csv |
bench_msm |
src/bn254/configs/bench_msm.config |
src/bn254/results/msm_bench.csv |
bench_pairing |
src/bn254/configs/bench_pairing.config |
src/bn254/results/pairing_bench.csv |
为了加快基准测试时间,您可以从不希望进行基准测试的配置中删除 .config
文件中的某些行。
标准库基准测试
要使用 criterion
crate运行更准确的基准测试,您可以运行以下命令
cargo bench --bench msm
cargo bench --bench fixed_base_msm
cargo bench --bench fp_mul
本运行对同一证明生成过程进行10次运行并收集平均值。每个电路都有一个固定配置,用于优化速度。这些基准测试主要用于性能优化。
Secp256k1 ECDSA
我们为Secp256k1曲线上的ECDSA签名验证提供了在不同机器上的基准测试。所有机器仅使用CPU。
在AWS EC2实例r6a.8xl(AMD,x86)和r6g.8xl(Graviton,arm64),都具有32个CPU核心,256 GB RAM的情况下,使用以下方法进行基准测试:
cargo test --release --no-default-features --features "halo2-axiom, jemallocator" -- --nocapture bench_secp256k1_ecdsa
为了优化内存分配,优先考虑CPU利用率,我们使用以下方法调整jemallocator:
export JEMALLOC_SYS_WITH_MALLOC_CONF="background_thread:true,metadata_thp:always,dirty_decay_ms:100000,muzzy_decay_ms:100000,narenas:1,abort_conf:true"
(实际上这并没有太大区别)。
在M2 Max Macbook Pro(12个CPU核心,96 GB RAM)上,我们使用以下方法进行基准测试:
cargo test --release --no-default-features --features "halo2-axiom, mimalloc" -- --nocapture bench_secp256k1_ecdsa
(“mimalloc”与“jemallocator”的性能相似)。
其他列提供了有关PLONKish算术化的信息。
k |
建议数量 | 查找建议数量 | 固定数量 | 证明时间(M2 Max) | 证明时间(r6a.8xl) | 证明时间(r6g.8xl) |
---|---|---|---|---|---|---|
11 | 291 | 53 | 4 | 3.5s | 7.3s | 7.2s |
12 | 139 | 24 | 2 | 2.6s | 3.3s | 5.3s |
13 | 68 | 12 | 1 | 2.2s | 2.6s | 4.7s |
14 | 34 | 6 | 1 | 2.1s | 2.4s | 4.5s |
15 | 17 | 3 | 1 | 1.98s ⚡ |
2.28s | 4.5s |
16 | 8 | 2 | 1 | 2.3s | 2.5s | 5.2s |
17 | 4 | 1 | 1 | 2.7s | 2.9s | 6s |
18 | 2 | 1 | 1 | 4.4s | 4.7s | 9.5s |
19 | 1 | 1 | 1 | 7.6s | 7.6s | 16s |
r6a的时钟速度高于r6g。
BN254 Pairing
我们为BN254在不同机器上提供了最优的Ate配对基准测试。所有机器仅使用CPU。
在AWS EC2实例r6a.8xl(AMD,x86)和r6g.8xl(Graviton,arm64),都具有32个CPU核心,256 GB RAM的情况下,使用以下方法进行基准测试:
cargo test --release --no-default-features --features "halo2-axiom, jemallocator" -- --nocapture bench_pairing
为了优化内存分配,优先考虑CPU利用率,我们使用以下方法调整jemallocator:
export JEMALLOC_SYS_WITH_MALLOC_CONF="background_thread:true,metadata_thp:always,dirty_decay_ms:100000,muzzy_decay_ms:100000,narenas:1,abort_conf:true"
(实际上这并没有太大区别)。
在M2 Max Macbook Pro(12个CPU核心,96 GB RAM)上,我们使用以下方法进行基准测试:
cargo test --release --no-default-features --features "halo2-axiom, mimalloc" -- --nocapture bench_pairing
(“mimalloc”与“jemallocator”的性能相似)。
其他列提供了有关PLONKish算术化的信息。
k |
建议数量 | 查找建议数量 | 固定数量 | 证明时间(M2 Max) | 证明时间(r6a.8xl) | 证明时间(r6g.8xl) |
---|---|---|---|---|---|---|
14 | 211 | 27 | 1 | 11.8s | 16.9s | 24.8s |
15 | 105 | 14 | 1 | 10.4s | 12.7s | 23.6s |
16 | 50 | 6 | 1 | 9.5 ⚡ |
10.96s | 21.6s |
17 | 25 | 3 | 1 | 9.7s | 11.2s | 22.7s |
18 | 13 | 2 | 1 | 11.9s | 13.5s | 27.3s |
19 | 6 | 1 | 1 | 14.8s | 15.3s | 30.6s |
20 | 3 | 1 | 1 | 23.7s | 23.8s | 48.1s |
21 | 2 | 1 | 1 | 40.3s | 40.8s | 82.5s |
22 | 1 | 1 | 1 | 69.1s | 66.9s | 135s |
r6a的时钟速度高于r6g。我们假设Apple Silicon集成的内存导致M2 Max上的性能更快。
BN254 MSM
我们为BN254提供了100个批次的乘法(MSM,多指数)的基准测试。
在M2 Max Macbook Pro(12个CPU核心,96 GB RAM)上,我们使用以下方法进行基准测试:
cargo test --release --no-default-features --features "halo2-axiom, mimalloc" -- --nocapture bench_msm
k |
建议数量 | 查找建议数量 | 固定数量 | 证明时间(M2 Max) |
---|---|---|---|---|
17 | 84 | 11 | 1 | 27.8 ⚡ |
18 | 42 | 6 | 1 | 29.95s |
19 | 20 | 3 | 1 | 32.6s |
20 | 11 | 2 | 1 | 41.3s |
21 | 6 | 1 | 1 | 51.9s |
使用halo2-lib
构建的项目
- Axiom -- 通过汇总区块头、账户和存储证明来证明关于以太坊链上数据的事实。
- Proof of Email -- 使用与电子邮件域名相同的信任假设来证明关于电子邮件的事实。
- halo2-fri-gadget -- halo2中的FRI验证器。
- eth-voice-recovery
- zkevm tx-circuit
- webauthn-halo2 -- 使用halo2进行WebAuthn的证明和验证。
- Fixed Point Arithmetic -- halo2中的定点算术库。
依赖关系
~5–11MB
~188K SLoC