keyfork-mnemonic-generate: begin work on tests
This commit is contained in:
parent
0d768a6eef
commit
7467a30c40
|
@ -56,10 +56,24 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "keyfork-mnemonic-generate"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
|
@ -69,6 +83,29 @@ version = "0.2.147"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.183"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c"
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.7"
|
||||
|
|
|
@ -7,3 +7,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
sha2 = "0.10.7"
|
||||
|
||||
[dev-dependencies]
|
||||
hex = "0.4.3"
|
||||
serde_json = "1.0.105"
|
||||
|
|
|
@ -61,6 +61,12 @@ fn ensure_offline() {
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_slice_hash(data: &[u8]) -> Vec<u8> {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(data);
|
||||
hasher.finalize().to_vec()
|
||||
}
|
||||
|
||||
fn build_wordlist() -> Vec<String> {
|
||||
let wordlist_file = include_str!("wordlist.txt");
|
||||
wordlist_file
|
||||
|
@ -85,17 +91,17 @@ fn u8_to_bitslice(byte: &u8) -> [bool; 8] {
|
|||
}
|
||||
|
||||
fn bitslice_to_usize(bitslice: [bool; 11]) -> usize {
|
||||
usize::from(bitslice[0])
|
||||
+ (usize::from(bitslice[1]) << 1)
|
||||
+ (usize::from(bitslice[2]) << 2)
|
||||
+ (usize::from(bitslice[3]) << 3)
|
||||
+ (usize::from(bitslice[4]) << 4)
|
||||
usize::from(bitslice[10])
|
||||
+ (usize::from(bitslice[9]) << 1)
|
||||
+ (usize::from(bitslice[8]) << 2)
|
||||
+ (usize::from(bitslice[7]) << 3)
|
||||
+ (usize::from(bitslice[6]) << 4)
|
||||
+ (usize::from(bitslice[5]) << 5)
|
||||
+ (usize::from(bitslice[6]) << 6)
|
||||
+ (usize::from(bitslice[7]) << 7)
|
||||
+ (usize::from(bitslice[8]) << 8)
|
||||
+ (usize::from(bitslice[9]) << 9)
|
||||
+ (usize::from(bitslice[10]) << 10)
|
||||
+ (usize::from(bitslice[4]) << 6)
|
||||
+ (usize::from(bitslice[3]) << 7)
|
||||
+ (usize::from(bitslice[2]) << 8)
|
||||
+ (usize::from(bitslice[1]) << 9)
|
||||
+ (usize::from(bitslice[0]) << 10)
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
@ -127,9 +133,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let entropy = &mut [0u8; 256 / 8];
|
||||
random_handle.read_exact(&mut entropy[..])?;
|
||||
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(&entropy);
|
||||
let hash = hasher.finalize();
|
||||
let hash = generate_slice_hash(entropy);
|
||||
let checksum = u8_to_bitslice(&hash[1]);
|
||||
|
||||
let mut seed_bits = entropy[..bit_size / 8]
|
||||
|
@ -149,3 +153,49 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn has_good_wordlist() {
|
||||
let wordlist = build_wordlist();
|
||||
assert_eq!(
|
||||
wordlist.len(),
|
||||
2usize.pow(11),
|
||||
"Wordlist did not include correct word count"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loads_mnemonics() -> Result<(), Box<dyn super::Error>> {
|
||||
let content = include_str!("test/vectors.json");
|
||||
let jsonobj: serde_json::Value = serde_json::from_str(content)?;
|
||||
let wordlist = build_wordlist();
|
||||
|
||||
for test in jsonobj["english"].as_array().unwrap() {
|
||||
let [ref hex_, ref seed, ..] = test.as_array().unwrap()[..] else {
|
||||
panic!("bad test: {test}");
|
||||
};
|
||||
let hex = hex::decode(hex_.as_str().unwrap()).unwrap();
|
||||
let hash = generate_slice_hash(&hex);
|
||||
let checksum = u8_to_bitslice(&hash.iter().next().unwrap());
|
||||
let mut seed_bits = hex.iter().flat_map(u8_to_bitslice).collect::<Vec<_>>();
|
||||
seed_bits.extend(if hex.len() == 256 / 8 {
|
||||
&checksum[..8]
|
||||
} else {
|
||||
&checksum[..4]
|
||||
});
|
||||
|
||||
let words = seed_bits
|
||||
.chunks_exact(11)
|
||||
.map(|chunk| {
|
||||
wordlist[bitslice_to_usize(chunk.try_into().expect("11 bit chunks"))].clone()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
panic!("{}", words.join(" "));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue