#[cfg(feature = "std")]
pub mod testing;
#[cfg(feature = "bandersnatch-experimental")]
use crate::core::bandersnatch;
#[cfg(feature = "bls-experimental")]
use crate::core::{bls381, ecdsa_bls381};
use crate::core::{
crypto::{ByteArray, CryptoTypeId, KeyTypeId},
ecdsa, ed25519, sr25519,
};
use alloc::{string::String, sync::Arc, vec::Vec};
#[derive(Debug)]
pub enum Error {
KeyNotSupported(KeyTypeId),
ValidationError(String),
Unavailable,
Other(String),
}
impl core::fmt::Display for Error {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
Error::KeyNotSupported(key_type) => write!(fmt, "Key not supported: {key_type:?}"),
Error::ValidationError(error) => write!(fmt, "Validation error: {error}"),
Error::Unavailable => fmt.write_str("Keystore unavailable"),
Error::Other(error) => write!(fmt, "An unknown keystore error occurred: {error}"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
pub trait Keystore: Send + Sync {
fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public>;
fn sr25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<sr25519::Public, Error>;
fn sr25519_sign(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
msg: &[u8],
) -> Result<Option<sr25519::Signature>, Error>;
fn sr25519_vrf_sign(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
data: &sr25519::vrf::VrfSignData,
) -> Result<Option<sr25519::vrf::VrfSignature>, Error>;
fn sr25519_vrf_pre_output(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
input: &sr25519::vrf::VrfInput,
) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error>;
fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public>;
fn ed25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ed25519::Public, Error>;
fn ed25519_sign(
&self,
key_type: KeyTypeId,
public: &ed25519::Public,
msg: &[u8],
) -> Result<Option<ed25519::Signature>, Error>;
fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public>;
fn ecdsa_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ecdsa::Public, Error>;
fn ecdsa_sign(
&self,
key_type: KeyTypeId,
public: &ecdsa::Public,
msg: &[u8],
) -> Result<Option<ecdsa::Signature>, Error>;
fn ecdsa_sign_prehashed(
&self,
key_type: KeyTypeId,
public: &ecdsa::Public,
msg: &[u8; 32],
) -> Result<Option<ecdsa::Signature>, Error>;
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public>;
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<bandersnatch::Public, Error>;
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_sign(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
msg: &[u8],
) -> Result<Option<bandersnatch::Signature>, Error>;
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_vrf_sign(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
input: &bandersnatch::vrf::VrfSignData,
) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error>;
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_vrf_pre_output(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
input: &bandersnatch::vrf::VrfInput,
) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error>;
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_ring_vrf_sign(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
input: &bandersnatch::vrf::VrfSignData,
prover: &bandersnatch::ring_vrf::RingProver,
) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error>;
#[cfg(feature = "bls-experimental")]
fn bls381_public_keys(&self, id: KeyTypeId) -> Vec<bls381::Public>;
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa_bls381::Public>;
#[cfg(feature = "bls-experimental")]
fn bls381_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<bls381::Public, Error>;
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ecdsa_bls381::Public, Error>;
#[cfg(feature = "bls-experimental")]
fn bls381_sign(
&self,
key_type: KeyTypeId,
public: &bls381::Public,
msg: &[u8],
) -> Result<Option<bls381::Signature>, Error>;
#[cfg(feature = "bls-experimental")]
fn bls381_generate_proof_of_possession(
&self,
key_type: KeyTypeId,
public: &bls381::Public,
owner: &[u8],
) -> Result<Option<bls381::ProofOfPossession>, Error>;
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_sign(
&self,
key_type: KeyTypeId,
public: &ecdsa_bls381::Public,
msg: &[u8],
) -> Result<Option<ecdsa_bls381::Signature>, Error>;
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_sign_with_keccak256(
&self,
key_type: KeyTypeId,
public: &ecdsa_bls381::Public,
msg: &[u8],
) -> Result<Option<ecdsa_bls381::Signature>, Error>;
fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()>;
fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error>;
fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool;
fn sign_with(
&self,
id: KeyTypeId,
crypto_id: CryptoTypeId,
public: &[u8],
msg: &[u8],
) -> Result<Option<Vec<u8>>, Error> {
use codec::Encode;
let signature = match crypto_id {
sr25519::CRYPTO_ID => {
let public = sr25519::Public::from_slice(public)
.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
self.sr25519_sign(id, &public, msg)?.map(|s| s.encode())
},
ed25519::CRYPTO_ID => {
let public = ed25519::Public::from_slice(public)
.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
self.ed25519_sign(id, &public, msg)?.map(|s| s.encode())
},
ecdsa::CRYPTO_ID => {
let public = ecdsa::Public::from_slice(public)
.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
self.ecdsa_sign(id, &public, msg)?.map(|s| s.encode())
},
#[cfg(feature = "bandersnatch-experimental")]
bandersnatch::CRYPTO_ID => {
let public = bandersnatch::Public::from_slice(public)
.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
self.bandersnatch_sign(id, &public, msg)?.map(|s| s.encode())
},
#[cfg(feature = "bls-experimental")]
bls381::CRYPTO_ID => {
let public = bls381::Public::from_slice(public)
.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
self.bls381_sign(id, &public, msg)?.map(|s| s.encode())
},
#[cfg(feature = "bls-experimental")]
ecdsa_bls381::CRYPTO_ID => {
let public = ecdsa_bls381::Public::from_slice(public)
.map_err(|_| Error::ValidationError("Invalid public key format".into()))?;
self.ecdsa_bls381_sign(id, &public, msg)?.map(|s| s.encode())
},
_ => return Err(Error::KeyNotSupported(id)),
};
Ok(signature)
}
}
impl<T: Keystore + ?Sized> Keystore for Arc<T> {
fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
(**self).sr25519_public_keys(key_type)
}
fn sr25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<sr25519::Public, Error> {
(**self).sr25519_generate_new(key_type, seed)
}
fn sr25519_sign(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
msg: &[u8],
) -> Result<Option<sr25519::Signature>, Error> {
(**self).sr25519_sign(key_type, public, msg)
}
fn sr25519_vrf_sign(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
data: &sr25519::vrf::VrfSignData,
) -> Result<Option<sr25519::vrf::VrfSignature>, Error> {
(**self).sr25519_vrf_sign(key_type, public, data)
}
fn sr25519_vrf_pre_output(
&self,
key_type: KeyTypeId,
public: &sr25519::Public,
input: &sr25519::vrf::VrfInput,
) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error> {
(**self).sr25519_vrf_pre_output(key_type, public, input)
}
fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
(**self).ed25519_public_keys(key_type)
}
fn ed25519_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ed25519::Public, Error> {
(**self).ed25519_generate_new(key_type, seed)
}
fn ed25519_sign(
&self,
key_type: KeyTypeId,
public: &ed25519::Public,
msg: &[u8],
) -> Result<Option<ed25519::Signature>, Error> {
(**self).ed25519_sign(key_type, public, msg)
}
fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
(**self).ecdsa_public_keys(key_type)
}
fn ecdsa_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ecdsa::Public, Error> {
(**self).ecdsa_generate_new(key_type, seed)
}
fn ecdsa_sign(
&self,
key_type: KeyTypeId,
public: &ecdsa::Public,
msg: &[u8],
) -> Result<Option<ecdsa::Signature>, Error> {
(**self).ecdsa_sign(key_type, public, msg)
}
fn ecdsa_sign_prehashed(
&self,
key_type: KeyTypeId,
public: &ecdsa::Public,
msg: &[u8; 32],
) -> Result<Option<ecdsa::Signature>, Error> {
(**self).ecdsa_sign_prehashed(key_type, public, msg)
}
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public> {
(**self).bandersnatch_public_keys(key_type)
}
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<bandersnatch::Public, Error> {
(**self).bandersnatch_generate_new(key_type, seed)
}
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_sign(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
msg: &[u8],
) -> Result<Option<bandersnatch::Signature>, Error> {
(**self).bandersnatch_sign(key_type, public, msg)
}
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_vrf_sign(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
input: &bandersnatch::vrf::VrfSignData,
) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error> {
(**self).bandersnatch_vrf_sign(key_type, public, input)
}
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_vrf_pre_output(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
input: &bandersnatch::vrf::VrfInput,
) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error> {
(**self).bandersnatch_vrf_pre_output(key_type, public, input)
}
#[cfg(feature = "bandersnatch-experimental")]
fn bandersnatch_ring_vrf_sign(
&self,
key_type: KeyTypeId,
public: &bandersnatch::Public,
input: &bandersnatch::vrf::VrfSignData,
prover: &bandersnatch::ring_vrf::RingProver,
) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error> {
(**self).bandersnatch_ring_vrf_sign(key_type, public, input, prover)
}
#[cfg(feature = "bls-experimental")]
fn bls381_public_keys(&self, id: KeyTypeId) -> Vec<bls381::Public> {
(**self).bls381_public_keys(id)
}
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_public_keys(&self, id: KeyTypeId) -> Vec<ecdsa_bls381::Public> {
(**self).ecdsa_bls381_public_keys(id)
}
#[cfg(feature = "bls-experimental")]
fn bls381_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<bls381::Public, Error> {
(**self).bls381_generate_new(key_type, seed)
}
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_generate_new(
&self,
key_type: KeyTypeId,
seed: Option<&str>,
) -> Result<ecdsa_bls381::Public, Error> {
(**self).ecdsa_bls381_generate_new(key_type, seed)
}
#[cfg(feature = "bls-experimental")]
fn bls381_sign(
&self,
key_type: KeyTypeId,
public: &bls381::Public,
msg: &[u8],
) -> Result<Option<bls381::Signature>, Error> {
(**self).bls381_sign(key_type, public, msg)
}
#[cfg(feature = "bls-experimental")]
fn bls381_generate_proof_of_possession(
&self,
key_type: KeyTypeId,
public: &bls381::Public,
owner: &[u8],
) -> Result<Option<bls381::ProofOfPossession>, Error> {
(**self).bls381_generate_proof_of_possession(key_type, public, owner)
}
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_sign(
&self,
key_type: KeyTypeId,
public: &ecdsa_bls381::Public,
msg: &[u8],
) -> Result<Option<ecdsa_bls381::Signature>, Error> {
(**self).ecdsa_bls381_sign(key_type, public, msg)
}
#[cfg(feature = "bls-experimental")]
fn ecdsa_bls381_sign_with_keccak256(
&self,
key_type: KeyTypeId,
public: &ecdsa_bls381::Public,
msg: &[u8],
) -> Result<Option<ecdsa_bls381::Signature>, Error> {
(**self).ecdsa_bls381_sign_with_keccak256(key_type, public, msg)
}
fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
(**self).insert(key_type, suri, public)
}
fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error> {
(**self).keys(key_type)
}
fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
(**self).has_keys(public_keys)
}
fn sign_with(
&self,
id: KeyTypeId,
crypto_id: CryptoTypeId,
public: &[u8],
msg: &[u8],
) -> Result<Option<Vec<u8>>, Error> {
(**self).sign_with(id, crypto_id, public, msg)
}
}
pub type KeystorePtr = Arc<dyn Keystore>;
crate::decl_extension! {
pub struct KeystoreExt(KeystorePtr);
}
impl KeystoreExt {
pub fn from(keystore: KeystorePtr) -> Self {
Self(keystore)
}
pub fn new<T: Keystore + 'static>(keystore: T) -> Self {
Self(Arc::new(keystore))
}
}
crate::generate_feature_enabled_macro!(
bandersnatch_experimental_enabled,
feature = "bandersnatch-experimental",
$
);
crate::generate_feature_enabled_macro!(
bls_experimental_enabled,
feature = "bls-experimental",
$
);