From cbd684927c2b1dbace19ccd04157f927a92c12c2 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 16 Dec 2021 00:24:48 +0100 Subject: [PATCH] Sha3 refactor unsafe (#338) --- sha3/src/lib.rs | 2 +- sha3/src/macros.rs | 10 ++-------- sha3/src/state.rs | 38 ++++++-------------------------------- 3 files changed, 9 insertions(+), 41 deletions(-) diff --git a/sha3/src/lib.rs b/sha3/src/lib.rs index b6dcee0b2..e584435cc 100644 --- a/sha3/src/lib.rs +++ b/sha3/src/lib.rs @@ -62,7 +62,7 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_root_url = "https://docs.rs/sha3/0.10.0" )] -#![deny(unsafe_code)] +#![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] pub use digest::{self, Digest}; diff --git a/sha3/src/macros.rs b/sha3/src/macros.rs index 1ec96367b..84d58329b 100644 --- a/sha3/src/macros.rs +++ b/sha3/src/macros.rs @@ -46,10 +46,7 @@ macro_rules! impl_sha3 { self.state.absorb_block(block); - let n = out.len(); - self.state.as_bytes(|state| { - out.copy_from_slice(&state[..n]); - }); + self.state.as_bytes(out); } } @@ -183,10 +180,7 @@ macro_rules! impl_shake { #[inline] fn read_block(&mut self) -> Block { let mut block = Block::::default(); - let n = block.len(); - self.state.as_bytes(|state| { - block.copy_from_slice(&state[..n]); - }); + self.state.as_bytes(&mut block); self.state.apply_f(); block } diff --git a/sha3/src/state.rs b/sha3/src/state.rs index a2494e76a..282515434 100644 --- a/sha3/src/state.rs +++ b/sha3/src/state.rs @@ -12,44 +12,18 @@ impl Sha3State { pub(crate) fn absorb_block(&mut self, block: &[u8]) { debug_assert_eq!(block.len() % 8, 0); - if cfg!(target_endian = "little") { - #[allow(unsafe_code)] - let state = unsafe { &mut *(self.state.as_mut_ptr() as *mut [u8; 8 * PLEN]) }; - for (d, i) in state.iter_mut().zip(block) { - *d ^= *i; - } - } else if cfg!(target_endian = "big") { - let n = block.len() / 8; - let mut buf = [0u64; 21]; - let buf = &mut buf[..n]; - for (o, chunk) in buf.iter_mut().zip(block.chunks_exact(8)) { - *o = u64::from_le_bytes(chunk.try_into().unwrap()); - } - for (d, i) in self.state[..n].iter_mut().zip(buf) { - *d ^= *i; - } + for (b, s) in block.chunks_exact(8).zip(self.state.iter_mut()) { + *s ^= u64::from_le_bytes(b.try_into().unwrap()); } keccak::f1600(&mut self.state); } #[inline(always)] - pub(crate) fn as_bytes(&self, f: F) { - let mut data_copy; - let data_ref: &[u8; 8 * PLEN] = if cfg!(target_endian = "little") { - #[allow(unsafe_code)] - unsafe { - &*(self.state.as_ptr() as *const [u8; 8 * PLEN]) - } - } else { - data_copy = [0u8; 8 * PLEN]; - - for (chunk, v) in data_copy.chunks_exact_mut(8).zip(self.state.iter()) { - chunk.copy_from_slice(&v.to_le_bytes()); - } - &data_copy - }; - f(data_ref); + pub(crate) fn as_bytes(&self, out: &mut [u8]) { + for (o, s) in out.chunks_mut(8).zip(self.state.iter()) { + o.copy_from_slice(&s.to_le_bytes()[..o.len()]); + } } #[inline(always)]