Skip to main content

Pedersen VRF API Reference

The PedersenVRF class implements a privacy-enhanced VRF using Pedersen commitments. The public key is blinded within the proof, preventing verifiers from linking proofs to specific signers.

Import

from dot_ring import PedersenVRF, Bandersnatch

Key Difference from IETF VRF

In Pedersen VRF, the public key is embedded in the proof using a blinding factor. This means:

  • ✅ Verifier does not need the public key
  • ✅ Proofs from the same key cannot be linked
  • ✅ Enhanced privacy for the signer
# IETF VRF - requires public key
ietf_valid = ietf_proof.verify(public_key, alpha, ad)

# Pedersen VRF - no public key needed!
pedersen_valid = pedersen_proof.verify(alpha, ad)

Class Methods

prove(alpha, secret_key, additional_data)

Generate a privacy-enhanced VRF proof with blinded public key.

Parameters:

NameTypeDescription
alphabytesInput data to sign
secret_keybytes32-byte secret key
additional_databytesOptional additional data bound to proof

Returns: PedersenProof object

Example:

from dot_ring import PedersenVRF, Bandersnatch
import secrets

secret_key = secrets.token_bytes(32)
alpha = b'anonymous-lottery'
additional_data = b''

proof = PedersenVRF[Bandersnatch].prove(alpha, secret_key, additional_data)

get_public_key(secret_key)

Derive the public key from a secret key.

Parameters:

NameTypeDescription
secret_keybytes32-byte secret key

Returns: bytes - The serialized public key

Example:

public_key = PedersenVRF[Bandersnatch].get_public_key(secret_key)

from_bytes(proof_bytes)

Deserialize a proof from bytes.

Parameters:

NameTypeDescription
proof_bytesbytesSerialized proof bytes

Returns: PedersenProof object

Example:

proof_bytes = proof.to_bytes()
restored = PedersenVRF[Bandersnatch].from_bytes(proof_bytes)

blinding(secret, input_point, additional_data)

Compute the blinding factor used in the proof.

Parameters:

NameTypeDescription
secretbytesSecret key bytes
input_pointbytesSerialized input point
additional_databytesAdditional data

Returns: int - The blinding scalar


PedersenProof Object

The proof object returned by prove().

Attributes

AttributeTypeDescription
output_pointPointVRF output point (Γ)
blinded_pkPointBlinded public key commitment (Yˉ\bar{Y})
result_pointPointProof R component
okPointProof OkO_k component
sintResponse scalar
sbintBlinding response scalar

Methods

verify(alpha, additional_data)

Verify the proof is valid. No public key required.

Parameters:

NameTypeDescription
alphabytesOriginal input data
additional_databytesOriginal additional data

Returns: bool - True if valid, False otherwise

Example:

is_valid = proof.verify(alpha, additional_data)

to_bytes()

Serialize the proof to bytes.

Returns: bytes - Serialized proof


proof_to_hash(output_point)

Convert the VRF output point to a pseudo-random hash. This is a class method.

Parameters:

NameTypeDescription
output_pointPointThe VRF output point from the proof

Returns: bytes - Hash output

Example:

random_output = PedersenVRF[Bandersnatch].proof_to_hash(proof.output_point)

Complete Example

from dot_ring import PedersenVRF, Bandersnatch
import secrets

# Setup
secret_key = secrets.token_bytes(32)

# Generate proof
alpha = b'private-lottery-entry'
additional_data = b''
proof = PedersenVRF[Bandersnatch].prove(alpha, secret_key, additional_data)

# Verify - no public key needed!
is_valid = proof.verify(alpha, additional_data)
assert is_valid, "Proof verification failed!"

# Get random output
random_bytes = PedersenVRF[Bandersnatch].proof_to_hash(proof.output_point)
print(f"Random output: {random_bytes.hex()}")

# Serialization
proof_bytes = proof.to_bytes()
print(f"Proof size: {len(proof_bytes)} bytes")

restored = PedersenVRF[Bandersnatch].from_bytes(proof_bytes)
assert restored.verify(alpha, additional_data)

Privacy Properties

Unlinkability

Two proofs from the same signer cannot be linked:

# Same key, different inputs
proof1 = PedersenVRF[Bandersnatch].prove(b'input1', secret_key, b'')
proof2 = PedersenVRF[Bandersnatch].prove(b'input2', secret_key, b'')

# Both are valid
assert proof1.verify(b'input1', b'')
assert proof2.verify(b'input2', b'')

# But verifier cannot tell they came from the same key!

Blinding Factor

The blinding factor is deterministically derived from the secret key, input point, and additional data.

This ensures:

  • Same inputs produce same blinding (deterministic)
  • Different inputs produce different blindings (unlinkable)

Proof Size

Pedersen VRF proofs are larger than IETF proofs due to the blinding commitment:

CurveProof Size
Bandersnatch192 bytes

Supported Curves

Pedersen VRF supports all 18 curves in DotRing. See Curves Reference.