#bulletproofs #zero-knowledge-proofs #ristretto #zero-knowledge #system-api #math

no-std sn_bulletproofs

使用Ristretto实现的Bulletproofs纯Rust实现

1个不稳定版本

0.1.0 2022年4月7日

#2469 in 密码学


用于sn_ringct

MIT许可证

1MB
3.5K SLoC

包含(压缩文件,280KB)aggregated-range-proof.sketch

此存储库是dalek-cryptography/bulletproofs的分支。

Bulletproofs

有史以来最快的Bulletproofs实现,具有单点和聚合范围证明,强类型多方计算,以及用于证明任意声明的可编程约束系统API(开发中)。

此库使用Ristretto实现Bulletproofs,使用curve25519-dalek中的ristretto255实现。当使用并行公式时,它验证64位rangeproofs的速度大约是原始基于libsecp256k1的Bulletproofs实现的2倍。

此库提供以下实现:

  • 使用聚合范围证明构造的单方证明单个或多个范围;

  • 在线多方计算,用于多个 parties 之间的 rangeproof 聚合,使用 会话类型 静态强制正确的协议流程;

  • 用于表达秩-1约束系统的可编程约束系统API,以及证明和验证任意声明的证明(不稳定,正在开发中,具有yoloproofs功能);

  • 聚合约束系统证明的在线多方计算(计划中的未来工作)。

这些证明使用Merlin转写实现,允许它们在不更改实现的情况下与其它证明任意组合。

开发路线图可以在 里程碑 部分找到,位于 Github 仓库

约束系统 API 仅用于实验,必须通过指定 yoloproofs 功能来启用。它不受 semver 兼容性的约束,且 未经通知可能会更改

目前,在发布的 crate 版本中已禁用 yoloproofs 功能,因此只能通过指定对 develop 分支的 git 依赖来使用。这意味着无法使用 R1CS API 发布 crate,因为它是仅用于实验的。

文档

该功能面向用户的文档可以在此处找到。此外,该库还包含大量关于 Bulletproofs 如何工作的笔记。这些笔记可以在库的内部文档中找到。

比较性能

以下表格给出了在英特尔 Skylake-X i7-7800X(@3.5GHz,禁用 Turbo Boost)上对 64 位范围证明进行证明和验证的比较时间。时间以微秒(越低越好)表示,与最快实现的相对速度。

实现 证明(μs) rel 验证(μs) rel
ours (avx2) ristretto255 7300 1.00x 1040 1.00x
ours (u64) ristretto255 11300 1.54x 1490 1.43x
libsecp+endo secp256k1 14300 1.96x 1900 1.83x
libsecp-endo secp256k1 16800 2.30x 2080 2.00x
Monero ed25519 (不安全) 53300 7.30x 4810 4.63x

使用 curve25519-dalek IFMA 后端在 Cannonlake i3-8121U 上可提供 1.5 倍的速度提升,将验证速度提升至 libsecp 的 3 倍,Monero 的 7 倍,但这些处理器尚未广泛可用。

此 crate 还包含其他基准测试;有关如何运行它们的详细信息,请参阅下面的 测试和基准测试 部分。

示例

以下示例展示了如何创建和验证一个 32 位范围证明。

# // The #-commented lines are hidden in Rustdoc but not in raw
# // markdown rendering, and contain boilerplate code so that the
# // code in the README.md is actually run as part of the test suite.
#
# extern crate rand;
# use rand::thread_rng;
#
# extern crate curve25519_dalek;
# use curve25519_dalek::scalar::Scalar;
#
# extern crate merlin;
# use merlin::Transcript;
#
# extern crate bulletproofs;
# use bulletproofs::{BulletproofGens, PedersenGens, RangeProof};
#
# fn main() {
// Generators for Pedersen commitments.  These can be selected
// independently of the Bulletproofs generators.
let pc_gens = PedersenGens::default();

// Generators for Bulletproofs, valid for proofs up to bitsize 64
// and aggregation size up to 1.
let bp_gens = BulletproofGens::new(64, 1);

// A secret value we want to prove lies in the range [0, 2^32)
let secret_value = 1037578891u64;

// The API takes a blinding factor for the commitment.
let blinding = Scalar::random(&mut thread_rng());

// The proof can be chained to an existing transcript.
// Here we create a transcript with a doctest domain separator.
let mut prover_transcript = Transcript::new(b"doctest example");

// Create a 32-bit rangeproof.
let (proof, committed_value) = RangeProof::prove_single(
    &bp_gens,
    &pc_gens,
    &mut prover_transcript,
    secret_value,
    &blinding,
    32,
).expect("A real program could handle errors");

// Verification requires a transcript with identical initial state:
let mut verifier_transcript = Transcript::new(b"doctest example");
assert!(
    proof
        .verify_single(&bp_gens, &pc_gens, &mut verifier_transcript, &committed_value, 32)
        .is_ok()
);
# }

构建

要成功编译,您需要安装 nightly Rust,而不是 stable。

您可以使用 rustup 安装 nightly Rust

rustup default nightly

测试和基准测试

使用 cargo test 运行测试。使用 cargo bench 运行基准测试。此 crate 使用 criterion.rs 进行基准测试。

功能

yoloproofs 功能启用对秩 1 约束系统证明的支持。它是 不稳定且不适用于部署 的,且 仅提供用于测试

功能 avx2_backend 启用 curve25519-dalek 的 AVX2 后端,该后端使用 并行公式 实现曲线算术。要用于 Bulletproofs,target_cpu 必须支持 AVX2。

RUSTFLAGS="-C target_cpu=skylake" cargo bench --features "avx2_backend"

Skylake-X CPU 的 AVX2 寄存器是两倍。要使用它们,尝试

RUSTFLAGS="-C target_cpu=skylake-avx512" cargo bench --features "avx2_backend"

这可以防止 AVX2 并行字段乘法代码中的溢出,但会导致其他地方的代码生成更差 ¯\_(ツ)_/¯

关于

这是一个由 Interstellar 赞助的研究项目,由 Henry de Valence、Cathie Yun 和 Oleg Andreev 开发。

依赖项

~6MB
~173K SLoC