Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Application Crypto cleanup #13746

Merged
merged 9 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions primitives/application-crypto/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ use sp_std::vec::Vec;
pub use sp_core::ecdsa::*;

mod app {
use sp_core::testing::ECDSA;

crate::app_crypto!(super, ECDSA);

impl crate::traits::BoundToRuntimeAppPublic for Public {
type Public = Self;
}
crate::app_crypto!(super, sp_core::testing::ECDSA);
}

#[cfg(feature = "full_crypto")]
Expand Down
8 changes: 1 addition & 7 deletions primitives/application-crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ use sp_std::vec::Vec;
pub use sp_core::ed25519::*;

mod app {
use sp_core::testing::ED25519;

crate::app_crypto!(super, ED25519);

impl crate::traits::BoundToRuntimeAppPublic for Public {
type Public = Self;
}
crate::app_crypto!(super, sp_core::testing::ED25519);
}

#[cfg(feature = "full_crypto")]
Expand Down
100 changes: 34 additions & 66 deletions primitives/application-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ mod traits;

pub use traits::*;

/// Declares Public, Pair, Signature types which are functionally equivalent to `$pair`, but are new
/// Application-specific types whose identifier is `$key_type`.
/// Declares `Public`, `Pair` and `Signature` types which are functionally equivalent
/// to the corresponding types defined by `$module` but are new application-specific
/// types whose identifier is `$key_type`.
///
/// ```rust
/// # use sp_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId};
/// // Declare a new set of crypto types using Ed25519 logic that identifies as `KeyTypeId`
/// # use sp_application_crypto::{app_crypto, ed25519, KeyTypeId};
/// // Declare a new set of crypto types using ed25519 logic that identifies as `KeyTypeId`
/// // of value `b"fuba"`.
/// app_crypto!(ed25519, KeyTypeId(*b"_uba"));
/// app_crypto!(ed25519, KeyTypeId(*b"fuba"));
/// ```
#[cfg(feature = "full_crypto")]
#[macro_export]
Expand All @@ -78,14 +79,15 @@ macro_rules! app_crypto {
};
}

/// Declares Public, Pair, Signature types which are functionally equivalent to `$pair`, but are new
/// Application-specific types whose identifier is `$key_type`.
/// Declares `Public`, `Pair` and `Signature` types which are functionally equivalent
/// to the corresponding types defined by `$module` but that are new application-specific
/// types whose identifier is `$key_type`.
///
/// ```rust
/// # use sp_application_crypto::{app_crypto, wrap, ed25519, KeyTypeId};
/// // Declare a new set of crypto types using Ed25519 logic that identifies as `KeyTypeId`
/// # use sp_application_crypto::{app_crypto, ed25519, KeyTypeId};
/// // Declare a new set of crypto types using ed25519 logic that identifies as `KeyTypeId`
/// // of value `b"fuba"`.
/// app_crypto!(ed25519, KeyTypeId(*b"_uba"));
/// app_crypto!(ed25519, KeyTypeId(*b"fuba"));
/// ```
#[cfg(not(feature = "full_crypto"))]
#[macro_export]
Expand All @@ -107,8 +109,8 @@ macro_rules! app_crypto {
};
}

