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
//! Traits and macros for constructing application specific strongly typed crypto wrappers.
19

            
20
#![warn(missing_docs)]
21
#![cfg_attr(not(feature = "std"), no_std)]
22

            
23
extern crate alloc;
24

            
25
pub use sp_core::crypto::{key_types, CryptoTypeId, DeriveJunction, KeyTypeId, Ss58Codec};
26
#[doc(hidden)]
27
pub use sp_core::crypto::{DeriveError, Pair, SecretStringError};
28
#[doc(hidden)]
29
pub use sp_core::{
30
	self,
31
	crypto::{ByteArray, CryptoType, Derive, IsWrappedBy, Public, Signature, UncheckedFrom, Wraps},
32
	RuntimeDebug,
33
};
34

            
35
#[doc(hidden)]
36
pub use alloc::vec::Vec;
37
#[doc(hidden)]
38
pub use codec;
39
#[doc(hidden)]
40
pub use core::ops::Deref;
41
#[doc(hidden)]
42
pub use scale_info;
43
#[doc(hidden)]
44
#[cfg(feature = "serde")]
45
pub use serde;
46

            
47
#[cfg(feature = "bandersnatch-experimental")]
48
pub mod bandersnatch;
49
#[cfg(feature = "bls-experimental")]
50
pub mod bls377;
51
#[cfg(feature = "bls-experimental")]
52
pub mod bls381;
53
pub mod ecdsa;
54
#[cfg(feature = "bls-experimental")]
55
pub mod ecdsa_bls377;
56
pub mod ed25519;
57
pub mod sr25519;
58
mod traits;
59

            
60
pub use traits::*;
61

            
62
/// Declares `Public`, `Pair` and `Signature` types which are functionally equivalent
63
/// to the corresponding types defined by `$module` but are new application-specific
64
/// types whose identifier is `$key_type`.
65
///
66
/// ```rust
67
/// # use sp_application_crypto::{app_crypto, ed25519, KeyTypeId};
68
/// // Declare a new set of crypto types using ed25519 logic that identifies as `KeyTypeId`
69
/// // of value `b"fuba"`.
70
/// app_crypto!(ed25519, KeyTypeId(*b"fuba"));
71
/// ```
72
#[cfg(feature = "full_crypto")]
73
#[macro_export]
74
macro_rules! app_crypto {
75
	($module:ident, $key_type:expr) => {
76
		$crate::app_crypto_public_full_crypto!($module::Public, $key_type, $module::CRYPTO_ID);
77
		$crate::app_crypto_public_common!(
78
			$module::Public,
79
			$module::Signature,
80
			$key_type,
81
			$module::CRYPTO_ID
82
		);
83
		$crate::app_crypto_signature_full_crypto!(
84
			$module::Signature,
85
			$key_type,
86
			$module::CRYPTO_ID
87
		);
88
		$crate::app_crypto_signature_common!($module::Signature, $key_type);
89
		$crate::app_crypto_pair_common!($module::Pair, $key_type, $module::CRYPTO_ID);
90
	};
91
}
92

            
93
/// Declares `Public`, `Pair` and `Signature` types which are functionally equivalent
94
/// to the corresponding types defined by `$module` but that are new application-specific
95
/// types whose identifier is `$key_type`.
96
///
97
/// ```rust
98
/// # use sp_application_crypto::{app_crypto, ed25519, KeyTypeId};
99
/// // Declare a new set of crypto types using ed25519 logic that identifies as `KeyTypeId`
100
/// // of value `b"fuba"`.
101
/// app_crypto!(ed25519, KeyTypeId(*b"fuba"));
102
/// ```
103
#[cfg(not(feature = "full_crypto"))]
104
#[macro_export]
105
macro_rules! app_crypto {
106
	($module:ident, $key_type:expr) => {
107
		$crate::app_crypto_public_not_full_crypto!($module::Public, $key_type, $module::CRYPTO_ID);
108
		$crate::app_crypto_public_common!(
109
			$module::Public,
110
			$module::Signature,
111
			$key_type,
112
			$module::CRYPTO_ID
113
		);
114
		$crate::app_crypto_signature_not_full_crypto!(
115
			$module::Signature,
116
			$key_type,
117
			$module::CRYPTO_ID
118
		);
119
		$crate::app_crypto_signature_common!($module::Signature, $key_type);
120
		$crate::app_crypto_pair_common!($module::Pair, $key_type, $module::CRYPTO_ID);
121
	};
122
}
123

            
124
/// Declares `Pair` type which is functionally equivalent to `$pair`, but is
125
/// new application-specific type whose identifier is `$key_type`.
126
/// It is a common part shared between full_crypto and non full_crypto environments.
127
#[macro_export]
128
macro_rules! app_crypto_pair_common {
129
	($pair:ty, $key_type:expr, $crypto_type:expr) => {
130
		$crate::wrap! {
131
			/// A generic `AppPublic` wrapper type over $pair crypto; this has no specific App.
132
			#[derive(Clone)]
133
			pub struct Pair($pair);
134
		}
135

            
136
		impl $crate::CryptoType for Pair {
137
			type Pair = Pair;
138
		}
139

            
140
		impl $crate::Pair for Pair {
141
			type Public = Public;
142
			type Seed = <$pair as $crate::Pair>::Seed;
143
			type Signature = Signature;
144

            
145
			$crate::app_crypto_pair_functions_if_std!($pair);
146
			$crate::app_crypto_pair_functions_if_full_crypto!($pair);
147

            
148
48
			fn from_phrase(
149
48
				phrase: &str,
150
48
				password: Option<&str>,
151
48
			) -> Result<(Self, Self::Seed), $crate::SecretStringError> {
152
48
				<$pair>::from_phrase(phrase, password).map(|r| (Self(r.0), r.1))
153
48
			}
154
72
			fn derive<Iter: Iterator<Item = $crate::DeriveJunction>>(
155
72
				&self,
156
72
				path: Iter,
157
72
				seed: Option<Self::Seed>,
158
72
			) -> Result<(Self, Option<Self::Seed>), $crate::DeriveError> {
159
72
				self.0.derive(path, seed).map(|x| (Self(x.0), x.1))
160
72
			}
161
			fn from_seed(seed: &Self::Seed) -> Self {
162
				Self(<$pair>::from_seed(seed))
163
			}
164
			fn from_seed_slice(seed: &[u8]) -> Result<Self, $crate::SecretStringError> {
165
				<$pair>::from_seed_slice(seed).map(Self)
166
			}
167
			fn verify<M: AsRef<[u8]>>(
168
				sig: &Self::Signature,
169
				message: M,
170
				pubkey: &Self::Public,
171
			) -> bool {
172
				<$pair>::verify(&sig.0, message, pubkey.as_ref())
173
			}
174
72
			fn public(&self) -> Self::Public {
175
72
				Public(self.0.public())
176
72
			}
177
			fn to_raw_vec(&self) -> $crate::Vec<u8> {
178
				self.0.to_raw_vec()
179
			}
180
		}
181

            
182
		impl $crate::AppCrypto for Pair {
183
			type Public = Public;
184
			type Pair = Pair;
185
			type Signature = Signature;
186
			const ID: $crate::KeyTypeId = $key_type;
187
			const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type;
188
		}
189

            
190
		impl $crate::AppPair for Pair {
191
			type Generic = $pair;
192
		}
193

            
194
		impl Pair {
195
			/// Convert into wrapped generic key pair type.
196
			pub fn into_inner(self) -> $pair {
197
				self.0
198
			}
199
		}
200
	};
201
}
202

            
203
/// Implements functions for the `Pair` trait when `feature = "std"` is enabled.
204
#[doc(hidden)]
205
#[cfg(feature = "std")]
206
#[macro_export]
207
macro_rules! app_crypto_pair_functions_if_std {
208
	($pair:ty) => {
209
		fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) {
210
			let r = <$pair>::generate_with_phrase(password);
211
			(Self(r.0), r.1, r.2)
212
		}
213
	};
