vrf_rfc9381/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![doc = include_str!("../README.md")]
3
4use crate::error::VrfResult;
5// #[cfg(feature = "rsa")]
6// compile_error!(
7//     "The `rsa` feature isn't implemented yet. Please express support for it in the repo for it to be implemented."
8// );
9
10pub(crate) mod consts;
11
12pub mod error;
13
14#[cfg(feature = "ec")]
15pub mod ec;
16// No support yet
17// #[cfg(feature = "rsa")]
18// pub mod rsa;
19
20#[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    /// Decodes the `pi_string` to a concrete Proof
64    fn decode_pi(pi: &[u8]) -> VrfResult<Self>
65    where
66        Self: Sized;
67    /// Encodes this proof to `pi_string`
68    fn encode_to_pi(&self) -> Vec<u8>;
69    /// Performs the proof to hash operation on the VRF Proof
70    fn proof_to_hash(&self, suite: Ciphersuite) -> VrfResult<digest::Output<H>>;
71}
72
73pub trait Prover<H: digest::Digest>: PartialEq + Eq {
74    /// The Proof emitted by this Prover
75    type Proof: Proof<H>;
76    /// The public counterpart (Verifier) of this Prover
77    type Verifier: Verifier<H, Proof = Self::Proof>;
78
79    #[cfg(feature = "hazmat")]
80    /// Hazmat internal allowing to check if the scalar x equals a value. Do not use!
81    fn x_equals(&self, value: &[u8]) -> bool;
82
83    /// Deserialize a Prover from its byte representation
84    fn from_slice(bytes: &[u8]) -> VrfResult<Self>
85    where
86        Self: Sized;
87
88    /// Get the public counterpart of this Prover
89    fn verifier(&self) -> Self::Verifier;
90    /// Proves `alpha` as a VRF Proof
91    fn prove(&self, alpha: &[u8]) -> VrfResult<Self::Proof>;
92}
93
94pub trait Verifier<H: digest::Digest>: PartialEq + Eq {
95    /// The Proof that this Verifier can verify
96    type Proof: Proof<H>;
97    fn from_slice(bytes: &[u8]) -> VrfResult<Self>
98    where
99        Self: Sized;
100    /// Verifies a (alpha, proof) combo, and outputs the VRF_proof_to_hash if successful
101    fn verify(&self, alpha: &[u8], proof: Self::Proof) -> VrfResult<digest::Output<H>>;
102}
103
104/// Supertrait that combines all the features of Proof, Verifier and Prover in an easy-to-use package
105pub trait VRF {
106    /// Hash algorithm in use
107    type Hash: digest::Digest;
108    /// The Proof type for this VRF.
109    type Proof: Proof<Self::Hash>;
110    /// The Verifier in use for this VRF; It's usually some sort of Public Key
111    type Verifier: Verifier<Self::Hash, Proof = Self::Proof>;
112    /// The Prover in use for this VRF; It's usually some sort of Secret Key
113    type Prover: Prover<Self::Hash, Proof = Self::Proof, Verifier = Self::Verifier>;
114    /// The Ciphersuite in use for this VRF
115    fn ciphersuite(&self) -> Ciphersuite;
116
117    /// Outputs pi
118    fn prove(&self, prover: &Self::Prover, alpha: &[u8]) -> VrfResult<Vec<u8>> {
119        Ok(prover.prove(alpha)?.encode_to_pi())
120    }
121
122    /// Outputs VRF_proof_to_hash(pi)
123    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}