diff options
author | Andreas Grois <andi@grois.info> | 2023-01-20 21:03:08 +0100 |
---|---|---|
committer | Andreas Grois <andi@grois.info> | 2023-01-20 21:13:39 +0100 |
commit | 212f20c72d703908f6e81b5d569b33d9f5a6ee85 (patch) | |
tree | 35e135e437375640cefd62398ad9fabc300891ce /src/passwordmaker/hmac.rs | |
parent | a55761caefadafbd88a743dd1f6d5811f6791b86 (diff) |
Simplify HMAC function.v0.2.0
It's quite a bit faster, and easier to understand.
Diffstat (limited to 'src/passwordmaker/hmac.rs')
-rw-r--r-- | src/passwordmaker/hmac.rs | 27 |
1 files changed, 12 insertions, 15 deletions
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<T, K, M>(key : K, data : M) -> T::Output +pub(super) fn hmac<T, M>(key : &[u8], data : M) -> T::Output where T : Hasher, T::Output : AsRef<[u8]>, - K : Iterator<Item=u8>, M : Iterator<Item=u8>, { - let key = key.collect::<Vec<_>>(); + //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::<Vec<_>>()); - T::hash(&outer_pad.iter().chain(hash.as_ref().iter()).copied().collect::<Vec<_>>()) + let hash = T::hash(&inner_pad.chain(data).collect::<Vec<_>>()); + T::hash(&outer_pad.chain(hash.as_ref().iter().copied()).collect::<Vec<_>>()) }
\ No newline at end of file |