2个版本

0.4.1 2024年1月18日
0.4.0 2023年12月4日

#896 in 密码学

Download history 24/week @ 2024-03-13 20/week @ 2024-03-20 39/week @ 2024-03-27 51/week @ 2024-04-03 16/week @ 2024-04-17 28/week @ 2024-04-24 16/week @ 2024-05-01 37/week @ 2024-05-08 62/week @ 2024-05-15 59/week @ 2024-05-22 47/week @ 2024-05-29 57/week @ 2024-06-05 72/week @ 2024-06-12 90/week @ 2024-06-19 60/week @ 2024-06-26

每月下载量281
10 个crate中使用 (直接使用2个)

MIT 许可证

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构建的基本函数。提供的方法可以在GateInstructionsRangeInstructions 中找到。后者是需要使用查找表进行范围检查的操作。

  • 阅读此crate的Rust文档
  • 要开始使用Halo 2并了解如何使用 halo2-base API进行构建,请参阅入门指南

要运行一些基本测试,请运行以下命令

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_ecdsabench_secp256k1_ecdsa 展示了如何为 secp256k1 实现 ECDSA 签名验证。(更多细节见下文。)
  • bn254:为 BN254 曲线专门化的 ecc 模块。
    • final_exppairing 模块一起实现了 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构建的项目

依赖关系

~5–11MB
~188K SLoC