mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 21:57:55 +00:00
Crypto fixes/improvements (#2008)
* Crypto fixes: - Use schnorrkel's HDKD derive - Assume all key URIs beginning with `/` are prefixed with public root phrase. * Remove commented code. * Update README * Update core/primitives/src/ed25519.rs Co-Authored-By: gavofyork <github@gavwood.com>
This commit is contained in:
@@ -25,6 +25,12 @@ use regex::Regex;
|
||||
#[cfg(feature = "std")]
|
||||
use base58::{FromBase58, ToBase58};
|
||||
|
||||
/// The root phrase for our publically known keys.
|
||||
pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk";
|
||||
|
||||
/// The address of the associated root phrase for our publically known keys.
|
||||
pub const DEV_ADDRESS: &str = "5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqAS7";
|
||||
|
||||
/// The infallible type.
|
||||
#[derive(Debug)]
|
||||
pub enum Infallible {}
|
||||
@@ -243,14 +249,16 @@ impl<T: AsMut<[u8]> + AsRef<[u8]> + Default + Derive> Ss58Codec for T {
|
||||
}
|
||||
|
||||
fn from_string(s: &str) -> Result<Self, PublicError> {
|
||||
let re = Regex::new(r"^(?P<ss58>[\w\d]+)(?P<path>(//?[^/]+)*)$")
|
||||
let re = Regex::new(r"^(?P<ss58>[\w\d]+)?(?P<path>(//?[^/]+)*)$")
|
||||
.expect("constructed from known-good static value; qed");
|
||||
let cap = re.captures(s).ok_or(PublicError::InvalidFormat)?;
|
||||
let re_junction = Regex::new(r"/(/?[^/]+)")
|
||||
.expect("constructed from known-good static value; qed");
|
||||
let path = re_junction.captures_iter(&cap["path"])
|
||||
.map(|f| DeriveJunction::from(&f[1]));
|
||||
Self::from_ss58check(&cap["ss58"])?.derive(path).ok_or(PublicError::InvalidPath)
|
||||
Self::from_ss58check(cap.name("ss58").map(|r| r.as_str()).unwrap_or(DEV_ADDRESS))?
|
||||
.derive(path)
|
||||
.ok_or(PublicError::InvalidPath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,6 +343,9 @@ pub trait Pair: Sized {
|
||||
/// - the phrase may be followed by one or more items delimited by `/` characters.
|
||||
/// - the path may be followed by `///`, in which case everything after the `///` is treated
|
||||
/// as a password.
|
||||
/// - If `s` begins with a `/` character it is prefixed with the Substrate public `DEV_PHRASE` and
|
||||
/// interpreted as above.
|
||||
///
|
||||
/// In this case they are interpreted as HDKD junctions; purely numeric items are interpreted as
|
||||
/// integers, non-numeric items as strings. Junctions prefixed with `/` are interpreted as soft
|
||||
/// junctions, and with `//` as hard junctions.
|
||||
@@ -359,7 +370,7 @@ pub trait Pair: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
let re = Regex::new(r"^(?P<phrase>\w+( \w+)*)(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$")
|
||||
let re = Regex::new(r"^(?P<phrase>\w+( \w+)*)?(?P<path>(//?[^/]+)*)(///(?P<password>.*))?$")
|
||||
.expect("constructed from known-good static value; qed");
|
||||
let cap = re.captures(s).ok_or(SecretStringError::InvalidFormat)?;
|
||||
let re_junction = Regex::new(r"/(/?[^/]+)")
|
||||
@@ -367,7 +378,7 @@ pub trait Pair: Sized {
|
||||
let path = re_junction.captures_iter(&cap["path"])
|
||||
.map(|f| DeriveJunction::from(&f[1]));
|
||||
Self::from_standard_components(
|
||||
&cap["phrase"],
|
||||
cap.name("phrase").map(|r| r.as_str()).unwrap_or(DEV_PHRASE),
|
||||
password_override.or_else(|| cap.name("password").map(|m| m.as_str())),
|
||||
path,
|
||||
)
|
||||
|
||||
@@ -523,7 +523,15 @@ impl Pair {
|
||||
mod test {
|
||||
use super::*;
|
||||
use hex_literal::{hex, hex_impl};
|
||||
use crate::Pair as _Pair;
|
||||
use crate::{Pair as _Pair, crypto::DEV_PHRASE};
|
||||
|
||||
#[test]
|
||||
fn default_phrase_should_be_used() {
|
||||
assert_eq!(
|
||||
Pair::from_string("//Alice///password", None).unwrap().public(),
|
||||
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vector_should_work() {
|
||||
|
||||
@@ -366,11 +366,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 {
|
||||
("SchnorrRistrettoHDKD", &secret.to_bytes()[..], cc).using_encoded(|data|
|
||||
MiniSecretKey::from_bytes(blake2_rfc::blake2b::blake2b(32, &[], data).as_bytes())
|
||||
.expect("all 32-byte crypto-hash results are valid MiniSecretKeys; qed")
|
||||
.expand()
|
||||
)
|
||||
secret.hard_derive_mini_secret_key(signing_context(b"SchnorrRistrettoHDKD").bytes(&cc[..])).expand()
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -507,9 +503,41 @@ impl Pair {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::Pair as _Pair;
|
||||
use crate::{Pair as _Pair, crypto::{Ss58Codec, DEV_PHRASE, DEV_ADDRESS}};
|
||||
use hex_literal::{hex, hex_impl};
|
||||
|
||||
|
||||
#[test]
|
||||
fn default_phrase_should_be_used() {
|
||||
assert_eq!(
|
||||
Pair::from_string("//Alice///password", None).unwrap().public(),
|
||||
Pair::from_string(&format!("{}//Alice", DEV_PHRASE), Some("password")).unwrap().public(),
|
||||
);
|
||||
assert_eq!(
|
||||
Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).as_ref().map(Pair::public),
|
||||
Pair::from_string("/Alice", None).as_ref().map(Pair::public)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_address_should_be_used() {
|
||||
assert_eq!(
|
||||
Public::from_string(&format!("{}/Alice", DEV_ADDRESS)),
|
||||
Public::from_string("/Alice")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_phrase_should_correspond_to_default_address() {
|
||||
assert_eq!(
|
||||
Pair::from_string(&format!("{}/Alice", DEV_PHRASE), None).unwrap().public(),
|
||||
Public::from_string(&format!("{}/Alice", DEV_ADDRESS)).unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
Pair::from_string("/Alice", None).unwrap().public(),
|
||||
Public::from_string("/Alice").unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_soft_should_work() {
|
||||
let pair: Pair = Pair::from_seed(hex!(
|
||||
|
||||
Reference in New Issue
Block a user