1use super::{Output, Proof, VRFExpandedPrivateKey, VRFPrivateKey, VRFPublicKey, VrfError};
11use crate::configuration::Configuration;
12use crate::{AkdLabel, AkdValue, NodeLabel, VersionFreshness};
13
14#[cfg(feature = "nostd")]
15use alloc::boxed::Box;
16#[cfg(feature = "nostd")]
17use alloc::vec::Vec;
18use async_trait::async_trait;
19use core::convert::TryInto;
20
21#[async_trait]
29pub trait VRFKeyStorage: Clone + Sync + Send {
30 async fn retrieve(&self) -> Result<Vec<u8>, VrfError>;
34
35 async fn get_vrf_private_key(&self) -> Result<VRFPrivateKey, VrfError> {
39 match self.retrieve().await {
40 Ok(bytes) => {
41 let pk_ref: &[u8] = &bytes;
42 pk_ref.try_into()
43 }
44 Err(other) => Err(other),
45 }
46 }
47
48 async fn get_vrf_public_key(&self) -> Result<VRFPublicKey, VrfError> {
50 self.get_vrf_private_key().await.map(|key| (&key).into())
51 }
52
53 async fn get_node_label<TC: Configuration>(
58 &self,
59 label: &AkdLabel,
60 freshness: VersionFreshness,
61 version: u64,
62 ) -> Result<NodeLabel, VrfError> {
63 let key = self.get_vrf_private_key().await?;
64 let expanded_key = VRFExpandedPrivateKey::from(&key);
65 let pk = VRFPublicKey::from(&key);
66 Ok(Self::get_node_label_with_expanded_key::<TC>(
67 &expanded_key,
68 &pk,
69 label,
70 freshness,
71 version,
72 ))
73 }
74
75 fn get_node_label_with_expanded_key<TC: Configuration>(
81 expanded_private_key: &VRFExpandedPrivateKey,
82 pk: &VRFPublicKey,
83 label: &AkdLabel,
84 freshness: VersionFreshness,
85 version: u64,
86 ) -> NodeLabel {
87 let output = Self::get_label_with_key_helper::<TC>(
88 expanded_private_key,
89 pk,
90 label,
91 freshness,
92 version,
93 );
94 NodeLabel::new(output.to_truncated_bytes(), 256)
95 }
96
97 async fn get_node_label_from_vrf_proof(&self, proof: Proof) -> NodeLabel {
99 let output: super::ecvrf_impl::Output = (&proof).into();
100 NodeLabel::new(output.to_truncated_bytes(), 256)
101 }
102
103 async fn get_label_proof<TC: Configuration>(
105 &self,
106 label: &AkdLabel,
107 freshness: VersionFreshness,
108 version: u64,
109 ) -> Result<Proof, VrfError> {
110 let key = self.get_vrf_private_key().await?;
111 Ok(Self::get_label_proof_with_key::<TC>(
112 &key, label, freshness, version,
113 ))
114 }
115
116 fn get_label_proof_with_key<TC: Configuration>(
118 key: &VRFPrivateKey,
119 label: &AkdLabel,
120 freshness: VersionFreshness,
121 version: u64,
122 ) -> Proof {
123 let hashed_label = TC::get_hash_from_label_input(label, freshness, version);
124 key.prove(&hashed_label)
125 }
126
127 fn get_label_with_key_helper<TC: Configuration>(
129 expanded_private_key: &VRFExpandedPrivateKey,
130 pk: &VRFPublicKey,
131 label: &AkdLabel,
132 freshness: VersionFreshness,
133 version: u64,
134 ) -> Output {
135 let hashed_label = TC::get_hash_from_label_input(label, freshness, version);
136 expanded_private_key.evaluate(pk, &hashed_label)
137 }
138
139 async fn get_node_labels<TC: Configuration>(
145 &self,
146 labels: &[(AkdLabel, VersionFreshness, u64, AkdValue)],
147 ) -> Result<Vec<((AkdLabel, VersionFreshness, u64, AkdValue), NodeLabel)>, VrfError> {
148 let key = self.get_vrf_private_key().await?;
149 let expanded_key = VRFExpandedPrivateKey::from(&key);
150 let pk = VRFPublicKey::from(&key);
151
152 #[cfg(feature = "parallel_vrf")]
153 {
154 #[cfg(feature = "nostd")]
155 use alloc::format;
156
157 let mut join_set = tokio::task::JoinSet::new();
158 let labels_vec = labels.to_vec();
159 for (label, freshness, version, value) in labels_vec.into_iter() {
160 let expanded_key_ref = expanded_key.clone();
161 let pk_ref = pk.clone();
162
163 let future = {
164 async move {
165 (
166 Self::get_node_label_with_expanded_key::<TC>(
167 &expanded_key_ref,
168 &pk_ref,
169 &label,
170 freshness,
171 version,
172 ),
173 (label, freshness, version, value),
174 )
175 }
176 };
177 join_set.spawn(future);
178 }
179
180 let mut results = Vec::new();
181 while let Some(res) = join_set.join_next().await {
182 match res {
183 Err(join_err) => {
184 return Err(VrfError::SigningKey(format!(
185 "Parallel VRF join error {join_err}"
186 )))
187 }
188 Ok((node_label, (label, freshness, version, value))) => {
189 results.push(((label, freshness, version, value), node_label));
190 }
191 }
192 }
193 Ok(results)
194 }
195 #[cfg(not(feature = "parallel_vrf"))]
196 {
197 let mut results = Vec::new();
198 for (label, freshness, version, value) in labels {
199 let node_label = Self::get_node_label_with_expanded_key::<TC>(
200 &expanded_key,
201 &pk,
202 label,
203 *freshness,
204 *version,
205 );
206 results.push((
207 (label.clone(), *freshness, *version, value.clone()),
208 node_label,
209 ));
210 }
211 Ok(results)
212 }
213 }
214}