1#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24#[cfg(feature = "std")]
25pub mod testing;
26
27#[cfg(feature = "bandersnatch-experimental")]
28use sp_core::bandersnatch;
29#[cfg(feature = "bls-experimental")]
30use sp_core::{bls381, ecdsa_bls381};
31use sp_core::{
32 crypto::{ByteArray, CryptoTypeId, KeyTypeId},
33 ecdsa, ed25519, sr25519,
34};
35
36use alloc::{string::String, sync::Arc, vec::Vec};
37
38#[derive(Debug)]
40pub enum Error {
41 KeyNotSupported(KeyTypeId),
43 ValidationError(String),
45 Unavailable,
47 Other(String),
49}
50
51impl core::fmt::Display for Error {
52 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
53 match self {
54 Error::KeyNotSupported(key_type) => write!(fmt, "Key not supported: {key_type:?}"),
55 Error::ValidationError(error) => write!(fmt, "Validation error: {error}"),
56 Error::Unavailable => fmt.write_str("Keystore unavailable"),
57 Error::Other(error) => write!(fmt, "An unknown keystore error occurred: {error}"),
58 }
59 }
60}
61
62#[cfg(feature = "std")]
63impl std::error::Error for Error {}
64
65pub trait Keystore: Send + Sync {
67 fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public>;
69
70 fn sr25519_generate_new(
75 &self,
76 key_type: KeyTypeId,
77 seed: Option<&str>,
78 ) -> Result<sr25519::Public, Error>;
79
80 fn sr25519_sign(
89 &self,
90 key_type: KeyTypeId,
91 public: &sr25519::Public,
92 msg: &[u8],
93 ) -> Result<Option<sr25519::Signature>, Error>;
94
95 fn sr25519_vrf_sign(
103 &self,
104 key_type: KeyTypeId,
105 public: &sr25519::Public,
106 data: &sr25519::vrf::VrfSignData,
107 ) -> Result<Option<sr25519::vrf::VrfSignature>, Error>;
108
109 fn sr25519_vrf_pre_output(
117 &self,
118 key_type: KeyTypeId,
119 public: &sr25519::Public,
120 input: &sr25519::vrf::VrfInput,
121 ) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error>;
122
123 fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public>;
125
126 fn ed25519_generate_new(
131 &self,
132 key_type: KeyTypeId,
133 seed: Option<&str>,
134 ) -> Result<ed25519::Public, Error>;
135
136 fn ed25519_sign(
145 &self,
146 key_type: KeyTypeId,
147 public: &ed25519::Public,
148 msg: &[u8],
149 ) -> Result<Option<ed25519::Signature>, Error>;
150
151 fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public>;
153
154 fn ecdsa_generate_new(
159 &self,
160 key_type: KeyTypeId,
161 seed: Option<&str>,
162 ) -> Result<ecdsa::Public, Error>;
163
164 fn ecdsa_sign(
173 &self,
174 key_type: KeyTypeId,
175 public: &ecdsa::Public,
176 msg: &[u8],
177 ) -> Result<Option<ecdsa::Signature>, Error>;
178
179 fn ecdsa_sign_prehashed(
188 &self,
189 key_type: KeyTypeId,
190 public: &ecdsa::Public,
191 msg: &[u8; 32],
192 ) -> Result<Option<ecdsa::Signature>, Error>;
193
194 #[cfg(feature = "bandersnatch-experimental")]
196 fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public>;
197
198 #[cfg(feature = "bandersnatch-experimental")]
203 fn bandersnatch_generate_new(
204 &self,
205 key_type: KeyTypeId,
206 seed: Option<&str>,
207 ) -> Result<bandersnatch::Public, Error>;
208
209 #[cfg(feature = "bandersnatch-experimental")]
218 fn bandersnatch_sign(
219 &self,
220 key_type: KeyTypeId,
221 public: &bandersnatch::Public,
222 msg: &[u8],
223 ) -> Result<Option<bandersnatch::Signature>, Error>;
224
225 #[cfg(feature = "bandersnatch-experimental")]
233 fn bandersnatch_vrf_sign(
234 &self,
235 key_type: KeyTypeId,
236 public: &bandersnatch::Public,
237 input: &bandersnatch::vrf::VrfSignData,
238 ) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error>;
239
240 #[cfg(feature = "bandersnatch-experimental")]
248 fn bandersnatch_vrf_pre_output(
249 &self,
250 key_type: KeyTypeId,
251 public: &bandersnatch::Public,
252 input: &bandersnatch::vrf::VrfInput,
253 ) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error>;
254
255 #[cfg(feature = "bandersnatch-experimental")]
271 fn bandersnatch_ring_vrf_sign(
272 &self,
273 key_type: KeyTypeId,
274 public: &bandersnatch::Public,
275 input: &bandersnatch::vrf::VrfSignData,
276 prover: &bandersnatch::ring_vrf::RingProver,
277 ) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error>;
278
279 #[cfg(feature = "bls-experimental")]
281 fn bls381_public_keys(&self, id: KeyTypeId) -> Vec<bls381::Public>;
282
283 #[cfg(feature = "bls-experimental")]
285 fn ecdsa_bls381_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa_bls381::Public>;
286
287 #[cfg(feature = "bls-experimental")]
292 fn bls381_generate_new(
293 &self,
294 key_type: KeyTypeId,
295 seed: Option<&str>,
296 ) -> Result<bls381::Public, Error>;
297
298 #[cfg(feature = "bls-experimental")]
303 fn ecdsa_bls381_generate_new(
304 &self,
305 key_type: KeyTypeId,
306 seed: Option<&str>,
307 ) -> Result<ecdsa_bls381::Public, Error>;
308
309 #[cfg(feature = "bls-experimental")]
318 fn bls381_sign(
319 &self,
320 key_type: KeyTypeId,
321 public: &bls381::Public,
322 msg: &[u8],
323 ) -> Result<Option<bls381::Signature>, Error>;
324
325 #[cfg(feature = "bls-experimental")]
334 fn ecdsa_bls381_sign(
335 &self,
336 key_type: KeyTypeId,
337 public: &ecdsa_bls381::Public,
338 msg: &[u8],
339 ) -> Result<Option<ecdsa_bls381::Signature>, Error>;
340
341 #[cfg(feature = "bls-experimental")]
352 fn ecdsa_bls381_sign_with_keccak256(
353 &self,
354 key_type: KeyTypeId,
355 public: &ecdsa_bls381::Public,
356 msg: &[u8],
357 ) -> Result<Option<ecdsa_bls381::Signature>, Error>;
358
359 fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()>;
361
362 fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error>;
366
367 fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool;
371
372 fn sign_with(
390 &self,
391 id: KeyTypeId,
392 crypto_id: CryptoTypeId,
393 public: &[u8],
394 msg: &[u8],
395 ) -> Result<Option<Vec<u8>>, Error> {
396 use codec::Encode;
397
398 let signature = match crypto_id {
399 sr25519::CRYPTO_ID => {
400 let public = sr25519::Public::from_slice(public)
401 .map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
402 self.sr25519_sign(id, &public, msg)?.map(|s| s.encode())
403 },
404 ed25519::CRYPTO_ID => {
405 let public = ed25519::Public::from_slice(public)
406 .map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
407 self.ed25519_sign(id, &public, msg)?.map(|s| s.encode())
408 },
409 ecdsa::CRYPTO_ID => {
410 let public = ecdsa::Public::from_slice(public)
411 .map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
412
413 self.ecdsa_sign(id, &public, msg)?.map(|s| s.encode())
414 },
415 #[cfg(feature = "bandersnatch-experimental")]
416 bandersnatch::CRYPTO_ID => {
417 let public = bandersnatch::Public::from_slice(public)
418 .map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
419 self.bandersnatch_sign(id, &public, msg)?.map(|s| s.encode())
420 },
421 #[cfg(feature = "bls-experimental")]
422 bls381::CRYPTO_ID => {
423 let public = bls381::Public::from_slice(public)
424 .map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
425 self.bls381_sign(id, &public, msg)?.map(|s| s.encode())
426 },
427 #[cfg(feature = "bls-experimental")]
428 ecdsa_bls381::CRYPTO_ID => {
429 let public = ecdsa_bls381::Public::from_slice(public)
430 .map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
431 self.ecdsa_bls381_sign(id, &public, msg)?.map(|s| s.encode())
432 },
433 _ => return Err(Error::KeyNotSupported(id)),
434 };
435 Ok(signature)
436 }
437}
438
439impl<T: Keystore + ?Sized> Keystore for Arc<T> {
440 fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
441 (**self).sr25519_public_keys(key_type)
442 }
443
444 fn sr25519_generate_new(
445 &self,
446 key_type: KeyTypeId,
447 seed: Option<&str>,
448 ) -> Result<sr25519::Public, Error> {
449 (**self).sr25519_generate_new(key_type, seed)
450 }
451
452 fn sr25519_sign(
453 &self,
454 key_type: KeyTypeId,
455 public: &sr25519::Public,
456 msg: &[u8],
457 ) -> Result<Option<sr25519::Signature>, Error> {
458 (**self).sr25519_sign(key_type, public, msg)
459 }
460
461 fn sr25519_vrf_sign(
462 &self,
463 key_type: KeyTypeId,
464 public: &sr25519::Public,
465 data: &sr25519::vrf::VrfSignData,
466 ) -> Result<Option<sr25519::vrf::VrfSignature>, Error> {
467 (**self).sr25519_vrf_sign(key_type, public, data)
468 }
469
470 fn sr25519_vrf_pre_output(
471 &self,
472 key_type: KeyTypeId,
473 public: &sr25519::Public,
474 input: &sr25519::vrf::VrfInput,
475 ) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error> {
476 (**self).sr25519_vrf_pre_output(key_type, public, input)
477 }
478
479 fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
480 (**self).ed25519_public_keys(key_type)
481 }
482
483 fn ed25519_generate_new(
484 &self,
485 key_type: KeyTypeId,
486 seed: Option<&str>,
487 ) -> Result<ed25519::Public, Error> {
488 (**self).ed25519_generate_new(key_type, seed)
489 }
490
491 fn ed25519_sign(
492 &self,
493 key_type: KeyTypeId,
494 public: &ed25519::Public,
495 msg: &[u8],
496 ) -> Result<Option<ed25519::Signature>, Error> {
497 (**self).ed25519_sign(key_type, public, msg)
498 }
499
500 fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
501 (**self).ecdsa_public_keys(key_type)
502 }
503
504 fn ecdsa_generate_new(
505 &self,
506 key_type: KeyTypeId,
507 seed: Option<&str>,
508 ) -> Result<ecdsa::Public, Error> {
509 (**self).ecdsa_generate_new(key_type, seed)
510 }
511
512 fn ecdsa_sign(
513 &self,
514 key_type: KeyTypeId,
515 public: &ecdsa::Public,
516 msg: &[u8],
517 ) -> Result<Option<ecdsa::Signature>, Error> {
518 (**self).ecdsa_sign(key_type, public, msg)
519 }
520
521 fn ecdsa_sign_prehashed(
522 &self,
523 key_type: KeyTypeId,
524 public: &ecdsa::Public,
525 msg: &[u8; 32],
526 ) -> Result<Option<ecdsa::Signature>, Error> {
527 (**self).ecdsa_sign_prehashed(key_type, public, msg)
528 }
529
530 #[cfg(feature = "bandersnatch-experimental")]
531 fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public> {
532 (**self).bandersnatch_public_keys(key_type)
533 }
534
535 #[cfg(feature = "bandersnatch-experimental")]
536 fn bandersnatch_generate_new(
537 &self,
538 key_type: KeyTypeId,
539 seed: Option<&str>,
540 ) -> Result<bandersnatch::Public, Error> {
541 (**self).bandersnatch_generate_new(key_type, seed)
542 }
543
544 #[cfg(feature = "bandersnatch-experimental")]
545 fn bandersnatch_sign(
546 &self,
547 key_type: KeyTypeId,
548 public: &bandersnatch::Public,
549 msg: &[u8],
550 ) -> Result<Option<bandersnatch::Signature>, Error> {
551 (**self).bandersnatch_sign(key_type, public, msg)
552 }
553
554 #[cfg(feature = "bandersnatch-experimental")]
555 fn bandersnatch_vrf_sign(
556 &self,
557 key_type: KeyTypeId,
558 public: &bandersnatch::Public,
559 input: &bandersnatch::vrf::VrfSignData,
560 ) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error> {
561 (**self).bandersnatch_vrf_sign(key_type, public, input)
562 }
563
564 #[cfg(feature = "bandersnatch-experimental")]
565 fn bandersnatch_vrf_pre_output(
566 &self,
567 key_type: KeyTypeId,
568 public: &bandersnatch::Public,
569 input: &bandersnatch::vrf::VrfInput,
570 ) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error> {
571 (**self).bandersnatch_vrf_pre_output(key_type, public, input)
572 }
573
574 #[cfg(feature = "bandersnatch-experimental")]
575 fn bandersnatch_ring_vrf_sign(
576 &self,
577 key_type: KeyTypeId,
578 public: &bandersnatch::Public,
579 input: &bandersnatch::vrf::VrfSignData,
580 prover: &bandersnatch::ring_vrf::RingProver,
581 ) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error> {
582 (**self).bandersnatch_ring_vrf_sign(key_type, public, input, prover)
583 }
584
585 #[cfg(feature = "bls-experimental")]
586 fn bls381_public_keys(&self, id: KeyTypeId) -> Vec<bls381::Public> {
587 (**self).bls381_public_keys(id)
588 }
589
590 #[cfg(feature = "bls-experimental")]
591 fn ecdsa_bls381_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa_bls381::Public> {
592 (**self).ecdsa_bls381_public_keys(id)
593 }
594
595 #[cfg(feature = "bls-experimental")]
596 fn bls381_generate_new(
597 &self,
598 key_type: KeyTypeId,
599 seed: Option<&str>,
600 ) -> Result<bls381::Public, Error> {
601 (**self).bls381_generate_new(key_type, seed)
602 }
603
604 #[cfg(feature = "bls-experimental")]
605 fn ecdsa_bls381_generate_new(
606 &self,
607 key_type: KeyTypeId,
608 seed: Option<&str>,
609 ) -> Result<ecdsa_bls381::Public, Error> {
610 (**self).ecdsa_bls381_generate_new(key_type, seed)
611 }
612
613 #[cfg(feature = "bls-experimental")]
614 fn bls381_sign(
615 &self,
616 key_type: KeyTypeId,
617 public: &bls381::Public,
618 msg: &[u8],
619 ) -> Result<Option<bls381::Signature>, Error> {
620 (**self).bls381_sign(key_type, public, msg)
621 }
622
623 #[cfg(feature = "bls-experimental")]
624 fn ecdsa_bls381_sign(
625 &self,
626 key_type: KeyTypeId,
627 public: &ecdsa_bls381::Public,
628 msg: &[u8],
629 ) -> Result<Option<ecdsa_bls381::Signature>, Error> {
630 (**self).ecdsa_bls381_sign(key_type, public, msg)
631 }
632
633 #[cfg(feature = "bls-experimental")]
634 fn ecdsa_bls381_sign_with_keccak256(
635 &self,
636 key_type: KeyTypeId,
637 public: &ecdsa_bls381::Public,
638 msg: &[u8],
639 ) -> Result<Option<ecdsa_bls381::Signature>, Error> {
640 (**self).ecdsa_bls381_sign_with_keccak256(key_type, public, msg)
641 }
642
643 fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
644 (**self).insert(key_type, suri, public)
645 }
646
647 fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error> {
648 (**self).keys(key_type)
649 }
650
651 fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
652 (**self).has_keys(public_keys)
653 }
654}
655
656pub type KeystorePtr = Arc<dyn Keystore>;
658
659sp_externalities::decl_extension! {
660 pub struct KeystoreExt(KeystorePtr);
662}
663
664impl KeystoreExt {
665 pub fn from(keystore: KeystorePtr) -> Self {
669 Self(keystore)
670 }
671
672 pub fn new<T: Keystore + 'static>(keystore: T) -> Self {
674 Self(Arc::new(keystore))
675 }
676}
677
678sp_core::generate_feature_enabled_macro!(
679 bandersnatch_experimental_enabled,
680 feature = "bandersnatch-experimental",
681 $
682);
683
684sp_core::generate_feature_enabled_macro!(
685 bls_experimental_enabled,
686 feature = "bls-experimental",
687 $
688);