Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [0.6.0] - 2026-09-26

Breaking release. Every entry under Changed alters the public API.
`BandersnatchSha512Ell2` also changes its outputs under the same `SUITE_ID`:
Expand All @@ -19,6 +19,23 @@ proofs and ring commitments made with 0.5.3 do not verify.

### Changed

- Proving and verification are functions of the proof types. The `Prover` and
`Verifier` traits of the four schemes are gone: `Proof::prove(ios, ad,
&secret)` (the Ring one also takes the `RingProver`) and
`proof.verify(ios, ad, key)`, where the key is the `Public` for Tiny and
Thin, nothing for Pedersen and the `RingVerifier` for Ring. The keys keep
shortcuts: `Secret::prove_tiny`, `prove_thin`, `prove_pedersen`,
`prove_ring`, `Public::verify_tiny` and `verify_thin`. The Thin and Ring
`BatchItem::new` and `BatchVerifier::push` take the key last.
- Ring members are `Public` keys. `RingSetup::keys`, `prover_key`,
`verifier_key` and `VerifierKeyBuilder::append` take any iterator of
`Public` or `&Public` (for example `&ring`) instead of `&[AffinePoint]`, so
the subgroup check of a key happens once, when the key is decoded.
`Public::padding()` gives the ring padding point as a key. `==` on
`Public`, `Input` and `Output` no longer needs `PartialEq` on the suite
type, so it works in code generic over the suite.
- `Error` is `#[non_exhaustive]`: a `match` on it needs a wildcard arm, and
a new variant is no longer a breaking change.
- Opaque types. `Public`, `Input` and `Output` are aliases of
`PointWrapper<S, K>`. Its point and the fields of the proof types, of
`RingSetup` and of `RingContext` are private, with accessors.
Expand Down Expand Up @@ -67,6 +84,10 @@ proofs and ring commitments made with 0.5.3 do not verify.
arkworks BLS12-381 decoder accepts. Call `Valid::check` after decoding a
`RingVerifierKey`, `RingCommitment` or `PcsVerifierParams` from untrusted
bytes.
- `VerifierKeyBuilder` deserialization rejects a padding point other than
`RingSuite::PADDING` and a capacity that no PIOP domain gives. A builder
still defines the ring: load it only from a source trusted like a verifier
key.

### Performance

Expand Down Expand Up @@ -317,6 +338,7 @@ of the Bandersnatch VRF specification.
- `no_std` support.
- `parallel` and `asm` optimization features.

[0.6.0]: https://github.com/davxy/ark-vrf/compare/v0.5.3...v0.6.0
[0.5.3]: https://github.com/davxy/ark-vrf/compare/v0.5.2...v0.5.3
[0.5.2]: https://github.com/davxy/ark-vrf/compare/v0.5.1...v0.5.2
[0.5.1]: https://github.com/davxy/ark-vrf/compare/v0.5.0...v0.5.1
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ark-vrf"
version = "0.5.3"
version = "0.6.0"
edition = "2024"
rust-version = "1.85"
authors = [ "Davide Galassi <davxy@datawok.net>" ]
Expand Down
61 changes: 28 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,22 @@ Compact VRF-AD producing a short `(c, s)` proof.

_Prove_
```rust,ignore
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");
let proof = TinyProof::prove(io, b"aux data", &secret);
```

_Verify_
```rust,ignore
use ark_vrf::tiny::Verifier;

// Verify the proof against the public key
let result = public.verify(io, b"aux data", &proof);
let result = proof.verify(io, b"aux data", &public);
assert!(result.is_ok());
```

The keys have the same operations as methods: `secret.prove_tiny(io, ad)` and
`public.verify_tiny(io, ad, &proof)`.

### Thin-VRF

The Thin VRF merges the public-key Schnorr pair and the VRF I/O pair into a
Expand All @@ -92,30 +91,27 @@ proof (R, s).

_Prove_
```rust,ignore
use ark_vrf::thin::Prover;

let io = secret.vrf_io(input);
let proof = secret.prove(io, b"aux data");
let proof = ThinProof::prove(io, b"aux data", &secret);
```

_Verify_
```rust,ignore
use ark_vrf::thin::Verifier;

let result = public.verify(io, b"aux data", &proof);
let result = proof.verify(io, b"aux data", &public);
assert!(result.is_ok());
```

As for Tiny, the keys have the same operations as methods: `secret.prove_thin`
and `public.verify_thin`.

_Batch verify_
```rust,ignore
use ark_vrf::thin::{Prover, BatchVerifier};
let proof1 = ThinProof::prove(io, b"data1", &secret);
let proof2 = ThinProof::prove(io, b"data2", &secret);

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);
let mut batch = ThinBatchVerifier::new();
batch.push(io, b"data1", &proof1, &public);
batch.push(io, b"data2", &proof2, &public);
assert!(batch.verify().is_ok());
```

Expand All @@ -125,12 +121,10 @@ Key-hiding VRF that replaces the public key with a Pedersen commitment to the se

_Prove_
```rust,ignore
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");
let (proof, blinding) = PedersenProof::prove(io, b"aux data", &secret);

// The proof includes a commitment to the public key
let key_commitment = proof.key_commitment();
Expand All @@ -139,12 +133,12 @@ let key_commitment = proof.key_commitment();
_Verify_
```rust,ignore
use ark_ec::CurveGroup;
use ark_vrf::pedersen::{PedersenSuite, Verifier};
use ark_vrf::pedersen::PedersenSuite;

// 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);
let result = proof.verify(io, b"aux data");
assert!(result.is_ok());

// Verify the proof was created using a specific public key.
Expand All @@ -153,6 +147,9 @@ let expected = (public.point() + BandersnatchSha512Ell2::BLINDING_BASE * blindin
assert_eq!(proof.key_commitment(), expected);
```

The secret key has the same operation as a method: `secret.prove_pedersen`.
Verification needs no public key, so `Public` has no Pedersen method.

### Ring-VRF

The Ring VRF provides anonymity within a set of public keys using zero-knowledge proofs.
Expand All @@ -167,15 +164,15 @@ 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().point()
Secret::from_seed(seed).public()
})
.collect::<Vec<_>>();

// Patch the ring with the public key of the prover
ring[prover_key_index] = public.point();
ring[prover_key_index] = public;

// Any key can be replaced with the padding point
ring[0] = RingSetup::padding_point();
ring[0] = Public::padding();

// Create parameters for the ring proof system.
// These parameters are reusable across multiple proofs.
Expand All @@ -201,8 +198,6 @@ let ring_setup = RingSetup::from_pcs_params(RING_SIZE, pcs_params).unwrap();

_Prove_
```rust,ignore
use ark_vrf::ring::Prover;

// Create a prover key specific to this ring
let prover_key = ring_setup.prover_key(&ring).unwrap();

Expand All @@ -217,13 +212,11 @@ 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);
let proof = RingProof::prove(io, b"aux data", &secret, &prover);
```

_Verify_
```rust,ignore
use ark_vrf::ring::Verifier;

// Create a verifier key for this ring
let verifier_key = ring_setup.verifier_key(&ring).unwrap();

Expand All @@ -235,9 +228,11 @@ let verifier = ring_ctx.ring_verifier(verifier_key);
// 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);
let result = proof.verify(io, b"aux data", &verifier);
```

The secret key has the same operation as a method: `secret.prove_ring`.

_Both keys_
```rust,ignore
// A party that needs both keys indexes the ring once. The two calls above
Expand Down
Loading
Loading