chaincraft_rust/crypto/
vrf.rs1use crate::error::{ChaincraftError, CryptoError, Result};
9use k256::ecdsa::{signature::Signer, SigningKey};
10use rand_core::OsRng;
11use sha2::{Digest, Sha256};
12use std::fmt;
13
14#[derive(Debug, Clone)]
16pub struct ECDSAVRF {
17 signing_key: SigningKey,
18}
19
20impl ECDSAVRF {
21 pub fn new() -> Result<Self> {
23 let signing_key = SigningKey::random(&mut OsRng);
24 Ok(Self { signing_key })
25 }
26
27 pub fn from_signing_key_bytes(bytes: &[u8]) -> Result<Self> {
29 let signing_key = SigningKey::from_slice(bytes)
30 .map_err(|_| ChaincraftError::Crypto(CryptoError::InvalidPrivateKey {
31 reason: "Invalid secp256k1 key".to_string(),
32 }))?;
33 Ok(Self { signing_key })
34 }
35
36 pub fn prove(&self, data: &[u8]) -> Result<Vec<u8>> {
38 let signature: k256::ecdsa::Signature = self.signing_key.sign(data);
39 Ok(signature.to_bytes().to_vec())
40 }
41
42 pub fn verify(&self, data: &[u8], proof: &[u8]) -> Result<Vec<u8>> {
44 use k256::ecdsa::{signature::Verifier, VerifyingKey};
45 let sig = k256::ecdsa::Signature::from_slice(proof)
46 .map_err(|_| ChaincraftError::Crypto(CryptoError::InvalidSignature))?;
47 let vk = VerifyingKey::from(&self.signing_key);
48 vk.verify(data, &sig).map_err(|_| {
49 ChaincraftError::Crypto(CryptoError::VrfVerificationFailed)
50 })?;
51 Ok(Self::vrf_output(proof))
52 }
53
54 pub fn vrf_output(proof: &[u8]) -> Vec<u8> {
56 Sha256::digest(proof).to_vec()
57 }
58
59 pub fn public_key_bytes(&self) -> Vec<u8> {
61 use k256::elliptic_curve::sec1::ToEncodedPoint;
62 self.signing_key
63 .verifying_key()
64 .to_encoded_point(true)
65 .as_bytes()
66 .to_vec()
67 }
68
69 pub fn verify_with_public_key(
71 public_key_bytes: &[u8],
72 data: &[u8],
73 proof: &[u8],
74 ) -> Result<Vec<u8>> {
75 use k256::ecdsa::{signature::Verifier, VerifyingKey};
76 let pk = k256::PublicKey::from_sec1_bytes(public_key_bytes)
77 .map_err(|_| ChaincraftError::Crypto(CryptoError::InvalidPublicKey {
78 reason: "Invalid secp256k1 public key".to_string(),
79 }))?;
80 let vk = VerifyingKey::from(pk);
81 let sig = k256::ecdsa::Signature::from_slice(proof)
82 .map_err(|_| ChaincraftError::Crypto(CryptoError::InvalidSignature))?;
83 vk.verify(data, &sig).map_err(|_| {
84 ChaincraftError::Crypto(CryptoError::VrfVerificationFailed)
85 })?;
86 Ok(Self::vrf_output(proof))
87 }
88}
89
90impl Default for ECDSAVRF {
91 fn default() -> Self {
92 Self::new().expect("VRF keygen")
93 }
94}
95
96#[derive(Debug, Clone)]
98pub struct VerifiableRandomFunction(ECDSAVRF);
99
100impl VerifiableRandomFunction {
101 pub fn new() -> Result<Self> {
102 ECDSAVRF::new().map(Self)
103 }
104}
105
106impl Default for VerifiableRandomFunction {
107 fn default() -> Self {
108 Self(ECDSAVRF::default())
109 }
110}
111
112impl fmt::Display for VerifiableRandomFunction {
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114 write!(f, "VerifiableRandomFunction(ECDSA)")
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_vrf_prove_verify() {
124 let vrf = ECDSAVRF::new().unwrap();
125 let data = b"vrf_input";
126 let proof = vrf.prove(data).unwrap();
127 assert!(!proof.is_empty());
128 let output = vrf.verify(data, &proof).unwrap();
129 assert_eq!(output.len(), 32);
130 assert_eq!(output, ECDSAVRF::vrf_output(&proof));
131 }
132
133 #[test]
134 fn test_vrf_verify_with_public_key() {
135 let vrf = ECDSAVRF::new().unwrap();
136 let pk = vrf.public_key_bytes();
137 let data = b"test";
138 let proof = vrf.prove(data).unwrap();
139 let output = ECDSAVRF::verify_with_public_key(&pk, data, &proof).unwrap();
140 assert_eq!(output, ECDSAVRF::vrf_output(&proof));
141 }
142
143 #[test]
144 fn test_vrf_invalid_proof_fails() {
145 let vrf = ECDSAVRF::new().unwrap();
146 let data = b"input";
147 let bad_proof = vec![0u8; 64];
148 assert!(vrf.verify(data, &bad_proof).is_err());
149 }
150}