Skip to main content

Python bindings for ark-vrf

Project description

py-ark-vrf

Python bindings for the ark-vrf Rust crate, offering Verifiable Random Function (VRF) constructions. This library specifically uses the Bandersnatch curve (suite::BandersnatchSha512Ell2) and exposes IETF and Ring VRF schemes.

This library requires a pre-generated SRS file bandersnatch_ring.srs for Ring VRF operations. The SRS file is automatically included in the package distribution and will be extracted when needed.

Type Checking Support

This package includes type stubs (.pyi files) and supports static type checking with tools like mypy, PyCharm, and VS Code. The package is marked with py.typed to indicate type checking support.

Installation

This project is built using setuptools-rust, so you will need the Rust toolchain installed.

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

After installing Rust, you can install the library using pip:

pip install .

Usage

Key Generation

You can generate a secret/public key pair from a 32-byte seed. The public key can also be derived from the secret scalar.

from py_ark_vrf import secret_from_seed, public_from_le_secret

# Generate keys from a seed
seed = 12345
public_key, secret_scalar = secret_from_seed(seed.to_bytes(32))

print(f"Public Key: {public_key.hex()}")
print(f"Secret Scalar: {secret_scalar.hex()}")

# Derive public key from the secret
derived_public_key = public_from_le_secret(secret_scalar)
assert derived_public_key == public_key

IETF VRF

This scheme is defined in the IETF draft for VRFs. You can create and verify proofs.

from py_ark_vrf import secret_from_seed, prove_ietf, verify_ietf, vrf_output

# 1. Key Generation
seed = 0
pub_key, scalar = secret_from_seed(seed.to_bytes(32))

# 2. Proving
input_data = b"hello"
ad = b"additional data" # associated data
proof = prove_ietf(scalar, input_data, ad)

assert len(proof) == 96

# 3. Verification
is_valid = verify_ietf(pub_key, proof, input_data, ad)
assert is_valid

# An invalid proof should fail verification
assert not verify_ietf(pub_key, bytes(96), input_data, ad)

# 4. Get VRF output hash
output = vrf_output(proof)
assert len(output) == 32
print(f"VRF Output: {output.hex()}")

Ring VRF

Ring VRFs allow proving that a secret key holder is part of a "ring" (a set of public keys) without revealing which one.

Note: Ring VRF operations require a Structured Reference String (SRS) file. The SRS file is automatically included in the package and will be extracted when needed. No manual setup is required.

from py_ark_vrf import secret_from_seed, prove_ring, verify_ring

# 1. Setup a ring of public keys
seeds = [1, 2, 3, 4, 5, 6, 7, 8]
keys = [secret_from_seed(seed.to_bytes(32)) for seed in seeds]
ring = [k[0] for k in keys]

# 2. Select a prover from the ring
prover_index = 4
prover_secret_scalar = keys[prover_index][1]

# 3. Proving
input_data = b"message"
ad = b""
ring_proof = prove_ring(prover_secret_scalar, input_data, ring, ad)

# 4. Verification
# Anyone with the ring can verify the proof
is_valid = verify_ring(input_data, ring_proof, ring, ad)
assert is_valid

# Verification should fail with wrong input
assert not verify_ring(b"wrong message", ring_proof, ring, ad)

API

secret_from_seed(seed: bytes) -> (bytes, bytes)

Generates a (public_key, secret_scalar) pair from a 32-byte seed.

public_from_le_secret(secret_scalar: bytes) -> bytes

Derives a public key from a secret scalar.

prove_ietf(secret_scalar: bytes, input_data: bytes, aux_data: bytes) -> bytes

Creates an IETF VRF proof. Returns a 96-byte proof.

verify_ietf(public_key: bytes, proof: bytes, input_data: bytes, aux_data: bytes) -> bool

Verifies an IETF VRF proof.

prove_ring(secret_scalar: bytes, input_data: bytes, ring: list[bytes], aux_data: bytes) -> bytes

Creates a Ring VRF proof. The prover's public key must be in the ring.

verify_ring(input_data: bytes, proof: bytes, ring: list[bytes], aux_data: bytes) -> bool

Verifies a Ring VRF proof.

vrf_output(proof: bytes) -> bytes

Extracts the 32-byte VRF output hash from a proof (works for both IETF and Ring proofs).

get_ring_root(public_keys: list[bytes]) -> bytes

Returns a 144-bytes ring root

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_ark_vrf-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

File details

Details for the file py_ark_vrf-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for py_ark_vrf-0.2.3-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 cd4da0b8c9e4d3600dd994a1968b53fd18e8f49a411060fde8e167a0f4580efd
MD5 5952eb2fec0deb449510b827d66ae802
BLAKE2b-256 e9b9b7349027a9932f4aeb5d3abeaaf6340f36432949b5facff640c8c2c03e47

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page