// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use codec::Codec; use scale_info::TypeInfo; use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Pair, Public}; use sp_std::{fmt::Debug, vec::Vec}; /// Application-specific cryptographic object. /// /// Combines all the core types and constants that are defined by a particular /// cryptographic scheme when it is used in a specific application domain. /// /// Typically, the implementers of this trait are its associated types themselves. /// This provides a convenient way to access generic information about the scheme /// given any of the associated types. pub trait AppCrypto: 'static + Sized + CryptoType { /// Identifier for application-specific key type. const ID: KeyTypeId; /// Identifier of the crypto type of this application-specific key type. const CRYPTO_ID: CryptoTypeId; /// The corresponding public key type in this application scheme. type Public: AppPublic; /// The corresponding signature type in this application scheme. type Signature: AppSignature; /// The corresponding key pair type in this application scheme. type Pair: AppPair; } /// Type which implements Hash in std, not when no-std (std variant). pub trait MaybeHash: sp_std::hash::Hash {} impl MaybeHash for T {} /// Application-specific key pair. pub trait AppPair: AppCrypto + Pair::Public, Signature = ::Signature> { /// The wrapped type which is just a plain instance of `Pair`. type Generic: IsWrappedBy + Pair::Public as AppPublic>::Generic> + Pair::Signature as AppSignature>::Generic>; } /// Application-specific public key. pub trait AppPublic: AppCrypto + Public + Debug + MaybeHash + Codec { /// The wrapped type which is just a plain instance of `Public`. type Generic: IsWrappedBy + Public + Debug + MaybeHash + Codec; } /// Application-specific signature. pub trait AppSignature: AppCrypto + Eq + PartialEq + Debug + Clone { /// The wrapped type which is just a plain instance of `Signature`. type Generic: IsWrappedBy + Eq + PartialEq + Debug; } /// Runtime interface for a public key. pub trait RuntimePublic: Sized { /// The signature that will be generated when signing with the corresponding private key. type Signature: Debug + Eq + PartialEq + Clone; /// Returns all public keys for the given key type in the keystore. fn all(key_type: KeyTypeId) -> crate::Vec; /// Generate a public/private pair for the given key type with an optional `seed` and /// store it in the keystore. /// /// The `seed` needs to be valid utf8. /// /// Returns the generated public key. fn generate_pair(key_type: KeyTypeId, seed: Option>) -> Self; /// Sign the given message with the corresponding private key of this public key. /// /// The private key will be requested from the keystore using the given key type. /// /// Returns the signature or `None` if the private key could not be found or some other error /// occurred. fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option; /// Verify that the given signature matches the given message using this public key. fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool; /// Returns `Self` as raw vec. fn to_raw_vec(&self) -> Vec; } /// Runtime interface for an application's public key. pub trait RuntimeAppPublic: Sized { /// An identifier for this application-specific key type. const ID: KeyTypeId; /// The signature that will be generated when signing with the corresponding private key. type Signature: Debug + Eq + PartialEq + Clone + TypeInfo + Codec; /// Returns all public keys for this application in the keystore. fn all() -> crate::Vec; /// Generate a public/private pair with an optional `seed` and store it in the keystore. /// /// The `seed` needs to be valid utf8. /// /// Returns the generated public key. fn generate_pair(seed: Option>) -> Self; /// Sign the given message with the corresponding private key of this public key. /// /// The private key will be requested from the keystore. /// /// Returns the signature or `None` if the private key could not be found or some other error /// occurred. fn sign>(&self, msg: &M) -> Option; /// Verify that the given signature matches the given message using this public key. fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool; /// Returns `Self` as raw vec. fn to_raw_vec(&self) -> Vec; } impl RuntimeAppPublic for T where T: AppPublic + AsRef<::Generic>, ::Generic: RuntimePublic, ::Signature: TypeInfo + Codec + From<<::Generic as RuntimePublic>::Signature> + AsRef<<::Generic as RuntimePublic>::Signature>, { const ID: KeyTypeId = ::ID; type Signature = ::Signature; fn all() -> crate::Vec { <::Generic as RuntimePublic>::all(Self::ID) .into_iter() .map(|p| p.into()) .collect() } fn generate_pair(seed: Option>) -> Self { <::Generic as RuntimePublic>::generate_pair(Self::ID, seed).into() } fn sign>(&self, msg: &M) -> Option { <::Generic as RuntimePublic>::sign(self.as_ref(), Self::ID, msg) .map(|s| s.into()) } fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { <::Generic as RuntimePublic>::verify(self.as_ref(), msg, signature.as_ref()) } fn to_raw_vec(&self) -> Vec { <::Generic as RuntimePublic>::to_raw_vec(self.as_ref()) } } /// Something that is bound to a fixed [`RuntimeAppPublic`]. pub trait BoundToRuntimeAppPublic { /// The [`RuntimeAppPublic`] this type is bound to. type Public: RuntimeAppPublic; } impl BoundToRuntimeAppPublic for T { type Public = Self; }