Skip to content

A VRF implementation using Stark curve and Poseidon hash.

Notifications You must be signed in to change notification settings

dojoengine/stark-vrf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stark VRF

This repository implements the VRF spec (https://datatracker.ietf.org/doc/html/rfc9381) using Stark curve and Poseidon hash for efficient verification on Starknet.

This repository contains two parts:

  • VRF prover and verifier implemented in Rust. It can be used not only to generate a VRF proof but also supplements all necessary hints for cheap verification in Cairo.
  • An efficient Cairo verifier.

Usage

Proof generation

Proofs can be generated by using the provided stark-vrf crate.

  use stark_vrf::{Error, generate_public_key, Proof, ScalarValue, StarkVRF};

  #[test]
  fn it_generates_proof() -> Result<Proof, Error> {
      let secret_key = ScalarValue!("190");
      let public_key = generate_public_key(secret_key);

      let seed = &[ScalarValue!("42")];
      let ecvrf = StarkVRF::new(public_key).unwrap();
      ecvrf.prove(&secret_key, seed)
  }

Hints for fast verification

VRF proof verification requires calculating a square root on field elements which is very inefficient when implemented in Cairo. Instead, Rust code can generate a "sqrt_ratio_hint" that makes verification much cheaper.

let sqrt_ratio_hint = ecvrf.hash_to_sqrt_ratio_hint(seed);

Proof verification, random output generation

For completeness and testing, Rust also provides a way to verify proofs generated by itself.

ecvrf.verify(&proof, seed).expect("proof correct");
let random_word = ecvrf.proof_to_hash(&proof).unwrap();

Proof verification in Cairo

This repository also provides a "stark_vrf" Scarb package for easy VRF proof verification in Cairo.

pub use stark_vrf::ecvrf::{Point, Proof, ECVRF, ECVRFImpl};

// sample output obtained from Rust code
fn proof_from_oracle() -> Proof {
    Proof {
        gamma: Point {
            x: 1506339363762384048749124975867331702319430609263271304275332020910807468800,
            y: 36259598506905210600179635686591002688831785399437338349196739602416217657
        },
        c: 2613903846701008054856365693011070443633034612733309583190565217827378733393,
        s: 1867682679224997956048283066055885717352683300581532690215097247223135564277,
        sqrt_ratio_hint: 2921944847064913001096235045564630676660517332237551444115611698074403533689,
    }
}

#[test]
fn ecvrf_verify() {
    // verifiers must ensure the public key hasn't changed
    let pk = Point {
        x: 2465182048640915825114623967805639036884813714770257338089158027381626459289,
        y: 3038635738014387716559859267483610492356329532552881764846792983975787300333
    }; 
    let proof = proof_from_oracle();
    let ecvrf = ECVRFImpl::new(pk);
    let mut seed = ArrayTrait::new();
    seed.append(42);

    // 👇 proof verification
    let actual_beta = ecvrf.verify(proof, seed.span()).unwrap();

    let expected_beta = 1749760720107131022781690892024891617311129198096286233628341005792224087740;
    assert_eq!(expected_beta, actual_beta);
}

About

A VRF implementation using Stark curve and Poseidon hash.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published