Skip to content

Commit 5d56110

Browse files
Verify checksum of mnemonic sentence
We are currently only checksum the number of words in the mnemonic and their validity. This implementation also checks the checksum to make sure that it was generated from the entropy of the mnemonic.
1 parent 93cd896 commit 5d56110

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

src/keys/bip39/mod.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,42 @@ impl Mnemonic {
111111

112112
let mut indices: Vec<u16> = Vec::with_capacity(words.len());
113113
let wordlist = language.wordlist();
114-
for word in words {
115-
let idx = match wordlist.iter().position(|&x| x == word) {
114+
let mut mnemonic_bits = vec![false; words.len() * 11];
115+
for (i, word) in words.iter().enumerate() {
116+
let idx = match wordlist.iter().position(|&x| x == *word) {
116117
Some(i) => i as u16,
117118
None => return Err(Error::InvalidWord(word.to_string())),
118119
};
119120

120121
indices.push(idx);
122+
123+
for j in 0..11 {
124+
mnemonic_bits[i * 11 + j] = (idx & (1 << 10 - j)) != 0;
125+
}
126+
}
127+
128+
//calculate the entropy length in bits using CS = ENT / 32 and
129+
//MS = (ENT + CS) / 11, then convert to bytes
130+
let entropy_bytes_len = (words.len() * 4) / 3;
131+
let mut entropy = vec![0u8; entropy_bytes_len];
132+
for i in 0..entropy_bytes_len {
133+
for j in 0..8 {
134+
if mnemonic_bits[i * 8 + j] {
135+
entropy[i] += 1 << 7 - j;
136+
}
137+
}
138+
}
139+
140+
let entropy_hash = sha256::Hash::hash(&entropy);
141+
let entropy_hash = entropy_hash.as_ref();
142+
let checksum_byte = entropy_hash[0];
143+
144+
//verify checksum calculated from entropy
145+
let entropy_bits_len = (words.len() * 32) / 3;
146+
for (i, &bit) in mnemonic_bits[entropy_bits_len..].iter().enumerate() {
147+
if (checksum_byte & (1 << 7 - i) != 0) != bit {
148+
return Err(Error::InvalidChecksum(checksum_byte as usize));
149+
}
121150
}
122151

123152
Ok(Mnemonic {

0 commit comments

Comments
 (0)