use codec::Codec;
use scale_info::TypeInfo;
use crate::core::crypto::{
CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Pair, Public, Signature,
};
use ::core::fmt::Debug;
use alloc::vec::Vec;
pub trait AppCrypto: 'static + Sized + CryptoType {
const ID: KeyTypeId;
const CRYPTO_ID: CryptoTypeId;
type Public: AppPublic;
type Signature: AppSignature;
type ProofOfPossession: AppSignature;
type Pair: AppPair;
}
pub trait MaybeHash: ::core::hash::Hash {}
impl<T: ::core::hash::Hash> MaybeHash for T {}
pub trait AppPair:
AppCrypto + Pair<Public = <Self as AppCrypto>::Public, Signature = <Self as AppCrypto>::Signature>
{
type Generic: IsWrappedBy<Self>
+ Pair<Public = <<Self as AppCrypto>::Public as AppPublic>::Generic>
+ Pair<Signature = <<Self as AppCrypto>::Signature as AppSignature>::Generic>;
}
pub trait AppPublic: AppCrypto + Public + Debug + MaybeHash + Codec {
type Generic: IsWrappedBy<Self> + Public + Debug + MaybeHash + Codec;
}
pub trait AppSignature: AppCrypto + Signature + Eq + PartialEq + Debug + Clone {
type Generic: IsWrappedBy<Self> + Signature + Eq + PartialEq + Debug;
}
pub trait RuntimePublic: Sized {
type Signature: Debug + Eq + PartialEq + Clone;
type ProofOfPossession: Debug + Eq + PartialEq + Clone;
fn all(key_type: KeyTypeId) -> super::Vec<Self>;
fn generate_pair(key_type: KeyTypeId, seed: Option<Vec<u8>>) -> Self;
fn sign<M: AsRef<[u8]>>(&self, key_type: KeyTypeId, msg: &M) -> Option<Self::Signature>;
fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool;
fn generate_proof_of_possession(
&mut self,
key_type: KeyTypeId,
owner: &[u8],
) -> Option<Self::ProofOfPossession>;
fn verify_proof_of_possession(&self, owner: &[u8], pop: &Self::ProofOfPossession) -> bool;
fn to_raw_vec(&self) -> Vec<u8>;
}
pub trait RuntimeAppPublic: Sized {
const ID: KeyTypeId;
type Signature: Debug + Eq + PartialEq + Clone + TypeInfo + Codec;
type ProofOfPossession: Debug + Eq + PartialEq + TypeInfo + Clone;
fn all() -> super::Vec<Self>;
fn generate_pair(seed: Option<Vec<u8>>) -> Self;
fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature>;
#[must_use]
fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool;
fn generate_proof_of_possession(&mut self, owner: &[u8]) -> Option<Self::ProofOfPossession>;
fn verify_proof_of_possession(&self, owner: &[u8], pop: &Self::ProofOfPossession) -> bool;
fn to_raw_vec(&self) -> Vec<u8>;
}
impl<T> RuntimeAppPublic for T
where
T: AppPublic + AsRef<<T as AppPublic>::Generic> + AsMut<<T as AppPublic>::Generic>,
<T as AppPublic>::Generic: RuntimePublic,
<T as AppCrypto>::Signature: TypeInfo
+ Codec
+ From<<<T as AppPublic>::Generic as RuntimePublic>::Signature>
+ AsRef<<<T as AppPublic>::Generic as RuntimePublic>::Signature>,
<T as AppCrypto>::ProofOfPossession: TypeInfo
+ Codec
+ From<<<T as AppPublic>::Generic as RuntimePublic>::ProofOfPossession>
+ AsRef<<<T as AppPublic>::Generic as RuntimePublic>::ProofOfPossession>,
{
const ID: KeyTypeId = <T as AppCrypto>::ID;
type Signature = <T as AppCrypto>::Signature;
type ProofOfPossession = <T as AppCrypto>::ProofOfPossession;
fn all() -> super::Vec<Self> {
<<T as AppPublic>::Generic as RuntimePublic>::all(Self::ID)
.into_iter()
.map(|p| p.into())
.collect()
}
fn generate_pair(seed: Option<Vec<u8>>) -> Self {
<<T as AppPublic>::Generic as RuntimePublic>::generate_pair(Self::ID, seed).into()
}
fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature> {
<<T as AppPublic>::Generic as RuntimePublic>::sign(self.as_ref(), Self::ID, msg)
.map(|s| s.into())
}
fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool {
<<T as AppPublic>::Generic as RuntimePublic>::verify(self.as_ref(), msg, signature.as_ref())
}
fn generate_proof_of_possession(&mut self, owner: &[u8]) -> Option<Self::ProofOfPossession> {
<<T as AppPublic>::Generic as RuntimePublic>::generate_proof_of_possession(
self.as_mut(),
Self::ID,
owner,
)
.map(|s| s.into())
}
fn verify_proof_of_possession(&self, owner: &[u8], pop: &Self::ProofOfPossession) -> bool {
<<T as AppPublic>::Generic as RuntimePublic>::verify_proof_of_possession(
self.as_ref(),
owner,
pop.as_ref(),
)
}
fn to_raw_vec(&self) -> Vec<u8> {
<<T as AppPublic>::Generic as RuntimePublic>::to_raw_vec(self.as_ref())
}
}
pub trait BoundToRuntimeAppPublic {
type Public: RuntimeAppPublic;
}
impl<T: RuntimeAppPublic> BoundToRuntimeAppPublic for T {
type Public = Self;
}