keyfork-mnemonic-generate: the math ain't mathin
This commit is contained in:
parent
2c06b96953
commit
3032e11b78
|
@ -2,6 +2,23 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bip39"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
|
||||||
|
dependencies = [
|
||||||
|
"bitcoin_hashes",
|
||||||
|
"serde",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitcoin_hashes"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
@ -72,6 +89,7 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||||
name = "keyfork-mnemonic-generate"
|
name = "keyfork-mnemonic-generate"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bip39",
|
||||||
"hex",
|
"hex",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
@ -117,12 +135,36 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
|
|
@ -9,5 +9,6 @@ edition = "2021"
|
||||||
sha2 = "0.10.7"
|
sha2 = "0.10.7"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
bip39 = "2.0.0"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
serde_json = "1.0.105"
|
serde_json = "1.0.105"
|
||||||
|
|
|
@ -93,6 +93,8 @@ fn ensure_offline() {
|
||||||
|
|
||||||
// TODO: Can a Mnemonic be formatted using a wordlist, without allocating or without storing the
|
// TODO: Can a Mnemonic be formatted using a wordlist, without allocating or without storing the
|
||||||
// entire word list?
|
// entire word list?
|
||||||
|
//
|
||||||
|
// NOTE: Yes, use a Language and pass a reference to this.
|
||||||
struct Mnemonic {
|
struct Mnemonic {
|
||||||
pub words: Vec<usize>,
|
pub words: Vec<usize>,
|
||||||
wordlist: Vec<String>,
|
wordlist: Vec<String>,
|
||||||
|
@ -233,19 +235,50 @@ mod tests {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_bip39_crate() {
|
||||||
|
let mut random_handle = File::open("/dev/random").unwrap();
|
||||||
|
let entropy = &mut [0u8; 256 / 8];
|
||||||
|
random_handle.read_exact(&mut entropy[..]).unwrap();
|
||||||
|
let my_mnemonic = super::Mnemonic::from_entropy(&entropy[..256 / 8]).unwrap();
|
||||||
|
let their_mnemonic = bip39::Mnemonic::from_entropy(&entropy[..256 / 8]).unwrap();
|
||||||
|
/*
|
||||||
|
let my_words = my_mnemonic.words.clone();
|
||||||
|
let their_words = their_mnemonic.word_iter().collect::<Vec<_>>();
|
||||||
|
*/
|
||||||
|
assert_eq!(my_mnemonic.to_string(), their_mnemonic.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn count_to_get_duplicate_words() {
|
fn count_to_get_duplicate_words() {
|
||||||
let mut count = 0.;
|
let mut count = 0.;
|
||||||
let mut random_handle = File::open("/dev/urandom").unwrap();
|
let mut smallest = 2048;
|
||||||
|
let mut largest = 0;
|
||||||
|
let mut random_handle = File::open("/dev/random").unwrap();
|
||||||
let entropy = &mut [0u8; 256 / 8];
|
let entropy = &mut [0u8; 256 / 8];
|
||||||
|
let mut set = std::collections::HashMap::<&str, u32>::new();
|
||||||
for _ in 0..100_000 {
|
for _ in 0..100_000 {
|
||||||
random_handle.read_exact(&mut entropy[..]).unwrap();
|
random_handle.read_exact(&mut entropy[..]).unwrap();
|
||||||
let mut mnemonic = Mnemonic::from_entropy(&entropy[..256 / 8]).unwrap();
|
// let bits = generate_slice_hash(entropy);
|
||||||
|
let mnemonic = bip39::Mnemonic::from_entropy(&entropy[..256 / 8]).unwrap();
|
||||||
|
/*
|
||||||
mnemonic.words.dedup();
|
mnemonic.words.dedup();
|
||||||
if mnemonic.words.len() != 24 {
|
*/
|
||||||
|
// NOTE: This pulls everything BUT the last word, just for testing.
|
||||||
|
// Change to ..24 to include the last word.
|
||||||
|
for (word, _) in mnemonic.word_iter().zip(0..23) {
|
||||||
|
*set.entry(word).or_insert(0) += 1;
|
||||||
|
}
|
||||||
|
let mut words = mnemonic.word_iter().collect::<Vec<_>>();
|
||||||
|
words.dedup();
|
||||||
|
if words.len() != 24 {
|
||||||
count += 1.;
|
count += 1.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic!("counts: {count} {}", count / 100_000.)
|
for entry in &set {
|
||||||
|
smallest = std::cmp::min(smallest, *entry.1);
|
||||||
|
largest = std::cmp::max(largest, *entry.1);
|
||||||
|
}
|
||||||
|
panic!("{count} len:{} smallest:{smallest} largest:{largest}", set.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue