From 212f20c72d703908f6e81b5d569b33d9f5a6ee85 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Fri, 20 Jan 2023 21:03:08 +0100 Subject: Simplify HMAC function. It's quite a bit faster, and easier to understand. --- src/passwordmaker/hmac.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src/passwordmaker/hmac.rs') diff --git a/src/passwordmaker/hmac.rs b/src/passwordmaker/hmac.rs index 62b77fd..339f7ef 100644 --- a/src/passwordmaker/hmac.rs +++ b/src/passwordmaker/hmac.rs @@ -1,26 +1,23 @@ use crate::Hasher; -pub(super) fn hmac(key : K, data : M) -> T::Output +pub(super) fn hmac(key : &[u8], data : M) -> T::Output where T : Hasher, T::Output : AsRef<[u8]>, - K : Iterator, M : Iterator, { - let key = key.collect::>(); + //Sorry for this uglyness. key_hash is an Option because we don't want to compute it if we don't need it, but + //we also want to be able to reference it in case it's needed. let key_hash = if key.len() > 64 { Some(T::hash(&key)) } else { None }; - let key = key_hash.as_ref().map(T::Output::as_ref).map(<&[u8]>::into_iter).unwrap_or_else(|| (&key).into_iter()).copied(); + let key = key_hash.as_ref().map(T::Output::as_ref).map(<&[u8]>::into_iter) + .unwrap_or_else(|| (&key).into_iter()).copied(); - let key = key.chain(std::iter::repeat(0)); //if key[i] does not exist, use 0 instead. + let key = key + .chain(std::iter::repeat(0)) //if key[i] does not exist, use 0 instead. + .take(64); //and the pads have 64 bytes - let mut inner_pad = [0u8;64]; - let mut outer_pad = [0u8;64]; + let inner_pad = key.clone().map(|k| k ^ 0x36); + let outer_pad = key.map(|k| k ^ 0x5C); - let pads = inner_pad.iter_mut().zip(outer_pad.iter_mut()); - for ((i,o),k) in pads.zip(key) { - *i = k ^ 0x36; - *o = k ^ 0x5C; - } - - let hash = T::hash(&inner_pad.iter().copied().chain(data).collect::>()); - T::hash(&outer_pad.iter().chain(hash.as_ref().iter()).copied().collect::>()) + let hash = T::hash(&inner_pad.chain(data).collect::>()); + T::hash(&outer_pad.chain(hash.as_ref().iter().copied()).collect::>()) } \ No newline at end of file -- cgit v1.2.3