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, 区块链基础设施, 可视化界面, 可验证随机函数, 密码学, 手动系统调用, 椭圆曲线, 网络流量审计, 通知系统, 零知识证明