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:
brenzi
2019-11-04 10:53:41 +01:00
committed by Bastian Köcher
parent 2e424f4d9f
commit ed5ac30a44
13 changed files with 352 additions and 151 deletions
+32 -16
View File
@@ -18,6 +18,7 @@
//! Cryptographic utilities.
// end::description[]
use rstd::{vec::Vec, hash::Hash};
#[cfg(feature = "std")]
use rstd::convert::TryInto;
use rstd::convert::TryFrom;
@@ -30,8 +31,7 @@ use codec::{Encode, Decode};
use regex::Regex;
#[cfg(feature = "std")]
use base58::{FromBase58, ToBase58};
#[cfg(feature = "std")]
use std::hash::Hash;
use zeroize::Zeroize;
#[doc(hidden)]
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
/// `CHAIN_CODE_LENGTH` in the context of Schnorrkel.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub const JUNCTION_ID_LEN: usize = 32;
/// 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.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub enum SecretStringError {
/// The overall format was invalid (e.g. the seed phrase contained symbols).
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 public key from an existing public key.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Encode, Decode)]
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub enum DeriveJunction {
/// Soft (vanilla) derivation. Public keys have a correspondent derivation.
Soft([u8; JUNCTION_ID_LEN]),
@@ -148,7 +148,7 @@ pub enum DeriveJunction {
Hard([u8; JUNCTION_ID_LEN]),
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl DeriveJunction {
/// Consume self to return a soft derive junction with the same chain code.
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 {
fn from(j: T) -> DeriveJunction {
let j = j.as_ref();
@@ -236,7 +236,7 @@ impl<T: AsRef<str>> From<T> for DeriveJunction {
}
/// An error type for SS58 decoding.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum PublicError {
/// Bad alphabet.
@@ -254,9 +254,10 @@ pub enum PublicError {
}
/// Key that can be encoded to/from SS58.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
/// Some if the string is a properly encoded SS58Check address.
#[cfg(feature = "std")]
fn from_ss58check(s: &str) -> Result<Self, PublicError> {
Self::from_ss58check_with_version(s)
.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.
#[cfg(feature = "std")]
fn from_ss58check_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
let mut res = Self::default();
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
/// a derivation path following.
#[cfg(feature = "std")]
fn from_string(s: &str) -> Result<Self, PublicError> {
Self::from_string_with_version(s)
.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.
#[cfg(feature = "std")]
fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String {
let mut v = vec![version.into()];
v.extend(self.as_ref());
@@ -309,9 +314,11 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default {
v.to_base58()
}
/// Return the ss58-check string for this key.
#[cfg(feature = "std")]
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
/// a derivation path following.
#[cfg(feature = "std")]
fn from_string_with_version(s: &str) -> Result<(Self, Ss58AddressFormat), PublicError> {
Self::from_ss58check_with_version(s)
}
@@ -346,7 +353,7 @@ lazy_static::lazy_static! {
}
/// A known address (sub)format/network ID for SS58.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Ss58AddressFormat {
/// Any Substrate network, direct checksum, standard account (*25519).
@@ -361,7 +368,7 @@ pub enum Ss58AddressFormat {
Custom(u8),
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl From<Ss58AddressFormat> for u8 {
fn from(x: Ss58AddressFormat) -> u8 {
match x {
@@ -374,7 +381,7 @@ impl From<Ss58AddressFormat> for u8 {
}
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl TryFrom<u8> for Ss58AddressFormat {
type Error = ();
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 {
type Error = ();
fn try_from(x: &'a str) -> Result<Ss58AddressFormat, ()> {
@@ -640,7 +647,9 @@ mod dummy {
type Seed = Dummy;
type Signature = Dummy;
type DeriveError = ();
#[cfg(feature = "std")]
fn generate_with_phrase(_: Option<&str>) -> (Self, String, Self::Seed) { Default::default() }
#[cfg(feature = "std")]
fn from_phrase(_: &str, _: Option<&str>)
-> Result<(Self, Self::Seed), SecretStringError>
{
@@ -662,7 +671,7 @@ mod dummy {
/// 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.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub trait Pair: CryptoType + Sized + Clone + Send + Sync + 'static {
/// The type which is used to encode a public key.
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
/// for storage. If you want a persistent key pair, use `generate_with_phrase` instead.
#[cfg(feature = "std")]
fn generate() -> (Self, Self::Seed) {
let mut seed = Self::Seed::default();
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
/// the key from the current session.
#[cfg(feature = "std")]
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.
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Self, Self::Seed), SecretStringError>;
/// 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.
///
/// `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>.*))?$")
.expect("constructed from known-good static value; qed");
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.
///
/// 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> {
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.
pub trait CryptoType {
/// The pair key type of this crypto.
#[cfg(feature="std")]
#[cfg(feature = "full_crypto")]
type Pair: Pair;
}
+31 -24
View File
@@ -18,27 +18,31 @@
//! Simple ECDSA API.
// end::description[]
use rstd::vec::Vec;
use rstd::cmp::Ordering;
use codec::{Encode, Decode};
#[cfg(feature = "std")]
use std::convert::{TryFrom, TryInto};
#[cfg(feature = "full_crypto")]
use core::convert::{TryFrom, TryInto};
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
#[cfg(feature = "std")]
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "full_crypto")]
use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError}};
#[cfg(feature = "std")]
use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, SecretStringError, Ss58Codec}};
use crate::crypto::Ss58Codec;
#[cfg(feature = "std")]
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive};
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
use secp256k1::{PublicKey, 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]>.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
type Seed = [u8; 32];
/// The ECDSA 33-byte compressed public key.
@@ -72,7 +76,7 @@ impl Default for Public {
}
/// A key pair.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
#[derive(Clone)]
pub struct Pair {
public: PublicKey,
@@ -117,7 +121,7 @@ impl From<Public> for [u8; 33] {
}
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl From<Pair> for Public {
fn from(x: Pair) -> Self {
x.public()
@@ -160,9 +164,9 @@ impl<'de> Deserialize<'de> for Public {
}
}
#[cfg(feature = "std")]
impl std::hash::Hash for Public {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
#[cfg(feature = "full_crypto")]
impl rstd::hash::Hash for Public {
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
@@ -238,10 +242,10 @@ impl std::fmt::Debug for Signature {
}
}
#[cfg(feature = "std")]
impl std::hash::Hash for Signature {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
std::hash::Hash::hash(&self.0[..], state);
#[cfg(feature = "full_crypto")]
impl rstd::hash::Hash for Signature {
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
rstd::hash::Hash::hash(&self.0[..], state);
}
}
@@ -255,7 +259,7 @@ impl Signature {
}
/// 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> {
let message = secp256k1::Message::parse(&blake2_256(message.as_ref()));
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 {
fn from(x: (secp256k1::Signature, secp256k1::RecoveryId)) -> Signature {
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) {
type 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 {}
/// Derive a single hard junction.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
("Secp256k1HDKD", secret_seed, cc).using_encoded(|data| {
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.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub enum DeriveError {
/// A soft key was found in the path (and is unsupported).
SoftKeyInPath,
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl TraitPair for Pair {
type Public = Public;
type Seed = Seed;
@@ -355,6 +359,7 @@ impl TraitPair for Pair {
/// Generate new secure (random) key pair and provide the recovery phrase.
///
/// You can recover the same key later with `from_phrase`.
#[cfg(feature = "std")]
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
let phrase = mnemonic.phrase();
@@ -368,6 +373,7 @@ impl TraitPair for Pair {
}
/// Generate key pair from given recovery phrase and password.
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
let big_seed = seed_from_entropy(
Mnemonic::from_phrase(phrase, Language::English)
@@ -454,7 +460,7 @@ impl TraitPair for Pair {
}
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl Pair {
/// Get the seed for this key.
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
/// 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 {
Self::from_string(s, password_override).unwrap_or_else(|_| {
let mut padded_seed: Seed = [' ' as u8; 32];
@@ -474,16 +481,16 @@ impl Pair {
}
impl CryptoType for Public {
#[cfg(feature="std")]
#[cfg(feature="full_crypto")]
type Pair = Pair;
}
impl CryptoType for Signature {
#[cfg(feature="std")]
#[cfg(feature="full_crypto")]
type Pair = Pair;
}
#[cfg(feature = "std")]
#[cfg(feature="full_crypto")]
impl CryptoType for Pair {
type Pair = Pair;
}
+24 -18
View File
@@ -18,18 +18,21 @@
//! Simple Ed25519 API.
// end::description[]
use rstd::vec::Vec;
use crate::{hash::H256, hash::H512};
use codec::{Encode, Decode};
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
use blake2_rfc;
#[cfg(feature = "std")]
use substrate_bip39::seed_from_entropy;
#[cfg(feature = "std")]
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "full_crypto")]
use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError};
#[cfg(feature = "std")]
use crate::crypto::{Pair as TraitPair, DeriveJunction, SecretStringError, Ss58Codec};
use crate::crypto::Ss58Codec;
#[cfg(feature = "std")]
use serde::{de, Serializer, Serialize, Deserializer, Deserialize};
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
/// 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).
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
type Seed = [u8; 32];
/// 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)]
pub struct Public(pub [u8; 32]);
/// A key pair.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub struct Pair(ed25519_dalek::Keypair);
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl Clone for Pair {
fn clone(&self) -> Self {
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 {
fn from(x: Pair) -> Self {
x.public()
@@ -240,10 +243,10 @@ impl rstd::fmt::Debug for Signature {
}
}
#[cfg(feature = "std")]
impl std::hash::Hash for Signature {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
std::hash::Hash::hash(&self.0[..], state);
#[cfg(feature = "full_crypto")]
impl rstd::hash::Hash for Signature {
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
rstd::hash::Hash::hash(&self.0[..], state);
}
}
@@ -337,7 +340,7 @@ impl TraitPublic for Public {
impl Derive for Public {}
/// Derive a single hard junction.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
fn derive_hard_junction(secret_seed: &Seed, cc: &[u8; 32]) -> Seed {
("Ed25519HDKD", secret_seed, cc).using_encoded(|data| {
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.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub enum DeriveError {
/// A soft key was found in the path (and is unsupported).
SoftKeyInPath,
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl TraitPair for Pair {
type Public = Public;
type Seed = Seed;
@@ -363,6 +366,7 @@ impl TraitPair for Pair {
/// Generate new secure (random) key pair and provide the recovery phrase.
///
/// You can recover the same key later with `from_phrase`.
#[cfg(feature = "std")]
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
let phrase = mnemonic.phrase();
@@ -376,6 +380,7 @@ impl TraitPair for Pair {
}
/// Generate key pair from given recovery phrase and password.
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
let big_seed = seed_from_entropy(
Mnemonic::from_phrase(phrase, Language::English)
@@ -466,7 +471,7 @@ impl TraitPair for Pair {
}
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl Pair {
/// Get the seed for this key.
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
/// 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 {
Self::from_string(s, password_override).unwrap_or_else(|_| {
let mut padded_seed: Seed = [' ' as u8; 32];
@@ -486,16 +492,16 @@ impl Pair {
}
impl CryptoType for Public {
#[cfg(feature="std")]
#[cfg(feature = "full_crypto")]
type Pair = Pair;
}
impl CryptoType for Signature {
#[cfg(feature="std")]
#[cfg(feature = "full_crypto")]
type Pair = Pair;
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl CryptoType for Pair {
type Pair = Pair;
}
+3 -3
View File
@@ -47,9 +47,9 @@ pub use substrate_debug_derive::RuntimeDebug;
#[cfg(feature = "std")]
pub use impl_serde::serialize as bytes;
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub mod hashing;
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256};
#[cfg(feature = "std")]
pub mod hexdisplay;
@@ -76,7 +76,7 @@ mod tests;
pub use self::hash::{H160, H256, H512, convert_hash};
pub use self::uint::U256;
pub use changes_trie::ChangesTrieConfiguration;
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub use crypto::{DeriveJunction, Pair, Public};
pub use hash_db::Hasher;
+28 -25
View File
@@ -20,8 +20,8 @@
//! Note: `CHAIN_CODE_LENGTH` must be equal to `crate::crypto::JUNCTION_ID_LEN`
//! for this to work.
// end::description[]
#[cfg(feature = "std")]
use rstd::vec::Vec;
#[cfg(feature = "full_crypto")]
use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey,
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;
#[cfg(feature = "std")]
use bip39::{Mnemonic, Language, MnemonicType};
#[cfg(feature = "std")]
#[cfg(feature = "full_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::hash::{H256, H512};
use codec::{Encode, Decode};
#[cfg(feature = "std")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
use schnorrkel::keys::{MINI_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH};
// signing context
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
const SIGNING_CTX: &[u8] = b"substrate";
/// 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)]
pub struct Public(pub [u8; 32]);
/// An Schnorrkel/Ristretto x25519 ("sr25519") key pair.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
pub struct Pair(Keypair);
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl Clone for Pair {
fn clone(&self) -> Self {
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 {
fn from(s: schnorrkel::Signature) -> Signature {
Signature(s.to_bytes())
@@ -248,10 +251,10 @@ impl rstd::fmt::Debug for Signature {
}
}
#[cfg(feature = "std")]
impl std::hash::Hash for Signature {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
std::hash::Hash::hash(&self.0[..], state);
#[cfg(feature = "full_crypto")]
impl rstd::hash::Hash for Signature {
fn hash<H: rstd::hash::Hasher>(&self, state: &mut H) {
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 {
fn from(p: schnorrkel::Keypair) -> Pair {
Pair(p)
}
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl From<Pair> for schnorrkel::Keypair {
fn from(p: Pair) -> schnorrkel::Keypair {
p.0
}
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl AsRef<schnorrkel::Keypair> for Pair {
fn as_ref(&self) -> &schnorrkel::Keypair {
&self.0
@@ -384,16 +387,16 @@ impl AsRef<schnorrkel::Keypair> for Pair {
}
/// Derive a single hard junction.
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> MiniSecretKey {
secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0
}
/// 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];
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl TraitPair for Pair {
type Public = Public;
type Seed = Seed;
@@ -440,7 +443,7 @@ impl TraitPair for Pair {
_ => Err(SecretStringError::InvalidSeedLength)
}
}
#[cfg(feature = "std")]
fn generate_with_phrase(password: Option<&str>) -> (Pair, String, Seed) {
let mnemonic = Mnemonic::new(MnemonicType::Words12, Language::English);
let phrase = mnemonic.phrase();
@@ -452,7 +455,7 @@ impl TraitPair for Pair {
seed,
)
}
#[cfg(feature = "std")]
fn from_phrase(phrase: &str, password: Option<&str>) -> Result<(Pair, Seed), SecretStringError> {
Mnemonic::from_phrase(phrase, Language::English)
.map_err(|_| SecretStringError::InvalidPhrase)
@@ -527,16 +530,16 @@ impl Pair {
}
impl CryptoType for Public {
#[cfg(feature="std")]
#[cfg(feature = "full_crypto")]
type Pair = Pair;
}
impl CryptoType for Signature {
#[cfg(feature="std")]
#[cfg(feature = "full_crypto")]
type Pair = Pair;
}
#[cfg(feature = "std")]
#[cfg(feature = "full_crypto")]
impl CryptoType for Pair {
type Pair = Pair;
}