1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc = include_str!("../README.md")]
3
4use crate::error::VrfResult;
5pub(crate) mod consts;
11
12pub mod error;
13
14#[cfg(feature = "ec")]
15pub mod ec;
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
21#[repr(transparent)]
22pub struct Ciphersuite(u8);
23
24impl Ciphersuite {
25 pub const ECVRF_P256_SHA256_TAI: Ciphersuite =
26 Ciphersuite(crate::consts::ecvrf::ciphersuites::ECVRF_P256_SHA256_TAI);
27 pub const ECVRF_P256_SHA256_SSWU: Ciphersuite =
28 Ciphersuite(crate::consts::ecvrf::ciphersuites::ECVRF_P256_SHA256_SSWU);
29 pub const ECVRF_EDWARDS25519_SHA512_TAI: Ciphersuite =
30 Ciphersuite(crate::consts::ecvrf::ciphersuites::ECVRF_EDWARDS25519_SHA512_TAI);
31 pub const ECVRF_EDWARDS25519_SHA512_ELL2: Ciphersuite =
32 Ciphersuite(crate::consts::ecvrf::ciphersuites::ECVRF_EDWARDS25519_SHA512_ELL2);
33
34 pub const RSA_FDH_VRF_SHA256: Ciphersuite =
35 Ciphersuite(crate::consts::rsavrf::ciphersuites::RSA_FDH_VRF_SHA256);
36 pub const RSA_FDH_VRF_SHA384: Ciphersuite =
37 Ciphersuite(crate::consts::rsavrf::ciphersuites::RSA_FDH_VRF_SHA384);
38 pub const RSA_FDH_VRF_SHA512: Ciphersuite =
39 Ciphersuite(crate::consts::rsavrf::ciphersuites::RSA_FDH_VRF_SHA512);
40}
41
42impl From<u8> for Ciphersuite {
43 fn from(value: u8) -> Self {
44 Self(value)
45 }
46}
47
48impl std::fmt::Display for Ciphersuite {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "Ciphersuite[{:#2X}]", self.0)
51 }
52}
53
54impl std::ops::Deref for Ciphersuite {
55 type Target = u8;
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61pub trait Proof<H: digest::Digest>: PartialEq + Eq {
62 const PROOF_LEN: usize;
63 fn decode_pi(pi: &[u8]) -> VrfResult<Self>
65 where
66 Self: Sized;
67 fn encode_to_pi(&self) -> Vec<u8>;
69 fn proof_to_hash(&self, suite: Ciphersuite) -> VrfResult<digest::Output<H>>;
71}
72
73pub trait Prover<H: digest::Digest>: PartialEq + Eq {
74 type Proof: Proof<H>;
76 type Verifier: Verifier<H, Proof = Self::Proof>;
78
79 #[cfg(feature = "hazmat")]
80 fn x_equals(&self, value: &[u8]) -> bool;
82
83 fn from_slice(bytes: &[u8]) -> VrfResult<Self>
85 where
86 Self: Sized;
87
88 fn verifier(&self) -> Self::Verifier;
90 fn prove(&self, alpha: &[u8]) -> VrfResult<Self::Proof>;
92}
93
94pub trait Verifier<H: digest::Digest>: PartialEq + Eq {
95 type Proof: Proof<H>;
97 fn from_slice(bytes: &[u8]) -> VrfResult<Self>
98 where
99 Self: Sized;
100 fn verify(&self, alpha: &[u8], proof: Self::Proof) -> VrfResult<digest::Output<H>>;
102}
103
104pub trait VRF {
106 type Hash: digest::Digest;
108 type Proof: Proof<Self::Hash>;
110 type Verifier: Verifier<Self::Hash, Proof = Self::Proof>;
112 type Prover: Prover<Self::Hash, Proof = Self::Proof, Verifier = Self::Verifier>;
114 fn ciphersuite(&self) -> Ciphersuite;
116
117 fn prove(&self, prover: &Self::Prover, alpha: &[u8]) -> VrfResult<Vec<u8>> {
119 Ok(prover.prove(alpha)?.encode_to_pi())
120 }
121
122 fn verify(
124 &self,
125 verifier: &Self::Verifier,
126 alpha: &[u8],
127 pi: &[u8],
128 ) -> VrfResult<digest::Output<Self::Hash>> {
129 verifier.verify(alpha, Self::Proof::decode_pi(pi)?)
130 }
131}