mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 19:51:02 +00:00
support crypto primitives for no_std introducing full_crypto feature (#3778)
* introduced "with_crypto" feature and applied switches like in substrate-api-client fork * introduced "with_crypto" feature and applied switches like in substraTEE-worker fork * distinguishing core::hash vs std::hash * @bkchr's review requests fulfilled * fixes * revert dependency upgrade ed25519-dalek * added full_crypto features to all crates using app_crypto! macro * fixing CI complaints. * fix again * adding CI test for with_crypto feature * added full_crypto for ecdsa. now builds wit h--no-deafault-features --features with_crypto * remove --release from CI test * @bkchr requested changes. moved full_crypto CI test to build stage * fixing no_std issue * CI fresh copy from srml-staking * gitlab CI with +nightly * solved no-feature-in-macro dilemma * cosmetics * Update core/application-crypto/src/sr25519.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * Update core/application-crypto/src/ed25519.rs Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com> * even more simple * undo line delete * refactoring app_crypto macro. splitting functionalities based on full_crypto feature * whitespace cosmetics
This commit is contained in:
@@ -230,6 +230,26 @@ node-exits:
|
|||||||
script:
|
script:
|
||||||
- ./ci/check_for_exit.sh
|
- ./ci/check_for_exit.sh
|
||||||
|
|
||||||
|
|
||||||
|
test-full-crypto-feature: &test-full-crypto-feature
|
||||||
|
stage: test
|
||||||
|
<<: *docker-env
|
||||||
|
variables:
|
||||||
|
# Enable debug assertions since we are running optimized builds for testing
|
||||||
|
# but still want to have debug assertions.
|
||||||
|
RUSTFLAGS: -Cdebug-assertions=y
|
||||||
|
RUST_BACKTRACE: 1
|
||||||
|
except:
|
||||||
|
variables:
|
||||||
|
- $DEPLOY_TAG
|
||||||
|
script:
|
||||||
|
- cd core/primitives/
|
||||||
|
- time cargo +nightly build --verbose --no-default-features --features full_crypto
|
||||||
|
- cd ../application-crypto
|
||||||
|
- time cargo +nightly build --verbose --no-default-features --features full_crypto
|
||||||
|
- sccache -s
|
||||||
|
|
||||||
|
|
||||||
#### stage: build
|
#### stage: build
|
||||||
|
|
||||||
build-linux-substrate:
|
build-linux-substrate:
|
||||||
|
|||||||
Generated
+7
-1
@@ -1492,6 +1492,11 @@ name = "hex"
|
|||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hex-literal"
|
name = "hex-literal"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@@ -5823,7 +5828,7 @@ dependencies = [
|
|||||||
"ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ed25519-dalek 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hash256-std-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -7536,6 +7541,7 @@ dependencies = [
|
|||||||
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
|
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
|
||||||
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||||
|
"checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
|
||||||
"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0"
|
"checksum hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0"
|
||||||
"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d"
|
"checksum hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d"
|
||||||
"checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a"
|
"checksum hmac 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a13f4163aa0c5ca1be584aace0e2212b2e41be5478218d4f657f5f778b2ae2a"
|
||||||
|
|||||||
@@ -18,4 +18,11 @@ sr-primitives = { path = "../sr-primitives" }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "std" ]
|
default = [ "std" ]
|
||||||
std = [ "primitives/std", "codec/std", "serde", "rstd/std", "runtime-io/std" ]
|
std = [ "full_crypto", "primitives/std", "codec/std", "serde", "rstd/std", "runtime-io/std" ]
|
||||||
|
|
||||||
|
# This feature enables all crypto primitives for `no_std` builds like microcontrollers
|
||||||
|
# or Intel SGX.
|
||||||
|
# For the regular wasm runtime builds this should not be used.
|
||||||
|
full_crypto = [
|
||||||
|
"primitives/full_crypto"
|
||||||
|
]
|
||||||
@@ -31,7 +31,7 @@ mod app {
|
|||||||
|
|
||||||
pub use app::Public as AppPublic;
|
pub use app::Public as AppPublic;
|
||||||
pub use app::Signature as AppSignature;
|
pub use app::Signature as AppSignature;
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub use app::Pair as AppPair;
|
pub use app::Pair as AppPair;
|
||||||
|
|
||||||
impl RuntimePublic for Public {
|
impl RuntimePublic for Public {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug};
|
pub use primitives::{self, crypto::{CryptoType, Public, Derive, IsWrappedBy, Wraps}, RuntimeDebug};
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub use primitives::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair};
|
pub use primitives::crypto::{SecretStringError, DeriveJunction, Ss58Codec, Pair};
|
||||||
pub use primitives::{crypto::{KeyTypeId, key_types}};
|
pub use primitives::{crypto::{KeyTypeId, key_types}};
|
||||||
|
|
||||||
@@ -50,17 +50,43 @@ pub use traits::*;
|
|||||||
/// // of value `b"fuba"`.
|
/// // of value `b"fuba"`.
|
||||||
/// app_crypto!(ed25519, KeyTypeId(*b"_uba"));
|
/// app_crypto!(ed25519, KeyTypeId(*b"_uba"));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(feature = "full_crypto")]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! app_crypto {
|
macro_rules! app_crypto {
|
||||||
($module:ident, $key_type:expr) => {
|
($module:ident, $key_type:expr) => {
|
||||||
#[cfg(feature="std")]
|
$crate::app_crypto_public_full_crypto!($module::Public, $key_type);
|
||||||
$crate::app_crypto!($module::Pair, $module::Public, $module::Signature, $key_type);
|
$crate::app_crypto_public_common!($module::Public, $module::Signature, $key_type);
|
||||||
#[cfg(not(feature="std"))]
|
$crate::app_crypto_signature_full_crypto!($module::Signature, $key_type);
|
||||||
$crate::app_crypto!($module::Public, $module::Signature, $key_type);
|
$crate::app_crypto_signature_common!($module::Signature, $key_type);
|
||||||
|
$crate::app_crypto_pair!($module::Pair, $key_type);
|
||||||
};
|
};
|
||||||
($pair:ty, $public:ty, $sig:ty, $key_type:expr) => {
|
}
|
||||||
$crate::app_crypto!($public, $sig, $key_type);
|
|
||||||
|
|
||||||
|
/// Declares Public, Pair, Signature types which are functionally equivalent to `$pair`, but are new
|
||||||
|
/// Application-specific types whose identifier is `$key_type`.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
///# use substrate_application_crypto::{app_crypto, wrap, 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"));
|
||||||
|
/// ```
|
||||||
|
#[cfg(not(feature = "full_crypto"))]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto {
|
||||||
|
($module:ident, $key_type:expr) => {
|
||||||
|
$crate::app_crypto_public_not_full_crypto!($module::Public, $key_type);
|
||||||
|
$crate::app_crypto_public_common!($module::Public, $module::Signature, $key_type);
|
||||||
|
$crate::app_crypto_signature_not_full_crypto!($module::Signature, $key_type);
|
||||||
|
$crate::app_crypto_signature_common!($module::Signature, $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) => {
|
||||||
$crate::wrap!{
|
$crate::wrap!{
|
||||||
/// A generic `AppPublic` wrapper type over $pair crypto; this has no specific App.
|
/// A generic `AppPublic` wrapper type over $pair crypto; this has no specific App.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -71,16 +97,18 @@ macro_rules! app_crypto {
|
|||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl $crate::Pair for Pair {
|
impl $crate::Pair for Pair {
|
||||||
type Public = Public;
|
type Public = Public;
|
||||||
type Seed = <$pair as $crate::Pair>::Seed;
|
type Seed = <$pair as $crate::Pair>::Seed;
|
||||||
type Signature = Signature;
|
type Signature = Signature;
|
||||||
type DeriveError = <$pair as $crate::Pair>::DeriveError;
|
type DeriveError = <$pair as $crate::Pair>::DeriveError;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) {
|
fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed) {
|
||||||
let r = <$pair>::generate_with_phrase(password);
|
let r = <$pair>::generate_with_phrase(password);
|
||||||
(Self(r.0), r.1, r.2)
|
(Self(r.0), r.1, r.2)
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_phrase(phrase: &str, password: Option<&str>)
|
fn from_phrase(phrase: &str, password: Option<&str>)
|
||||||
-> Result<(Self, Self::Seed), $crate::SecretStringError>
|
-> Result<(Self, Self::Seed), $crate::SecretStringError>
|
||||||
{
|
{
|
||||||
@@ -115,6 +143,7 @@ macro_rules! app_crypto {
|
|||||||
fn public(&self) -> Self::Public { Public(self.0.public()) }
|
fn public(&self) -> Self::Public { Public(self.0.public()) }
|
||||||
fn to_raw_vec(&self) -> Vec<u8> { self.0.to_raw_vec() }
|
fn to_raw_vec(&self) -> Vec<u8> { self.0.to_raw_vec() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::AppKey for Pair {
|
impl $crate::AppKey for Pair {
|
||||||
type UntypedGeneric = $pair;
|
type UntypedGeneric = $pair;
|
||||||
type Public = Public;
|
type Public = Public;
|
||||||
@@ -122,11 +151,20 @@ macro_rules! app_crypto {
|
|||||||
type Signature = Signature;
|
type Signature = Signature;
|
||||||
const ID: $crate::KeyTypeId = $key_type;
|
const ID: $crate::KeyTypeId = $key_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::AppPair for Pair {
|
impl $crate::AppPair for Pair {
|
||||||
type Generic = $pair;
|
type Generic = $pair;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($public:ty, $sig:ty, $key_type:expr) => {
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto_public_full_crypto {
|
||||||
|
($public:ty, $key_type:expr) => {
|
||||||
$crate::wrap!{
|
$crate::wrap!{
|
||||||
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
|
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
|
||||||
#[derive(
|
#[derive(
|
||||||
@@ -135,10 +173,59 @@ macro_rules! app_crypto {
|
|||||||
$crate::codec::Decode,
|
$crate::codec::Decode,
|
||||||
$crate::RuntimeDebug,
|
$crate::RuntimeDebug,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "std", derive(Hash))]
|
#[derive(Hash)]
|
||||||
pub struct Public($public);
|
pub struct Public($public);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl $crate::CryptoType for Public {
|
||||||
|
type Pair = Pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::AppKey for Public {
|
||||||
|
type UntypedGeneric = $public;
|
||||||
|
type Public = Public;
|
||||||
|
type Pair = Pair;
|
||||||
|
type Signature = Signature;
|
||||||
|
const ID: $crate::KeyTypeId = $key_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto_public_not_full_crypto {
|
||||||
|
($public:ty, $key_type:expr) => {
|
||||||
|
$crate::wrap!{
|
||||||
|
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
|
||||||
|
#[derive(
|
||||||
|
Clone, Default, Eq, PartialEq, Ord, PartialOrd,
|
||||||
|
$crate::codec::Encode,
|
||||||
|
$crate::codec::Decode,
|
||||||
|
$crate::RuntimeDebug,
|
||||||
|
)]
|
||||||
|
pub struct Public($public);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::CryptoType for Public {}
|
||||||
|
|
||||||
|
impl $crate::AppKey for Public {
|
||||||
|
type UntypedGeneric = $public;
|
||||||
|
type Public = Public;
|
||||||
|
type Signature = Signature;
|
||||||
|
const ID: $crate::KeyTypeId = $key_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto_public_common {
|
||||||
|
($public:ty, $sig:ty, $key_type:expr) => {
|
||||||
impl $crate::Derive for Public {
|
impl $crate::Derive for Public {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
fn derive<Iter: Iterator<Item=$crate::DeriveJunction>>(&self,
|
fn derive<Iter: Iterator<Item=$crate::DeriveJunction>>(&self,
|
||||||
@@ -183,24 +270,10 @@ macro_rules! app_crypto {
|
|||||||
fn as_mut(&mut self) -> &mut [u8] { self.0.as_mut() }
|
fn as_mut(&mut self) -> &mut [u8] { self.0.as_mut() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::CryptoType for Public {
|
|
||||||
#[cfg(feature="std")]
|
|
||||||
type Pair = Pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $crate::Public for Public {
|
impl $crate::Public for Public {
|
||||||
fn from_slice(x: &[u8]) -> Self { Self(<$public>::from_slice(x)) }
|
fn from_slice(x: &[u8]) -> Self { Self(<$public>::from_slice(x)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::AppKey for Public {
|
|
||||||
type UntypedGeneric = $public;
|
|
||||||
type Public = Public;
|
|
||||||
#[cfg(feature="std")]
|
|
||||||
type Pair = Pair;
|
|
||||||
type Signature = Signature;
|
|
||||||
const ID: $crate::KeyTypeId = $key_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $crate::AppPublic for Public {
|
impl $crate::AppPublic for Public {
|
||||||
type Generic = $public;
|
type Generic = $public;
|
||||||
}
|
}
|
||||||
@@ -229,7 +302,16 @@ macro_rules! app_crypto {
|
|||||||
<$public as $crate::RuntimePublic>::verify(self.as_ref(), msg, &signature.as_ref())
|
<$public as $crate::RuntimePublic>::verify(self.as_ref(), msg, &signature.as_ref())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto_signature_full_crypto {
|
||||||
|
($sig:ty, $key_type:expr) => {
|
||||||
$crate::wrap! {
|
$crate::wrap! {
|
||||||
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
|
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
|
||||||
#[derive(Clone, Default, Eq, PartialEq,
|
#[derive(Clone, Default, Eq, PartialEq,
|
||||||
@@ -237,10 +319,58 @@ macro_rules! app_crypto {
|
|||||||
$crate::codec::Decode,
|
$crate::codec::Decode,
|
||||||
$crate::RuntimeDebug,
|
$crate::RuntimeDebug,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "std", derive(Hash))]
|
#[derive(Hash)]
|
||||||
pub struct Signature($sig);
|
pub struct Signature($sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl $crate::CryptoType for Signature {
|
||||||
|
type Pair = Pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::AppKey for Signature {
|
||||||
|
type UntypedGeneric = $sig;
|
||||||
|
type Public = Public;
|
||||||
|
type Pair = Pair;
|
||||||
|
type Signature = Signature;
|
||||||
|
const ID: $crate::KeyTypeId = $key_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto_signature_not_full_crypto {
|
||||||
|
($sig:ty, $key_type:expr) => {
|
||||||
|
$crate::wrap! {
|
||||||
|
/// A generic `AppPublic` wrapper type over $public crypto; this has no specific App.
|
||||||
|
#[derive(Clone, Default, Eq, PartialEq,
|
||||||
|
$crate::codec::Encode,
|
||||||
|
$crate::codec::Decode,
|
||||||
|
$crate::RuntimeDebug,
|
||||||
|
)]
|
||||||
|
pub struct Signature($sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl $crate::CryptoType for Signature {}
|
||||||
|
|
||||||
|
impl $crate::AppKey for Signature {
|
||||||
|
type UntypedGeneric = $sig;
|
||||||
|
type Public = Public;
|
||||||
|
type Signature = Signature;
|
||||||
|
const ID: $crate::KeyTypeId = $key_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! app_crypto_signature_common {
|
||||||
|
($sig:ty, $key_type:expr) => {
|
||||||
impl $crate::Deref for Signature {
|
impl $crate::Deref for Signature {
|
||||||
type Target = [u8];
|
type Target = [u8];
|
||||||
|
|
||||||
@@ -251,20 +381,6 @@ macro_rules! app_crypto {
|
|||||||
fn as_ref(&self) -> &[u8] { self.0.as_ref() }
|
fn as_ref(&self) -> &[u8] { self.0.as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $crate::CryptoType for Signature {
|
|
||||||
#[cfg(feature="std")]
|
|
||||||
type Pair = Pair;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $crate::AppKey for Signature {
|
|
||||||
type UntypedGeneric = $sig;
|
|
||||||
type Public = Public;
|
|
||||||
#[cfg(feature="std")]
|
|
||||||
type Pair = Pair;
|
|
||||||
type Signature = Signature;
|
|
||||||
const ID: $crate::KeyTypeId = $key_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $crate::AppSignature for Signature {
|
impl $crate::AppSignature for Signature {
|
||||||
type Generic = $sig;
|
type Generic = $sig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ mod app {
|
|||||||
|
|
||||||
pub use app::Public as AppPublic;
|
pub use app::Public as AppPublic;
|
||||||
pub use app::Signature as AppSignature;
|
pub use app::Signature as AppSignature;
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub use app::Pair as AppPair;
|
pub use app::Pair as AppPair;
|
||||||
|
|
||||||
impl RuntimePublic for Public {
|
impl RuntimePublic for Public {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use primitives::crypto::Pair;
|
use primitives::crypto::Pair;
|
||||||
|
|
||||||
use codec::Codec;
|
use codec::Codec;
|
||||||
@@ -30,7 +30,7 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone {
|
|||||||
type Public: AppPublic;
|
type Public: AppPublic;
|
||||||
|
|
||||||
/// The corresponding key pair type in this application scheme.
|
/// The corresponding key pair type in this application scheme.
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Pair: AppPair;
|
type Pair: AppPair;
|
||||||
|
|
||||||
/// The corresponding signature type in this application scheme.
|
/// The corresponding signature type in this application scheme.
|
||||||
@@ -42,16 +42,22 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone {
|
|||||||
|
|
||||||
/// Type which implements Hash in std, not when no-std (std variant).
|
/// Type which implements Hash in std, not when no-std (std variant).
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub trait MaybeHash: std::hash::Hash {}
|
pub trait MaybeHash: rstd::hash::Hash {}
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<T: std::hash::Hash> MaybeHash for T {}
|
impl<T: rstd::hash::Hash> MaybeHash for T {}
|
||||||
|
|
||||||
/// Type which implements Hash in std, not when no-std (no-std variant).
|
/// Type which implements Hash in std, not when no-std (no-std variant).
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))]
|
||||||
pub trait MaybeHash {}
|
pub trait MaybeHash {}
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))]
|
||||||
impl<T> MaybeHash for T {}
|
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: rstd::hash::Hash {}
|
||||||
|
#[cfg(all(not(feature = "std"), feature = "full_crypto"))]
|
||||||
|
impl<T: rstd::hash::Hash> MaybeDebugHash for T {}
|
||||||
|
|
||||||
/// A application's public key.
|
/// A application's public key.
|
||||||
pub trait AppPublic:
|
pub trait AppPublic:
|
||||||
AppKey + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec
|
AppKey + Public + Ord + PartialOrd + Eq + PartialEq + Debug + MaybeHash + codec::Codec
|
||||||
@@ -62,7 +68,7 @@ pub trait AppPublic:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A application's key pair.
|
/// A application's key pair.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub trait AppPair: AppKey + Pair<Public=<Self as AppKey>::Public> {
|
pub trait AppPair: AppKey + Pair<Public=<Self as AppKey>::Public> {
|
||||||
/// The wrapped type which is just a plain instance of `Pair`.
|
/// The wrapped type which is just a plain instance of `Pair`.
|
||||||
type Generic: IsWrappedBy<Self> + Pair<Public=<<Self as AppKey>::Public as AppPublic>::Generic>;
|
type Generic: IsWrappedBy<Self> + Pair<Public=<<Self as AppKey>::Public as AppPublic>::Generic>;
|
||||||
|
|||||||
@@ -10,28 +10,28 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features =
|
|||||||
rustc-hex = { version = "2.0.1", default-features = false }
|
rustc-hex = { version = "2.0.1", default-features = false }
|
||||||
log = { version = "0.4.8", default-features = false }
|
log = { version = "0.4.8", default-features = false }
|
||||||
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
serde = { version = "1.0.101", optional = true, features = ["derive"] }
|
||||||
twox-hash = { version = "1.5.0", optional = true }
|
twox-hash = { version = "1.5.0", default-features = false, optional = true }
|
||||||
byteorder = { version = "1.3.2", default-features = false }
|
byteorder = { version = "1.3.2", default-features = false }
|
||||||
primitive-types = { version = "0.6", default-features = false, features = ["codec"] }
|
primitive-types = { version = "0.6", default-features = false, features = ["codec"] }
|
||||||
impl-serde = { version = "0.2.3", optional = true }
|
impl-serde = { version = "0.2.3", optional = true }
|
||||||
wasmi = { version = "0.5.1", optional = true }
|
wasmi = { version = "0.5.1", optional = true }
|
||||||
hash-db = { version = "0.15.2", default-features = false }
|
hash-db = { version = "0.15.2", default-features = false }
|
||||||
hash256-std-hasher = { version = "0.15.2", default-features = false }
|
hash256-std-hasher = { version = "0.15.2", default-features = false }
|
||||||
ed25519-dalek = { version = "0.9.1", optional = true }
|
ed25519-dalek = { version = "0.9.1", default-features = false, features = ["u64_backend"], optional = true }
|
||||||
base58 = { version = "0.1.0", optional = true }
|
base58 = { version = "0.1.0", optional = true }
|
||||||
blake2-rfc = { version = "0.2.18", optional = true }
|
blake2-rfc = { version = "0.2.18", default-features = false, optional = true }
|
||||||
schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], optional = true }
|
schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"], default-features = false, optional = true }
|
||||||
rand = { version = "0.7.2", optional = true }
|
rand = { version = "0.7.2", optional = true }
|
||||||
sha2 = { version = "0.8.0", optional = true }
|
sha2 = { version = "0.8.0", default-features = false, optional = true }
|
||||||
substrate-bip39 = { version = "0.3.1", optional = true }
|
substrate-bip39 = { version = "0.3.1", optional = true }
|
||||||
tiny-bip39 = { version = "0.6.2", optional = true }
|
tiny-bip39 = { version = "0.6.2", optional = true }
|
||||||
hex = { version = "0.3.2", optional = true }
|
hex = { version = "0.4", default-features = false, optional = true }
|
||||||
regex = { version = "1.3.1", optional = true }
|
regex = { version = "1.3.1", optional = true }
|
||||||
num-traits = { version = "0.2.8", default-features = false }
|
num-traits = { version = "0.2.8", default-features = false }
|
||||||
zeroize = "0.10.1"
|
zeroize = { version = "0.10.1", default-features = false }
|
||||||
lazy_static = { version = "1.4.0", optional = true }
|
lazy_static = { version = "1.4.0", default-features = false, optional = true }
|
||||||
parking_lot = { version = "0.9.0", optional = true }
|
parking_lot = { version = "0.9.0", optional = true }
|
||||||
libsecp256k1 = { version = "0.3.0", optional = true }
|
libsecp256k1 = { version = "0.3.0", default-features = false, optional = true }
|
||||||
tiny-keccak = { version = "1.5.0", optional = true }
|
tiny-keccak = { version = "1.5.0", optional = true }
|
||||||
substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" }
|
substrate-debug-derive = { version = "2.0.0", path = "./debug-derive" }
|
||||||
externalities = { package = "substrate-externalities", path = "../externalities", optional = true }
|
externalities = { package = "substrate-externalities", path = "../externalities", optional = true }
|
||||||
@@ -54,6 +54,7 @@ bench = false
|
|||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = [
|
std = [
|
||||||
|
"full_crypto",
|
||||||
"log/std",
|
"log/std",
|
||||||
"wasmi",
|
"wasmi",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -70,18 +71,18 @@ std = [
|
|||||||
"rstd/std",
|
"rstd/std",
|
||||||
"serde",
|
"serde",
|
||||||
"rustc-hex/std",
|
"rustc-hex/std",
|
||||||
"twox-hash",
|
"twox-hash/std",
|
||||||
"blake2-rfc",
|
"blake2-rfc/std",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek/std",
|
||||||
"hex",
|
"hex/std",
|
||||||
"base58",
|
"base58",
|
||||||
"substrate-bip39",
|
"substrate-bip39",
|
||||||
"tiny-bip39",
|
"tiny-bip39",
|
||||||
"serde",
|
"serde",
|
||||||
"byteorder/std",
|
"byteorder/std",
|
||||||
"rand",
|
"rand",
|
||||||
"sha2",
|
"sha2/std",
|
||||||
"schnorrkel",
|
"schnorrkel/std",
|
||||||
"regex",
|
"regex",
|
||||||
"num-traits/std",
|
"num-traits/std",
|
||||||
"libsecp256k1",
|
"libsecp256k1",
|
||||||
@@ -90,3 +91,16 @@ std = [
|
|||||||
"externalities",
|
"externalities",
|
||||||
"primitives-storage/std",
|
"primitives-storage/std",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# This feature enables all crypto primitives for `no_std` builds like microcontrollers
|
||||||
|
# or Intel SGX.
|
||||||
|
# For the regular wasm runtime builds this should not be used.
|
||||||
|
full_crypto = [
|
||||||
|
"ed25519-dalek",
|
||||||
|
"blake2-rfc",
|
||||||
|
"schnorrkel",
|
||||||
|
"libsecp256k1",
|
||||||
|
"hex",
|
||||||
|
"sha2",
|
||||||
|
"twox-hash"
|
||||||
|
]
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
//! Cryptographic utilities.
|
//! Cryptographic utilities.
|
||||||
// end::description[]
|
// end::description[]
|
||||||
|
|
||||||
|
use rstd::{vec::Vec, hash::Hash};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use rstd::convert::TryInto;
|
use rstd::convert::TryInto;
|
||||||
use rstd::convert::TryFrom;
|
use rstd::convert::TryFrom;
|
||||||
@@ -30,8 +31,7 @@ use codec::{Encode, Decode};
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use base58::{FromBase58, ToBase58};
|
use base58::{FromBase58, ToBase58};
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::hash::Hash;
|
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use rstd::ops::Deref;
|
pub use rstd::ops::Deref;
|
||||||
@@ -48,7 +48,7 @@ pub enum Infallible {}
|
|||||||
|
|
||||||
/// The length of the junction identifier. Note that this is also referred to as the
|
/// The length of the junction identifier. Note that this is also referred to as the
|
||||||
/// `CHAIN_CODE_LENGTH` in the context of Schnorrkel.
|
/// `CHAIN_CODE_LENGTH` in the context of Schnorrkel.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub const JUNCTION_ID_LEN: usize = 32;
|
pub const JUNCTION_ID_LEN: usize = 32;
|
||||||
|
|
||||||
/// Similar to `From`, except that the onus is on the part of the caller to ensure
|
/// Similar to `From`, except that the onus is on the part of the caller to ensure
|
||||||
@@ -120,7 +120,7 @@ impl<T: Zeroize> Drop for Protected<T> {
|
|||||||
|
|
||||||
/// An error with the interpretation of a secret.
|
/// An error with the interpretation of a secret.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub enum SecretStringError {
|
pub enum SecretStringError {
|
||||||
/// The overall format was invalid (e.g. the seed phrase contained symbols).
|
/// The overall format was invalid (e.g. the seed phrase contained symbols).
|
||||||
InvalidFormat,
|
InvalidFormat,
|
||||||
@@ -140,7 +140,7 @@ pub enum SecretStringError {
|
|||||||
/// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex`
|
/// a new secret key from an existing secret key and, in the case of `SoftRaw` and `SoftIndex`
|
||||||
/// a new public key from an existing public key.
|
/// a new public key from an existing public key.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)]
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub enum DeriveJunction {
|
pub enum DeriveJunction {
|
||||||
/// Soft (vanilla) derivation. Public keys have a correspondent derivation.
|
/// Soft (vanilla) derivation. Public keys have a correspondent derivation.
|
||||||
Soft([u8; JUNCTION_ID_LEN]),
|
Soft([u8; JUNCTION_ID_LEN]),
|
||||||
@@ -148,7 +148,7 @@ pub enum DeriveJunction {
|
|||||||
Hard([u8; JUNCTION_ID_LEN]),
|
Hard([u8; JUNCTION_ID_LEN]),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl DeriveJunction {
|
impl DeriveJunction {
|
||||||
/// Consume self to return a soft derive junction with the same chain code.
|
/// Consume self to return a soft derive junction with the same chain code.
|
||||||
pub fn soften(self) -> Self { DeriveJunction::Soft(self.unwrap_inner()) }
|
pub fn soften(self) -> Self { DeriveJunction::Soft(self.unwrap_inner()) }
|
||||||
@@ -209,7 +209,7 @@ impl DeriveJunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl<T: AsRef<str>> From<T> for DeriveJunction {
|
impl<T: AsRef<str>> From<T> for DeriveJunction {
|
||||||
fn from(j: T) -> DeriveJunction {
|
fn from(j: T) -> DeriveJunction {
|
||||||
let j = j.as_ref();
|
let j = j.as_ref();
|
||||||
@@ -236,7 +236,7 @@ impl<T: AsRef<str>> From<T> for DeriveJunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error type for SS58 decoding.
|
/// An error type for SS58 decoding.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
pub enum PublicError {
|
pub enum PublicError {
|
||||||
/// Bad alphabet.
|
/// Bad alphabet.
|
||||||
@@ -254,9 +254,10 @@ pub enum PublicError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Key that can be encoded to/from SS58.
|
/// Key that can be encoded to/from SS58.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
|
pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
|
||||||
/// Some if the string is a properly encoded SS58Check address.
|
/// Some if the string is a properly encoded SS58Check address.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_ss58check(s: &str) -> Result<Self, PublicError> {
|
fn from_ss58check(s: &str) -> Result<Self, PublicError> {
|
||||||
Self::from_ss58check_with_version(s)
|
Self::from_ss58check_with_version(s)
|
||||||
.and_then(|(r, v)| match v {
|
.and_then(|(r, v)| match v {
|
||||||
@@ -269,6 +270,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
/// Some if the string is a properly encoded SS58Check address.
|
/// Some if the string is a properly encoded SS58Check address.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
|
fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
|
||||||
let mut res = Self::default();
|
let mut res = Self::default();
|
||||||
let len = res.as_mut().len();
|
let len = res.as_mut().len();
|
||||||
@@ -288,6 +290,7 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
|
|||||||
}
|
}
|
||||||
/// Some if the string is a properly encoded SS58Check address, optionally with
|
/// Some if the string is a properly encoded SS58Check address, optionally with
|
||||||
/// a derivation path following.
|
/// a derivation path following.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_string(s: &str) -> Result<Self, PublicError> {
|
fn from_string(s: &str) -> Result<Self, PublicError> {
|
||||||
Self::from_string_with_version(s)
|
Self::from_string_with_version(s)
|
||||||
.and_then(|(r, v)| match v {
|
.and_then(|(r, v)| match v {
|
||||||
@@ -301,6 +304,8 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the ss58-check string for this key.
|
/// Return the ss58-check string for this key.
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String {
|
fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String {
|
||||||
let mut v = vec![version.into()];
|
let mut v = vec![version.into()];
|
||||||
v.extend(self.as_ref());
|
v.extend(self.as_ref());
|
||||||
@@ -309,9 +314,11 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
|
|||||||
v.to_base58()
|
v.to_base58()
|
||||||
}
|
}
|
||||||
/// Return the ss58-check string for this key.
|
/// Return the ss58-check string for this key.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) }
|
fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) }
|
||||||
/// Some if the string is a properly encoded SS58Check address, optionally with
|
/// Some if the string is a properly encoded SS58Check address, optionally with
|
||||||
/// a derivation path following.
|
/// a derivation path following.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
|
fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
|
||||||
Self::from_ss58check_with_version(s)
|
Self::from_ss58check_with_version(s)
|
||||||
}
|
}
|
||||||
@@ -346,7 +353,7 @@ lazy_static::lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A known address (sub)format/network ID for SS58.
|
/// A known address (sub)format/network ID for SS58.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum Ss58AddressFormat {
|
pub enum Ss58AddressFormat {
|
||||||
/// Any Substrate network, direct checksum, standard account (*25519).
|
/// Any Substrate network, direct checksum, standard account (*25519).
|
||||||
@@ -361,7 +368,7 @@ pub enum Ss58AddressFormat {
|
|||||||
Custom(u8),
|
Custom(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<Ss58AddressFormat> for u8 {
|
impl From<Ss58AddressFormat> for u8 {
|
||||||
fn from(x: Ss58AddressFormat) -> u8 {
|
fn from(x: Ss58AddressFormat) -> u8 {
|
||||||
match x {
|
match x {
|
||||||
@@ -374,7 +381,7 @@ impl From<Ss58AddressFormat> for u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl TryFrom<u8> for Ss58AddressFormat {
|
impl TryFrom<u8> for Ss58AddressFormat {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(x: u8) -> Result<Ss58AddressFormat, ()> {
|
fn try_from(x: u8) -> Result<Ss58AddressFormat, ()> {
|
||||||
@@ -388,7 +395,7 @@ impl TryFrom<u8> for Ss58AddressFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl<'a> TryFrom<&'a str> for Ss58AddressFormat {
|
impl<'a> TryFrom<&'a str> for Ss58AddressFormat {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(x: &'a str) -> Result<Ss58AddressFormat, ()> {
|
fn try_from(x: &'a str) -> Result<Ss58AddressFormat, ()> {
|
||||||
@@ -640,7 +647,9 @@ mod dummy {
|
|||||||
type Seed = Dummy;
|
type Seed = Dummy;
|
||||||
type Signature = Dummy;
|
type Signature = Dummy;
|
||||||
type DeriveError = ();
|
type DeriveError = ();
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) { Default::default() }
|
fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) { Default::default() }
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_phrase(_: &str, _: Option<&str>)
|
fn from_phrase(_: &str, _: Option<&str>)
|
||||||
-> Result<(Self, Self::Seed), SecretStringError>
|
-> Result<(Self, Self::Seed), SecretStringError>
|
||||||
{
|
{
|
||||||
@@ -662,7 +671,7 @@ mod dummy {
|
|||||||
/// Trait suitable for typical cryptographic PKI key pair type.
|
/// Trait suitable for typical cryptographic PKI key pair type.
|
||||||
///
|
///
|
||||||
/// For now it just specifies how to create a key from a phrase and derivation path.
|
/// For now it just specifies how to create a key from a phrase and derivation path.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
|
pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
|
||||||
/// The type which is used to encode a public key.
|
/// The type which is used to encode a public key.
|
||||||
type Public: Public + Hash;
|
type Public: Public + Hash;
|
||||||
@@ -682,6 +691,7 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
|
|||||||
///
|
///
|
||||||
/// This is only for ephemeral keys really, since you won't have access to the secret key
|
/// This is only for ephemeral keys really, since you won't have access to the secret key
|
||||||
/// for storage. If you want a persistent key pair, use `generate_with_phrase` instead.
|
/// for storage. If you want a persistent key pair, use `generate_with_phrase` instead.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate() -> (Self, Self::Seed) {
|
fn generate() -> (Self, Self::Seed) {
|
||||||
let mut seed = Self::Seed::default();
|
let mut seed = Self::Seed::default();
|
||||||
OsRng.fill_bytes(seed.as_mut());
|
OsRng.fill_bytes(seed.as_mut());
|
||||||
@@ -694,9 +704,11 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
|
|||||||
///
|
///
|
||||||
/// This is generally slower than `generate()`, so prefer that unless you need to persist
|
/// This is generally slower than `generate()`, so prefer that unless you need to persist
|
||||||
/// the key from the current session.
|
/// the key from the current session.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed);
|
fn generate_with_phrase(password: Option<&str>) -> (Self, String, Self::Seed);
|
||||||
|
|
||||||
/// Returns the KeyPair from the English BIP39 seed `phrase`, or `None` if it's invalid.
|
/// Returns the KeyPair from the English BIP39 seed `phrase`, or `None` if it's invalid.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>;
|
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>;
|
||||||
|
|
||||||
/// Derive a child key from a series of given junctions.
|
/// Derive a child key from a series of given junctions.
|
||||||
@@ -758,7 +770,10 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
|
|||||||
/// be equivalent to no password at all.
|
/// be equivalent to no password at all.
|
||||||
///
|
///
|
||||||
/// `None` is returned if no matches are found.
|
/// `None` is returned if no matches are found.
|
||||||
fn from_string_with_seed(s: &str, password_override: Option<&str>) -> Result<(Self, Option<Self::Seed>), SecretStringError> {
|
#[cfg(feature = "std")]
|
||||||
|
fn from_string_with_seed(s: &str, password_override: Option<&str>)
|
||||||
|
-> Result<(Self, Option<Self::Seed>), SecretStringError>
|
||||||
|
{
|
||||||
let re = Regex::new(r"^(?P<phrase>[\d\w ]+)?(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$")
|
let re = Regex::new(r"^(?P<phrase>[\d\w ]+)?(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$")
|
||||||
.expect("constructed from known-good static value; qed");
|
.expect("constructed from known-good static value; qed");
|
||||||
let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?;
|
let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?;
|
||||||
@@ -793,6 +808,7 @@ pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
|
|||||||
/// Interprets the string `s` in order to generate a key pair.
|
/// Interprets the string `s` in order to generate a key pair.
|
||||||
///
|
///
|
||||||
/// See [`from_string_with_seed`](Self::from_string_with_seed) for more extensive documentation.
|
/// See [`from_string_with_seed`](Self::from_string_with_seed) for more extensive documentation.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_string(s: &str, password_override: Option<&str>) -> Result<Self, SecretStringError> {
|
fn from_string(s: &str, password_override: Option<&str>) -> Result<Self, SecretStringError> {
|
||||||
Self::from_string_with_seed(s, password_override).map(|x| x.0)
|
Self::from_string_with_seed(s, password_override).map(|x| x.0)
|
||||||
}
|
}
|
||||||
@@ -839,7 +855,7 @@ impl<Inner, Outer, T> UncheckedFrom<T> for Outer where
|
|||||||
/// Type which has a particular kind of crypto associated with it.
|
/// Type which has a particular kind of crypto associated with it.
|
||||||
pub trait CryptoType {
|
pub trait CryptoType {
|
||||||
/// The pair key type of this crypto.
|
/// The pair key type of this crypto.
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Pair: Pair;
|
type Pair: Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,27 +18,31 @@
|
|||||||
//! Simple ECDSA API.
|
//! Simple ECDSA API.
|
||||||
// end::description[]
|
// end::description[]
|
||||||
|
|
||||||
|
use rstd::vec::Vec;
|
||||||
|
|
||||||
use rstd::cmp::Ordering;
|
use rstd::cmp::Ordering;
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use std::convert::{TryFrom, TryInto};
|
use core::convert::{TryFrom, TryInto};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use substrate_bip39::seed_from_entropy;
|
use substrate_bip39::seed_from_entropy;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use bip39::{Mnemonic, Language, MnemonicType};
|
use bip39::{Mnemonic, Language, MnemonicType};
|
||||||
|
#[cfg(feature = "full_crypto")]
|
||||||
|
use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError, Ss58Codec}};
|
use crate::crypto::Ss58Codec;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
|
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
|
||||||
use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive};
|
use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use secp256k1::{PublicKey, SecretKey};
|
use secp256k1::{PublicKey, SecretKey};
|
||||||
|
|
||||||
/// A secret seed (which is bytewise essentially equivalent to a SecretKey).
|
/// A secret seed (which is bytewise essentially equivalent to a SecretKey).
|
||||||
///
|
///
|
||||||
/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>.
|
/// We need it as a different type because `Seed` is expected to be AsRef<[u8]>.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Seed = [u8; 32];
|
type Seed = [u8; 32];
|
||||||
|
|
||||||
/// The ECDSA 33-byte compressed public key.
|
/// The ECDSA 33-byte compressed public key.
|
||||||
@@ -72,7 +76,7 @@ impl Default for Public {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A key pair.
|
/// A key pair.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Pair {
|
pub struct Pair {
|
||||||
public: PublicKey,
|
public: PublicKey,
|
||||||
@@ -117,7 +121,7 @@ impl From<Public> for [u8; 33] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<Pair> for Public {
|
impl From<Pair> for Public {
|
||||||
fn from(x: Pair) -> Self {
|
fn from(x: Pair) -> Self {
|
||||||
x.public()
|
x.public()
|
||||||
@@ -160,9 +164,9 @@ impl<'de> Deserialize<'de> for Public {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl std::hash::Hash for Public {
|
impl rstd::hash::Hash for Public {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.0.hash(state);
|
self.0.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,10 +242,10 @@ impl std::fmt::Debug for Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl std::hash::Hash for Signature {
|
impl rstd::hash::Hash for Signature {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
|
||||||
std::hash::Hash::hash(&self.0[..], state);
|
rstd::hash::Hash::hash(&self.0[..], state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +259,7 @@ impl Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Recover the public key from this signature and a message.
|
/// Recover the public key from this signature and a message.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub fn recover<M: AsRef<[u8]>>(&self, message: M) -> Option<Public> {
|
pub fn recover<M: AsRef<[u8]>>(&self, message: M) -> Option<Public> {
|
||||||
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
|
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
|
||||||
let sig: (_, _) = self.try_into().ok()?;
|
let sig: (_, _) = self.try_into().ok()?;
|
||||||
@@ -264,7 +268,7 @@ impl Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature {
|
impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature {
|
||||||
fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature {
|
fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature {
|
||||||
let mut r = Self::default();
|
let mut r = Self::default();
|
||||||
@@ -274,7 +278,7 @@ impl From<(secp256k1::Signature, secp256k1::RecoveryId)> for Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) {
|
impl<'a> TryFrom<&'a Signature> for (secp256k1::Signature, secp256k1::RecoveryId) {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> {
|
fn try_from(x: &'a Signature) -> Result<(secp256k1::Signature, secp256k1::RecoveryId), Self::Error> {
|
||||||
@@ -329,7 +333,7 @@ impl TraitPublic for Public {
|
|||||||
impl Derive for Public {}
|
impl Derive for Public {}
|
||||||
|
|
||||||
/// Derive a single hard junction.
|
/// Derive a single hard junction.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
|
fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
|
||||||
("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| {
|
("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| {
|
||||||
let mut res = [0u8; 32];
|
let mut res = [0u8; 32];
|
||||||
@@ -339,13 +343,13 @@ fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error when deriving a key.
|
/// An error when deriving a key.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub enum DeriveError {
|
pub enum DeriveError {
|
||||||
/// A soft key was found in the path (and is unsupported).
|
/// A soft key was found in the path (and is unsupported).
|
||||||
SoftKeyInPath,
|
SoftKeyInPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl TraitPair for Pair {
|
impl TraitPair for Pair {
|
||||||
type Public = Public;
|
type Public = Public;
|
||||||
type Seed = Seed;
|
type Seed = Seed;
|
||||||
@@ -355,6 +359,7 @@ impl TraitPair for Pair {
|
|||||||
/// Generate new secure (random) key pair and provide the recovery phrase.
|
/// Generate new secure (random) key pair and provide the recovery phrase.
|
||||||
///
|
///
|
||||||
/// You can recover the same key later with `from_phrase`.
|
/// You can recover the same key later with `from_phrase`.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
|
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
|
||||||
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
||||||
let phrase = mnemonic.phrase();
|
let phrase = mnemonic.phrase();
|
||||||
@@ -368,6 +373,7 @@ impl TraitPair for Pair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate key pair from given recovery phrase and password.
|
/// Generate key pair from given recovery phrase and password.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
|
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
|
||||||
let big_seed = seed_from_entropy(
|
let big_seed = seed_from_entropy(
|
||||||
Mnemonic::from_phrase(phrase, Language::English)
|
Mnemonic::from_phrase(phrase, Language::English)
|
||||||
@@ -454,7 +460,7 @@ impl TraitPair for Pair {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl Pair {
|
impl Pair {
|
||||||
/// Get the seed for this key.
|
/// Get the seed for this key.
|
||||||
pub fn seed(&self) -> Seed {
|
pub fn seed(&self) -> Seed {
|
||||||
@@ -463,6 +469,7 @@ impl Pair {
|
|||||||
|
|
||||||
/// Exactly as `from_string` except that if no matches are found then, the the first 32
|
/// Exactly as `from_string` except that if no matches are found then, the the first 32
|
||||||
/// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey.
|
/// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair {
|
pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair {
|
||||||
Self::from_string(s, password_override).unwrap_or_else(|_| {
|
Self::from_string(s, password_override).unwrap_or_else(|_| {
|
||||||
let mut padded_seed: Seed = [' ' as u8; 32];
|
let mut padded_seed: Seed = [' ' as u8; 32];
|
||||||
@@ -474,16 +481,16 @@ impl Pair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoType for Public {
|
impl CryptoType for Public {
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature="full_crypto")]
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoType for Signature {
|
impl CryptoType for Signature {
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature="full_crypto")]
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature="full_crypto")]
|
||||||
impl CryptoType for Pair {
|
impl CryptoType for Pair {
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,21 @@
|
|||||||
//! Simple Ed25519 API.
|
//! Simple Ed25519 API.
|
||||||
// end::description[]
|
// end::description[]
|
||||||
|
|
||||||
|
use rstd::vec::Vec;
|
||||||
|
|
||||||
use crate::{hash::H256, hash::H512};
|
use crate::{hash::H256, hash::H512};
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use blake2_rfc;
|
use blake2_rfc;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use substrate_bip39::seed_from_entropy;
|
use substrate_bip39::seed_from_entropy;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use bip39::{Mnemonic, Language, MnemonicType};
|
use bip39::{Mnemonic, Language, MnemonicType};
|
||||||
|
#[cfg(feature = "full_crypto")]
|
||||||
|
use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError, Ss58Codec};
|
use crate::crypto::Ss58Codec;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
|
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
|
||||||
use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}};
|
use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}};
|
||||||
@@ -37,19 +40,19 @@ use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}};
|
|||||||
/// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys
|
/// A secret seed. It's not called a "secret key" because ring doesn't expose the secret keys
|
||||||
/// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we
|
/// of the key pair (yeah, dumb); as such we're forced to remember the seed manually if we
|
||||||
/// will need it later (such as for HDKD).
|
/// will need it later (such as for HDKD).
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Seed = [u8; 32];
|
type Seed = [u8; 32];
|
||||||
|
|
||||||
/// A public key.
|
/// A public key.
|
||||||
#[cfg_attr(feature = "std", derive(Hash))]
|
#[cfg_attr(feature = "full_crypto", derive(Hash))]
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)]
|
||||||
pub struct Public(pub [u8; 32]);
|
pub struct Public(pub [u8; 32]);
|
||||||
|
|
||||||
/// A key pair.
|
/// A key pair.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub struct Pair(ed25519_dalek::Keypair);
|
pub struct Pair(ed25519_dalek::Keypair);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl Clone for Pair {
|
impl Clone for Pair {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Pair(ed25519_dalek::Keypair {
|
Pair(ed25519_dalek::Keypair {
|
||||||
@@ -98,7 +101,7 @@ impl From<Public> for [u8; 32] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<Pair> for Public {
|
impl From<Pair> for Public {
|
||||||
fn from(x: Pair) -> Self {
|
fn from(x: Pair) -> Self {
|
||||||
x.public()
|
x.public()
|
||||||
@@ -240,10 +243,10 @@ impl rstd::fmt::Debug for Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl std::hash::Hash for Signature {
|
impl rstd::hash::Hash for Signature {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
|
||||||
std::hash::Hash::hash(&self.0[..], state);
|
rstd::hash::Hash::hash(&self.0[..], state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +340,7 @@ impl TraitPublic for Public {
|
|||||||
impl Derive for Public {}
|
impl Derive for Public {}
|
||||||
|
|
||||||
/// Derive a single hard junction.
|
/// Derive a single hard junction.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
|
fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
|
||||||
("Ed25519HDKD", secret_seed, cc).using_encoded(|data| {
|
("Ed25519HDKD", secret_seed, cc).using_encoded(|data| {
|
||||||
let mut res = [0u8; 32];
|
let mut res = [0u8; 32];
|
||||||
@@ -347,13 +350,13 @@ fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error when deriving a key.
|
/// An error when deriving a key.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub enum DeriveError {
|
pub enum DeriveError {
|
||||||
/// A soft key was found in the path (and is unsupported).
|
/// A soft key was found in the path (and is unsupported).
|
||||||
SoftKeyInPath,
|
SoftKeyInPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl TraitPair for Pair {
|
impl TraitPair for Pair {
|
||||||
type Public = Public;
|
type Public = Public;
|
||||||
type Seed = Seed;
|
type Seed = Seed;
|
||||||
@@ -363,6 +366,7 @@ impl TraitPair for Pair {
|
|||||||
/// Generate new secure (random) key pair and provide the recovery phrase.
|
/// Generate new secure (random) key pair and provide the recovery phrase.
|
||||||
///
|
///
|
||||||
/// You can recover the same key later with `from_phrase`.
|
/// You can recover the same key later with `from_phrase`.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
|
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
|
||||||
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
||||||
let phrase = mnemonic.phrase();
|
let phrase = mnemonic.phrase();
|
||||||
@@ -376,6 +380,7 @@ impl TraitPair for Pair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate key pair from given recovery phrase and password.
|
/// Generate key pair from given recovery phrase and password.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
|
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
|
||||||
let big_seed = seed_from_entropy(
|
let big_seed = seed_from_entropy(
|
||||||
Mnemonic::from_phrase(phrase, Language::English)
|
Mnemonic::from_phrase(phrase, Language::English)
|
||||||
@@ -466,7 +471,7 @@ impl TraitPair for Pair {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl Pair {
|
impl Pair {
|
||||||
/// Get the seed for this key.
|
/// Get the seed for this key.
|
||||||
pub fn seed(&self) -> &Seed {
|
pub fn seed(&self) -> &Seed {
|
||||||
@@ -475,6 +480,7 @@ impl Pair {
|
|||||||
|
|
||||||
/// Exactly as `from_string` except that if no matches are found then, the the first 32
|
/// Exactly as `from_string` except that if no matches are found then, the the first 32
|
||||||
/// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey.
|
/// characters are taken (padded with spaces as necessary) and used as the MiniSecretKey.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair {
|
pub fn from_legacy_string(s: &str, password_override: Option<&str>) -> Pair {
|
||||||
Self::from_string(s, password_override).unwrap_or_else(|_| {
|
Self::from_string(s, password_override).unwrap_or_else(|_| {
|
||||||
let mut padded_seed: Seed = [' ' as u8; 32];
|
let mut padded_seed: Seed = [' ' as u8; 32];
|
||||||
@@ -486,16 +492,16 @@ impl Pair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoType for Public {
|
impl CryptoType for Public {
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoType for Signature {
|
impl CryptoType for Signature {
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl CryptoType for Pair {
|
impl CryptoType for Pair {
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ pub use substrate_debug_derive::RuntimeDebug;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use impl_serde::serialize as bytes;
|
pub use impl_serde::serialize as bytes;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub mod hashing;
|
pub mod hashing;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256};
|
pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod hexdisplay;
|
pub mod hexdisplay;
|
||||||
@@ -76,7 +76,7 @@ mod tests;
|
|||||||
pub use self::hash::{H160, H256, H512, convert_hash};
|
pub use self::hash::{H160, H256, H512, convert_hash};
|
||||||
pub use self::uint::U256;
|
pub use self::uint::U256;
|
||||||
pub use changes_trie::ChangesTrieConfiguration;
|
pub use changes_trie::ChangesTrieConfiguration;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub use crypto::{DeriveJunction, Pair, Public};
|
pub use crypto::{DeriveJunction, Pair, Public};
|
||||||
|
|
||||||
pub use hash_db::Hasher;
|
pub use hash_db::Hasher;
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
//! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN`
|
//! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN`
|
||||||
//! for this to work.
|
//! for this to work.
|
||||||
// end::description[]
|
// end::description[]
|
||||||
|
use rstd::vec::Vec;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey,
|
use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey,
|
||||||
derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH}
|
derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH}
|
||||||
};
|
};
|
||||||
@@ -29,33 +29,36 @@ use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretK
|
|||||||
use substrate_bip39::mini_secret_from_entropy;
|
use substrate_bip39::mini_secret_from_entropy;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use bip39::{Mnemonic, Language, MnemonicType};
|
use bip39::{Mnemonic, Language, MnemonicType};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use crate::crypto::{
|
use crate::crypto::{
|
||||||
Pair as TraitPair, DeriveJunction, Infallible, SecretStringError, Ss58Codec
|
Pair as TraitPair, DeriveJunction, Infallible, SecretStringError
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use crate::crypto::Ss58Codec;
|
||||||
|
|
||||||
use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}};
|
use crate::{crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive}};
|
||||||
use crate::hash::{H256, H512};
|
use crate::hash::{H256, H512};
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH};
|
use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH};
|
||||||
|
|
||||||
// signing context
|
// signing context
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
const SIGNING_CTX: &[u8] = b"substrate";
|
const SIGNING_CTX: &[u8] = b"substrate";
|
||||||
|
|
||||||
/// An Schnorrkel/Ristretto x25519 ("sr25519") public key.
|
/// An Schnorrkel/Ristretto x25519 ("sr25519") public key.
|
||||||
#[cfg_attr(feature = "std", derive(Hash))]
|
#[cfg_attr(feature = "full_crypto", derive(Hash))]
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Default)]
|
||||||
pub struct Public(pub [u8; 32]);
|
pub struct Public(pub [u8; 32]);
|
||||||
|
|
||||||
/// An Schnorrkel/Ristretto x25519 ("sr25519") key pair.
|
/// An Schnorrkel/Ristretto x25519 ("sr25519") key pair.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
pub struct Pair(Keypair);
|
pub struct Pair(Keypair);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl Clone for Pair {
|
impl Clone for Pair {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Pair(schnorrkel::Keypair {
|
Pair(schnorrkel::Keypair {
|
||||||
@@ -229,7 +232,7 @@ impl AsMut<[u8]> for Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<schnorrkel::Signature> for Signature {
|
impl From<schnorrkel::Signature> for Signature {
|
||||||
fn from(s: schnorrkel::Signature) -> Signature {
|
fn from(s: schnorrkel::Signature) -> Signature {
|
||||||
Signature(s.to_bytes())
|
Signature(s.to_bytes())
|
||||||
@@ -248,10 +251,10 @@ impl rstd::fmt::Debug for Signature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl std::hash::Hash for Signature {
|
impl rstd::hash::Hash for Signature {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
|
||||||
std::hash::Hash::hash(&self.0[..], state);
|
rstd::hash::Hash::hash(&self.0[..], state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,21 +365,21 @@ impl From<SecretKey> for Pair {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<schnorrkel::Keypair> for Pair {
|
impl From<schnorrkel::Keypair> for Pair {
|
||||||
fn from(p: schnorrkel::Keypair) -> Pair {
|
fn from(p: schnorrkel::Keypair) -> Pair {
|
||||||
Pair(p)
|
Pair(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl From<Pair> for schnorrkel::Keypair {
|
impl From<Pair> for schnorrkel::Keypair {
|
||||||
fn from(p: Pair) -> schnorrkel::Keypair {
|
fn from(p: Pair) -> schnorrkel::Keypair {
|
||||||
p.0
|
p.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl AsRef<schnorrkel::Keypair> for Pair {
|
impl AsRef<schnorrkel::Keypair> for Pair {
|
||||||
fn as_ref(&self) -> &schnorrkel::Keypair {
|
fn as_ref(&self) -> &schnorrkel::Keypair {
|
||||||
&self.0
|
&self.0
|
||||||
@@ -384,16 +387,16 @@ impl AsRef<schnorrkel::Keypair> for Pair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Derive a single hard junction.
|
/// Derive a single hard junction.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey {
|
fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey {
|
||||||
secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0
|
secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The raw secret seed, which can be used to recreate the `Pair`.
|
/// The raw secret seed, which can be used to recreate the `Pair`.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Seed = [u8; MINI_SECRET_KEY_LENGTH];
|
type Seed = [u8; MINI_SECRET_KEY_LENGTH];
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl TraitPair for Pair {
|
impl TraitPair for Pair {
|
||||||
type Public = Public;
|
type Public = Public;
|
||||||
type Seed = Seed;
|
type Seed = Seed;
|
||||||
@@ -440,7 +443,7 @@ impl TraitPair for Pair {
|
|||||||
_ => Err(SecretStringError::InvalidSeedLength)
|
_ => Err(SecretStringError::InvalidSeedLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
|
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
|
||||||
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
|
||||||
let phrase = mnemonic.phrase();
|
let phrase = mnemonic.phrase();
|
||||||
@@ -452,7 +455,7 @@ impl TraitPair for Pair {
|
|||||||
seed,
|
seed,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "std")]
|
||||||
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
|
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
|
||||||
Mnemonic::from_phrase(phrase, Language::English)
|
Mnemonic::from_phrase(phrase, Language::English)
|
||||||
.map_err(|_| SecretStringError::InvalidPhrase)
|
.map_err(|_| SecretStringError::InvalidPhrase)
|
||||||
@@ -527,16 +530,16 @@ impl Pair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoType for Public {
|
impl CryptoType for Public {
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CryptoType for Signature {
|
impl CryptoType for Signature {
|
||||||
#[cfg(feature="std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "full_crypto")]
|
||||||
impl CryptoType for Pair {
|
impl CryptoType for Pair {
|
||||||
type Pair = Pair;
|
type Pair = Pair;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user