akd_core/ecvrf/mod.rs
1// Copyright (c) Meta Platforms, Inc. and affiliates.
2//
3// This source code is dual-licensed under either the MIT license found in the
4// LICENSE-MIT file in the root directory of this source tree or the Apache
5// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
6// of this source tree. You may select, at your option, one of the above-listed licenses.
7
8//! This module contains implementations of a
9//! [verifiable random function](https://en.wikipedia.org/wiki/Verifiable_random_function)
10//! (currently only ECVRF). VRFs are used, in the case of this crate, to anonymize the
11//! user id <-> node label mapping into a 1-way hash, which is verifyable without being
12//! regeneratable without the secret key.
13//!
14//! VRFs allow us to have the server generate a constant mapping from a user id to a node label
15//! but the client cannot themselves generate the mapping, only verify it. They can confirm
16//! a user id matches the label, but don't have the ability to determine the labels of other
17//! users in the directory.
18//!
19//! This module implements an instantiation of a verifiable random function known as
20//! [ECVRF-EDWARDS25519-SHA512-TAI from RFC9381](https://www.ietf.org/rfc/rfc9381.html).
21//!
22//!
23//! Adapted from Diem's NextGen Crypto module available [here](https://github.com/diem/diem/blob/502936fbd59e35276e2cf455532b143796d68a16/crypto/nextgen_crypto/src/vrf/ecvrf.rs)
24
25mod ecvrf_impl;
26mod traits;
27// export the functionality we want visible
28pub use crate::ecvrf::ecvrf_impl::{
29 Output, Proof, VRFExpandedPrivateKey, VRFPrivateKey, VRFPublicKey,
30};
31pub use crate::ecvrf::traits::VRFKeyStorage;
32#[cfg(feature = "nostd")]
33use alloc::boxed::Box;
34#[cfg(feature = "nostd")]
35use alloc::format;
36#[cfg(feature = "nostd")]
37use alloc::string::String;
38#[cfg(feature = "nostd")]
39use alloc::string::ToString;
40#[cfg(feature = "nostd")]
41use alloc::vec::Vec;
42
43#[cfg(test)]
44mod tests;
45
46/// A error related to verifiable random functions
47#[derive(Debug, Eq, PartialEq)]
48pub enum VrfError {
49 /// A problem retrieving or decoding the VRF public key
50 PublicKey(String),
51 /// A problem retrieving or decoding the VRF signing key
52 SigningKey(String),
53 /// A problem verifying the VRF proof
54 Verification(String),
55}
56
57impl core::fmt::Display for VrfError {
58 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
59 let code = match &self {
60 VrfError::PublicKey(msg) => format!("(Public Key) - {msg}"),
61 VrfError::SigningKey(msg) => format!("(Signing Key) - {msg}"),
62 VrfError::Verification(msg) => format!("(Verification) - {msg}"),
63 };
64 write!(f, "Verifiable random function error {code}")
65 }
66}
67
68/// This is a version of VRFKeyStorage for testing purposes, which uses the example from the VRF crate.
69///
70/// const KEY_MATERIAL: &str = "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721";
71#[derive(Clone)]
72pub struct HardCodedAkdVRF;
73
74unsafe impl Sync for HardCodedAkdVRF {}
75unsafe impl Send for HardCodedAkdVRF {}
76
77#[async_trait::async_trait]
78impl VRFKeyStorage for HardCodedAkdVRF {
79 async fn retrieve(&self) -> Result<Vec<u8>, VrfError> {
80 hex::decode("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721")
81 .map_err(|hex_err| VrfError::PublicKey(hex_err.to_string()))
82 }
83}