mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 07:41:08 +00:00
Key generation utility (#176)
* RPCs for versioning. * Build fix for bad merge. * Add system_name RPC * Fix tests. * Fix demo build. * Remove BadFormat. * Add ss58check encoding and subkey. * Improvements. * Update Cargo.toml
This commit is contained in:
Generated
+16
@@ -79,6 +79,11 @@ dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base58"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.9.0"
|
||||
@@ -310,6 +315,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "ed25519"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-primitives 0.1.0",
|
||||
@@ -1839,6 +1846,14 @@ name = "strsim"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "subkey"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ed25519 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-bft"
|
||||
version = "0.1.0"
|
||||
@@ -2706,6 +2721,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859"
|
||||
"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2"
|
||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||
"checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83"
|
||||
"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4"
|
||||
"checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd"
|
||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
||||
|
||||
@@ -60,6 +60,7 @@ members = [
|
||||
"demo/executor",
|
||||
"demo/cli",
|
||||
"safe-mix",
|
||||
"subkey",
|
||||
]
|
||||
exclude = [
|
||||
"polkadot/runtime/wasm",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "subkey"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
ed25519 = { version = "*", path = "../substrate/ed25519" }
|
||||
substrate-primitives = { version = "*", path = "../substrate/primitives" }
|
||||
@@ -0,0 +1,55 @@
|
||||
extern crate ed25519;
|
||||
extern crate substrate_primitives;
|
||||
|
||||
use std::env::args;
|
||||
use ed25519::Pair;
|
||||
use substrate_primitives::hexdisplay::HexDisplay;
|
||||
|
||||
fn good_waypoint(done: u64) -> u64 {
|
||||
match done {
|
||||
0 ... 1_000_000 => 100_000,
|
||||
0 ... 10_000_000 => 1_000_000,
|
||||
0 ... 100_000_000 => 10_000_000,
|
||||
_ => 100_000_000,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
if args().len() != 2 {
|
||||
println!("Usage: subkey <search string>");
|
||||
return;
|
||||
}
|
||||
let desired = args().last().unwrap();
|
||||
let score = |s: &str| {
|
||||
for truncate in 0..desired.len() - 1 {
|
||||
let snip_size = desired.len() - truncate;
|
||||
let truncated = &desired[0..snip_size];
|
||||
if let Some(pos) = s.find(truncated) {
|
||||
return (31 - pos) + (snip_size * 32);
|
||||
}
|
||||
}
|
||||
0
|
||||
};
|
||||
let top = 30 + (desired.len() * 32);
|
||||
let mut best = 0;
|
||||
let mut seed = Pair::generate().public().0;
|
||||
let mut done = 0;
|
||||
loop {
|
||||
let p = Pair::from_seed(&seed);
|
||||
let ss58 = p.public().to_ss58check();
|
||||
let s = score(&ss58);
|
||||
if s > best {
|
||||
println!("{}: {} ({}% complete)", ss58, HexDisplay::from(&seed), s * 100 / top);
|
||||
best = s;
|
||||
if best == top {
|
||||
break;
|
||||
}
|
||||
}
|
||||
seed = p.public().0;
|
||||
done += 1;
|
||||
|
||||
if done % good_waypoint(done) == 0 {
|
||||
println!("{} keys searched", done);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,3 +8,5 @@ ring = "0.12"
|
||||
untrusted = "0.5"
|
||||
substrate-primitives = { version = "0.1", path = "../primitives" }
|
||||
hex-literal = "0.1"
|
||||
base58 = "0.1"
|
||||
blake2-rfc = "0.2"
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
//! Simple Ed25519 API.
|
||||
|
||||
extern crate ring;
|
||||
extern crate base58;
|
||||
extern crate substrate_primitives as primitives;
|
||||
extern crate untrusted;
|
||||
extern crate blake2_rfc;
|
||||
|
||||
use ring::{rand, signature};
|
||||
use primitives::hash::H512;
|
||||
use base58::{ToBase58, FromBase58};
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
@@ -67,6 +70,14 @@ impl ::std::hash::Hash for Public {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
pub enum PublicError {
|
||||
BadBase58,
|
||||
BadLength,
|
||||
UnknownVersion,
|
||||
InvalidChecksum,
|
||||
}
|
||||
|
||||
impl Public {
|
||||
/// A new instance from the given 32-byte `data`.
|
||||
pub fn from_raw(data: [u8; 32]) -> Self {
|
||||
@@ -80,6 +91,24 @@ impl Public {
|
||||
Public(r)
|
||||
}
|
||||
|
||||
/// Some if the string is a properly encoded SS58Check address.
|
||||
pub fn from_ss58check(s: &str) -> Result<Self, PublicError> {
|
||||
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<u8>` filled with raw data.
|
||||
pub fn to_raw_vec(self) -> Vec<u8> {
|
||||
let r: &[u8; 32] = self.as_ref();
|
||||
@@ -96,6 +125,15 @@ impl Public {
|
||||
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 {
|
||||
@@ -281,4 +319,21 @@ mod test {
|
||||
let pair = Pair::generate();
|
||||
let _pair2 = pair.derive_child_probably_bad(b"session_1234");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ss58check_roundtrip_works() {
|
||||
let pair = Pair::from_seed(b"12345678901234567890123456789012");
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user