From b69fa15e20ae8491710af5390101f487513f56a7 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 11 Jul 2019 15:11:01 -0400 Subject: [PATCH 1/6] hmac: Refer to HashEngine and Hash as *Trait --- src/hmac.rs | 54 +++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/hmac.rs b/src/hmac.rs index 09a846b..6201b2a 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -23,13 +23,15 @@ use core::{borrow, fmt, ops, str}; #[cfg(feature="serde")] use serde::{Serialize, Serializer, Deserialize, Deserializer}; -use {Error, Hash, HashEngine}; +use HashEngine as EngineTrait; +use Hash as HashTrait; +use Error; /// A hash computed from a RFC 2104 HMAC. Parameterized by the underlying hash function. #[derive(Copy, Clone, PartialEq, Eq, Default, PartialOrd, Ord, Hash)] -pub struct Hmac(T); +pub struct Hmac(T); -impl str::FromStr for Hmac { +impl str::FromStr for Hmac { type Err = ::Err; fn from_str(s: &str) -> Result { Ok(Hmac(str::FromStr::from_str(s)?)) @@ -38,21 +40,21 @@ impl str::FromStr for Hmac { /// Pair of underlying hash midstates which represent the current state /// of an `HmacEngine` -pub struct HmacMidState { +pub struct HmacMidState { /// Midstate of the inner hash engine - pub inner: ::MidState, + pub inner: ::MidState, /// Midstate of the outer hash engine - pub outer: ::MidState, + pub outer: ::MidState, } /// Pair of underyling hash engines, used for the inner and outer hash of HMAC #[derive(Clone)] -pub struct HmacEngine { +pub struct HmacEngine { iengine: T::Engine, oengine: T::Engine, } -impl HmacEngine { +impl HmacEngine { /// Construct a new keyed HMAC with the given key. We only support underlying hashes /// whose block sizes are ≤ 128 bytes; larger hashes will result in panics. pub fn new(key: &[u8]) -> HmacEngine { @@ -61,12 +63,12 @@ impl HmacEngine { let mut ipad = [0x36u8; 128]; let mut opad = [0x5cu8; 128]; let mut ret = HmacEngine { - iengine: ::engine(), - oengine: ::engine(), + iengine: ::engine(), + oengine: ::engine(), }; if key.len() > T::Engine::BLOCK_SIZE { - let hash = ::hash(key); + let hash = ::hash(key); for (b_i, b_h) in ipad.iter_mut().zip(&hash[..]) { *b_i ^= *b_h; } @@ -82,13 +84,13 @@ impl HmacEngine { } }; - HashEngine::input(&mut ret.iengine, &ipad[..T::Engine::BLOCK_SIZE]); - HashEngine::input(&mut ret.oengine, &opad[..T::Engine::BLOCK_SIZE]); + EngineTrait::input(&mut ret.iengine, &ipad[..T::Engine::BLOCK_SIZE]); + EngineTrait::input(&mut ret.oengine, &opad[..T::Engine::BLOCK_SIZE]); ret } } -impl HashEngine for HmacEngine { +impl EngineTrait for HmacEngine { type MidState = HmacMidState; fn midstate(&self) -> Self::MidState { @@ -105,66 +107,66 @@ impl HashEngine for HmacEngine { } } -impl fmt::Debug for Hmac { +impl fmt::Debug for Hmac { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&self.0, f) } } -impl fmt::Display for Hmac { +impl fmt::Display for Hmac { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } -impl fmt::LowerHex for Hmac { +impl fmt::LowerHex for Hmac { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) } } -impl ops::Index for Hmac { +impl ops::Index for Hmac { type Output = u8; fn index(&self, index: usize) -> &u8 { &self.0[index] } } -impl ops::Index> for Hmac { +impl ops::Index> for Hmac { type Output = [u8]; fn index(&self, index: ops::Range) -> &[u8] { &self.0[index] } } -impl ops::Index> for Hmac { +impl ops::Index> for Hmac { type Output = [u8]; fn index(&self, index: ops::RangeFrom) -> &[u8] { &self.0[index] } } -impl ops::Index> for Hmac { +impl ops::Index> for Hmac { type Output = [u8]; fn index(&self, index: ops::RangeTo) -> &[u8] { &self.0[index] } } -impl ops::Index for Hmac { +impl ops::Index for Hmac { type Output = [u8]; fn index(&self, index: ops::RangeFull) -> &[u8] { &self.0[index] } } -impl borrow::Borrow<[u8]> for Hmac { +impl borrow::Borrow<[u8]> for Hmac { fn borrow(&self) -> &[u8] { &self[..] } } -impl Hash for Hmac { +impl HashTrait for Hmac { type Engine = HmacEngine; type Inner = T::Inner; @@ -195,14 +197,14 @@ impl Hash for Hmac { } #[cfg(feature="serde")] -impl Serialize for Hmac { +impl Serialize for Hmac { fn serialize(&self, s: S) -> Result { Serialize::serialize(&self.0, s) } } #[cfg(feature="serde")] -impl<'de, T: Hash + Deserialize<'de>> Deserialize<'de> for Hmac { +impl<'de, T: HashTrait + Deserialize<'de>> Deserialize<'de> for Hmac { fn deserialize>(d: D) -> Result, D::Error> { let inner = Deserialize::deserialize(d)?; Ok(Hmac(inner)) From 1d98049ec01d3dd68058c8ecfccbc1412e6fdd0e Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 11 Jul 2019 15:24:54 -0400 Subject: [PATCH 2/6] Derive Clone instead of implementing. --- src/ripemd160.rs | 11 +---------- src/sha1.rs | 11 +---------- src/sha256.rs | 11 +---------- src/sha512.rs | 11 +---------- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/src/ripemd160.rs b/src/ripemd160.rs index a398250..0a75b1d 100644 --- a/src/ripemd160.rs +++ b/src/ripemd160.rs @@ -29,22 +29,13 @@ use Error; const BLOCK_SIZE: usize = 64; /// Engine to compute RIPEMD160 hash function +#[derive(Clone)] pub struct HashEngine { buffer: [u8; BLOCK_SIZE], h: [u32; 5], length: usize, } -impl Clone for HashEngine { - fn clone(&self) -> HashEngine { - HashEngine { - h: self.h, - length: self.length, - buffer: self.buffer, - } - } -} - impl EngineTrait for HashEngine { type MidState = [u8; 20]; diff --git a/src/sha1.rs b/src/sha1.rs index 57e7152..a1587b8 100644 --- a/src/sha1.rs +++ b/src/sha1.rs @@ -24,22 +24,13 @@ use Error; const BLOCK_SIZE: usize = 64; /// Engine to compute SHA1 hash function +#[derive(Clone)] pub struct HashEngine { buffer: [u8; BLOCK_SIZE], h: [u32; 5], length: usize, } -impl Clone for HashEngine { - fn clone(&self) -> HashEngine { - HashEngine { - h: self.h, - length: self.length, - buffer: self.buffer, - } - } -} - impl EngineTrait for HashEngine { type MidState = [u8; 20]; diff --git a/src/sha256.rs b/src/sha256.rs index c1205db..51c3def 100644 --- a/src/sha256.rs +++ b/src/sha256.rs @@ -25,22 +25,13 @@ use Error; const BLOCK_SIZE: usize = 64; /// Engine to compute SHA256 hash function +#[derive(Clone)] pub struct HashEngine { buffer: [u8; BLOCK_SIZE], h: [u32; 8], length: usize, } -impl Clone for HashEngine { - fn clone(&self) -> HashEngine { - HashEngine { - h: self.h, - length: self.length, - buffer: self.buffer, - } - } -} - impl EngineTrait for HashEngine { type MidState = Midstate; diff --git a/src/sha512.rs b/src/sha512.rs index 22b2fc1..dca533e 100644 --- a/src/sha512.rs +++ b/src/sha512.rs @@ -30,22 +30,13 @@ use Error; const BLOCK_SIZE: usize = 128; /// Engine to compute SHA512 hash function +#[derive(Clone)] pub struct HashEngine { h: [u64; 8], length: usize, buffer: [u8; BLOCK_SIZE], } -impl Clone for HashEngine { - fn clone(&self) -> HashEngine { - HashEngine { - h: self.h, - length: self.length, - buffer: self.buffer, - } - } -} - impl EngineTrait for HashEngine { type MidState = [u8; 64]; From b1d045f390c6dddb26d8b13d22245d2f4721d31c Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 11 Jul 2019 15:29:55 -0400 Subject: [PATCH 3/6] Implement Default for Engines, use for HashTrait::engine() --- src/hmac.rs | 10 ++++++---- src/lib.rs | 6 ++++-- src/ripemd160.rs | 18 ++++++++++-------- src/sha1.rs | 18 ++++++++++-------- src/sha256.rs | 18 ++++++++++-------- src/sha512.rs | 24 +++++++++++++----------- src/siphash24.rs | 10 ++++++---- 7 files changed, 59 insertions(+), 45 deletions(-) diff --git a/src/hmac.rs b/src/hmac.rs index 6201b2a..6034250 100644 --- a/src/hmac.rs +++ b/src/hmac.rs @@ -54,6 +54,12 @@ pub struct HmacEngine { oengine: T::Engine, } +impl Default for HmacEngine { + fn default() -> Self { + HmacEngine::new(&[]) + } +} + impl HmacEngine { /// Construct a new keyed HMAC with the given key. We only support underlying hashes /// whose block sizes are ≤ 128 bytes; larger hashes will result in panics. @@ -170,10 +176,6 @@ impl HashTrait for Hmac { type Engine = HmacEngine; type Inner = T::Inner; - fn engine() -> HmacEngine { - HmacEngine::new(&[]) - } - fn from_engine(mut e: HmacEngine) -> Hmac { let ihash = T::from_engine(e.iengine); e.oengine.input(&ihash[..]); diff --git a/src/lib.rs b/src/lib.rs index 9d215c9..2824837 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ pub use error::Error; /// A hashing engine which bytes can be serialized into. It is expected /// to implement the `io::Write` trait, but to never return errors under /// any conditions. -pub trait HashEngine: Clone { +pub trait HashEngine: Clone + Default { /// Byte array representing the internal state of the hash engine type MidState; @@ -93,7 +93,9 @@ pub trait Hash: Copy + Clone + PartialEq + Eq + Default + PartialOrd + Ord + type Inner: hex::FromHex; /// Construct a new engine - fn engine() -> Self::Engine; + fn engine() -> Self::Engine { + Self::Engine::default() + } /// Produce a hash from the current state of a given engine fn from_engine(e: Self::Engine) -> Self; diff --git a/src/ripemd160.rs b/src/ripemd160.rs index 0a75b1d..f01f77a 100644 --- a/src/ripemd160.rs +++ b/src/ripemd160.rs @@ -36,6 +36,16 @@ pub struct HashEngine { length: usize, } +impl Default for HashEngine { + fn default() -> Self { + HashEngine { + h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0], + length: 0, + buffer: [0; BLOCK_SIZE], + } + } +} + impl EngineTrait for HashEngine { type MidState = [u8; 20]; @@ -80,14 +90,6 @@ impl HashTrait for Hash { type Engine = HashEngine; type Inner = [u8; 20]; - fn engine() -> HashEngine { - HashEngine { - h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0], - length: 0, - buffer: [0; BLOCK_SIZE], - } - } - #[cfg(not(feature = "fuzztarget"))] fn from_engine(mut e: HashEngine) -> Hash { // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining diff --git a/src/sha1.rs b/src/sha1.rs index a1587b8..23d82a0 100644 --- a/src/sha1.rs +++ b/src/sha1.rs @@ -31,6 +31,16 @@ pub struct HashEngine { length: usize, } +impl Default for HashEngine { + fn default() -> Self { + HashEngine { + h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0], + length: 0, + buffer: [0; BLOCK_SIZE], + } + } +} + impl EngineTrait for HashEngine { type MidState = [u8; 20]; @@ -75,14 +85,6 @@ impl HashTrait for Hash { type Engine = HashEngine; type Inner = [u8; 20]; - fn engine() -> HashEngine { - HashEngine { - h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0], - length: 0, - buffer: [0; BLOCK_SIZE], - } - } - fn from_engine(mut e: HashEngine) -> Hash { // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining let data_len = e.length as u64; diff --git a/src/sha256.rs b/src/sha256.rs index 51c3def..c3a019b 100644 --- a/src/sha256.rs +++ b/src/sha256.rs @@ -32,6 +32,16 @@ pub struct HashEngine { length: usize, } +impl Default for HashEngine { + fn default() -> Self { + HashEngine { + h: [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19], + length: 0, + buffer: [0; BLOCK_SIZE], + } + } +} + impl EngineTrait for HashEngine { type MidState = Midstate; @@ -76,14 +86,6 @@ impl HashTrait for Hash { type Engine = HashEngine; type Inner = [u8; 32]; - fn engine() -> HashEngine { - HashEngine { - h: [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19], - length: 0, - buffer: [0; BLOCK_SIZE], - } - } - #[cfg(not(feature = "fuzztarget"))] fn from_engine(mut e: HashEngine) -> Hash { // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining diff --git a/src/sha512.rs b/src/sha512.rs index dca533e..aebe857 100644 --- a/src/sha512.rs +++ b/src/sha512.rs @@ -37,6 +37,19 @@ pub struct HashEngine { buffer: [u8; BLOCK_SIZE], } +impl Default for HashEngine { + fn default() -> Self { + HashEngine { + h: [ + 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, + ], + length: 0, + buffer: [0; BLOCK_SIZE], + } + } +} + impl EngineTrait for HashEngine { type MidState = [u8; 64]; @@ -122,17 +135,6 @@ impl HashTrait for Hash { type Engine = HashEngine; type Inner = [u8; 64]; - fn engine() -> HashEngine { - HashEngine { - h: [ - 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, - 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, - ], - length: 0, - buffer: [0; BLOCK_SIZE], - } - } - #[cfg(not(feature = "fuzztarget"))] fn from_engine(mut e: HashEngine) -> Hash { // pad buffer with a single 1-bit then all 0s, until there are exactly 16 bytes remaining diff --git a/src/siphash24.rs b/src/siphash24.rs index 83bb81b..c1996be 100644 --- a/src/siphash24.rs +++ b/src/siphash24.rs @@ -134,6 +134,12 @@ impl HashEngine { } } +impl Default for HashEngine { + fn default() -> Self { + HashEngine::new() + } +} + impl EngineTrait for HashEngine { type MidState = State; @@ -251,10 +257,6 @@ impl HashTrait for Hash { type Engine = HashEngine; type Inner = [u8; 8]; - fn engine() -> HashEngine { - HashEngine::new() - } - #[cfg(not(feature = "fuzztarget"))] fn from_engine(e: HashEngine) -> Hash { Hash::from_u64(Hash::from_engine_to_u64(e)) From b1570b8802252b107457c1cedea8258e3dc30a79 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 11 Jul 2019 15:32:31 -0400 Subject: [PATCH 4/6] Better compilation-time checking using From trait --- src/siphash24.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/siphash24.rs b/src/siphash24.rs index c1996be..bd409e7 100644 --- a/src/siphash24.rs +++ b/src/siphash24.rs @@ -298,15 +298,15 @@ unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { let mut i = 0; // current byte index (from LSB) in the output u64 let mut out = 0; if i + 3 < len { - out = load_int_le!(buf, start + i, u32) as u64; + out = u64::from(load_int_le!(buf, start + i, u32)); i += 4; } if i + 1 < len { - out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8); + out |= u64::from(load_int_le!(buf, start + i, u16)) << (i * 8); i += 2 } if i < len { - out |= (*buf.get_unchecked(start + i) as u64) << (i * 8); + out |= u64::from(*buf.get_unchecked(start + i)) << (i * 8); i += 1; } debug_assert_eq!(i, len); From db056a88bda8294ea0bdd9c1f9515034f56725c2 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 11 Jul 2019 15:33:27 -0400 Subject: [PATCH 5/6] Don't reference then immediately dereference --- src/ripemd160.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ripemd160.rs b/src/ripemd160.rs index f01f77a..acb9a95 100644 --- a/src/ripemd160.rs +++ b/src/ripemd160.rs @@ -172,8 +172,8 @@ macro_rules! process_block( $( par_round5: h_ordering $pf0:expr, $pf1:expr, $pf2:expr, $pf3:expr, $pf4:expr; data_index $pdata_index5:expr; roll_shift $pbits5:expr; )* ) => ({ - let mut bb = *$h; - let mut bbb = *$h; + let mut bb = $h; + let mut bbb = $h; // Round 1 $( round!(bb[$f0], bb[$f1], bb[$f2], bb[$f3], bb[$f4], @@ -246,7 +246,7 @@ impl HashEngine { let mut w = [0u32; 16]; LittleEndian::read_u32_into(&self.buffer, &mut w); - process_block!(&mut self.h, &mut w, + process_block!(self.h, w, // Round 1 round1: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 11; round1: h_ordering 4, 0, 1, 2, 3; data_index 1; roll_shift 14; From 835e37a2becefcbd1e382e2167bdb6ccf875426c Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 11 Jul 2019 15:39:43 -0400 Subject: [PATCH 6/6] Use iter instead of into_iter as no move occurs --- src/hex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hex.rs b/src/hex.rs index e325a89..d851924 100644 --- a/src/hex.rs +++ b/src/hex.rs @@ -127,7 +127,7 @@ pub fn format_hex(data: &[u8], f: &mut fmt::Formatter) -> fmt::Result { for _ in (2 * data.len())..width { f.write_str("0")?; } - for ch in data.into_iter().take(prec / 2) { + for ch in data.iter().take(prec / 2) { write!(f, "{:02x}", *ch)?; } if prec < 2 * data.len() && prec % 2 == 1 {