1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

            
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// 	http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

            
18
use codec::Codec;
19
use scale_info::TypeInfo;
20

            
21
use alloc::vec::Vec;
22
use core::fmt::Debug;
23
use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Pair, Public};
24

            
25
/// Application-specific cryptographic object.
26
///
27
/// Combines all the core types and constants that are defined by a particular
28
/// cryptographic scheme when it is used in a specific application domain.
29
///
30
/// Typically, the implementers of this trait are its associated types themselves.
31
/// This provides a convenient way to access generic information about the scheme
32
/// given any of the associated types.
33
pub trait AppCrypto: 'static + Sized + CryptoType {
34
	/// Identifier for application-specific key type.
35
	const ID: KeyTypeId;
36

            
37
	/// Identifier of the crypto type of this application-specific key type.
38
	const CRYPTO_ID: CryptoTypeId;
39

            
40
	/// The corresponding public key type in this application scheme.
41
	type Public: AppPublic;
42

            
43
	/// The corresponding signature type in this application scheme.
44
	type Signature: AppSignature;
45

            
46
	/// The corresponding key pair type in this application scheme.
47
	type Pair: AppPair;
48
}
49

            
50
/// Type which implements Hash in std, not when no-std (std variant).
51
pub trait MaybeHash: core::hash::Hash {}
52
impl<T: core::hash::Hash> MaybeHash for T {}
53

            
54
/// Application-specific key pair.
55
pub trait AppPair:
56
	AppCrypto + Pair<Public = <Self as AppCrypto>::Public, Signature = <Self as AppCrypto>::Signature>
57
{
58
	/// The wrapped type which is just a plain instance of `Pair`.
59
	type Generic: IsWrappedBy<Self>
60
		+ Pair<Public = <<Self as AppCrypto>::Public as AppPublic>::Generic>
61
		+ Pair<Signature = <<Self as AppCrypto>::Signature as AppSignature>::Generic>;
62
}
63

            
64
/// Application-specific public key.
65
pub trait AppPublic: AppCrypto + Public + Debug + MaybeHash + Codec {
66
	/// The wrapped type which is just a plain instance of `Public`.
67
	type Generic: IsWrappedBy<Self> + Public + Debug + MaybeHash + Codec;
68
}
69

            
70
/// Application-specific signature.
71
pub trait AppSignature: AppCrypto + Eq + PartialEq + Debug + Clone {
72
	/// The wrapped type which is just a plain instance of `Signature`.
73
	type Generic: IsWrappedBy<Self> + Eq + PartialEq + Debug;
74
}
75

            
76
/// Runtime interface for a public key.
77
pub trait RuntimePublic: Sized {
78
	/// The signature that will be generated when signing with the corresponding private key.
79
	type Signature: Debug + Eq + PartialEq + Clone;
80

            
81
	/// Returns all public keys for the given key type in the keystore.
82
	fn all(key_type: KeyTypeId) -> crate::Vec<Self>;
83

            
84
	/// Generate a public/private pair for the given key type with an optional `seed` and
85
	/// store it in the keystore.
86
	///
87
	/// The `seed` needs to be valid utf8.
88
	///
89
	/// Returns the generated public key.
90
	fn generate_pair(key_type: KeyTypeId, seed: Option<Vec<u8>>) -> Self;
91

            
92
	/// Sign the given message with the corresponding private key of this public key.
93
	///
94
	/// The private key will be requested from the keystore using the given key type.
95
	///
96
	/// Returns the signature or `None` if the private key could not be found or some other error
97
	/// occurred.
98
	fn sign<M: AsRef<[u8]>>(&self, key_type: KeyTypeId, msg: &M) -> Option<Self::Signature>;
99

            
100
	/// Verify that the given signature matches the given message using this public key.
101
	fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool;
102

            
103
	/// Returns `Self` as raw vec.
104
	fn to_raw_vec(&self) -> Vec<u8>;
105
}
106

            
107
/// Runtime interface for an application's public key.
108
pub trait RuntimeAppPublic: Sized {
109
	/// An identifier for this application-specific key type.
110
	const ID: KeyTypeId;
111

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

            
115
	/// Returns all public keys for this application in the keystore.
116
	fn all() -> crate::Vec<Self>;
117

            
118
	/// Generate a public/private pair with an optional `seed` and store it in the keystore.
119
	///
120
	/// The `seed` needs to be valid utf8.
121
	///
122
	/// Returns the generated public key.
123
	fn generate_pair(seed: Option<Vec<u8>>) -> Self;
124

            
125
	/// Sign the given message with the corresponding private key of this public key.
126
	///
127
	/// The private key will be requested from the keystore.
128
	///
129
	/// Returns the signature or `None` if the private key could not be found or some other error
130
	/// occurred.
131
	fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature>;
132

            
133
	/// Verify that the given signature matches the given message using this public key.
134
	fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool;
135

            
136
	/// Returns `Self` as raw vec.
137
	fn to_raw_vec(&self) -> Vec<u8>;
138
}
139

            
140
impl<T> RuntimeAppPublic for T
141
where
142
	T: AppPublic + AsRef<<T as AppPublic>::Generic>,
143
	<T as AppPublic>::Generic: RuntimePublic,
144
	<T as AppCrypto>::Signature: TypeInfo
145
		+ Codec
146
		+ From<<<T as AppPublic>::Generic as RuntimePublic>::Signature>
147
		+ AsRef<<<T as AppPublic>::Generic as RuntimePublic>::Signature>,
148
{
149
	const ID: KeyTypeId = <T as AppCrypto>::ID;
150

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

            
153
	fn all() -> crate::Vec<Self> {
154
		<<T as AppPublic>::Generic as RuntimePublic>::all(Self::ID)
155
			.into_iter()
156
			.map(|p| p.into())
157
			.collect()
158
	}
159

            
160
	fn generate_pair(seed: Option<Vec<u8>>) -> Self {
161
		<<T as AppPublic>::Generic as RuntimePublic>::generate_pair(Self::ID, seed).into()
162
	}
163

            
164
	fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature> {
165
		<<T as AppPublic>::Generic as RuntimePublic>::sign(self.as_ref(), Self::ID, msg)
166
			.map(|s| s.into())
167
	}
168

            
169
2814
	fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool {
170
2814
		<<T as AppPublic>::Generic as RuntimePublic>::verify(self.as_ref(), msg, signature.as_ref())
171
2814
	}
172

            
173
	fn to_raw_vec(&self) -> Vec<u8> {
174
		<<T as AppPublic>::Generic as RuntimePublic>::to_raw_vec(self.as_ref())
175
	}
176
}
177

            
178
/// Something that is bound to a fixed [`RuntimeAppPublic`].
179
pub trait BoundToRuntimeAppPublic {
180
	/// The [`RuntimeAppPublic`] this type is bound to.
181
	type Public: RuntimeAppPublic;
182
}
183

            
184
impl<T: RuntimeAppPublic> BoundToRuntimeAppPublic for T {
185
	type Public = Self;
186
}