sp_application_crypto/traits.rs
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
18use codec::Codec;
19use scale_info::TypeInfo;
20
21use alloc::vec::Vec;
22use core::fmt::Debug;
23use sp_core::crypto::{CryptoType, CryptoTypeId, IsWrappedBy, KeyTypeId, Pair, Public, Signature};
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.
33pub 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 proof of possession type in this application scheme.
47 type ProofOfPossession: AppSignature;
48
49 /// The corresponding key pair type in this application scheme.
50 type Pair: AppPair;
51}
52
53/// Type which implements Hash in std, not when no-std (std variant).
54pub trait MaybeHash: core::hash::Hash {}
55impl<T: core::hash::Hash> MaybeHash for T {}
56
57/// Application-specific key pair.
58pub trait AppPair:
59 AppCrypto + Pair<Public = <Self as AppCrypto>::Public, Signature = <Self as AppCrypto>::Signature>
60{
61 /// The wrapped type which is just a plain instance of `Pair`.
62 type Generic: IsWrappedBy<Self>
63 + Pair<Public = <<Self as AppCrypto>::Public as AppPublic>::Generic>
64 + Pair<Signature = <<Self as AppCrypto>::Signature as AppSignature>::Generic>;
65}
66
67/// Application-specific public key.
68pub trait AppPublic: AppCrypto + Public + Debug + MaybeHash + Codec {
69 /// The wrapped type which is just a plain instance of `Public`.
70 type Generic: IsWrappedBy<Self> + Public + Debug + MaybeHash + Codec;
71}
72
73/// Application-specific signature and Proof Of Possession
74pub trait AppSignature: AppCrypto + Signature + Eq + PartialEq + Debug + Clone {
75 /// The wrapped type which is just a plain instance of `Signature`.
76 type Generic: IsWrappedBy<Self> + Signature + Eq + PartialEq + Debug;
77}
78
79/// Runtime interface for a public key.
80pub trait RuntimePublic: Sized {
81 /// The signature that will be generated when signing with the corresponding private key.
82 type Signature: Debug + Eq + PartialEq + Clone;
83
84 /// The Proof Of Possession the corresponding private key.
85 type ProofOfPossession: Debug + Eq + PartialEq + Clone;
86
87 /// Returns all public keys for the given key type in the keystore.
88 fn all(key_type: KeyTypeId) -> crate::Vec<Self>;
89
90 /// Generate a public/private pair for the given key type with an optional `seed` and
91 /// store it in the keystore.
92 ///
93 /// The `seed` needs to be valid utf8.
94 ///
95 /// Returns the generated public key.
96 fn generate_pair(key_type: KeyTypeId, seed: Option<Vec<u8>>) -> Self;
97
98 /// Sign the given message with the corresponding private key of this public key.
99 ///
100 /// The private key will be requested from the keystore using the given key type.
101 ///
102 /// Returns the signature or `None` if the private key could not be found or some other error
103 /// occurred.
104 fn sign<M: AsRef<[u8]>>(&self, key_type: KeyTypeId, msg: &M) -> Option<Self::Signature>;
105
106 /// Verify that the given signature matches the given message using this public key.
107 fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool;
108
109 /// Generates the necessary proof(s) usually as a signature or list of signatures, for the
110 /// corresponding public key to be accepted as legitimate by the network.
111 ///
112 /// This includes attestation of the owner of the public key in the form of signing the owner's
113 /// identity. It might also includes other signatures such as signature obtained by signing
114 /// the corresponding public in different context than normal signatures in case of BLS
115 /// key pair.
116 ///
117 /// The `owner` is an arbitrary byte array representing the identity of the owner of
118 /// the key which has been signed by the private key in process of generating the proof.
119 ///
120 /// The private key will be requested from the keystore using the given key type.
121 ///
122 /// Returns the proof of possession or `None` if it failed or is not able to do
123 /// so.
124 fn generate_proof_of_possession(
125 &mut self,
126 key_type: KeyTypeId,
127 owner: &[u8],
128 ) -> Option<Self::ProofOfPossession>;
129
130 /// Verifies that the given proof is valid for the corresponding public key.
131 /// The proof is usually a signature or list of signatures, for the corresponding
132 /// public key to be accepted by the network. It include attestation of the owner of
133 /// the public key in the form signing the owner's identity but might also includes
134 /// other signatures.
135 ///
136 /// The `owner` is an arbitrary byte array representing the identity of the owner of
137 /// the key which has been signed by the private key in process of generating the proof.
138 ///
139 /// Returns `true` if the proof is deemed correct by the cryto type.
140 fn verify_proof_of_possession(&self, owner: &[u8], pop: &Self::ProofOfPossession) -> bool;
141
142 /// Returns `Self` as raw vec.
143 fn to_raw_vec(&self) -> Vec<u8>;
144}
145
146/// Runtime interface for an application's public key.
147pub trait RuntimeAppPublic: Sized {
148 /// An identifier for this application-specific key type.
149 const ID: KeyTypeId;
150
151 /// The signature that will be generated when signing with the corresponding private key.
152 type Signature: Debug + Eq + PartialEq + Clone + TypeInfo + Codec;
153
154 /// The Proof Of Possession the corresponding private key.
155 type ProofOfPossession: Debug + Eq + PartialEq + TypeInfo + Clone;
156
157 /// Returns all public keys for this application in the keystore.
158 fn all() -> crate::Vec<Self>;
159
160 /// Generate a public/private pair with an optional `seed` and store it in the keystore.
161 ///
162 /// The `seed` needs to be valid utf8.
163 ///
164 /// Returns the generated public key.
165 fn generate_pair(seed: Option<Vec<u8>>) -> Self;
166
167 /// Sign the given message with the corresponding private key of this public key.
168 ///
169 /// The private key will be requested from the keystore.
170 ///
171 /// Returns the signature or `None` if the private key could not be found or some other error
172 /// occurred.
173 fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature>;
174
175 /// Verify that the given signature matches the given message using this public key.
176 fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool;
177
178 /// Generate proof of legitimacy for the corresponding public key
179 ///
180 /// Returns the proof of possession, usually a signature or a list of signature, or `None` if
181 /// it failed or is not able to do so.
182 fn generate_proof_of_possession(&mut self, owner: &[u8]) -> Option<Self::ProofOfPossession>;
183
184 /// Verify that the given proof of possession is valid for the corresponding public key.
185 fn verify_proof_of_possession(&self, owner: &[u8], pop: &Self::ProofOfPossession) -> bool;
186
187 /// Returns `Self` as raw vec.
188 fn to_raw_vec(&self) -> Vec<u8>;
189}
190
191impl<T> RuntimeAppPublic for T
192where
193 T: AppPublic + AsRef<<T as AppPublic>::Generic> + AsMut<<T as AppPublic>::Generic>,
194 <T as AppPublic>::Generic: RuntimePublic,
195 <T as AppCrypto>::Signature: TypeInfo
196 + Codec
197 + From<<<T as AppPublic>::Generic as RuntimePublic>::Signature>
198 + AsRef<<<T as AppPublic>::Generic as RuntimePublic>::Signature>,
199 <T as AppCrypto>::ProofOfPossession: TypeInfo
200 + Codec
201 + From<<<T as AppPublic>::Generic as RuntimePublic>::ProofOfPossession>
202 + AsRef<<<T as AppPublic>::Generic as RuntimePublic>::ProofOfPossession>,
203{
204 const ID: KeyTypeId = <T as AppCrypto>::ID;
205
206 type Signature = <T as AppCrypto>::Signature;
207 type ProofOfPossession = <T as AppCrypto>::ProofOfPossession;
208
209 fn all() -> crate::Vec<Self> {
210 <<T as AppPublic>::Generic as RuntimePublic>::all(Self::ID)
211 .into_iter()
212 .map(|p| p.into())
213 .collect()
214 }
215
216 fn generate_pair(seed: Option<Vec<u8>>) -> Self {
217 <<T as AppPublic>::Generic as RuntimePublic>::generate_pair(Self::ID, seed).into()
218 }
219
220 fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature> {
221 <<T as AppPublic>::Generic as RuntimePublic>::sign(self.as_ref(), Self::ID, msg)
222 .map(|s| s.into())
223 }
224
225 fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool {
226 <<T as AppPublic>::Generic as RuntimePublic>::verify(self.as_ref(), msg, signature.as_ref())
227 }
228
229 fn generate_proof_of_possession(&mut self, owner: &[u8]) -> Option<Self::ProofOfPossession> {
230 <<T as AppPublic>::Generic as RuntimePublic>::generate_proof_of_possession(
231 self.as_mut(),
232 Self::ID,
233 owner,
234 )
235 .map(|s| s.into())
236 }
237
238 fn verify_proof_of_possession(&self, owner: &[u8], pop: &Self::ProofOfPossession) -> bool {
239 <<T as AppPublic>::Generic as RuntimePublic>::verify_proof_of_possession(
240 self.as_ref(),
241 owner,
242 pop.as_ref(),
243 )
244 }
245
246 fn to_raw_vec(&self) -> Vec<u8> {
247 <<T as AppPublic>::Generic as RuntimePublic>::to_raw_vec(self.as_ref())
248 }
249}
250
251/// Something that is bound to a fixed [`RuntimeAppPublic`].
252pub trait BoundToRuntimeAppPublic {
253 /// The [`RuntimeAppPublic`] this type is bound to.
254 type Public: RuntimeAppPublic;
255}
256
257impl<T: RuntimeAppPublic> BoundToRuntimeAppPublic for T {
258 type Public = Self;
259}