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
+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;
}