keyfork-mnemonic-generate: fix endianness

This commit is contained in:
Ryan Heywood 2023-08-16 15:49:37 -05:00
parent 7eff9531bc
commit 6a99a09089
Signed by: ryan
GPG Key ID: 8E401478A3FBEF72
1 changed files with 29 additions and 47 deletions

View File

@ -76,32 +76,34 @@ fn build_wordlist() -> Vec<String> {
.collect() .collect()
} }
#[allow(clippy::trivially_copy_pass_by_ref)] fn bitslice_to_usize(bitslice: [bool; 11]) -> usize {
fn u8_to_bitslice(byte: &u8) -> [bool; 8] { let mut index = 0usize;
[ for i in 0..11 {
byte & (1 << 0) != 0, index += usize::from(bitslice[10 - i]) << i;
byte & (1 << 1) != 0, }
byte & (1 << 2) != 0, index
byte & (1 << 3) != 0,
byte & (1 << 4) != 0,
byte & (1 << 5) != 0,
byte & (1 << 6) != 0,
byte & (1 << 7) != 0,
]
} }
fn bitslice_to_usize(bitslice: [bool; 11]) -> usize { fn entropy_to_bits(bytes: &[u8]) -> Vec<bool> {
usize::from(bitslice[10]) let bit_count = bytes.len() * 8;
+ (usize::from(bitslice[9]) << 1) let hash = generate_slice_hash(bytes);
+ (usize::from(bitslice[8]) << 2)
+ (usize::from(bitslice[7]) << 3) assert_eq!(bit_count % 32, 0, "bit count must be in 32 bit increments");
+ (usize::from(bitslice[6]) << 4)
+ (usize::from(bitslice[5]) << 5) let mut bits = vec![false; bit_count + bit_count / 32];
+ (usize::from(bitslice[4]) << 6)
+ (usize::from(bitslice[3]) << 7) for byte_index in 0..bit_count / 8 {
+ (usize::from(bitslice[2]) << 8) for bit_index in 0..8 {
+ (usize::from(bitslice[1]) << 9) bits[byte_index * 8 + bit_index] = (bytes[byte_index] & (1 << (7 - bit_index))) > 0;
+ (usize::from(bitslice[0]) << 10) }
}
for check_bit in 0..bit_count / 32 {
bits[bit_count + check_bit] = (hash[check_bit / 8] & (1 << (7 - (check_bit % 8)))) > 0;
}
assert_eq!(bits.len() % 11, 0, "unstable bit count");
bits
} }
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
@ -133,18 +135,8 @@ fn main() -> Result<(), Box<dyn Error>> {
let entropy = &mut [0u8; 256 / 8]; let entropy = &mut [0u8; 256 / 8];
random_handle.read_exact(&mut entropy[..])?; random_handle.read_exact(&mut entropy[..])?;
let hash = generate_slice_hash(entropy); let seed_bits = entropy_to_bits(entropy);
let checksum = u8_to_bitslice(&hash[1]);
let mut seed_bits = entropy[..bit_size / 8]
.iter()
.flat_map(u8_to_bitslice)
.collect::<Vec<_>>();
seed_bits.extend(if bit_size == 256 {
&checksum[..8]
} else {
&checksum[..4]
});
let words = seed_bits let words = seed_bits
.chunks_exact(11) .chunks_exact(11)
.map(|chunk| wordlist[bitslice_to_usize(chunk.try_into().expect("11 bit chunks"))].clone()) .map(|chunk| wordlist[bitslice_to_usize(chunk.try_into().expect("11 bit chunks"))].clone())
@ -179,18 +171,8 @@ mod tests {
panic!("bad test: {test}"); panic!("bad test: {test}");
}; };
let hex = hex::decode(hex_.as_str().unwrap()).unwrap(); let hex = hex::decode(hex_.as_str().unwrap()).unwrap();
let hash = generate_slice_hash(&hex);
let checksum = { let seed_bits = entropy_to_bits(&hex);
let mut bits = u8_to_bitslice(&hash.iter().next().unwrap());
bits.reverse();
bits
};
let mut seed_bits = hex.iter().flat_map(u8_to_bitslice).collect::<Vec<_>>();
seed_bits.extend(if hex.len() == 256 / 8 {
&checksum[..8]
} else {
&checksum[..4]
});
let words = seed_bits let words = seed_bits
.chunks_exact(11) .chunks_exact(11)