From 226382691a87e68f9791a559caf19a3306f322c2 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 6 Feb 2019 14:54:05 +0100 Subject: [PATCH 1/6] first draft of ristretto crypto module #1685 --- core/primitives/Cargo.toml | 3 + core/primitives/src/lib.rs | 5 + core/primitives/src/sr25519.rs | 351 +++++++++++++++++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100644 core/primitives/src/sr25519.rs diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index d3f1a59172732..4295c7f43579c 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -22,6 +22,9 @@ untrusted = { version = "0.6", optional = true } hex-literal = { version = "0.1", optional = true } base58 = { version = "0.1", optional = true } blake2-rfc = { version = "0.2.18", optional = true } +schnorrkel = { git = "https://github.com/w3f/schnorrkel.git", optional = false } +rand = { version = "0.6.5", optional = false } +sha2 = { version = "0.8.0", optional = false } [dev-dependencies] substrate-serializer = { path = "../serializer" } diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 9b3d4e193b9ef..7d0f55d853fd6 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -71,6 +71,10 @@ extern crate heapsize; #[macro_use] extern crate pretty_assertions; +extern crate rand; +extern crate sha2; +extern crate schnorrkel; + #[macro_export] macro_rules! map { ($( $name:expr => $value:expr ),*) => ( @@ -94,6 +98,7 @@ pub use hashing::{blake2_256, twox_128, twox_256}; pub mod hexdisplay; #[cfg(feature = "std")] pub mod ed25519; +pub mod sr25519; pub mod u32_trait; diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs new file mode 100644 index 0000000000000..0c9c531f80e13 --- /dev/null +++ b/core/primitives/src/sr25519.rs @@ -0,0 +1,351 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! Simple sr25519 (Schnorr-Ristretto) API. +// end::description[] + +use base58::{FromBase58, ToBase58}; +use blake2_rfc; +use rand::rngs::OsRng; +use schnorrkel::{signing_context, Keypair, MiniSecretKey, PublicKey}; +use sha2::Sha512; + +#[cfg(feature = "std")] +use serde::{de, Deserialize, Deserializer, Serializer}; + +// signing context +const SIGNING_CTX: &'static [u8] = b"polkadot transaction"; + +/// Instead of importing it for the local module, alias it to be available as a public type +pub type Signature = schnorrkel::Signature; + +/// A localized signature also contains sender information. +/// TODO: Encode and Decode traits are supported in ed25519 but not possible for now here. +#[derive(PartialEq, Eq, Clone, Debug)] +pub struct LocalizedSignature { + /// The signer of the signature. + pub signer: Public, + /// The signature itself. + pub signature: Signature, +} + +/// A public key. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +pub struct Public(pub [u8; 32]); + +/// A schnorrkel key pair. +pub struct Pair(Keypair); + +impl ::std::hash::Hash for Public { + fn hash(&self, state: &mut H) { + self.0.hash(state); + } +} + +/// An error type for SS58 decoding. +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum PublicError { + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, +} + +impl Public { + /// A new instance from the given 32-byte `data`. + pub fn from_raw(data: [u8; 32]) -> Self { + Public(data) + } + + /// A new instance from the given slice that should be 32 bytes long. + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(data); + Public(r) + } + + /// Some if the string is a properly encoded SS58Check address. + pub fn from_ss58check(s: &str) -> Result { + let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. + if d.len() != 35 { + // Invalid length. + return Err(PublicError::BadLength); + } + if d[0] != 42 { + // Invalid version. + return Err(PublicError::UnknownVersion); + } + if d[33..35] != blake2_rfc::blake2b::blake2b(64, &[], &d[0..33]).as_bytes()[0..2] { + // Invalid checksum. + return Err(PublicError::InvalidChecksum); + } + Ok(Self::from_slice(&d[1..33])) + } + + /// Return a `Vec` filled with raw data. + pub fn to_raw_vec(self) -> Vec { + let r: &[u8; 32] = self.as_ref(); + r.to_vec() + } + + // convert the public key byte array to a schnorrkel type + pub fn to_schnorrkel_pubkey(&self) -> PublicKey { + PublicKey::from_bytes(self.as_ref()).expect("32 byte array is always a pubkey; qed") + } + + /// Return a slice filled with raw data. + pub fn as_slice(&self) -> &[u8] { + let r: &[u8; 32] = self.as_ref(); + &r[..] + } + + /// Return a slice filled with raw data. + pub fn as_array_ref(&self) -> &[u8; 32] { + self.as_ref() + } + + /// Return the ss58-check string for this key. + pub fn to_ss58check(&self) -> String { + let mut v = vec![42u8]; + v.extend(self.as_slice()); + let r = blake2_rfc::blake2b::blake2b(64, &[], &v); + v.extend(&r.as_bytes()[0..2]); + v.to_base58() + } +} + +impl AsRef<[u8; 32]> for Public { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } +} + +impl AsRef<[u8]> for Public { + fn as_ref(&self) -> &[u8] { + &self.0[..] + } +} + +impl Into<[u8; 32]> for Public { + fn into(self) -> [u8; 32] { + self.0 + } +} + +impl AsRef for Public { + fn as_ref(&self) -> &Public { + &self + } +} + +impl AsRef for Pair { + fn as_ref(&self) -> &Pair { + &self + } +} + +impl ::std::fmt::Display for Public { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } +} + +impl ::std::fmt::Debug for Public { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + let s = self.to_ss58check(); + write!( + f, + "{} ({}...)", + ::hexdisplay::HexDisplay::from(&self.0), + &s[0..8] + ) + } +} + +impl Pair { + /// Generate new secure (random) key pair. + pub fn generate() -> Pair { + let mut csprng: OsRng = OsRng::new().expect("os random generator works; qed"); + let keypair: Keypair = Keypair::generate(&mut csprng); + Pair(keypair) + } + + /// Make a new key pair from a seed phrase. + /// This is generated using schnorrkel's Mini-Secret-Keys. + /// A MiniSecretKey is lieterally what Ed25519 calls a SecreyKey, which is just 32 random bytes. + pub fn from_seed(seed: &[u8; 32]) -> Pair { + let mini_key: MiniSecretKey = MiniSecretKey::from_bytes(seed).unwrap(); + let kp = mini_key.expand_to_keypair::(); + Pair(kp) + } + + /// Sign a message. + pub fn sign(&self, message: &[u8]) -> Signature { + let context = signing_context(SIGNING_CTX); + self.0.sign(context.bytes(message)) + } + + /// Get the public key. + pub fn public(&self) -> Public { + let mut pk = [0u8; 32]; + pk.copy_from_slice(&self.0.public.to_bytes()); + Public(pk) + } +} + +/// Verify a signature on a message. Returns true if the signature is good. +/// NOTE: this is technically checking a (signature, message) against a pubkey, I think +/// hence `Verifiable` trait should be implemented for `Public`, not `Signature`. +/// FIXME: should we still use `untrusted` crate here? +pub fn verify_strong>(sig: &Signature, message: &[u8], pubkey: P) -> bool { + match PublicKey::from_bytes(pubkey.as_ref().as_slice()) { + Ok(pk) => pk.verify(signing_context(SIGNING_CTX).bytes(message), sig), + Err(_) => false, + } +} + +/// Verify a message without type checking the parameters' types for the right size. +/// Returns true if both the pubkey and the signature is good. +/// TODO: clean this and probably use some helper function / traits to make the conversion easier. +pub fn verify>(sig: &[u8], message: &[u8], pubkey: P) -> bool { + let signature = match Signature::from_bytes(sig) { + Ok(sig) => sig, + Err(_) => return false, + }; + match PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pk) => pk.verify_simple(SIGNING_CTX, message, &signature), + Err(_) => false, + } +} + +/// Something that acts as a signature allowing a message to be verified. +pub trait Verifiable { + /// Verify something that acts like a signature. + fn verify>(&self, message: &[u8], pubkey: P) -> bool; +} + +impl Verifiable for Signature { + /// Verify something that acts like a signature. + fn verify>(&self, message: &[u8], pubkey: P) -> bool { + verify_strong(&self, message, pubkey) + } +} + +impl Verifiable for LocalizedSignature { + fn verify>(&self, message: &[u8], pubkey: P) -> bool { + pubkey.as_ref() == &self.signer && self.signature.verify(message, pubkey) + } +} + +/// Deserialize from `ss58` into something that can be constructed from `[u8; 32]`. +#[cfg(feature = "std")] +pub fn deserialize<'de, D, T: From<[u8; 32]>>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let ss58 = String::deserialize(deserializer)?; + Public::from_ss58check(&ss58) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + .map(|v| v.0.into()) +} + +/// Serializes something that implements `AsRef<[u8; 32]>` into `ss58`. +#[cfg(feature = "std")] +pub fn serialize>(data: &T, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_str(&Public(*data.as_ref()).to_ss58check()) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn sr_test_vector_should_work() { + let pair: Pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let public = pair.public(); + assert_eq!( + public, + Public::from_raw(hex!( + "44a996beb1eef7bdcab976ab6d2ca26104834164ecf28fb375600576fcc6eb0f" + )) + ); + let message = b""; + let signature: Signature = Signature::from_bytes(&hex!("d46f56ab56414eb14daaece2bd7dd421b6a9d6bef7d9259fc154696076423f48756c42b7db942ebe8e5d9c36d5a607ee3919e7a8847fa9dc66674630f2b46d04")).unwrap(); + assert!(verify(&signature.to_bytes(), message, &public.0)); + assert!(verify_strong(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let pair = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(verify_strong(&signature, &message[..], &public)); + } + + #[test] + fn seeded_pair_should_work() { + use hexdisplay::HexDisplay; + + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!( + public, + Public::from_raw(hex!( + "741c08a06f41c596608f6774259bd9043304adfa5d3eea62760bd9be97634d63" + )) + ); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + assert!(verify_strong(&signature, &message[..], &public)); + } + + // #[test] + // fn generate_with_pkcs8_recovery_possible() { + // let (pair1, pkcs8) = Pair::generate_with_pkcs8(); + // let pair2 = Pair::from_pkcs8(&pkcs8).unwrap(); + + // assert_eq!(pair1.public(), pair2.public()); + // } + + #[test] + fn ss58check_roundtrip_works() { + let pair = Pair::generate(); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } + + #[test] + fn ss58check_known_works() { + let k = "5CGavy93sZgPPjHyziRohwVumxiHXMGmQLyuqQP4ZFx5vRU9"; + let enc = hex!["090fa15cb5b1666222fff584b4cc2b1761fe1e238346b340491b37e25ea183ff"]; + assert_eq!(Public::from_ss58check(k).unwrap(), Public::from_raw(enc)); + } +} From 1894c0848b5aacefdae97832f4a4fbf9dfc37080 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 6 Feb 2019 15:22:25 +0100 Subject: [PATCH 2/6] adds better comments and code-style --- core/primitives/src/sr25519.rs | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index 0c9c531f80e13..76f7cde6160e5 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -34,7 +34,7 @@ const SIGNING_CTX: &'static [u8] = b"polkadot transaction"; pub type Signature = schnorrkel::Signature; /// A localized signature also contains sender information. -/// TODO: Encode and Decode traits are supported in ed25519 but not possible for now here. +/// NOTE: Encode and Decode traits are supported in ed25519 but not possible for now here. #[derive(PartialEq, Eq, Clone, Debug)] pub struct LocalizedSignature { /// The signer of the signature. @@ -106,11 +106,6 @@ impl Public { r.to_vec() } - // convert the public key byte array to a schnorrkel type - pub fn to_schnorrkel_pubkey(&self) -> PublicKey { - PublicKey::from_bytes(self.as_ref()).expect("32 byte array is always a pubkey; qed") - } - /// Return a slice filled with raw data. pub fn as_slice(&self) -> &[u8] { let r: &[u8; 32] = self.as_ref(); @@ -171,12 +166,7 @@ impl ::std::fmt::Display for Public { impl ::std::fmt::Debug for Public { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { let s = self.to_ss58check(); - write!( - f, - "{} ({}...)", - ::hexdisplay::HexDisplay::from(&self.0), - &s[0..8] - ) + write!(f, "{} ({}...)", ::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) } } @@ -212,9 +202,7 @@ impl Pair { } /// Verify a signature on a message. Returns true if the signature is good. -/// NOTE: this is technically checking a (signature, message) against a pubkey, I think -/// hence `Verifiable` trait should be implemented for `Public`, not `Signature`. -/// FIXME: should we still use `untrusted` crate here? +/// FIXME: use `untrusted` crate here? pub fn verify_strong>(sig: &Signature, message: &[u8], pubkey: P) -> bool { match PublicKey::from_bytes(pubkey.as_ref().as_slice()) { Ok(pk) => pk.verify(signing_context(SIGNING_CTX).bytes(message), sig), @@ -224,7 +212,6 @@ pub fn verify_strong>(sig: &Signature, message: &[u8], pubkey: /// Verify a message without type checking the parameters' types for the right size. /// Returns true if both the pubkey and the signature is good. -/// TODO: clean this and probably use some helper function / traits to make the conversion easier. pub fn verify>(sig: &[u8], message: &[u8], pubkey: P) -> bool { let signature = match Signature::from_bytes(sig) { Ok(sig) => sig, @@ -309,7 +296,6 @@ mod test { #[test] fn seeded_pair_should_work() { - use hexdisplay::HexDisplay; let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); @@ -324,14 +310,6 @@ mod test { assert!(verify_strong(&signature, &message[..], &public)); } - // #[test] - // fn generate_with_pkcs8_recovery_possible() { - // let (pair1, pkcs8) = Pair::generate_with_pkcs8(); - // let pair2 = Pair::from_pkcs8(&pkcs8).unwrap(); - - // assert_eq!(pair1.public(), pair2.public()); - // } - #[test] fn ss58check_roundtrip_works() { let pair = Pair::generate(); From 80895ca2ba6fbeefa4f588a28875a834a21bc0a8 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 6 Feb 2019 16:07:17 +0100 Subject: [PATCH 3/6] remove the last evil unwrap --- core/primitives/src/sr25519.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index 76f7cde6160e5..f4d67172f5719 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -182,7 +182,8 @@ impl Pair { /// This is generated using schnorrkel's Mini-Secret-Keys. /// A MiniSecretKey is lieterally what Ed25519 calls a SecreyKey, which is just 32 random bytes. pub fn from_seed(seed: &[u8; 32]) -> Pair { - let mini_key: MiniSecretKey = MiniSecretKey::from_bytes(seed).unwrap(); + let mini_key: MiniSecretKey = MiniSecretKey::from_bytes(seed) + .expect("32 bytes can always build a key; qed"); let kp = mini_key.expand_to_keypair::(); Pair(kp) } From a9bc9f1355605be62272e314b77ffe2d2b3b5258 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 6 Feb 2019 17:48:22 +0100 Subject: [PATCH 4/6] remove a mistakenly committed lockfile --- core/primitives/Cargo.toml | 9 +- core/primitives/src/lib.rs | 4 + core/primitives/src/sr25519.rs | 418 ++++++++++++++++----------------- 3 files changed, 219 insertions(+), 212 deletions(-) diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 4295c7f43579c..9bc3fa7157c30 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -22,9 +22,9 @@ untrusted = { version = "0.6", optional = true } hex-literal = { version = "0.1", optional = true } base58 = { version = "0.1", optional = true } blake2-rfc = { version = "0.2.18", optional = true } -schnorrkel = { git = "https://github.com/w3f/schnorrkel.git", optional = false } -rand = { version = "0.6.5", optional = false } -sha2 = { version = "0.8.0", optional = false } +schnorrkel = { git = "https://github.com/w3f/schnorrkel.git", optional = true } +rand = { version = "0.6", optional = true } +sha2 = { version = "0.8", optional = true } [dev-dependencies] substrate-serializer = { path = "../serializer" } @@ -56,4 +56,7 @@ std = [ "base58", "serde_derive", "byteorder/std", + "rand", + "sha2", + "schnorrkel", ] diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index 7d0f55d853fd6..3335dd491245c 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -71,8 +71,11 @@ extern crate heapsize; #[macro_use] extern crate pretty_assertions; +#[cfg(feature = "std")] extern crate rand; +#[cfg(feature = "std")] extern crate sha2; +#[cfg(feature = "std")] extern crate schnorrkel; #[macro_export] @@ -98,6 +101,7 @@ pub use hashing::{blake2_256, twox_128, twox_256}; pub mod hexdisplay; #[cfg(feature = "std")] pub mod ed25519; +#[cfg(feature = "std")] pub mod sr25519; pub mod u32_trait; diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index f4d67172f5719..1dff31a066d1b 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -37,10 +37,10 @@ pub type Signature = schnorrkel::Signature; /// NOTE: Encode and Decode traits are supported in ed25519 but not possible for now here. #[derive(PartialEq, Eq, Clone, Debug)] pub struct LocalizedSignature { - /// The signer of the signature. - pub signer: Public, - /// The signature itself. - pub signature: Signature, + /// The signer of the signature. + pub signer: Public, + /// The signature itself. + pub signature: Signature, } /// A public key. @@ -51,280 +51,280 @@ pub struct Public(pub [u8; 32]); pub struct Pair(Keypair); impl ::std::hash::Hash for Public { - fn hash(&self, state: &mut H) { - self.0.hash(state); - } + fn hash(&self, state: &mut H) { + self.0.hash(state); + } } /// An error type for SS58 decoding. #[derive(Clone, Copy, Eq, PartialEq, Debug)] pub enum PublicError { - /// Bad alphabet. - BadBase58, - /// Bad length. - BadLength, - /// Unknown version. - UnknownVersion, - /// Invalid checksum. - InvalidChecksum, + /// Bad alphabet. + BadBase58, + /// Bad length. + BadLength, + /// Unknown version. + UnknownVersion, + /// Invalid checksum. + InvalidChecksum, } impl Public { - /// A new instance from the given 32-byte `data`. - pub fn from_raw(data: [u8; 32]) -> Self { - Public(data) - } - - /// A new instance from the given slice that should be 32 bytes long. - pub fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(data); - Public(r) - } - - /// Some if the string is a properly encoded SS58Check address. - pub fn from_ss58check(s: &str) -> Result { - let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. - if d.len() != 35 { - // Invalid length. - return Err(PublicError::BadLength); - } - if d[0] != 42 { - // Invalid version. - return Err(PublicError::UnknownVersion); - } - if d[33..35] != blake2_rfc::blake2b::blake2b(64, &[], &d[0..33]).as_bytes()[0..2] { - // Invalid checksum. - return Err(PublicError::InvalidChecksum); - } - Ok(Self::from_slice(&d[1..33])) - } - - /// Return a `Vec` filled with raw data. - pub fn to_raw_vec(self) -> Vec { - let r: &[u8; 32] = self.as_ref(); - r.to_vec() - } - - /// Return a slice filled with raw data. - pub fn as_slice(&self) -> &[u8] { - let r: &[u8; 32] = self.as_ref(); - &r[..] - } - - /// Return a slice filled with raw data. - pub fn as_array_ref(&self) -> &[u8; 32] { - self.as_ref() - } - - /// Return the ss58-check string for this key. - pub fn to_ss58check(&self) -> String { - let mut v = vec![42u8]; - v.extend(self.as_slice()); - let r = blake2_rfc::blake2b::blake2b(64, &[], &v); - v.extend(&r.as_bytes()[0..2]); - v.to_base58() - } + /// A new instance from the given 32-byte `data`. + pub fn from_raw(data: [u8; 32]) -> Self { + Public(data) + } + + /// A new instance from the given slice that should be 32 bytes long. + pub fn from_slice(data: &[u8]) -> Self { + let mut r = [0u8; 32]; + r.copy_from_slice(data); + Public(r) + } + + /// Some if the string is a properly encoded SS58Check address. + pub fn from_ss58check(s: &str) -> Result { + let d = s.from_base58().map_err(|_| PublicError::BadBase58)?; // failure here would be invalid encoding. + if d.len() != 35 { + // Invalid length. + return Err(PublicError::BadLength); + } + if d[0] != 42 { + // Invalid version. + return Err(PublicError::UnknownVersion); + } + if d[33..35] != blake2_rfc::blake2b::blake2b(64, &[], &d[0..33]).as_bytes()[0..2] { + // Invalid checksum. + return Err(PublicError::InvalidChecksum); + } + Ok(Self::from_slice(&d[1..33])) + } + + /// Return a `Vec` filled with raw data. + pub fn to_raw_vec(self) -> Vec { + let r: &[u8; 32] = self.as_ref(); + r.to_vec() + } + + /// Return a slice filled with raw data. + pub fn as_slice(&self) -> &[u8] { + let r: &[u8; 32] = self.as_ref(); + &r[..] + } + + /// Return a slice filled with raw data. + pub fn as_array_ref(&self) -> &[u8; 32] { + self.as_ref() + } + + /// Return the ss58-check string for this key. + pub fn to_ss58check(&self) -> String { + let mut v = vec![42u8]; + v.extend(self.as_slice()); + let r = blake2_rfc::blake2b::blake2b(64, &[], &v); + v.extend(&r.as_bytes()[0..2]); + v.to_base58() + } } impl AsRef<[u8; 32]> for Public { - fn as_ref(&self) -> &[u8; 32] { - &self.0 - } + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } } impl AsRef<[u8]> for Public { - fn as_ref(&self) -> &[u8] { - &self.0[..] - } + fn as_ref(&self) -> &[u8] { + &self.0[..] + } } impl Into<[u8; 32]> for Public { - fn into(self) -> [u8; 32] { - self.0 - } + fn into(self) -> [u8; 32] { + self.0 + } } impl AsRef for Public { - fn as_ref(&self) -> &Public { - &self - } + fn as_ref(&self) -> &Public { + &self + } } impl AsRef for Pair { - fn as_ref(&self) -> &Pair { - &self - } + fn as_ref(&self) -> &Pair { + &self + } } impl ::std::fmt::Display for Public { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(f, "{}", self.to_ss58check()) - } + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.to_ss58check()) + } } impl ::std::fmt::Debug for Public { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - let s = self.to_ss58check(); - write!(f, "{} ({}...)", ::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) - } + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + let s = self.to_ss58check(); + write!(f, "{} ({}...)", ::hexdisplay::HexDisplay::from(&self.0), &s[0..8]) + } } impl Pair { - /// Generate new secure (random) key pair. - pub fn generate() -> Pair { - let mut csprng: OsRng = OsRng::new().expect("os random generator works; qed"); - let keypair: Keypair = Keypair::generate(&mut csprng); - Pair(keypair) - } - - /// Make a new key pair from a seed phrase. - /// This is generated using schnorrkel's Mini-Secret-Keys. - /// A MiniSecretKey is lieterally what Ed25519 calls a SecreyKey, which is just 32 random bytes. - pub fn from_seed(seed: &[u8; 32]) -> Pair { - let mini_key: MiniSecretKey = MiniSecretKey::from_bytes(seed) + /// Generate new secure (random) key pair. + pub fn generate() -> Pair { + let mut csprng: OsRng = OsRng::new().expect("os random generator works; qed"); + let keypair: Keypair = Keypair::generate(&mut csprng); + Pair(keypair) + } + + /// Make a new key pair from a seed phrase. + /// This is generated using schnorrkel's Mini-Secret-Keys. + /// A MiniSecretKey is lieterally what Ed25519 calls a SecreyKey, which is just 32 random bytes. + pub fn from_seed(seed: &[u8; 32]) -> Pair { + let mini_key: MiniSecretKey = MiniSecretKey::from_bytes(seed) .expect("32 bytes can always build a key; qed"); - let kp = mini_key.expand_to_keypair::(); - Pair(kp) - } - - /// Sign a message. - pub fn sign(&self, message: &[u8]) -> Signature { - let context = signing_context(SIGNING_CTX); - self.0.sign(context.bytes(message)) - } - - /// Get the public key. - pub fn public(&self) -> Public { - let mut pk = [0u8; 32]; - pk.copy_from_slice(&self.0.public.to_bytes()); - Public(pk) - } + let kp = mini_key.expand_to_keypair::(); + Pair(kp) + } + + /// Sign a message. + pub fn sign(&self, message: &[u8]) -> Signature { + let context = signing_context(SIGNING_CTX); + self.0.sign(context.bytes(message)) + } + + /// Get the public key. + pub fn public(&self) -> Public { + let mut pk = [0u8; 32]; + pk.copy_from_slice(&self.0.public.to_bytes()); + Public(pk) + } } /// Verify a signature on a message. Returns true if the signature is good. /// FIXME: use `untrusted` crate here? pub fn verify_strong>(sig: &Signature, message: &[u8], pubkey: P) -> bool { - match PublicKey::from_bytes(pubkey.as_ref().as_slice()) { - Ok(pk) => pk.verify(signing_context(SIGNING_CTX).bytes(message), sig), - Err(_) => false, - } + match PublicKey::from_bytes(pubkey.as_ref().as_slice()) { + Ok(pk) => pk.verify(signing_context(SIGNING_CTX).bytes(message), sig), + Err(_) => false, + } } /// Verify a message without type checking the parameters' types for the right size. /// Returns true if both the pubkey and the signature is good. pub fn verify>(sig: &[u8], message: &[u8], pubkey: P) -> bool { - let signature = match Signature::from_bytes(sig) { - Ok(sig) => sig, - Err(_) => return false, - }; - match PublicKey::from_bytes(pubkey.as_ref()) { - Ok(pk) => pk.verify_simple(SIGNING_CTX, message, &signature), - Err(_) => false, - } + let signature = match Signature::from_bytes(sig) { + Ok(sig) => sig, + Err(_) => return false, + }; + match PublicKey::from_bytes(pubkey.as_ref()) { + Ok(pk) => pk.verify_simple(SIGNING_CTX, message, &signature), + Err(_) => false, + } } /// Something that acts as a signature allowing a message to be verified. pub trait Verifiable { - /// Verify something that acts like a signature. - fn verify>(&self, message: &[u8], pubkey: P) -> bool; + /// Verify something that acts like a signature. + fn verify>(&self, message: &[u8], pubkey: P) -> bool; } impl Verifiable for Signature { - /// Verify something that acts like a signature. - fn verify>(&self, message: &[u8], pubkey: P) -> bool { - verify_strong(&self, message, pubkey) - } + /// Verify something that acts like a signature. + fn verify>(&self, message: &[u8], pubkey: P) -> bool { + verify_strong(&self, message, pubkey) + } } impl Verifiable for LocalizedSignature { - fn verify>(&self, message: &[u8], pubkey: P) -> bool { - pubkey.as_ref() == &self.signer && self.signature.verify(message, pubkey) - } + fn verify>(&self, message: &[u8], pubkey: P) -> bool { + pubkey.as_ref() == &self.signer && self.signature.verify(message, pubkey) + } } /// Deserialize from `ss58` into something that can be constructed from `[u8; 32]`. #[cfg(feature = "std")] pub fn deserialize<'de, D, T: From<[u8; 32]>>(deserializer: D) -> Result where - D: Deserializer<'de>, + D: Deserializer<'de>, { - let ss58 = String::deserialize(deserializer)?; - Public::from_ss58check(&ss58) - .map_err(|e| de::Error::custom(format!("{:?}", e))) - .map(|v| v.0.into()) + let ss58 = String::deserialize(deserializer)?; + Public::from_ss58check(&ss58) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + .map(|v| v.0.into()) } /// Serializes something that implements `AsRef<[u8; 32]>` into `ss58`. #[cfg(feature = "std")] pub fn serialize>(data: &T, serializer: S) -> Result where - S: Serializer, + S: Serializer, { - serializer.serialize_str(&Public(*data.as_ref()).to_ss58check()) + serializer.serialize_str(&Public(*data.as_ref()).to_ss58check()) } #[cfg(test)] mod test { - use super::*; - - #[test] - fn sr_test_vector_should_work() { - let pair: Pair = Pair::from_seed(&hex!( - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" - )); - let public = pair.public(); - assert_eq!( - public, - Public::from_raw(hex!( - "44a996beb1eef7bdcab976ab6d2ca26104834164ecf28fb375600576fcc6eb0f" - )) - ); - let message = b""; - let signature: Signature = Signature::from_bytes(&hex!("d46f56ab56414eb14daaece2bd7dd421b6a9d6bef7d9259fc154696076423f48756c42b7db942ebe8e5d9c36d5a607ee3919e7a8847fa9dc66674630f2b46d04")).unwrap(); - assert!(verify(&signature.to_bytes(), message, &public.0)); - assert!(verify_strong(&signature, &message[..], &public)); - } - - #[test] - fn generated_pair_should_work() { - let pair = Pair::generate(); - let public = pair.public(); - let message = b"Something important"; - let signature = pair.sign(&message[..]); - assert!(verify_strong(&signature, &message[..], &public)); - } - - #[test] - fn seeded_pair_should_work() { - - let pair = Pair::from_seed(b"12345678901234567890123456789012"); - let public = pair.public(); - assert_eq!( - public, - Public::from_raw(hex!( - "741c08a06f41c596608f6774259bd9043304adfa5d3eea62760bd9be97634d63" - )) - ); - let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); - let signature = pair.sign(&message[..]); - assert!(verify_strong(&signature, &message[..], &public)); - } - - #[test] - fn ss58check_roundtrip_works() { - let pair = Pair::generate(); - let public = pair.public(); - let s = public.to_ss58check(); - println!("Correct: {}", s); - let cmp = Public::from_ss58check(&s).unwrap(); - assert_eq!(cmp, public); - } - - #[test] - fn ss58check_known_works() { - let k = "5CGavy93sZgPPjHyziRohwVumxiHXMGmQLyuqQP4ZFx5vRU9"; - let enc = hex!["090fa15cb5b1666222fff584b4cc2b1761fe1e238346b340491b37e25ea183ff"]; - assert_eq!(Public::from_ss58check(k).unwrap(), Public::from_raw(enc)); - } + use super::*; + + #[test] + fn sr_test_vector_should_work() { + let pair: Pair = Pair::from_seed(&hex!( + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60" + )); + let public = pair.public(); + assert_eq!( + public, + Public::from_raw(hex!( + "44a996beb1eef7bdcab976ab6d2ca26104834164ecf28fb375600576fcc6eb0f" + )) + ); + let message = b""; + let signature: Signature = Signature::from_bytes(&hex!("d46f56ab56414eb14daaece2bd7dd421b6a9d6bef7d9259fc154696076423f48756c42b7db942ebe8e5d9c36d5a607ee3919e7a8847fa9dc66674630f2b46d04")).unwrap(); + assert!(verify(&signature.to_bytes(), message, &public.0)); + assert!(verify_strong(&signature, &message[..], &public)); + } + + #[test] + fn generated_pair_should_work() { + let pair = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(verify_strong(&signature, &message[..], &public)); + } + + #[test] + fn seeded_pair_should_work() { + + let pair = Pair::from_seed(b"12345678901234567890123456789012"); + let public = pair.public(); + assert_eq!( + public, + Public::from_raw(hex!( + "741c08a06f41c596608f6774259bd9043304adfa5d3eea62760bd9be97634d63" + )) + ); + let message = hex!("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000200d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000"); + let signature = pair.sign(&message[..]); + assert!(verify_strong(&signature, &message[..], &public)); + } + + #[test] + fn ss58check_roundtrip_works() { + let pair = Pair::generate(); + let public = pair.public(); + let s = public.to_ss58check(); + println!("Correct: {}", s); + let cmp = Public::from_ss58check(&s).unwrap(); + assert_eq!(cmp, public); + } + + #[test] + fn ss58check_known_works() { + let k = "5CGavy93sZgPPjHyziRohwVumxiHXMGmQLyuqQP4ZFx5vRU9"; + let enc = hex!["090fa15cb5b1666222fff584b4cc2b1761fe1e238346b340491b37e25ea183ff"]; + assert_eq!(Public::from_ss58check(k).unwrap(), Public::from_raw(enc)); + } } From 6d48551e53f95525beffdb4b5221fcdc8e92ebe0 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 6 Feb 2019 18:36:48 +0100 Subject: [PATCH 5/6] add a fresh new lockfile --will probably need a manual merge later --- Cargo.lock | 91 ++++++++++++++++++++++++++++++++++ core/primitives/src/sr25519.rs | 2 +- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index e845b1c8ac46f..a1cc71df7c16c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -626,6 +626,30 @@ dependencies = [ "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "curve25519-dalek" +version = "1.0.3" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek#4bdccd7b7c394d9f8ffc4b29d5acc23c972f3d7a" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curve25519-dalek" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "data-encoding" version = "2.1.2" @@ -687,6 +711,18 @@ dependencies = [ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ed25519-dalek" +version = "1.0.0-pre.1" +source = "git+https://github.com/dalek-cryptography/ed25519-dalek?branch=develop#ebd9ad6a6ef232860a9a68d8dc7a9796eb9719f3" +dependencies = [ + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "either" version = "1.5.0" @@ -1206,6 +1242,11 @@ dependencies = [ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "keccak-hasher" version = "0.2.1" @@ -1715,6 +1756,18 @@ name = "memory_units" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "merlin" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mime" version = "0.2.6" @@ -2663,6 +2716,22 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "schnorrkel" +version = "0.0.1" +source = "git+https://github.com/w3f/schnorrkel.git#b16dbbc96c9a6a96f63b3b196a2b7900f92d1889" +dependencies = [ + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.0.3 (git+https://github.com/dalek-cryptography/curve25519-dalek)", + "ed25519-dalek 1.0.0-pre.1 (git+https://github.com/dalek-cryptography/ed25519-dalek?branch=develop)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "merlin 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha3 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scoped-tls" version = "0.1.2" @@ -2780,6 +2849,18 @@ dependencies = [ "opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha3" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "shell32-sys" version = "0.1.2" @@ -3809,10 +3890,13 @@ dependencies = [ "parity-codec-derive 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.13.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.0.1 (git+https://github.com/w3f/schnorrkel.git)", "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", "substrate-serializer 0.1.0", "twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4856,6 +4940,8 @@ dependencies = [ "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e" "checksum cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" "checksum curve25519-dalek 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eacf6ff1b911e3170a8c400b402e10c86dc3cb166bd69034ebbc2b785fea4c2" +"checksum curve25519-dalek 1.0.3 (git+https://github.com/dalek-cryptography/curve25519-dalek)" = "" +"checksum curve25519-dalek 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dae47cc3529cdab597dbc8b606e565707209b506e55848f3c15679214a56c956" "checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" @@ -4864,6 +4950,7 @@ dependencies = [ "checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" "checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" "checksum ed25519-dalek 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cd66d8a16ef71c23cf5eeb2140d8d3cd293457c6c7fd6804b593397a933fcf1e" +"checksum ed25519-dalek 1.0.0-pre.1 (git+https://github.com/dalek-cryptography/ed25519-dalek?branch=develop)" = "" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" @@ -4922,6 +5009,7 @@ dependencies = [ "checksum jsonrpc-pubsub 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56608ed54b1b2a69f4357cb8bdfbcbd99fe1179383c03a09bb428931bd35f592" "checksum jsonrpc-server-utils 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5521613b31ea22d36d9f95ad642058dccec846a94ed8690957652d479f620707" "checksum jsonrpc-ws-server 10.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20b8333a5a6e6ccbcf5c90f90919de557cba4929efa164e9bd0e8e497eb20e46" +"checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum keccak-hasher 0.2.1 (git+https://github.com/paritytech/trie)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" @@ -4965,6 +5053,7 @@ dependencies = [ "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memory-db 0.9.1 (git+https://github.com/paritytech/trie)" = "" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" +"checksum merlin 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a9e97b439f6d38cbe2a4a4aa93f6770c5305f62761b78b1851406c09c87ee2a" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" @@ -5059,6 +5148,7 @@ dependencies = [ "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" +"checksum schnorrkel 0.0.1 (git+https://github.com/w3f/schnorrkel.git)" = "" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum secp256k1 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfaccd3a23619349e0878d9a241f34b1982343cdf67367058cd7d078d326b63e" @@ -5073,6 +5163,7 @@ dependencies = [ "checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" +"checksum sha3 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34a5e54083ce2b934bf059fdf38e7330a154177e029ab6c4e18638f2f624053a" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index 1dff31a066d1b..b00409f15202c 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -28,7 +28,7 @@ use sha2::Sha512; use serde::{de, Deserialize, Deserializer, Serializer}; // signing context -const SIGNING_CTX: &'static [u8] = b"polkadot transaction"; +const SIGNING_CTX: &'static [u8] = b"substrate transaction"; /// Instead of importing it for the local module, alias it to be available as a public type pub type Signature = schnorrkel::Signature; From 6f0e07c1738645e0699d41b46aeec8109809adb8 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 6 Feb 2019 19:05:30 +0100 Subject: [PATCH 6/6] fix an invalid old test vector --- core/primitives/src/sr25519.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/primitives/src/sr25519.rs b/core/primitives/src/sr25519.rs index b00409f15202c..cf27b0bbfb7e7 100644 --- a/core/primitives/src/sr25519.rs +++ b/core/primitives/src/sr25519.rs @@ -281,7 +281,7 @@ mod test { )) ); let message = b""; - let signature: Signature = Signature::from_bytes(&hex!("d46f56ab56414eb14daaece2bd7dd421b6a9d6bef7d9259fc154696076423f48756c42b7db942ebe8e5d9c36d5a607ee3919e7a8847fa9dc66674630f2b46d04")).unwrap(); + let signature = pair.sign(message); assert!(verify(&signature.to_bytes(), message, &public.0)); assert!(verify_strong(&signature, &message[..], &public)); }