1use crate::HexError;
6use zeroize::Zeroizing;
7
8pub fn lower_hex_to_bytes(input: &str) -> Result<Vec<u8>, HexError> {
10 let (pairs, remainder) = input.as_bytes().as_chunks::<2>();
11 if !remainder.is_empty() {
12 return Err(HexError::OddLength);
13 }
14
15 let mut output = Zeroizing::new(Vec::with_capacity(pairs.len()));
16 for [high_byte, low_byte] in pairs {
17 let high = lower_hex_value(*high_byte)?;
18 let low = lower_hex_value(*low_byte)?;
19 output.push((high << 4) | low);
20 }
21
22 Ok(core::mem::take(&mut *output))
23}
24
25fn lower_hex_value(byte: u8) -> Result<u8, HexError> {
26 match byte {
27 b'0'..=b'9' => Ok(byte - b'0'),
28 b'a'..=b'f' => Ok(byte - b'a' + 10),
29 b'A'..=b'F' => Err(HexError::Uppercase),
30 _ => Err(HexError::InvalidCharacter),
31 }
32}