1use tet_core::crypto::KeyTypeId;
21use tet_core::{
22 crypto::{Pair, Public, CryptoTypePublicPair},
23 ed25519, sr25519, ecdsa,
24};
25use crate::{
26 {CryptoStore, SyncCryptoStorePtr, Error, SyncCryptoStore},
27 vrf::{VRFTranscriptData, VRFSignature, make_transcript},
28};
29use std::{collections::{HashMap, HashSet}, sync::Arc};
30use parking_lot::RwLock;
31use async_trait::async_trait;
32
33#[derive(Default)]
35pub struct KeyStore {
36 keys: Arc<RwLock<HashMap<KeyTypeId, HashMap<Vec<u8>, String>>>>,
38}
39
40impl KeyStore {
41 pub fn new() -> Self {
43 Self::default()
44 }
45
46 fn sr25519_key_pair(&self, id: KeyTypeId, pub_key: &sr25519::Public) -> Option<sr25519::Pair> {
47 self.keys.read().get(&id)
48 .and_then(|inner|
49 inner.get(pub_key.as_slice())
50 .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid"))
51 )
52 }
53
54 fn ed25519_key_pair(&self, id: KeyTypeId, pub_key: &ed25519::Public) -> Option<ed25519::Pair> {
55 self.keys.read().get(&id)
56 .and_then(|inner|
57 inner.get(pub_key.as_slice())
58 .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid"))
59 )
60 }
61
62 fn ecdsa_key_pair(&self, id: KeyTypeId, pub_key: &ecdsa::Public) -> Option<ecdsa::Pair> {
63 self.keys.read().get(&id)
64 .and_then(|inner|
65 inner.get(pub_key.as_slice())
66 .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid"))
67 )
68 }
69
70}
71
72#[async_trait]
73impl CryptoStore for KeyStore {
74 async fn keys(&self, id: KeyTypeId) -> Result<Vec<CryptoTypePublicPair>, Error> {
75 SyncCryptoStore::keys(self, id)
76 }
77
78 async fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec<sr25519::Public> {
79 SyncCryptoStore::sr25519_public_keys(self, id)
80 }
81
82 async fn sr25519_generate_new(
83 &self,
84 id: KeyTypeId,
85 seed: Option<&str>,
86 ) -> Result<sr25519::Public, Error> {
87 SyncCryptoStore::sr25519_generate_new(self, id, seed)
88 }
89
90 async fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec<ed25519::Public> {
91 SyncCryptoStore::ed25519_public_keys(self, id)
92 }
93
94 async fn ed25519_generate_new(
95 &self,
96 id: KeyTypeId,
97 seed: Option<&str>,
98 ) -> Result<ed25519::Public, Error> {
99 SyncCryptoStore::ed25519_generate_new(self, id, seed)
100 }
101
102 async fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa::Public> {
103 SyncCryptoStore::ecdsa_public_keys(self, id)
104 }
105
106 async fn ecdsa_generate_new(
107 &self,
108 id: KeyTypeId,
109 seed: Option<&str>,
110 ) -> Result<ecdsa::Public, Error> {
111 SyncCryptoStore::ecdsa_generate_new(self, id, seed)
112 }
113
114 async fn insert_unknown(&self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
115 SyncCryptoStore::insert_unknown(self, id, suri, public)
116 }
117
118 async fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
119 SyncCryptoStore::has_keys(self, public_keys)
120 }
121
122 async fn supported_keys(
123 &self,
124 id: KeyTypeId,
125 keys: Vec<CryptoTypePublicPair>,
126 ) -> std::result::Result<Vec<CryptoTypePublicPair>, Error> {
127 SyncCryptoStore::supported_keys(self, id, keys)
128 }
129
130 async fn sign_with(
131 &self,
132 id: KeyTypeId,
133 key: &CryptoTypePublicPair,
134 msg: &[u8],
135 ) -> Result<Vec<u8>, Error> {
136 SyncCryptoStore::sign_with(self, id, key, msg)
137 }
138
139 async fn sr25519_vrf_sign(
140 &self,
141 key_type: KeyTypeId,
142 public: &sr25519::Public,
143 transcript_data: VRFTranscriptData,
144 ) -> Result<VRFSignature, Error> {
145 SyncCryptoStore::sr25519_vrf_sign(self, key_type, public, transcript_data)
146 }
147}
148
149impl SyncCryptoStore for KeyStore {
150 fn keys(&self, id: KeyTypeId) -> Result<Vec<CryptoTypePublicPair>, Error> {
151 self.keys.read()
152 .get(&id)
153 .map(|map| {
154 Ok(map.keys()
155 .fold(Vec::new(), |mut v, k| {
156 v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone()));
157 v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone()));
158 v.push(CryptoTypePublicPair(ecdsa::CRYPTO_ID, k.clone()));
159 v
160 }))
161 })
162 .unwrap_or_else(|| Ok(vec![]))
163 }
164
165 fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec<sr25519::Public> {
166 self.keys.read().get(&id)
167 .map(|keys|
168 keys.values()
169 .map(|s| sr25519::Pair::from_string(s, None).expect("`sr25519` seed slice is valid"))
170 .map(|p| p.public())
171 .collect()
172 )
173 .unwrap_or_default()
174 }
175
176 fn sr25519_generate_new(
177 &self,
178 id: KeyTypeId,
179 seed: Option<&str>,
180 ) -> Result<sr25519::Public, Error> {
181 match seed {
182 Some(seed) => {
183 let pair = sr25519::Pair::from_string(seed, None)
184 .map_err(|_| Error::ValidationError("Generates an `sr25519` pair.".to_owned()))?;
185 self.keys.write().entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
186 Ok(pair.public())
187 },
188 None => {
189 let (pair, phrase, _) = sr25519::Pair::generate_with_phrase(None);
190 self.keys.write().entry(id).or_default().insert(pair.public().to_raw_vec(), phrase);
191 Ok(pair.public())
192 }
193 }
194 }
195
196 fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec<ed25519::Public> {
197 self.keys.read().get(&id)
198 .map(|keys|
199 keys.values()
200 .map(|s| ed25519::Pair::from_string(s, None).expect("`ed25519` seed slice is valid"))
201 .map(|p| p.public())
202 .collect()
203 )
204 .unwrap_or_default()
205 }
206
207 fn ed25519_generate_new(
208 &self,
209 id: KeyTypeId,
210 seed: Option<&str>,
211 ) -> Result<ed25519::Public, Error> {
212 match seed {
213 Some(seed) => {
214 let pair = ed25519::Pair::from_string(seed, None)
215 .map_err(|_| Error::ValidationError("Generates an `ed25519` pair.".to_owned()))?;
216 self.keys.write().entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
217 Ok(pair.public())
218 },
219 None => {
220 let (pair, phrase, _) = ed25519::Pair::generate_with_phrase(None);
221 self.keys.write().entry(id).or_default().insert(pair.public().to_raw_vec(), phrase);
222 Ok(pair.public())
223 }
224 }
225 }
226
227 fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa::Public> {
228 self.keys.read().get(&id)
229 .map(|keys|
230 keys.values()
231 .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid"))
232 .map(|p| p.public())
233 .collect()
234 )
235 .unwrap_or_default()
236 }
237
238 fn ecdsa_generate_new(
239 &self,
240 id: KeyTypeId,
241 seed: Option<&str>,
242 ) -> Result<ecdsa::Public, Error> {
243 match seed {
244 Some(seed) => {
245 let pair = ecdsa::Pair::from_string(seed, None)
246 .map_err(|_| Error::ValidationError("Generates an `ecdsa` pair.".to_owned()))?;
247 self.keys.write().entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into());
248 Ok(pair.public())
249 },
250 None => {
251 let (pair, phrase, _) = ecdsa::Pair::generate_with_phrase(None);
252 self.keys.write().entry(id).or_default().insert(pair.public().to_raw_vec(), phrase);
253 Ok(pair.public())
254 }
255 }
256 }
257
258 fn insert_unknown(&self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
259 self.keys.write().entry(id).or_default().insert(public.to_owned(), suri.to_string());
260 Ok(())
261 }
262
263 fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
264 public_keys.iter().all(|(k, t)| self.keys.read().get(&t).and_then(|s| s.get(k)).is_some())
265 }
266
267 fn supported_keys(
268 &self,
269 id: KeyTypeId,
270 keys: Vec<CryptoTypePublicPair>,
271 ) -> std::result::Result<Vec<CryptoTypePublicPair>, Error> {
272 let provided_keys = keys.into_iter().collect::<HashSet<_>>();
273 let all_keys = SyncCryptoStore::keys(self, id)?.into_iter().collect::<HashSet<_>>();
274
275 Ok(provided_keys.intersection(&all_keys).cloned().collect())
276 }
277
278 fn sign_with(
279 &self,
280 id: KeyTypeId,
281 key: &CryptoTypePublicPair,
282 msg: &[u8],
283 ) -> Result<Vec<u8>, Error> {
284 use codec::Encode;
285
286 match key.0 {
287 ed25519::CRYPTO_ID => {
288 let key_pair: ed25519::Pair = self
289 .ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice()))
290 .ok_or_else(|| Error::PairNotFound("ed25519".to_owned()))?;
291 return Ok(key_pair.sign(msg).encode());
292 }
293 sr25519::CRYPTO_ID => {
294 let key_pair: sr25519::Pair = self
295 .sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice()))
296 .ok_or_else(|| Error::PairNotFound("sr25519".to_owned()))?;
297 return Ok(key_pair.sign(msg).encode());
298 }
299 ecdsa::CRYPTO_ID => {
300 let key_pair: ecdsa::Pair = self
301 .ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice()))
302 .ok_or_else(|| Error::PairNotFound("ecdsa".to_owned()))?;
303 return Ok(key_pair.sign(msg).encode());
304 }
305 _ => Err(Error::KeyNotSupported(id))
306 }
307 }
308
309 fn sr25519_vrf_sign(
310 &self,
311 key_type: KeyTypeId,
312 public: &sr25519::Public,
313 transcript_data: VRFTranscriptData,
314 ) -> Result<VRFSignature, Error> {
315 let transcript = make_transcript(transcript_data);
316 let pair = self.sr25519_key_pair(key_type, public)
317 .ok_or_else(|| Error::PairNotFound("Not found".to_owned()))?;
318 let (inout, proof, _) = pair.as_ref().vrf_sign(transcript);
319 Ok(VRFSignature {
320 output: inout.to_output(),
321 proof,
322 })
323 }
324}
325
326impl Into<SyncCryptoStorePtr> for KeyStore {
327 fn into(self) -> SyncCryptoStorePtr {
328 Arc::new(self)
329 }
330}
331
332impl Into<Arc<dyn CryptoStore>> for KeyStore {
333 fn into(self) -> Arc<dyn CryptoStore> {
334 Arc::new(self)
335 }
336}
337
338#[cfg(test)]
339mod tests {
340 use super::*;
341 use tet_core::{sr25519, testing::{ED25519, SR25519}};
342 use crate::{SyncCryptoStore, vrf::VRFTranscriptValue};
343
344 #[test]
345 fn store_key_and_extract() {
346 let store = KeyStore::new();
347
348 let public = SyncCryptoStore::ed25519_generate_new(&store, ED25519, None)
349 .expect("Generates key");
350
351 let public_keys = SyncCryptoStore::keys(&store, ED25519).unwrap();
352
353 assert!(public_keys.contains(&public.into()));
354 }
355
356 #[test]
357 fn store_unknown_and_extract_it() {
358 let store = KeyStore::new();
359
360 let secret_uri = "//Alice";
361 let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair");
362
363 SyncCryptoStore::insert_unknown(
364 &store,
365 SR25519,
366 secret_uri,
367 key_pair.public().as_ref(),
368 ).expect("Inserts unknown key");
369
370 let public_keys = SyncCryptoStore::keys(&store, SR25519).unwrap();
371
372 assert!(public_keys.contains(&key_pair.public().into()));
373 }
374
375 #[test]
376 fn vrf_sign() {
377 let store = KeyStore::new();
378
379 let secret_uri = "//Alice";
380 let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair");
381
382 let transcript_data = VRFTranscriptData {
383 label: b"Test",
384 items: vec![
385 ("one", VRFTranscriptValue::U64(1)),
386 ("two", VRFTranscriptValue::U64(2)),
387 ("three", VRFTranscriptValue::Bytes("test".as_bytes().to_vec())),
388 ]
389 };
390
391 let result = SyncCryptoStore::sr25519_vrf_sign(
392 &store,
393 SR25519,
394 &key_pair.public(),
395 transcript_data.clone(),
396 );
397 assert!(result.is_err());
398
399 SyncCryptoStore::insert_unknown(
400 &store,
401 SR25519,
402 secret_uri,
403 key_pair.public().as_ref(),
404 ).expect("Inserts unknown key");
405
406 let result = SyncCryptoStore::sr25519_vrf_sign(
407 &store,
408 SR25519,
409 &key_pair.public(),
410 transcript_data,
411 );
412
413 assert!(result.is_ok());
414 }
415}