Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Update to schnorrkel 0.8.0 (#3267)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* 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.
  • Loading branch information
bkchr authored and folsen committed Aug 7, 2019
1 parent 25f68b3 commit e2d9619
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 51 deletions.
25 changes: 11 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/consensus/babe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
2 changes: 1 addition & 1 deletion core/consensus/babe/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
13 changes: 7 additions & 6 deletions core/consensus/babe/primitives/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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(),
}
}
2 changes: 1 addition & 1 deletion core/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
4 changes: 2 additions & 2 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
77 changes: 54 additions & 23 deletions core/primitives/src/sr25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -341,7 +341,7 @@ impl AsRef<Pair> for Pair {
#[cfg(feature = "std")]
impl From<MiniSecretKey> for Pair {
fn from(sec: MiniSecretKey) -> Pair {
Pair(sec.expand_to_keypair())
Pair(sec.expand_to_keypair(ExpansionMode::Ed25519))
}
}

Expand Down Expand Up @@ -376,7 +376,7 @@ impl AsRef<schnorrkel::Keypair> 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`.
Expand Down Expand Up @@ -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 => {
Expand Down Expand Up @@ -476,28 +476,23 @@ impl TraitPair for Pair {

/// Verify a signature on a message. Returns true if the signature is good.
fn verify<P: AsRef<Self::Public>, 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<P: AsRef<[u8]>, 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,
}
}
Expand All @@ -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())
}
}
Expand All @@ -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::*;
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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));
}
}
2 changes: 1 addition & 1 deletion node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
3 changes: 1 addition & 2 deletions subkey/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down

0 comments on commit e2d9619

Please sign in to comment.