From e2d9619d4905822bad8e253b80ea5d7a0f1d9b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 7 Aug 2019 12:59:54 +0200 Subject: [PATCH] Update to schnorrkel `0.8.0` (#3267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update to schnorrkel `0.8.0` * Increase `spec_version` * Bump schnorrkel to 0.8.3 (#3283) * Schnorrkel 0.8.1 (builds on bkchr upgrade branch) * Add tests for known hard/soft derivation values * Bump all schnorrkel versions * Flatten for easier inspection * 0.8.2 * 0.8.3 * Update subkey/Cargo.toml Co-Authored-By: Bastian Köcher * Update `Cargo.lock` * 0.8.4 * Fix cargo lock file. * Adding an error message for `NotMarkedSchnorrkel` as that was missing. Also fixing a typo, strage -> stage. --- Cargo.lock | 25 +++---- core/consensus/babe/Cargo.toml | 2 +- core/consensus/babe/primitives/Cargo.toml | 2 +- core/consensus/babe/primitives/src/digest.rs | 13 ++-- core/consensus/babe/src/lib.rs | 2 +- core/primitives/Cargo.toml | 4 +- core/primitives/src/sr25519.rs | 77 ++++++++++++++------ node/runtime/src/lib.rs | 2 +- subkey/Cargo.toml | 3 +- 9 files changed, 79 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b101fb31baeb..24e830af718dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3310,19 +3310,17 @@ dependencies = [ [[package]] name = "schnorrkel" -version = "0.1.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "merlin 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4198,11 +4196,10 @@ dependencies = [ "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "srml-balances 2.0.0", "srml-system 2.0.0", - "substrate-bip39 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4236,12 +4233,12 @@ dependencies = [ [[package]] name = "substrate-bip39" -version = "0.2.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4394,7 +4391,7 @@ dependencies = [ "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-version 2.0.0", @@ -4419,8 +4416,8 @@ dependencies = [ name = "substrate-consensus-babe-primitives" version = "2.0.0" dependencies = [ + "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "sr-std 2.0.0", "substrate-client 2.0.0", @@ -4723,11 +4720,11 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 2.0.0", - "substrate-bip39 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-serializer 2.0.0", "tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "twox-hash 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6324,7 +6321,7 @@ dependencies = [ "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" -"checksum schnorrkel 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5eff518f9bed3d803a0d002af0ab96339b0ebbedde3bec98a684986134b7a39" +"checksum schnorrkel 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "77e8d6a92f49a53f21b71c090a5559bf45c469071ebe556aebaf2dca3abc5cb5" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum sct 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f5adf8fbd58e1b1b52699dc8bed2630faecb6d8c7bee77d009d6bbe4af569b9" @@ -6364,7 +6361,7 @@ dependencies = [ "checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" "checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" "checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" -"checksum substrate-bip39 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d69ace596e9ca97837cc41f8edcfc4e0a997f227d5fc153d1010b60a0fe9acda" +"checksum substrate-bip39 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" "checksum substrate-wasm-builder-runner 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f52ecbff6cc3d6e5c6401828e15937b680f459d6803ce238f01fe615bc40d071" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01dca13cf6c3b179864ab3292bd794e757618d35a7766b7c46050c614ba00829" diff --git a/core/consensus/babe/Cargo.toml b/core/consensus/babe/Cargo.toml index 855daab1e0e1e..8bcade80232cc 100644 --- a/core/consensus/babe/Cargo.toml +++ b/core/consensus/babe/Cargo.toml @@ -28,7 +28,7 @@ futures01 = { package = "futures", version = "0.1" } futures-timer = "0.2.1" parking_lot = "0.8.0" log = "0.4.6" -schnorrkel = "0.1.1" +schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"] } rand = "0.6.5" merlin = "1.0.3" diff --git a/core/consensus/babe/primitives/Cargo.toml b/core/consensus/babe/primitives/Cargo.toml index cf52d270c733e..3948c9727caf3 100644 --- a/core/consensus/babe/primitives/Cargo.toml +++ b/core/consensus/babe/primitives/Cargo.toml @@ -11,8 +11,8 @@ rstd = { package = "sr-std", path = "../../../sr-std", default-features = false sr-primitives = { path = "../../../sr-primitives", default-features = false } primitives = { package = "substrate-primitives", path = "../../../primitives", default-features = false } slots = { package = "substrate-consensus-slots", path = "../../slots", optional = true } +schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"], optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } -schnorrkel = { version = "0.1.1", optional = true } [features] default = ["std"] diff --git a/core/consensus/babe/primitives/src/digest.rs b/core/consensus/babe/primitives/src/digest.rs index 52e7e26e52a91..81effef5d6e60 100644 --- a/core/consensus/babe/primitives/src/digest.rs +++ b/core/consensus/babe/primitives/src/digest.rs @@ -153,6 +153,7 @@ fn convert_error(e: SignatureError) -> codec::Error { EquationFalse => "Signature error: `EquationFalse`".into(), PointDecompressionError => "Signature error: `PointDecompressionError`".into(), ScalarFormatError => "Signature error: `ScalarFormatError`".into(), + NotMarkedSchnorrkel => "Signature error: `NotMarkedSchnorrkel`".into(), BytesLengthError { .. } => "Signature error: `BytesLengthError`".into(), MuSigAbsent { musig_stage: Commitment } => "Signature error: `MuSigAbsent` at stage `Commitment`".into(), @@ -161,16 +162,16 @@ fn convert_error(e: SignatureError) -> codec::Error { MuSigAbsent { musig_stage: Cosignature } => "Signature error: `MuSigAbsent` at stage `Commitment`".into(), MuSigInconsistent { musig_stage: Commitment, duplicate: true } => - "Signature error: `MuSigInconsistent` at strage `Commitment` on duplicate".into(), + "Signature error: `MuSigInconsistent` at stage `Commitment` on duplicate".into(), MuSigInconsistent { musig_stage: Commitment, duplicate: false } => - "Signature error: `MuSigInconsistent` at strage `Commitment` on not duplicate".into(), + "Signature error: `MuSigInconsistent` at stage `Commitment` on not duplicate".into(), MuSigInconsistent { musig_stage: Reveal, duplicate: true } => - "Signature error: `MuSigInconsistent` at strage `Reveal` on duplicate".into(), + "Signature error: `MuSigInconsistent` at stage `Reveal` on duplicate".into(), MuSigInconsistent { musig_stage: Reveal, duplicate: false } => - "Signature error: `MuSigInconsistent` at strage `Reveal` on not duplicate".into(), + "Signature error: `MuSigInconsistent` at stage `Reveal` on not duplicate".into(), MuSigInconsistent { musig_stage: Cosignature, duplicate: true } => - "Signature error: `MuSigInconsistent` at strage `Cosignature` on duplicate".into(), + "Signature error: `MuSigInconsistent` at stage `Cosignature` on duplicate".into(), MuSigInconsistent { musig_stage: Cosignature, duplicate: false } => - "Signature error: `MuSigInconsistent` at strage `Cosignature` on not duplicate".into(), + "Signature error: `MuSigInconsistent` at stage `Cosignature` on not duplicate".into(), } } diff --git a/core/consensus/babe/src/lib.rs b/core/consensus/babe/src/lib.rs index e61fb04062f2b..722c63bb9530e 100644 --- a/core/consensus/babe/src/lib.rs +++ b/core/consensus/babe/src/lib.rs @@ -837,7 +837,7 @@ fn claim_slot( let threshold = calculate_threshold(c, authorities, authority_index); get_keypair(key) - .vrf_sign_n_check(transcript, |inout| check(inout, threshold)) + .vrf_sign_after_check(transcript, |inout| check(inout, threshold)) .map(|s|(s, authority_index)) } diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index c927ddfeb61b2..49d5a0de3080f 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -19,10 +19,10 @@ hash256-std-hasher = { version = "0.15.0", default-features = false } ed25519-dalek = { version = "1.0.0-pre.1", optional = true } base58 = { version = "0.1", optional = true } blake2-rfc = { version = "0.2.18", optional = true } -schnorrkel = { version = "0.1.1", optional = true } +schnorrkel = { version = "0.8.4", features = ["preaudit_deprecated"], optional = true } rand = { version = "0.6", optional = true } sha2 = { version = "0.8", optional = true } -substrate-bip39 = { version = "0.2.2", optional = true } +substrate-bip39 = { version = "0.3.1", optional = true } tiny-bip39 = { version = "0.6.1", optional = true } hex = { version = "0.3", optional = true } regex = { version = "1.1", optional = true } diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index f87a0078effc0..b0c217c64fee7 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -22,7 +22,7 @@ // end::description[] #[cfg(feature = "std")] -use schnorrkel::{signing_context, Keypair, SecretKey, MiniSecretKey, PublicKey, +use schnorrkel::{signing_context, ExpansionMode, Keypair, SecretKey, MiniSecretKey, PublicKey, derive::{Derivation, ChainCode, CHAIN_CODE_LENGTH} }; #[cfg(feature = "std")] @@ -341,7 +341,7 @@ impl AsRef for Pair { #[cfg(feature = "std")] impl From for Pair { fn from(sec: MiniSecretKey) -> Pair { - Pair(sec.expand_to_keypair()) + Pair(sec.expand_to_keypair(ExpansionMode::Ed25519)) } } @@ -376,7 +376,7 @@ impl AsRef for Pair { /// Derive a single hard junction. #[cfg(feature = "std")] fn derive_hard_junction(secret: &SecretKey, cc: &[u8; CHAIN_CODE_LENGTH]) -> SecretKey { - secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0.expand() + secret.hard_derive_mini_secret_key(Some(ChainCode(cc.clone())), b"").0.expand(ExpansionMode::Ed25519) } /// The raw secret seed, which can be used to recreate the `Pair`. @@ -417,7 +417,7 @@ impl TraitPair for Pair { Ok(Pair( MiniSecretKey::from_bytes(seed) .map_err(|_| SecretStringError::InvalidSeed)? - .expand_to_keypair() + .expand_to_keypair(ExpansionMode::Ed25519) )) } SECRET_KEY_LENGTH => { @@ -476,28 +476,23 @@ impl TraitPair for Pair { /// Verify a signature on a message. Returns true if the signature is good. fn verify, M: AsRef<[u8]>>(sig: &Self::Signature, message: M, pubkey: P) -> bool { - let signature: schnorrkel::Signature = match schnorrkel::Signature::from_bytes(&sig.as_ref()) { - Ok(some_signature) => some_signature, - Err(_) => return false - }; + // Match both schnorrkel 0.1.1 and 0.8.0+ signatures, supporting both wallets + // that have not been upgraded and those that have. To swap to 0.8.0 only, + // create `schnorrkel::Signature` and pass that into `verify_simple` match PublicKey::from_bytes(pubkey.as_ref().as_slice()) { - Ok(pk) => pk.verify( - signing_context(SIGNING_CTX).bytes(message.as_ref()), &signature - ), + Ok(pk) => pk.verify_simple_preaudit_deprecated( + SIGNING_CTX, message.as_ref(), &sig.as_ref(), + ).is_ok(), Err(_) => false, } } /// Verify a signature on a message. Returns true if the signature is good. fn verify_weak, M: AsRef<[u8]>>(sig: &[u8], message: M, pubkey: P) -> bool { - let signature: schnorrkel::Signature = match schnorrkel::Signature::from_bytes(sig) { - Ok(some_signature) => some_signature, - Err(_) => return false - }; match PublicKey::from_bytes(pubkey.as_ref()) { - Ok(pk) => pk.verify( - signing_context(SIGNING_CTX).bytes(message.as_ref()), &signature - ), + Ok(pk) => pk.verify_simple_preaudit_deprecated( + SIGNING_CTX, message.as_ref(), &sig, + ).is_ok(), Err(_) => false, } } @@ -518,7 +513,7 @@ impl Pair { let mini_key: MiniSecretKey = mini_secret_from_entropy(entropy, password.unwrap_or("")) .expect("32 bytes can always build a key; qed"); - let kp = mini_key.expand_to_keypair(); + let kp = mini_key.expand_to_keypair(ExpansionMode::Ed25519); (Pair(kp), mini_key.to_bytes()) } } @@ -536,6 +531,43 @@ impl TypedKey for Pair { const KEY_TYPE: KeyTypeId = key_types::SR25519; } +#[cfg(test)] +mod compatibility_test { + use super::*; + use crate::crypto::{DEV_PHRASE}; + use hex_literal::hex; + + // NOTE: tests to ensure addresses that are created with the `0.1.x` version (pre-audit) are + // still functional. + + #[test] + fn derive_soft_known_pair_should_work() { + let pair = Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).unwrap(); + // known address of DEV_PHRASE with 1.1 + let known = hex!("d6c71059dbbe9ad2b0ed3f289738b800836eb425544ce694825285b958ca755e"); + assert_eq!(pair.public().to_raw_vec(), known); + } + + #[test] + fn derive_hard_known_pair_should_work() { + let pair = Pair::from_string(&format!("{}//Alice", DEV_PHRASE), None).unwrap(); + // known address of DEV_PHRASE with 1.1 + let known = hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"); + assert_eq!(pair.public().to_raw_vec(), known); + } + + #[test] + fn verify_known_message_should_work() { + let public = Public::from_raw(hex!("b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918")); + // signature generated by the 1.1 version with the same ^^ public key. + let signature = Signature::from_raw(hex!( + "5a9755f069939f45d96aaf125cf5ce7ba1db998686f87f2fb3cbdea922078741a73891ba265f70c31436e18a9acd14d189d73c12317ab6c313285cd938453202" + )); + let message = b"Verifying that I am the owner of 5G9hQLdsKQswNPgB499DeA5PkFBbgkLPJWkkS6FAM6xGQ8xD. Hash: 221455a3\n"; + assert!(Pair::verify(&signature, &message[..], &public)); + } +} + #[cfg(test)] mod test { use super::*; @@ -646,7 +678,6 @@ mod test { #[test] fn seeded_pair_should_work() { - let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); assert_eq!( @@ -679,9 +710,9 @@ mod test { &hex!("0000000000000000000000000000000000000000000000000000000000000000") ); let public = pk.public(); - let js_signature = Signature::from_raw( - hex!("28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00") - ); + let js_signature = Signature::from_raw(hex!( + "28a854d54903e056f89581c691c1f7d2ff39f8f896c9e9c22475e60902cc2b3547199e0e91fa32902028f2ca2355e8cdd16cfe19ba5e8b658c94aa80f3b81a00" + )); assert!(Pair::verify(&js_signature, b"SUBSTRATE", public)); } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index f89e1f4a862ec..c2c52529692b8 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -79,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 129, + spec_version: 130, impl_version: 130, apis: RUNTIME_API_VERSIONS, }; diff --git a/subkey/Cargo.toml b/subkey/Cargo.toml index da97ace38edd4..9e7112a029c20 100644 --- a/subkey/Cargo.toml +++ b/subkey/Cargo.toml @@ -13,8 +13,7 @@ rand = "0.6" clap = { version = "~2.32", features = ["yaml"] } tiny-bip39 = "0.6.0" rustc-hex = "2.0" -substrate-bip39 = "0.2.2" -schnorrkel = "0.1.1" +substrate-bip39 = "0.3.1" hex = "0.3" hex-literal = "0.2" codec = { package = "parity-scale-codec", version = "1.0.0" }