davxy/ark-vrf

GitHub: davxy/ark-vrf

基于 Arkworks 的椭圆曲线 VRF 密码学库,提供 Tiny、Thin、Pedersen 及 Ring VRF 等多种可验证随机函数方案的 Rust 实现。

Stars: 32 | Forks: 6

# 椭圆曲线 VRF 可验证随机函数与额外数据 (VRF-AD) 的实现 基于 transcript 的 Fiat-Shamir 变换构建,并通过 delinearization 支持多个输入/输出对。 基于 [Arkworks](https://github.com/arkworks-rs) 框架构建,支持可配置的密码学参数以及 `no_std` 支持。 ## 支持的方案 - **Tiny VRF**:紧凑型证明。松散地借鉴了 [RFC-9381](https://datatracker.ietf.org/doc/rfc9381), 并结合了基于 transcript 的 Fiat-Shamir 变换、对额外数据的支持,以及通过 delinearization 实现的多 I/O 对支持。 - **Thin VRF**:与 Tiny VRF 结构相同,但存储的是 nonce commitment 而不是 challenge,从而支持批量验证,代价是证明略大。 - **Pedersen VRF**:隐藏密钥的 VRF,基于 [BCHSV23](https://eprint.iacr.org/2023/002) 提出的结构。将公钥替换为对私钥的 Pedersen commitment,作为匿名化 ring signature 的构建模块。 - **Ring VRF**:匿名 ring VRF,将 Pedersen VRF 与源自 [CSSV22](https://eprint.iacr.org/2022/1362) 的 ring proof 方案相结合。证明单个 blinded key 属于已承诺的 ring 的一部分,且不泄露具体是哪一个。 ### 规范 - [VRF 方案](https://github.com/davxy/bandersnatch-vrf-spec) - [Ring Proof](https://github.com/davxy/ring-proof-spec) ## 内置套件 该库有条件地包含以下预配置套件(参见 features 部分): - **Ed25519**:支持 Tiny、Thin 和 Pedersen VRF。 - **Secp256r1**:支持 Tiny、Thin 和 Pedersen VRF。 - **Bandersnatch**(_BLS12-381 上的 Edwards 曲线_):支持 Tiny、Thin、Pedersen 和 Ring VRF。 - **JubJub**(_BLS12-381 上的 Edwards 曲线_):支持 Tiny、Thin、Pedersen 和 Ring VRF。 - **Baby-JubJub**(_BN254 上的 Edwards 曲线_):支持 Tiny、Thin、Pedersen 和 Ring VRF。 ## 基本用法 ``` use ark_vrf::suites::bandersnatch::*; // Create a secret key from a seed let secret = Secret::from_seed([0; 32]); // Derive the corresponding public key let public = secret.public(); // Create an input by hashing data to a curve point let input = Input::new(b"example input").unwrap(); // Compute the VRF output (gamma point) let output = secret.output(input); // Get a deterministic hash from the VRF output point let hash_bytes = output.hash(); ``` ### 微型 VRF 生成简短 `(c, s)` 证明的紧凑型 VRF-AD。 _证明_ ``` use ark_vrf::tiny::Prover; let io = secret.vrf_io(input); // Generate a proof that binds the input-output pair and auxiliary data let proof = secret.prove(io, b"aux data"); ``` _验证_ ``` use ark_vrf::tiny::Verifier; // Verify the proof against the public key let result = public.verify(io, b"aux data", &proof); assert!(result.is_ok()); ``` ### Thin-VRF Thin VRF 通过 delinearization 将公钥 Schnorr 对和 VRF I/O 对合并为单一的 DLEQ 关系,然后使用类似 Schnorr 的证明 (R, s) 来证明它。 _证明_ ``` use ark_vrf::thin::Prover; let io = secret.vrf_io(input); let proof = secret.prove(io, b"aux data"); ``` _验证_ ``` use ark_vrf::thin::Verifier; let result = public.verify(io, b"aux data", &proof); assert!(result.is_ok()); ``` _批量验证_ ``` use ark_vrf::thin::{Prover, BatchVerifier}; let proof1 = secret.prove(io, b"data1"); let proof2 = secret.prove(io, b"data2"); let mut batch = BatchVerifier::new(); batch.push(&public, io, b"data1", &proof1); batch.push(&public, io, b"data2", &proof2); assert!(batch.verify().is_ok()); ``` ### Pedersen-VRF 隐藏密钥的 VRF,将对私钥的 Pedersen commitment 替换掉公钥。 _证明_ ``` use ark_vrf::pedersen::Prover; let io = secret.vrf_io(input); // Generate a proof with a blinding factor let (proof, blinding) = secret.prove(io, b"aux data"); // The proof includes a commitment to the public key let key_commitment = proof.key_commitment(); ``` _验证_ ``` use ark_vrf::pedersen::Verifier; // Verify without knowing which specific public key was used. // Verifies that the secret key used to generate `output` is the same as // the secret key used to generate `proof.key_commitment()`. let result = Public::verify(io, b"aux data", &proof); assert!(result.is_ok()); // Verify the proof was created using a specific public key. // This requires knowledge of the blinding factor. let expected = (public.0 + BandersnatchSha512Ell2::BLINDING_BASE * blinding).into_affine(); assert_eq!(proof.key_commitment(), expected); ``` ### Ring-VRF Ring VRF 使用零知识证明在一组公钥中提供匿名性。 _Ring 构建_ ``` const RING_SIZE: usize = 100; let prover_key_index = 3; // Construct an example ring with dummy keys let mut ring = (0..RING_SIZE) .map(|i| { let mut seed = [0u8; 32]; seed[..8].copy_from_slice(&i.to_le_bytes()); Secret::from_seed(seed).public().0 }) .collect::>(); // Patch the ring with the public key of the prover ring[prover_key_index] = public.0; // Any key can be replaced with the padding point ring[0] = RingSetup::padding_point(); // Create parameters for the ring proof system. // These parameters are reusable across multiple proofs. let ring_setup = RingSetup::from_seed(RING_SIZE, [0x42; 32]); ``` _证明_ ``` use ark_vrf::ring::Prover; // Create a prover key specific to this ring let prover_key = ring_setup.prover_key(&ring).unwrap(); // Create a lightweight ring context for prover/verifier construction let ring_ctx = ring_setup.ring_context(); // Create a prover instance for the specific position in the ring let prover = ring_ctx.ring_prover(prover_key, prover_key_index); let io = secret.vrf_io(input); // Generate a zero-knowledge proof that: // 1. The prover knows a secret key for one of the public keys in the ring // 2. That secret key was used to generate the VRF output let proof = secret.prove(io, b"aux data", &prover); ``` _验证_ ``` use ark_vrf::ring::Verifier; // Create a verifier key for this ring let verifier_key = ring_setup.verifier_key(&ring).unwrap(); // Create a verifier instance let ring_ctx = ring_setup.ring_context(); let verifier = ring_ctx.ring_verifier(verifier_key); // Verify the proof - this confirms that: // 1. The proof was created by someone who knows a secret key in the ring // 2. The VRF output is correct for the given input // But it does NOT reveal which ring member created the proof let result = Public::verify(io, b"aux data", &proof, &verifier); ``` _从 commitment 获取验证者密钥_ ``` // For efficiency, a commitment to the ring can be shared let ring_commitment = ring_setup.verifier_key(&ring).unwrap().commitment(); // A verifier can reconstruct the verifier key from just the commitment // without needing the full ring of public keys let verifier_key = ring_setup.verifier_key_from_commitment(ring_commitment); ``` ## 特性 - `default`:`std` - `full`:启用除 `secret-split`、`parallel`、`asm`、`test-vectors` 之外的所有下列 features。 - `secret-split`:拆分秘密标量乘法。将秘密标量拆分为两个标量之和,这两个标量会随机变异但保持总和不变。在一些内部合理的标量乘法中会导致 2 倍的性能损失,但提供了侧信道防御。 - `ring`:针对支持它的曲线提供 Ring-VRF。 - `test-vectors`:确定性 ring-vrf 证明。适用于可复现的测试向量生成。 ### 曲线 - `ed25519` - `jubjub` - `bandersnatch` - `baby-jubjub` - `secp256r1` ### Arkworks 优化 - `parallel`:在值得使用 `rayon` 的地方进行并行执行。 - `asm`:某些低级操作的汇编实现。 ## 许可证 基于 [MIT 许可证](./LICENSE) 分发。
标签:Rust, 区块链基础设施, 可视化界面, 可验证随机函数, 密码学, 手动系统调用, 椭圆曲线, 网络流量审计, 通知系统, 零知识证明