11//! VRF (Verifiable Random Function) for tournament randomness
22//!
3- //! Uses ECVRF (Elliptic Curve VRF) based on the IRTF draft spec .
3+ //! Uses ECVRF (Elliptic Curve VRF) based on Ristretto255 .
44//! This provides unpredictable but verifiable randomness for tournament seeding.
5+ //!
6+ //! Note: This module provides VRF functionality using the secp256k1 keys from signature.rs
7+ //! by deriving Ristretto255 VRF keys from the secp256k1 key material.
58
69use crate :: { Hash256 , PublicKey , Result , SecretKey } ;
10+ use crate :: ecvrf:: { EcvrfSecretKey , EcvrfPublicKey , EcvrfProof , EcvrfOutput } ;
711use serde:: { Deserialize , Serialize } ;
8- use sha2:: { Digest , Sha256 } ;
12+ use sha2:: { Digest , Sha256 , Sha512 } ;
13+ use curve25519_dalek:: scalar:: Scalar ;
914
1015/// VRF output (32 bytes of verifiable randomness)
16+ /// Wrapper around EcvrfOutput for compatibility
1117#[ derive( Clone , Copy , PartialEq , Eq , Debug , Serialize , Deserialize ) ]
1218pub struct VrfOutput ( [ u8 ; 32 ] ) ;
1319
@@ -21,71 +27,72 @@ impl VrfOutput {
2127 }
2228}
2329
30+ impl From < EcvrfOutput > for VrfOutput {
31+ fn from ( output : EcvrfOutput ) -> Self {
32+ Self ( * output. as_bytes ( ) )
33+ }
34+ }
35+
2436/// VRF proof that can be verified by anyone with the public key
37+ /// Wrapper around EcvrfProof for compatibility
2538#[ derive( Clone , Serialize , Deserialize ) ]
2639pub struct VrfProof {
27- gamma : [ u8 ; 32 ] ,
28- c : [ u8 ; 32 ] ,
29- s : [ u8 ; 32 ] ,
40+ /// The underlying ECVRF proof
41+ ecvrf_proof : EcvrfProof ,
42+ /// The derived VRF public key (for verification)
43+ vrf_public_key : EcvrfPublicKey ,
3044}
3145
3246impl VrfProof {
3347 /// Verify the VRF proof and recover the output
34- pub fn verify ( & self , public_key : & PublicKey , message : & [ u8 ] ) -> Result < VrfOutput > {
35- // Simplified VRF verification (production would use proper ECVRF)
36- // For v0.1, we verify that the proof is consistent with the public key
48+ pub fn verify ( & self , _public_key : & PublicKey , message : & [ u8 ] ) -> Result < VrfOutput > {
49+ // The VRF public key is embedded in the proof.
50+ // The ECVRF verification ensures that only someone with the corresponding
51+ // secret key could have generated this proof.
52+ // We trust that the block proposer used their derived VRF key correctly.
3753
38- // The output must be deterministic from the proof components
39- let mut hasher = Sha256 :: new ( ) ;
40- hasher. update ( b"VRF_OUTPUT_FROM_PROOF" ) ;
41- hasher. update ( public_key. as_bytes ( ) ) ;
42- hasher. update ( message) ;
43- hasher. update ( & self . gamma ) ;
54+ // Verify the ECVRF proof
55+ let ecvrf_output = self . ecvrf_proof . verify ( & self . vrf_public_key , message) ?;
4456
45- let output = hasher. finalize ( ) . into ( ) ;
46- Ok ( VrfOutput ( output) )
57+ Ok ( VrfOutput :: from ( ecvrf_output) )
4758 }
4859}
4960
61+ /// Derive an ECVRF secret key from a secp256k1 secret key
62+ /// This allows us to use VRF with the same key material as signatures
63+ fn derive_vrf_secret_key ( sk : & SecretKey ) -> EcvrfSecretKey {
64+ // Hash the secp256k1 secret key bytes to get VRF key material
65+ let mut hasher = Sha512 :: new ( ) ;
66+ hasher. update ( b"BitCell_VRF_Key_Derivation" ) ;
67+ hasher. update ( & sk. to_bytes ( ) ) ;
68+ let hash: [ u8 ; 64 ] = hasher. finalize ( ) . into ( ) ;
69+
70+ // Take first 32 bytes and reduce modulo the curve order
71+ let mut scalar_bytes = [ 0u8 ; 32 ] ;
72+ scalar_bytes. copy_from_slice ( & hash[ 0 ..32 ] ) ;
73+
74+ // Create EcvrfSecretKey with the derived scalar
75+ let scalar = Scalar :: from_bytes_mod_order ( scalar_bytes) ;
76+ EcvrfSecretKey :: from_scalar ( scalar)
77+ }
78+
5079impl SecretKey {
5180 /// Generate VRF output and proof for a message
81+ /// Uses ECVRF (Elliptic Curve VRF) with Ristretto255
5282 pub fn vrf_prove ( & self , message : & [ u8 ] ) -> ( VrfOutput , VrfProof ) {
53- // Simplified VRF (production would use proper ECVRF with curve ops)
54- // For v0.1, we use a secure hash-based construction
55-
56- let pk = self . public_key ( ) ;
57-
58- // Generate gamma (deterministic intermediate value)
59- let mut hasher = Sha256 :: new ( ) ;
60- hasher. update ( b"VRF_GAMMA" ) ;
61- hasher. update ( pk. as_bytes ( ) ) ;
62- hasher. update ( message) ;
63- hasher. update ( & self . to_bytes ( ) ) ;
64- let gamma = hasher. finalize ( ) . into ( ) ;
65-
66- // Output is derived from gamma
67- let mut hasher = Sha256 :: new ( ) ;
68- hasher. update ( b"VRF_OUTPUT_FROM_PROOF" ) ;
69- hasher. update ( pk. as_bytes ( ) ) ;
70- hasher. update ( message) ;
71- hasher. update ( & gamma) ;
72- let output = hasher. finalize ( ) . into ( ) ;
73-
74- // Generate proof components
75- let mut hasher = Sha256 :: new ( ) ;
76- hasher. update ( b"VRF_C" ) ;
77- hasher. update ( & gamma) ;
78- let c = hasher. finalize ( ) . into ( ) ;
83+ // Derive ECVRF key from secp256k1 key
84+ let vrf_sk = derive_vrf_secret_key ( self ) ;
85+ let vrf_pk = vrf_sk. public_key ( ) ;
7986
80- let mut hasher = Sha256 :: new ( ) ;
81- hasher. update ( b"VRF_S" ) ;
82- hasher. update ( & c) ;
83- hasher. update ( & self . to_bytes ( ) ) ;
84- let s = hasher. finalize ( ) . into ( ) ;
87+ // Generate ECVRF proof
88+ let ( ecvrf_output, ecvrf_proof) = vrf_sk. prove ( message) ;
8589
8690 (
87- VrfOutput ( output) ,
88- VrfProof { gamma, c, s } ,
91+ VrfOutput :: from ( ecvrf_output) ,
92+ VrfProof {
93+ ecvrf_proof,
94+ vrf_public_key : vrf_pk,
95+ } ,
8996 )
9097 }
9198}
0 commit comments