-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add function to get list of possible final words? #75
Comments
Had to use the BigInt package to copy the python implementation pub fn generate_possible_final_words(phrase: &str) -> Result<Vec<String>, Error> {
let (word_count, encoded_phrase) = split_and_encode_phrase(phrase);
if ![11, 14, 17, 20, 23].contains(&word_count) {
return Err(Error::InvalidNumberOfWords(word_count));
}
let checksum_width = (word_count + 1) / 3;
let byte_width = (((word_count + 1) * 11) - checksum_width) / 8;
let partial_result = encoded_phrase << (11 - checksum_width);
let wordlist = Language::English.word_list();
let final_words = (0..(1 << (11 - checksum_width)))
.map(move |candidate| {
let encoded = partial_result.clone() | BigUint::from(candidate);
let encoded_bytes = encoded.to_bytes_be();
let mut padding = vec![0; byte_width - encoded_bytes.len()];
// encoded_bytes less than byte width we are looking for
// so pad at the front
let final_byte_array = if encoded_bytes.len() < byte_width {
padding.extend_from_slice(encoded_bytes.as_slice());
padding.as_slice()
} else {
&encoded_bytes[..byte_width]
};
let mut hasher = Sha256::new();
hasher.update(final_byte_array);
let checksum = hasher.finalize()[0] >> (8 - checksum_width);
let word_index = (candidate << checksum_width) + (checksum as u64);
wordlist[word_index as usize].to_string()
})
.collect();
Ok(final_words)
}
fn split_and_encode_phrase(phrase: &str) -> (usize, BigUint) {
let words: Vec<&str> = if phrase.contains(' ') {
phrase.split_whitespace().collect()
} else {
vec![phrase]
};
let word_count = words.len();
let mut encoded_phrase = BigUint::from(0u32);
for word in words {
if let Some(word_index) = Language::English.find_word(word) {
encoded_phrase = (encoded_phrase << 11) | BigUint::from(word_index as u64);
}
}
(word_count, encoded_phrase)
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The python library has it, and i need it right now, i'm working on porting it to rust, if you guys wanted, I could open a PR when i'm done.
https://github.com/switck/libngu/blob/2537f1581d0bad2c16fa391bc6fade328450a217/ngu/bip39.py#L384
The text was updated successfully, but these errors were encountered: