MCPcopy Index your code
hub / github.com/davxy/ark-vrf

github.com/davxy/ark-vrf @v0.5.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.5.0 ↗ · + Follow
325 symbols 769 edges 29 files 117 documented · 36%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Elliptic Curve VRF

Implementations of Verifiable Random Function with Additional Data (VRF-AD) schemes built on a transcript-based Fiat-Shamir transform with support for multiple input/output pairs via delinearization.

Built on the Arkworks framework with configurable cryptographic parameters and no_std support.

Supported Schemes

  • Tiny VRF: Compact proof. Loosely inspired by RFC-9381, adapted with a transcript-based Fiat-Shamir transform, support for additional data, and multiple I/O pairs via delinearization.

  • Thin VRF: Same structure as Tiny VRF but stores the nonce commitment instead of the challenge, enabling batch verification at the cost of a slightly larger proof.

  • Pedersen VRF: Key-hiding VRF based on the construction introduced by BCHSV23. Replaces the public key with a Pedersen commitment to the secret key, serving as a building block for anonymized ring signatures.

  • Ring VRF: Anonymized ring VRF combining Pedersen VRF with the ring proof scheme derived from CSSV22. Proves that a single blinded key is a member of a committed ring without revealing which one.

Specifications

Built-In Suites

The library conditionally includes the following pre-configured suites (see features section):

  • Ed25519: Supports Tiny, Thin, and Pedersen VRF.
  • Secp256r1: Supports Tiny, Thin, and Pedersen VRF.
  • Bandersnatch (Edwards curve on BLS12-381): Supports Tiny, Thin, Pedersen, and Ring VRF.
  • JubJub (Edwards curve on BLS12-381): Supports Tiny, Thin, Pedersen, and Ring VRF.
  • Baby-JubJub (Edwards curve on BN254): Supports Tiny, Thin, Pedersen, and Ring VRF.

Basic Usage

```rust,ignore 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();


### Tiny VRF

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");

Verify ```rust,ignore 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

The Thin VRF merges the public-key Schnorr pair and the VRF I/O pair into a
single DLEQ relation via delinearization, then proves it with a Schnorr-like
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");

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

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


_Batch verify_
```rust,ignore
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

Key-hiding VRF that replaces the public key with a Pedersen commitment to the secret key.

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");

// The proof includes a commitment to the public key let key_commitment = proof.key_commitment();


_Verify_
```rust,ignore
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

The Ring VRF provides anonymity within a set of public keys using zero-knowledge proofs.

Ring construction ```rust,ignore 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::<Vec<_>>();

// 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]);


_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();

// 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);

Verify ```rust,ignore 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);


_Verifier key from commitment_
```rust,ignore
// 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);

Features

  • default: std
  • full: Enables all features listed below except secret-split, parallel, asm, test-vectors.
  • secret-split: Split-secret scalar multiplication. Secret scalar is split into the sum of two scalars, which randomly mutate but retain the same sum. Incurs 2x penalty in some internal sensible scalar multiplications, but provides side channel defenses.
  • ring: Ring-VRF for the curves supporting it.
  • test-vectors: Deterministic ring-vrf proof. Useful for reproducible test vectors generation.

Curves

  • ed25519
  • jubjub
  • bandersnatch
  • baby-jubjub
  • secp256r1

Arkworks optimizations

  • parallel: Parallel execution where worth using rayon.
  • asm: Assembly implementation of some low level operations.

License

Distributed under the MIT License.

Extension points exported contracts — how you extend this code

PedersenSuite (Interface)
Suite extension for Pedersen VRF support. Provides the additional cryptographic parameters required by the Pedersen VRF [8 …
src/pedersen.rs
Suite (Interface)
Defines a cipher suite. Configures the elliptic curve, transcript, and core operations (nonce generation, challenge der [8 …
src/lib.rs
RingSuite (Interface)
Ring suite. This trait provides the cryptographic primitives needed for ring VRF signatures. All required bounds are ex [5 …
src/ring.rs
SuiteExt (Interface)
(no doc) [8 implementers]
src/testing.rs
SWMapping (Interface)
Trait for types that can be converted from/to Short Weierstrass form. This trait provides methods to convert between a [2 …
src/utils/te_sw_map.rs
TinySuite (Interface)
Marker trait for suites that support the Tiny VRF scheme. Blanket-implemented for all types implementing [`Suite`]. [1 …
src/tiny.rs
ThinVrfSuite (Interface)
Marker trait for suites that support the Thin VRF scheme. Blanket-implemented for all types implementing [`Suite`]. [1 …
src/thin.rs
SuiteExt (Interface)
(no doc) [1 implementers]
benches/bench_utils.rs

Core symbols most depended-on inside this repo

clone
called by 49
src/utils/transcript.rs
public
called by 24
src/lib.rs
vrf_io
called by 24
src/lib.rs
absorb_raw
called by 21
src/utils/transcript.rs
push
called by 20
src/pedersen.rs
prove
called by 19
src/tiny.rs
push
called by 15
src/ring.rs
push
called by 15
src/thin.rs

Shape

Method 144
Function 111
Class 43
Interface 24
Enum 3

Languages

Rust99%
Python1%

Modules by API surface

src/ring.rs67 symbols
src/lib.rs32 symbols
src/thin.rs27 symbols
src/testing.rs26 symbols
src/pedersen.rs26 symbols
src/utils/transcript.rs24 symbols
src/utils/common.rs23 symbols
src/tiny.rs22 symbols
src/utils/te_sw_map.rs11 symbols
src/utils/hash_to_curve.rs8 symbols
benches/common.rs8 symbols
benches/ring.rs7 symbols

For agents

$ claude mcp add ark-vrf \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact