Add entropy bounds check

This commit is contained in:
Yancy Ribbens 2020-06-20 11:49:26 -05:00
parent c4f7a37b5c
commit 57c79a33cd
1 changed files with 29 additions and 5 deletions

View File

@ -54,8 +54,7 @@ pub enum Error {
BadWordCount(usize),
/// Mnemonic contains an unknown word.
UnknownWord(String),
/// Entropy was not a multiple of 32 bits.
/// Parameter is the number of bits in the entropy.
/// Entropy was not a multiple of 32 bits or between 128-256n bits in length.
BadEntropyBitCount(usize),
/// The mnemonic has an invalid checksum.
InvalidChecksum,
@ -72,7 +71,7 @@ impl fmt::Display for Error {
w, bitcoin_hashes::hex::ToHex::to_hex(w.as_bytes()),
),
Error::BadEntropyBitCount(c) => write!(f,
"entropy was not a multiple of 32 bits: {} bits", c,
"entropy was not between 128-256 bits or not a multiple of 32 bits: {} bits", c,
),
Error::InvalidChecksum => write!(f, "the mnemonic has an invalid checksum"),
}
@ -118,12 +117,16 @@ impl Mnemonic {
}
/// Create a new [Mnemonic] in the specified language from the given entropy.
/// Entropy must be a multiple of 32 bits (4 bytes).
/// Entropy must be a multiple of 32 bits (4 bytes) and 128-256 bits in length.
pub fn from_entropy_in(language: Language, entropy: &[u8]) -> Result<Mnemonic, Error> {
if entropy.len() % 4 != 0 {
return Err(Error::BadEntropyBitCount(entropy.len() * 8));
}
if (entropy.len() * 8) < 128 || (entropy.len() * 8) > 256 {
return Err(Error::BadEntropyBitCount(entropy.len() * 8));
}
let check = sha256::Hash::hash(&entropy);
let mut bits = vec![false; entropy.len() * 8 + entropy.len() / 4];
for i in 0..entropy.len() {
@ -150,7 +153,7 @@ impl Mnemonic {
}
/// Create a new English [Mnemonic] in from the given entropy.
/// Entropy must be a multiple of 32 bits (4 bytes).
/// Entropy must be a multiple of 32 bits (4 bytes) and 128-256 bits in length.
pub fn from_entropy(entropy: &[u8]) -> Result<Mnemonic, Error> {
Mnemonic::from_entropy_in(Language::English, entropy)
}
@ -532,6 +535,27 @@ mod tests {
);
}
#[test]
fn test_invalid_entropy() {
//between 128 and 256 bits, but not divisible by 32
assert_eq!(
Mnemonic::from_entropy(&vec![b'x'; 17]),
Err(Error::BadEntropyBitCount(136))
);
//less than 128 bits
assert_eq!(
Mnemonic::from_entropy(&vec![b'x'; 4]),
Err(Error::BadEntropyBitCount(32))
);
//greater than 256 bits
assert_eq!(
Mnemonic::from_entropy(&vec![b'x'; 36]),
Err(Error::BadEntropyBitCount(288))
);
}
#[cfg(feature = "japanese")]
#[test]
fn test_vectors_japanese() {