chaincraft_rust/crypto/
vdf.rs1use crate::error::{ChaincraftError, Result};
7
8#[derive(Debug, Clone)]
10pub struct VerifiableDelayFunction {
11 num_bits: u16,
12}
13
14impl VerifiableDelayFunction {
15 pub fn new() -> Self {
16 Self::with_bits(2048)
17 }
18
19 pub fn with_bits(num_bits: u16) -> Self {
20 Self { num_bits }
21 }
22
23 pub fn solve(&self, challenge: &[u8], iterations: u64) -> Result<Vec<u8>> {
25 #[cfg(feature = "vdf-crypto")]
26 {
27 use vdf::{PietrzakVDFParams, VDF, VDFParams};
28 let vdf = PietrzakVDFParams(self.num_bits).new();
29 vdf.solve(challenge, iterations).map_err(|e| {
30 ChaincraftError::Crypto(crate::error::CryptoError::VdfError {
31 reason: format!("{:?}", e),
32 })
33 })
34 }
35 #[cfg(not(feature = "vdf-crypto"))]
36 {
37 let _ = (challenge, iterations);
38 Err(ChaincraftError::Crypto(crate::error::CryptoError::VdfError {
39 reason: "VDF requires feature 'vdf-crypto'. Enable with: chaincraft-rust = { version = \"..\", features = [\"vdf-crypto\"] }".to_string(),
40 }))
41 }
42 }
43
44 pub fn verify(&self, challenge: &[u8], iterations: u64, solution: &[u8]) -> Result<bool> {
46 #[cfg(feature = "vdf-crypto")]
47 {
48 use vdf::{PietrzakVDFParams, VDF, VDFParams};
49 let vdf = PietrzakVDFParams(self.num_bits).new();
50 vdf.verify(challenge, iterations, solution)
51 .map(|_| true)
52 .map_err(|e| {
53 ChaincraftError::Crypto(crate::error::CryptoError::VdfError {
54 reason: format!("{:?}", e),
55 })
56 })
57 }
58 #[cfg(not(feature = "vdf-crypto"))]
59 {
60 let _ = (challenge, iterations, solution);
61 Err(ChaincraftError::Crypto(crate::error::CryptoError::VdfError {
62 reason: "VDF requires feature 'vdf-crypto'".to_string(),
63 }))
64 }
65 }
66}
67
68impl Default for VerifiableDelayFunction {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[cfg(not(feature = "vdf-crypto"))]
79 #[test]
80 fn test_vdf_without_feature_returns_error() {
81 let vdf = VerifiableDelayFunction::new();
82 let err = vdf.solve(b"challenge", 10);
83 assert!(err.is_err());
84 assert!(err.unwrap_err().to_string().contains("vdf-crypto"));
85 }
86
87 #[cfg(feature = "vdf-crypto")]
88 #[test]
89 fn test_vdf_solve_and_verify() {
90 let vdf = VerifiableDelayFunction::with_bits(1024);
91 let challenge = b"test";
92 let iterations = 66u64; let solution = vdf.solve(challenge, iterations).expect("solve");
94 assert!(!solution.is_empty());
95 assert!(vdf.verify(challenge, iterations, &solution).unwrap());
96 }
97}