Skip to content

Commit

Permalink
test: add BIP39 seed vectors
Browse files Browse the repository at this point in the history
  • Loading branch information
redshiftzero committed Sep 8, 2023
1 parent ad056c4 commit ff45f82
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 6 deletions.
4 changes: 2 additions & 2 deletions crates/core/keys/src/keys/bip44.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ impl Bip44Path {

/// Per BIP44, coin type is a constant set for each currency.
pub fn coin_type(&self) -> u32 {
self.coin_type
self.coin_type | 0x80000000
}

/// Per BIP44, account splits the key space into independent user identities.
pub fn account(&self) -> u32 {
self.account
self.account | 0x80000000
}

/// Change is set to 1 to denote change addresses.
Expand Down
42 changes: 38 additions & 4 deletions crates/core/keys/src/keys/seed_phrase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,16 @@ fn convert_bits_to_usize(bits: &[bool]) -> usize {

#[cfg(test)]
mod tests {
use hmac::Hmac;
use pbkdf2::pbkdf2;
use std::str::FromStr;

use super::*;

#[test]
fn bip39_mnemonic_derivation() {
// These test vectors are taken from: https://github.com/trezor/python-mnemonic/blob/master/vectors.json
let randomness_arr: [&str; 16] = [
let randomness_arr = [
"00000000000000000000000000000000",
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
"80808080808080808080808080808080",
Expand All @@ -242,7 +244,7 @@ mod tests {
"066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad",
"f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f",
];
let expected_phrase_arr: [&str; 16] = [
let expected_phrase_arr = [
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
"legal winner thank year wave sausage worth useful legal winner thank yellow",
"letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
Expand All @@ -260,16 +262,48 @@ mod tests {
"all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform",
"void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold",
];
let seed_result_arr = [
"c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04",
"2e8905819b8723fe2c1d161860e5ee1830318dbf49a83bd451cfb8440c28bd6fa457fe1296106559a3c80937a1c1069be3a3a5bd381ee6260e8d9739fce1f607",
"d71de856f81a8acc65e6fc851a38d4d7ec216fd0796d0a6827a3ad6ed5511a30fa280f12eb2e47ed2ac03b5c462a0358d18d69fe4f985ec81778c1b370b652a8",
"ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069",
"274ddc525802f7c828d8ef7ddbcdc5304e87ac3535913611fbbfa986d0c9e5476c91689f9c8a54fd55bd38606aa6a8595ad213d4c9c9f9aca3fb217069a41028",
"ea725895aaae8d4c1cf682c1bfd2d358d52ed9f0f0591131b559e2724bb234fca05aa9c02c57407e04ee9dc3b454aa63fbff483a8b11de949624b9f1831a9612",
"deb5f45449e615feff5640f2e49f933ff51895de3b4381832b3139941c57b59205a42480c52175b6efcffaa58a2503887c1e8b363a707256bdd2b587b46541f5",
"2aaa9242daafcee6aa9d7269f17d4efe271e1b9a529178d7dc139cd18747090bf9d60295d0ce74309a78852a9caadf0af48aae1c6253839624076224374bc63f",
"bda85446c68413707090a52022edd26a1c9462295029f2e60cd7c4f2bbd3097170af7a4d73245cafa9c3cca8d561a7c3de6f5d4a10be8ed2a5e608d68f92fcc8",
"bc09fca1804f7e69da93c2f2028eb238c227f2e9dda30cd63699232578480a4021b146ad717fbb7e451ce9eb835f43620bf5c514db0f8add49f5d121449d3e87",
"c0c519bd0e91a2ed54357d9d1ebef6f5af218a153624cf4f2da911a0ed8f7a09e2ef61af0aca007096df430022f7a2b6fb91661a9589097069720d015e4e982f",
"dd48c104698c30cfe2b6142103248622fb7bb0ff692eebb00089b32d22484e1613912f0a5b694407be899ffd31ed3992c456cdf60f5d4564b8ba3f05a69890ad",
"64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440",
"72be8e052fc4919d2adf28d5306b5474b0069df35b02303de8c1729c9538dbb6fc2d731d5f832193cd9fb6aeecbc469594a70e3dd50811b5067f3b88b28c3e8d",
"26e975ec644423f4a4c4f4215ef09b4bd7ef924e85d1d17c4cf3f136c2863cf6df0a475045652c57eb5fb41513ca2a2d67722b77e954b4b3fc11f7590449191d",
"01f5bced59dec48e362f2c45b5de68b9fd6c92c6634f44d6d40aab69056506f0e35524a518034ddc1192e1dacd32c1ed3eaa3c3b131c88ed8e7e54c49a5d0998",
];

for (hex_randomness, expected_phrase) in
randomness_arr.iter().zip(expected_phrase_arr.iter())
for (i, (hex_randomness, expected_phrase)) in randomness_arr
.iter()
.zip(expected_phrase_arr.iter())
.enumerate()
{
let randomness = hex::decode(hex_randomness).expect("can decode test vector");
let actual_phrase = SeedPhrase::from_randomness(&randomness[..]);
assert_eq!(actual_phrase.to_string(), *expected_phrase);
actual_phrase
.verify_checksum()
.expect("checksum should validate");

let password = format!("{actual_phrase}");
let mut seed_bytes = [0u8; 64];
pbkdf2::<Hmac<sha2::Sha512>>(
password.as_bytes(),
"mnemonicTREZOR".as_bytes(),
NUM_PBKDF2_ROUNDS,
&mut seed_bytes,
)
.expect("seed phrase hash always succeeds");
let seed_result = hex::encode(seed_bytes);
assert_eq!(seed_result, seed_result_arr[i]);
}
}

Expand Down

0 comments on commit ff45f82

Please sign in to comment.