214
}
215

            
216
#[doc(hidden)]
217
#[cfg(not(feature = "std"))]
218
#[macro_export]
219
macro_rules! app_crypto_pair_functions_if_std {
220
	($pair:ty) => {};
221
}
222

            
223
/// Implements functions for the `Pair` trait when `feature = "full_crypto"` is enabled.
224
#[doc(hidden)]
225
#[cfg(feature = "full_crypto")]
226
#[macro_export]
227
macro_rules! app_crypto_pair_functions_if_full_crypto {
228
	($pair:ty) => {
229
		fn sign(&self, msg: &[u8]) -> Self::Signature {
230
			Signature(self.0.sign(msg))
231
		}
232
	};
233
}
234

            
235
#[doc(hidden)]
236
#[cfg(not(feature = "full_crypto"))]
237
#[macro_export]
238
macro_rules! app_crypto_pair_functions_if_full_crypto {
239
	($pair:ty) => {};
240
}
241

            
242
/// Declares `Public` type which is functionally equivalent to `$public` but is
243
/// new application-specific type whose identifier is `$key_type`.
244
/// For full functionality, `app_crypto_public_common!` must be called too.
245
/// Can only be used with `full_crypto` feature.
246
#[doc(hidden)]
247
#[macro_export]
248
macro_rules! app_crypto_public_full_crypto {
249
	($public:ty, $key_type:expr, $crypto_type:expr) => {
250
		$crate::wrap! {
251
			/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
252
			#[derive(
253
				Clone, Eq, Hash, PartialEq, PartialOrd, Ord,
254
				$crate::codec::Encode,
255
				$crate::codec::Decode,
256
				$crate::RuntimeDebug,
257
				$crate::codec::MaxEncodedLen,
258
				$crate::scale_info::TypeInfo,
259
			)]
260
			#[codec(crate = $crate::codec)]
261
			pub struct Public($public);
262
		}
263

            
264
		impl $crate::CryptoType for Public {
265
			type Pair = Pair;
266
		}
267

            
268
		impl $crate::AppCrypto for Public {
269
			type Public = Public;
270
			type Pair = Pair;
271
			type Signature = Signature;
272
			const ID: $crate::KeyTypeId = $key_type;
273
			const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type;
274
		}
275
	};
276
}
277

            
278
/// Declares `Public` type which is functionally equivalent to `$public` but is
279
/// new application-specific type whose identifier is `$key_type`.
280
/// For full functionality, `app_crypto_public_common!` must be called too.
281
/// Can only be used without `full_crypto` feature.
282
#[doc(hidden)]
283
#[macro_export]
284
macro_rules! app_crypto_public_not_full_crypto {
285
	($public:ty, $key_type:expr, $crypto_type:expr) => {
286
		$crate::wrap! {
287
			/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
288
			#[derive(
289
				Clone, Eq, Hash, PartialEq, Ord, PartialOrd,
290
				$crate::codec::Encode,
291
				$crate::codec::Decode,
292
				$crate::RuntimeDebug,
293
				$crate::codec::MaxEncodedLen,
294
				$crate::scale_info::TypeInfo,
295
			)]
296
			pub struct Public($public);
297
		}
298

            
299
		impl $crate::CryptoType for Public {
300
			type Pair = Pair;
301
		}
302

            
303
		impl $crate::AppCrypto for Public {
304
			type Public = Public;
305
			type Pair = Pair;
306
			type Signature = Signature;
307
			const ID: $crate::KeyTypeId = $key_type;
308
			const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type;
309
		}
310
	};
311
}
312

            
313
/// Declares `Public` type which is functionally equivalent to `$public` but is
314
/// new application-specific type whose identifier is `$key_type`.
315
/// For full functionality, `app_crypto_public_(not)_full_crypto!` must be called too.
316
#[doc(hidden)]
317
#[macro_export]
318
macro_rules! app_crypto_public_common {
319
	($public:ty, $sig:ty, $key_type:expr, $crypto_type:expr) => {
320
		$crate::app_crypto_public_common_if_serde!();
321

            
322
		impl AsRef<[u8]> for Public {
323
37564
			fn as_ref(&self) -> &[u8] {
324
37564
				self.0.as_ref()
325
37564
			}
326
		}
327

            
328
		impl AsMut<[u8]> for Public {
329
24
			fn as_mut(&mut self) -> &mut [u8] {
330
24
				self.0.as_mut()
331
24
			}
332
		}
333

            
334
		impl $crate::ByteArray for Public {
335
			const LEN: usize = <$public>::LEN;
336
		}
337

            
338
		impl $crate::Public for Public {}
339

            
340
		impl $crate::AppPublic for Public {
341
			type Generic = $public;
342
		}
343

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

            
347
			fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> {
348
				<$public>::try_from(data).map(Into::into)
349
			}
350
		}
351

            
352
		impl Public {
353
			/// Convert into wrapped generic public key type.
354
			pub fn into_inner(self) -> $public {
355
				self.0
356
			}
357
		}
358
	};
359
}
360

            
361
#[doc(hidden)]
362
pub mod module_format_string_prelude {
363
	#[cfg(all(not(feature = "std"), feature = "serde"))]
364
	pub use alloc::{format, string::String};
365
	#[cfg(feature = "std")]
366
	pub use std::{format, string::String};
367
}
368

            
369
/// Implements traits for the public key type if `feature = "serde"` is enabled.
370
#[cfg(feature = "serde")]
371
#[doc(hidden)]
372
#[macro_export]
373
macro_rules! app_crypto_public_common_if_serde {
374
	() => {
375
		impl $crate::Derive for Public {
376
			fn derive<Iter: Iterator<Item = $crate::DeriveJunction>>(
377
				&self,
378
				path: Iter,
379
			) -> Option<Self> {
380
				self.0.derive(path).map(Self)
381
			}
382
		}
383

            
384
		impl core::fmt::Display for Public {
385
			fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
386
				use $crate::Ss58Codec;
387
				write!(f, "{}", self.0.to_ss58check())
388
			}
389
		}
390

            
391
		impl $crate::serde::Serialize for Public {
392
			fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
393
			where
394
				S: $crate::serde::Serializer,
395
			{
396
				use $crate::Ss58Codec;
397
				serializer.serialize_str(&self.to_ss58check())
398
			}
399
		}
400

            
401
		impl<'de> $crate::serde::Deserialize<'de> for Public {
402
			fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
403
			where
404
				D: $crate::serde::Deserializer<'de>,
405
			{
406
				use $crate::{module_format_string_prelude::*, Ss58Codec};
407

            
408
				Public::from_ss58check(&String::deserialize(deserializer)?)
409
					.map_err(|e| $crate::serde::de::Error::custom(format!("{:?}", e)))
410
			}
411
		}
412
	};
413
}
414

            
415
#[cfg(not(feature = "serde"))]
416
#[doc(hidden)]
417
#[macro_export]
418
macro_rules! app_crypto_public_common_if_serde {
419
	() => {
420
		impl $crate::Derive for Public {}
421
	};
422
}
423

            
424
/// Declares Signature type which is functionally equivalent to `$sig`, but is new
425
/// Application-specific type whose identifier is `$key_type`.
426
/// For full functionality, app_crypto_public_common! must be called too.
427
/// Can only be used with `full_crypto` feature
428
#[doc(hidden)]
429
#[macro_export]
430
macro_rules! app_crypto_signature_full_crypto {
431
	($sig:ty, $key_type:expr, $crypto_type:expr) => {
432
		$crate::wrap! {
433
			/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
434
			#[derive(Clone, Eq, PartialEq,
435
				$crate::codec::Encode,
436
				$crate::codec::Decode,
437
				$crate::RuntimeDebug,
438
				$crate::scale_info::TypeInfo,
439
			)]
440
			#[derive(Hash)]
441
			pub struct Signature($sig);
442
		}
443

            
444
		impl $crate::CryptoType for Signature {
445
			type Pair = Pair;
446
		}
447

            
448
		impl $crate::AppCrypto for Signature {
449
			type Public = Public;
450
			type Pair = Pair;
451
			type Signature = Signature;
452
			const ID: $crate::KeyTypeId = $key_type;
453
			const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type;
454
		}
455
	};
456
}
457

            
458
/// Declares `Signature` type which is functionally equivalent to `$sig`, but is new
459
/// application-specific type whose identifier is `$key_type`.
460
/// For full functionality, `app_crypto_signature_common` must be called too.
461
/// Can only be used without `full_crypto` feature.
462
#[doc(hidden)]
463
#[macro_export]
464
macro_rules! app_crypto_signature_not_full_crypto {
465
	($sig:ty, $key_type:expr, $crypto_type:expr) => {
466
		$crate::wrap! {
467
			/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
468
			#[derive(Clone, Eq, PartialEq,
469
				$crate::codec::Encode,
470
				$crate::codec::Decode,
471
				$crate::RuntimeDebug,
472
				$crate::scale_info::TypeInfo,
473
			)]
474
			pub struct Signature($sig);
475
		}
476

            
477
		impl $crate::CryptoType for Signature {
478
			type Pair = Pair;
479
		}
480

            
481
		impl $crate::AppCrypto for Signature {
482
			type Public = Public;
483
			type Pair = Pair;
484
			type Signature = Signature;
485
			const ID: $crate::KeyTypeId = $key_type;
486
			const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type;
487
		}