/// Declares Pair type which is functionally equivalent to `$pair`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// Declares `Pair` type which is functionally equivalent to `$pair`, but is
/// new application-specific type whose identifier is `$key_type`.
#[macro_export]
macro_rules! app_crypto_pair {
($pair:ty, $key_type:expr, $crypto_type:expr) => {
Expand Down Expand Up @@ -208,10 +210,10 @@ macro_rules! app_crypto_pair_functions_if_std {
($pair:ty) => {};
}

/// Declares Public type which is functionally equivalent to `$public`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// can only be used together with `full_crypto` feature
/// For full functionality, app_crypto_public_common! must be called too.
/// Declares `Public` type which is functionally equivalent to `$public` but is
/// new application-specific type whose identifier is `$key_type`.
/// For full functionality, `app_crypto_public_common!` must be called too.
/// Can only be used with `full_crypto` feature.
#[doc(hidden)]
#[macro_export]
macro_rules! app_crypto_public_full_crypto {
Expand Down Expand Up @@ -244,10 +246,10 @@ macro_rules! app_crypto_public_full_crypto {
};
}

/// Declares Public type which is functionally equivalent to `$public`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// can only be used without `full_crypto` feature
/// For full functionality, app_crypto_public_common! must be called too.
/// Declares `Public` type which is functionally equivalent to `$public` but is
/// new application-specific type whose identifier is `$key_type`.
/// For full functionality, `app_crypto_public_common!` must be called too.
/// Can only be used without `full_crypto` feature.
#[doc(hidden)]
#[macro_export]
macro_rules! app_crypto_public_not_full_crypto {
Expand Down Expand Up @@ -276,9 +278,9 @@ macro_rules! app_crypto_public_not_full_crypto {
};
}

/// Declares Public type which is functionally equivalent to `$public`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// For full functionality, app_crypto_public_(not)_full_crypto! must be called too.
/// Declares `Public` type which is functionally equivalent to `$public` but is
/// new application-specific type whose identifier is `$key_type`.
/// For full functionality, `app_crypto_public_(not)_full_crypto!` must be called too.
#[doc(hidden)]
#[macro_export]
macro_rules! app_crypto_public_common {
Expand Down Expand Up @@ -307,40 +309,6 @@ macro_rules! app_crypto_public_common {
type Generic = $public;
}

impl $crate::RuntimeAppPublic for Public
where
$public: $crate::RuntimePublic<Signature = $sig>,
{
const ID: $crate::KeyTypeId = $key_type;
const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type;

type Signature = Signature;

fn all() -> $crate::Vec<Self> {
<$public as $crate::RuntimePublic>::all($key_type)
.into_iter()
.map(Self)
.collect()
}

fn generate_pair(seed: Option<$crate::Vec<u8>>) -> Self {
Self(<$public as $crate::RuntimePublic>::generate_pair($key_type, seed))
}

fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature> {
<$public as $crate::RuntimePublic>::sign(self.as_ref(), $key_type, msg)
.map(Signature)
}

fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool {
<$public as $crate::RuntimePublic>::verify(self.as_ref(), msg, &signature.as_ref())
}

fn to_raw_vec(&self) -> $crate::Vec<u8> {
<$public as $crate::RuntimePublic>::to_raw_vec(&self.0)
}
}

impl<'a> TryFrom<&'a [u8]> for Public {
type Error = ();

Expand Down Expand Up @@ -407,8 +375,8 @@ macro_rules! app_crypto_public_common_if_std {

/// Declares Signature type which is functionally equivalent to `$sig`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// can only be used together with `full_crypto` feature
/// For full functionality, app_crypto_public_common! must be called too.
/// Can only be used with `full_crypto` feature
#[doc(hidden)]
#[macro_export]
macro_rules! app_crypto_signature_full_crypto {
Expand Down Expand Up @@ -439,10 +407,10 @@ macro_rules! app_crypto_signature_full_crypto {
};
}

/// Declares Signature type which is functionally equivalent to `$sig`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// can only be used without `full_crypto` feature
/// For full functionality, app_crypto_public_common! must be called too.
/// Declares `Signature` type which is functionally equivalent to `$sig`, but is new
/// application-specific type whose identifier is `$key_type`.
/// For full functionality, `app_crypto_signature_common` must be called too.
/// Can only be used without `full_crypto` feature.
#[doc(hidden)]
#[macro_export]
macro_rules! app_crypto_signature_not_full_crypto {
Expand All @@ -452,8 +420,8 @@ macro_rules! app_crypto_signature_not_full_crypto {
#[derive(Clone, Eq, PartialEq,
$crate::codec::Encode,
$crate::codec::Decode,
$crate::scale_info::TypeInfo,
$crate::RuntimeDebug,
$crate::scale_info::TypeInfo,
)]
pub struct Signature($sig);
}
Expand All @@ -469,9 +437,9 @@ macro_rules! app_crypto_signature_not_full_crypto {
};
}

/// Declares Signature type which is functionally equivalent to `$sig`, but is new
/// Application-specific type whose identifier is `$key_type`.
/// For full functionality, app_crypto_public_(not)_full_crypto! must be called too.
/// Declares `Signature` type which is functionally equivalent to `$sig`, but is new
/// application-specific type whose identifier is `$key_type`.
/// For full functionality, app_crypto_signature_(not)_full_crypto! must be called too.
#[doc(hidden)]
#[macro_export]
macro_rules! app_crypto_signature_common {
Expand Down
8 changes: 1 addition & 7 deletions primitives/application-crypto/src/sr25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ use sp_std::vec::Vec;
pub use sp_core::sr25519::*;

mod app {
use sp_core::testing::SR25519;

crate::app_crypto!(super, SR25519);

impl crate::traits::BoundToRuntimeAppPublic for Public {
type Public = Self;
}
crate::app_crypto!(super, sp_core::testing::SR25519);
}

#[cfg(feature = "full_crypto")]
Expand Down
69 changes: 52 additions & 17 deletions primitives/application-crypto/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use codec::Codec;
use scale_info::TypeInfo;

#[cfg(feature = "full_crypto")]
use sp_core::crypto::Pair;

use codec::Codec;
use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Public};
use sp_std::{fmt::Debug, vec::Vec};

Expand Down Expand Up @@ -60,15 +61,9 @@ pub trait MaybeHash {}
#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))]
impl<T> MaybeHash for T {}

/// Type which implements Debug and Hash in std, not when no-std (no-std variant with crypto).
#[cfg(all(not(feature = "std"), feature = "full_crypto"))]
pub trait MaybeDebugHash: sp_std::hash::Hash {}
#[cfg(all(not(feature = "std"), feature = "full_crypto"))]
impl<T: sp_std::hash::Hash> MaybeDebugHash for T {}

/// A application's public key.
pub trait AppPublic:
AppCrypto + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec
AppCrypto + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + Codec
{
/// The wrapped type which is just a plain instance of `Public`.
type Generic: IsWrappedBy<Self>
Expand All @@ -79,7 +74,7 @@ pub trait AppPublic:
+ PartialEq
+ Debug
+ MaybeHash
+ codec::Codec;
+ Codec;
}

/// A application's key pair.
Expand All @@ -92,15 +87,15 @@ pub trait AppPair: AppCrypto + Pair<Public = <Self as AppCrypto>::Public> {
}

/// A application's signature.
pub trait AppSignature: AppCrypto + Eq + PartialEq + Debug + MaybeHash {
pub trait AppSignature: AppCrypto + Eq + PartialEq + Debug {
/// The wrapped type which is just a plain instance of `Signature`.
type Generic: IsWrappedBy<Self> + Eq + PartialEq + Debug + MaybeHash;
type Generic: IsWrappedBy<Self> + Eq + PartialEq + Debug;
}

/// A 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: Codec + Debug + MaybeHash + Eq + PartialEq + Clone;
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<Self>;
Expand Down Expand Up @@ -132,11 +127,9 @@ pub trait RuntimePublic: Sized {
pub trait RuntimeAppPublic: Sized {
/// An identifier for this application-specific key type.
const ID: KeyTypeId;
/// The identifier of the crypto type of this application-specific key type.
const CRYPTO_ID: CryptoTypeId;

/// The signature that will be generated when signing with the corresponding private key.
type Signature: Codec + Debug + MaybeHash + Eq + PartialEq + Clone + scale_info::TypeInfo;
type Signature: Debug + Eq + PartialEq + Clone + TypeInfo + Codec;

/// Returns all public keys for this application in the keystore.
fn all() -> crate::Vec<Self>;
Expand All @@ -163,8 +156,50 @@ pub trait RuntimeAppPublic: Sized {
fn to_raw_vec(&self) -> Vec<u8>;
}

/// Something that bound to a fixed [`RuntimeAppPublic`].
impl<T> RuntimeAppPublic for T
where
T: AppPublic + AsRef<<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>,
{
const ID: KeyTypeId = <T as AppCrypto>::ID;

type Signature = <T as AppCrypto>::Signature;

fn all() -> crate::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 to_raw_vec(&self) -> Vec<u8> {
<<T as AppPublic>::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<T: RuntimeAppPublic> BoundToRuntimeAppPublic for T {
type Public = Self;
}
2 changes: 1 addition & 1 deletion primitives/core/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ pub trait ByteArray: AsRef<[u8]> + AsMut<[u8]> + for<'a> TryFrom<&'a [u8], Error
}
}

/// Trait suitable for typical cryptographic PKI key public type.
/// Trait suitable for typical cryptographic key public type.
pub trait Public: ByteArray + Derive + CryptoType + PartialEq + Eq + Clone + Send + Sync {}

/// An opaque 32-byte cryptographic identifier.
Expand Down
7 changes: 1 addition & 6 deletions primitives/runtime/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
PostDispatchInfoOf, SignedExtension, ValidateUnsigned,
},
transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
ApplyExtrinsicResultWithInfo, CryptoTypeId, KeyTypeId,
ApplyExtrinsicResultWithInfo, KeyTypeId,
};
use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
use sp_core::{
Expand Down Expand Up @@ -115,7 +115,6 @@ impl UintAuthorityId {

impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId {
const ID: KeyTypeId = key_types::DUMMY;
const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"dumm");

type Signature = TestSignature;

Expand Down Expand Up @@ -157,10 +156,6 @@ impl OpaqueKeys for UintAuthorityId {
}
}

impl crate::BoundToRuntimeAppPublic for UintAuthorityId {
type Public = Self;
}

impl traits::IdentifyAccount for UintAuthorityId {
type AccountId = u64;

Expand Down