Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl Mnemonic {
/// can be avoided for languages without special UTF8 characters.
#[inline]
#[cfg(feature = "std")]
fn normalize_utf8_cow<'a>(cow: &mut Cow<'a, str>) {
fn normalize_utf8_cow(cow: &mut Cow<str>) {
let is_nfkd = unicode_normalization::is_nfkd_quick(cow.as_ref().chars());
if is_nfkd != unicode_normalization::IsNormalized::Yes {
*cow = Cow::Owned(cow.as_ref().nfkd().to_string());
Expand All @@ -184,7 +184,7 @@ impl Mnemonic {

/// Create a new [Mnemonic] in the specified language from the given entropy.
/// 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> {
pub fn from_entropy_in(lang: Language, entropy: &[u8]) -> Result<Mnemonic, Error> {
const MAX_ENTROPY_BITS: usize = 256;
const MIN_ENTROPY_BITS: usize = 128;
const MAX_CHECKSUM_BITS: usize = 8;
Expand All @@ -195,11 +195,11 @@ impl Mnemonic {
if nb_bits % 32 != 0 {
return Err(Error::BadEntropyBitCount(nb_bits));
}
if nb_bits < MIN_ENTROPY_BITS || nb_bits > MAX_ENTROPY_BITS {
if !(MIN_ENTROPY_BITS..=MAX_ENTROPY_BITS).contains(&nb_bits) {
return Err(Error::BadEntropyBitCount(nb_bits));
}

let check = sha256::Hash::hash(&entropy);
let check = sha256::Hash::hash(entropy);
let mut bits = [false; MAX_ENTROPY_BITS + MAX_CHECKSUM_BITS];
for i in 0..nb_bytes {
for j in 0..8 {
Expand All @@ -223,8 +223,8 @@ impl Mnemonic {
}

Ok(Mnemonic {
lang: language,
words: words,
lang,
words,
})
}

Expand Down Expand Up @@ -320,7 +320,7 @@ impl Mnemonic {
{
// Start scope to drop first_word so that words can be reborrowed later.
let first_word = words.peek().ok_or(Error::BadWordCount(0))?;
if first_word.len() == 0 {
if first_word.is_empty() {
return Err(Error::BadWordCount(0));
}

Expand Down Expand Up @@ -364,7 +364,7 @@ impl Mnemonic {
}
}

return Err(Error::AmbiguousLanguages(AmbiguousLanguages(possible)));
Err(Error::AmbiguousLanguages(AmbiguousLanguages(possible)))
}

/// Determine the language of the mnemonic.
Expand All @@ -382,7 +382,7 @@ impl Mnemonic {
}

/// Parse a mnemonic in normalized UTF8 in the given language.
pub fn parse_in_normalized(language: Language, s: &str) -> Result<Mnemonic, Error> {
pub fn parse_in_normalized(lang: Language, s: &str) -> Result<Mnemonic, Error> {
let nb_words = s.split_whitespace().count();
if is_invalid_word_count(nb_words) {
return Err(Error::BadWordCount(nb_words));
Expand All @@ -396,7 +396,7 @@ impl Mnemonic {
let mut bits = [false; MAX_NB_WORDS * 11];

for (i, word) in s.split_whitespace().enumerate() {
let idx = language.find_word(word).ok_or(Error::UnknownWord(i))?;
let idx = lang.find_word(word).ok_or(Error::UnknownWord(i))?;

words[i] = idx;

Expand Down Expand Up @@ -424,8 +424,8 @@ impl Mnemonic {
}

Ok(Mnemonic {
lang: language,
words: words,
lang,
words,
})
}

Expand All @@ -443,7 +443,8 @@ impl Mnemonic {
) -> Result<Mnemonic, Error> {
let mut cow = s.into();
Mnemonic::normalize_utf8_cow(&mut cow);
Ok(Mnemonic::parse_in_normalized(language, cow.as_ref())?)

Mnemonic::parse_in_normalized(language, cow.as_ref())
}

/// Parse a mnemonic and detect the language from the enabled languages.
Expand All @@ -458,7 +459,7 @@ impl Mnemonic {
Mnemonic::language_of(cow.as_ref())?
};

Ok(Mnemonic::parse_in_normalized(language, cow.as_ref())?)
Mnemonic::parse_in_normalized(language, cow.as_ref())
}

/// Get the number of words in the mnemonic.
Expand Down
23 changes: 14 additions & 9 deletions src/pbkdf2.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use bitcoin_hashes::{hmac, sha512, Hash, HashEngine};

const SALT_PREFIX: &'static str = "mnemonic";
const SALT_PREFIX: &str = "mnemonic";

/// Calculate the binary size of the mnemonic.
fn mnemonic_byte_len<M>(mnemonic: M) -> usize
where M: Iterator<Item = &'static str> + Clone,
where
M: Iterator<Item = &'static str> + Clone,
{
let mut len = 0;
for (i, word) in mnemonic.enumerate() {
Expand All @@ -18,7 +19,8 @@ fn mnemonic_byte_len<M>(mnemonic: M) -> usize

/// Wrote the mnemonic in binary form into the hash engine.
fn mnemonic_write_into<M>(mnemonic: M, engine: &mut sha512::HashEngine)
where M: Iterator<Item = &'static str> + Clone,
where
M: Iterator<Item = &'static str> + Clone,
{
for (i, word) in mnemonic.enumerate() {
if i > 0 {
Expand All @@ -32,7 +34,8 @@ fn mnemonic_write_into<M>(mnemonic: M, engine: &mut sha512::HashEngine)
/// We need a special method because we can't allocate a new byte
/// vector for the entire serialized mnemonic.
fn create_hmac_engine<M>(mnemonic: M) -> hmac::HmacEngine<sha512::Hash>
where M: Iterator<Item = &'static str> + Clone,
where
M: Iterator<Item = &'static str> + Clone,
{
// Inner code is borrowed from the bitcoin_hashes::hmac::HmacEngine::new method.
let mut ipad = [0x36u8; 128];
Expand All @@ -58,8 +61,8 @@ fn create_hmac_engine<M>(mnemonic: M) -> hmac::HmacEngine<sha512::Hash>
let mut cursor = 0;
for (i, word) in mnemonic.enumerate() {
if i > 0 {
ipad[cursor] ^= ' ' as u8;
opad[cursor] ^= ' ' as u8;
ipad[cursor] ^= b' ';
opad[cursor] ^= b' ';
cursor += 1;
}
for (b_i, b_h) in ipad.iter_mut().skip(cursor).zip(word.as_bytes()) {
Expand All @@ -82,9 +85,10 @@ fn create_hmac_engine<M>(mnemonic: M) -> hmac::HmacEngine<sha512::Hash>
#[inline]
fn u32_to_array_be(val: u32) -> [u8; 4] {
let mut res = [0; 4];
for i in 0..4 {
res[i] = ((val >> (4 - i - 1) * 8) & 0xff) as u8;
for (i, item) in res.iter_mut().enumerate() {
*item = ((val >> ((4 - i - 1) * 8)) & 0xff) as u8;
}

res
}

Expand All @@ -97,7 +101,8 @@ fn xor(res: &mut [u8], salt: &[u8]) {

/// PBKDF2-HMAC-SHA512 implementation using bitcoin_hashes.
pub(crate) fn pbkdf2<M>(mnemonic: M, unprefixed_salt: &[u8], c: usize, res: &mut [u8])
where M: Iterator<Item = &'static str> + Clone,
where
M: Iterator<Item = &'static str> + Clone,
{
let prf = create_hmac_engine(mnemonic);

Expand Down