488
	};
489
}
490

            
491
/// Declares `Signature` type which is functionally equivalent to `$sig`, but is new
492
/// application-specific type whose identifier is `$key_type`.
493
/// For full functionality, app_crypto_signature_(not)_full_crypto! must be called too.
494
#[doc(hidden)]
495
#[macro_export]
496
macro_rules! app_crypto_signature_common {
497
	($sig:ty, $key_type:expr) => {
498
		impl $crate::Deref for Signature {
499
			type Target = [u8];
500

            
501
			fn deref(&self) -> &Self::Target {
502
				self.0.as_ref()
503
			}
504
		}
505

            
506
		impl AsRef<[u8]> for Signature {
507
			fn as_ref(&self) -> &[u8] {
508
				self.0.as_ref()
509
			}
510
		}
511

            
512
		impl AsMut<[u8]> for Signature {
513
			fn as_mut(&mut self) -> &mut [u8] {
514
				self.0.as_mut()
515
			}
516
		}
517

            
518
		impl $crate::AppSignature for Signature {
519
			type Generic = $sig;
520
		}
521

            
522
		impl<'a> TryFrom<&'a [u8]> for Signature {
523
			type Error = ();
524

            
525
			fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> {
526
				<$sig>::try_from(data).map(Into::into)
527
			}
528
		}
529

            
530
		impl TryFrom<$crate::Vec<u8>> for Signature {
531
			type Error = ();
532

            
533
			fn try_from(data: $crate::Vec<u8>) -> Result<Self, Self::Error> {
534
				Self::try_from(&data[..])
535
			}
536
		}
537

            
538
		impl $crate::Signature for Signature {}
539

            
540
		impl $crate::ByteArray for Signature {
541
			const LEN: usize = <$sig>::LEN;
542
		}
543

            
544
		impl Signature {
545
			/// Convert into wrapped generic signature type.
546
			pub fn into_inner(self) -> $sig {
547
				self.0
548
			}
549
		}
550
	};
551
}
552

            
553
/// Implement bidirectional `From` and on-way `AsRef`/`AsMut` for two types, `$inner` and `$outer`.
554
///
555
/// ```rust
556
/// sp_application_crypto::wrap! {
557
///     pub struct Wrapper(u32);
558
/// }
559
/// ```
560
#[macro_export]
561
macro_rules! wrap {
562
	($( #[ $attr:meta ] )* struct $outer:ident($inner:ty);) => {
563
		$( #[ $attr ] )*
564
		struct $outer( $inner );
565
		$crate::wrap!($inner, $outer);
566
	};
567
	($( #[ $attr:meta ] )* pub struct $outer:ident($inner:ty);) => {
568
		$( #[ $attr ] )*
569
		pub struct $outer( $inner );
570
		$crate::wrap!($inner, $outer);
571
	};
572
	($inner:ty, $outer:ty) => {
573
		impl $crate::Wraps for $outer {
574
			type Inner = $inner;
575
		}
576
		impl From<$inner> for $outer {
577
20
			fn from(inner: $inner) -> Self {
578
20
				Self(inner)
579
20
			}
580
		}
581
		impl From<$outer> for $inner {
582
16
			fn from(outer: $outer) -> Self {
583
16
				outer.0
584
16
			}
585
		}
586
		impl AsRef<$inner> for $outer {
587
5628
			fn as_ref(&self) -> &$inner {
588
5628
				&self.0
589
5628
			}
590
		}
591
		impl AsMut<$inner> for $outer {
592
			fn as_mut(&mut self) -> &mut $inner {
593
				&mut self.0
594
			}
595
		}
596
	}
597
}
598

            
599
/// Generate the given code if the pair type is available.
600
///
601
/// The pair type is available when `feature = "std"` || `feature = "full_crypto"`.
602
///
603
/// # Example
604
///
605
/// ```
606
/// sp_application_crypto::with_pair! {
607
///     pub type Pair = ();
608
/// }
609
/// ```
610
#[macro_export]
611
#[cfg(any(feature = "std", feature = "full_crypto"))]
612
macro_rules! with_pair {
613
	( $( $def:tt )* ) => {
614
		$( $def )*
615
	}
616
}
617

            
618
#[doc(hidden)]
619
#[macro_export]
620
#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))]
621
macro_rules! with_pair {
622
	( $( $def:tt )* ) => {};
623
}