From aab74012f69ceda00470b814ef6fe49963a70b03 Mon Sep 17 00:00:00 2001 From: Stanimal Date: Fri, 29 Apr 2022 15:19:42 +0200 Subject: [PATCH] fix(key-manager): remove floating point math from mnemonic code --- base_layer/key_manager/src/mnemonic.rs | 29 ++++++++++++++------------ 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/base_layer/key_manager/src/mnemonic.rs b/base_layer/key_manager/src/mnemonic.rs index d467f86bc1..a429ee2b73 100644 --- a/base_layer/key_manager/src/mnemonic.rs +++ b/base_layer/key_manager/src/mnemonic.rs @@ -185,7 +185,11 @@ pub fn from_bytes(bytes: &[u8], language: MnemonicLanguage) -> Result 0 { + padded_size += 1; + } + padded_size *= group_bit_count; bits.resize(padded_size, false); // Group each set of 11 bits to form one mnemonic word @@ -193,12 +197,10 @@ pub fn from_bytes(bytes: &[u8], language: MnemonicLanguage) -> Result mnemonic_sequence.push(mnemonic_word), - Err(err) => return Err(err), - } + let mnemonic_word = find_mnemonic_word_from_index(word_index, language)?; + mnemonic_sequence.push(mnemonic_word); } Ok(mnemonic_sequence) @@ -216,10 +218,10 @@ pub fn to_bytes(mnemonic_seq: &[String]) -> Result, MnemonicError> { /// look something like this: /// .....CCCCCCCCCCCBBBBBBBBBBBAAAAAAAAAAA, the input represented as one very large number would look like /// A+B*2^11+C*2^22+... And we want to cut it (from the right) to 8 bit long numbers like this: -/// .....eddddddddccccccccbbbbbbbbaaaaaaaa, the output represented as one very large number would look liek +/// .....eddddddddccccccccbbbbbbbbaaaaaaaa, the output represented as one very large number would look like /// a+b*2^8+c*2^16+... Where 'A' is the first mnemonic word in the seq and 'a' is the first byte output. /// So the algo works like this: -/// We add 11bits number to what we have 'rest' shited by the number of bit representation of rest ('rest_bits'). +/// We add 11bits number to what we have 'rest' shifted by the number of bit representation of rest ('rest_bits'). /// We now have enough bits to get some output, we take 8 bits and produce output byte. We do this as long as we have at /// least 8 bits in the 'rest'. /// Sample of couple first steps: @@ -227,25 +229,26 @@ pub fn to_bytes(mnemonic_seq: &[String]) -> Result, MnemonicError> { /// 2) We add 5 bits from 'B' to generate 'b', the leftover is 6 bits from 'B' /// 3) We add 2 bits from 'C to generate 'c', now we have 8 bits needed to generate 'd' and we have 1 bit leftover. pub fn to_bytes_with_language(mnemonic_seq: &[String], language: &MnemonicLanguage) -> Result, MnemonicError> { - let mut bytes: Vec = Vec::new(); - let mut rest = 0; + const MASK: u64 = (1u64 << 8) - 1; + let mut bytes = Vec::new(); + let mut rest = 0u64; let mut rest_bits: u8 = 0; for curr_word in mnemonic_seq { - let index = find_mnemonic_index_from_word(curr_word, *language)?; + let index = find_mnemonic_index_from_word(curr_word, *language)? as u64; // Add 11 bits to the front rest += index << rest_bits; rest_bits += 11; while rest_bits >= 8 { // Get last 8 bits and shift it - bytes.push(rest as u8); + bytes.push((rest & MASK) as u8); rest >>= 8; rest_bits -= 8; } } // If we have any leftover, we write it. if rest > 0 { - bytes.push(rest as u8); + bytes.push((rest & MASK) as u8); } Ok(bytes) }