From 4d7fb0ee74d529cf7cbebcc6e9d7a860d6aef820 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Thu, 11 Jan 2024 00:00:24 +0300 Subject: [PATCH] Reduce amount of `unsafe` (#540) --- belt-hash/src/lib.rs | 1 - blake2/src/lib.rs | 2 +- gost94/src/gost94_core.rs | 2 +- groestl/src/compress1024.rs | 1 - groestl/src/compress512.rs | 1 - jh/benches/machine.rs | 2 +- jh/src/compressor.rs | 2 +- md4/src/lib.rs | 2 +- md5/src/compress/soft.rs | 1 - md5/src/lib.rs | 18 ++++-------------- ripemd/src/c128.rs | 2 -- ripemd/src/c160.rs | 2 -- ripemd/src/c256.rs | 2 +- ripemd/src/c320.rs | 2 +- sha1/src/compress.rs | 11 ++--------- sha1/src/compress/soft.rs | 1 - sha1/src/compress/x86.rs | 18 +++++------------- sha1/src/lib.rs | 5 ++++- sha2/src/core_api.rs | 7 +++++-- sha2/src/sha256.rs | 8 +------- sha2/src/sha256/soft.rs | 1 - sha2/src/sha256/x86.rs | 14 +++++++------- sha2/src/sha512.rs | 8 +------- sha2/src/sha512/soft.rs | 1 - sha2/src/sha512/x86.rs | 22 +++++++++++----------- sha3/src/state.rs | 1 - sha3/tests/turboshake.rs | 2 +- shabal/src/core_api.rs | 21 +++++++-------------- sm3/src/compress.rs | 1 - streebog/src/core_api.rs | 2 +- tiger/src/compress.rs | 1 - whirlpool/src/compress.rs | 7 ++----- whirlpool/src/lib.rs | 21 +++++++-------------- 33 files changed, 65 insertions(+), 127 deletions(-) diff --git a/belt-hash/src/lib.rs b/belt-hash/src/lib.rs index d441158cc..a2550bb3f 100644 --- a/belt-hash/src/lib.rs +++ b/belt-hash/src/lib.rs @@ -158,7 +158,6 @@ pub fn belt_compress(x1: [u32; 4], x2: [u32; 4], x34: [u32; 8]) -> ([u32; 4], [u #[inline(always)] fn xor(a: [u32; 4], b: [u32; 4]) -> [u32; 4] { - // TODO: use array zip on stabilization and MSRV bump [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]] } diff --git a/blake2/src/lib.rs b/blake2/src/lib.rs index e98a07570..d884d1f9f 100644 --- a/blake2/src/lib.rs +++ b/blake2/src/lib.rs @@ -13,7 +13,7 @@ extern crate std; pub use digest::{self, Digest}; -use core::{convert::TryInto, fmt, marker::PhantomData, ops::Div}; +use core::{fmt, marker::PhantomData, ops::Div}; use digest::{ array::{Array, ArraySize}, block_buffer::{Lazy, LazyBuffer}, diff --git a/gost94/src/gost94_core.rs b/gost94/src/gost94_core.rs index 825abf610..671dae661 100644 --- a/gost94/src/gost94_core.rs +++ b/gost94/src/gost94_core.rs @@ -1,5 +1,5 @@ #![allow(clippy::many_single_char_names)] -use core::{convert::TryInto, fmt}; +use core::fmt; use digest::{ block_buffer::Eager, core_api::{ diff --git a/groestl/src/compress1024.rs b/groestl/src/compress1024.rs index fa142c396..56010d1ea 100644 --- a/groestl/src/compress1024.rs +++ b/groestl/src/compress1024.rs @@ -1,6 +1,5 @@ #![allow(clippy::needless_range_loop)] use crate::table::TABLE; -use core::{convert::TryInto, u64}; pub(crate) const COLS: usize = 16; const ROUNDS: u64 = 14; diff --git a/groestl/src/compress512.rs b/groestl/src/compress512.rs index 121e1a395..4257b4f1f 100644 --- a/groestl/src/compress512.rs +++ b/groestl/src/compress512.rs @@ -1,6 +1,5 @@ #![allow(clippy::needless_range_loop)] use crate::table::TABLE; -use core::{convert::TryInto, u64}; pub(crate) const COLS: usize = 8; const ROUNDS: u64 = 10; diff --git a/jh/benches/machine.rs b/jh/benches/machine.rs index 6583eaf44..e503592de 100644 --- a/jh/benches/machine.rs +++ b/jh/benches/machine.rs @@ -22,7 +22,7 @@ macro_rules! mach_bench { input: *const [u8; 64], ) { for _ in 0..160 { - jh::f8_impl(m, state, input as *const _); + jh::f8_impl(m, state, input.cast()); } } b.iter(|| unsafe { runner(m, &mut state, &input) }); diff --git a/jh/src/compressor.rs b/jh/src/compressor.rs index a1b2ea2ac..5cb40a8ca 100644 --- a/jh/src/compressor.rs +++ b/jh/src/compressor.rs @@ -97,7 +97,7 @@ union X2Bytes { #[doc(hidden)] pub fn f8_impl(mach: M, state: &mut [vec128_storage; 8], data: *const u8) { #[allow(clippy::cast_ptr_alignment)] - let data = data as *const M::u128x1; + let data: *const M::u128x1 = data.cast(); let mut y = X8::( mach.unpack(state[0]), mach.unpack(state[1]), diff --git a/md4/src/lib.rs b/md4/src/lib.rs index c25022eba..24d2f6bc8 100644 --- a/md4/src/lib.rs +++ b/md4/src/lib.rs @@ -9,7 +9,7 @@ pub use digest::{self, Digest}; -use core::{convert::TryInto, fmt, num::Wrapping as W}; +use core::{fmt, num::Wrapping as W}; #[cfg(feature = "oid")] use digest::const_oid::{AssociatedOid, ObjectIdentifier}; use digest::{ diff --git a/md5/src/compress/soft.rs b/md5/src/compress/soft.rs index 40630a121..6096f8f90 100644 --- a/md5/src/compress/soft.rs +++ b/md5/src/compress/soft.rs @@ -1,6 +1,5 @@ #![allow(clippy::many_single_char_names, clippy::unreadable_literal)] use crate::consts::RC; -use core::convert::TryInto; #[inline(always)] fn op_f(w: u32, x: u32, y: u32, z: u32, m: u32, c: u32, s: u32) -> u32 { diff --git a/md5/src/lib.rs b/md5/src/lib.rs index 53b5dc07c..2930b5afb 100644 --- a/md5/src/lib.rs +++ b/md5/src/lib.rs @@ -15,6 +15,7 @@ use core::{fmt, slice::from_ref}; #[cfg(feature = "oid")] use digest::const_oid::{AssociatedOid, ObjectIdentifier}; use digest::{ + array::ArrayOps, block_buffer::Eager, core_api::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, @@ -49,7 +50,8 @@ impl UpdateCore for Md5Core { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { self.block_len = self.block_len.wrapping_add(blocks.len() as u64); - compress::compress(&mut self.state, convert(blocks)) + let blocks = ArrayOps::cast_slice_to_core(blocks); + compress::compress(&mut self.state, blocks) } } @@ -62,9 +64,7 @@ impl FixedOutputCore for Md5Core { .wrapping_add(buffer.get_pos() as u64) .wrapping_mul(8); let mut s = self.state; - buffer.len64_padding_le(bit_len, |b| { - compress::compress(&mut s, convert(from_ref(b))) - }); + buffer.len64_padding_le(bit_len, |b| compress::compress(&mut s, from_ref(&b.0))); for (chunk, v) in out.chunks_exact_mut(4).zip(s.iter()) { chunk.copy_from_slice(&v.to_le_bytes()); } @@ -108,13 +108,3 @@ impl AssociatedOid for Md5Core { /// MD5 hasher state. pub type Md5 = CoreWrapper; - -const BLOCK_SIZE: usize = ::BlockSize::USIZE; - -#[inline(always)] -fn convert(blocks: &[Block]) -> &[[u8; BLOCK_SIZE]] { - // SAFETY: Array and [u8; 64] have - // exactly the same memory layout - let p = blocks.as_ptr() as *const [u8; BLOCK_SIZE]; - unsafe { core::slice::from_raw_parts(p, blocks.len()) } -} diff --git a/ripemd/src/c128.rs b/ripemd/src/c128.rs index b531e1b05..432613a03 100644 --- a/ripemd/src/c128.rs +++ b/ripemd/src/c128.rs @@ -1,5 +1,3 @@ -use core::convert::TryInto; - pub const DIGEST_BUF_LEN: usize = 4; pub const WORK_BUF_LEN: usize = 16; diff --git a/ripemd/src/c160.rs b/ripemd/src/c160.rs index db2e3fb19..f3e14a098 100644 --- a/ripemd/src/c160.rs +++ b/ripemd/src/c160.rs @@ -1,5 +1,3 @@ -use core::convert::TryInto; - pub const DIGEST_BUF_LEN: usize = 5; pub const WORK_BUF_LEN: usize = 16; diff --git a/ripemd/src/c256.rs b/ripemd/src/c256.rs index bdcd0c393..cd54e8af0 100644 --- a/ripemd/src/c256.rs +++ b/ripemd/src/c256.rs @@ -1,4 +1,4 @@ -use core::{convert::TryInto, mem::swap}; +use core::mem::swap; pub const DIGEST_BUF_LEN: usize = 8; pub const HALF_DIGEST_BUF_LEN: usize = DIGEST_BUF_LEN / 2; diff --git a/ripemd/src/c320.rs b/ripemd/src/c320.rs index af85eff2a..d962f54ff 100644 --- a/ripemd/src/c320.rs +++ b/ripemd/src/c320.rs @@ -1,4 +1,4 @@ -use core::{convert::TryInto, mem::swap}; +use core::mem::swap; pub const HALF_DIGEST_BUF_LEN: usize = 5; pub const DIGEST_BUF_LEN: usize = 10; diff --git a/sha1/src/compress.rs b/sha1/src/compress.rs index f2bd14426..aa5873519 100644 --- a/sha1/src/compress.rs +++ b/sha1/src/compress.rs @@ -1,5 +1,4 @@ -use crate::{Block, BlockSizeUser, Sha1Core}; -use digest::typenum::Unsigned; +use crate::BLOCK_SIZE; cfg_if::cfg_if! { if #[cfg(feature = "force-soft")] { @@ -27,14 +26,8 @@ cfg_if::cfg_if! { } } -const BLOCK_SIZE: usize = ::BlockSize::USIZE; - /// SHA-1 compression function #[cfg_attr(docsrs, doc(cfg(feature = "compress")))] -pub fn compress(state: &mut [u32; 5], blocks: &[Block]) { - // SAFETY: Array and [u8; 64] have - // exactly the same memory layout - let blocks: &[[u8; BLOCK_SIZE]] = - unsafe { &*(blocks as *const _ as *const [[u8; BLOCK_SIZE]]) }; +pub fn compress(state: &mut [u32; 5], blocks: &[[u8; BLOCK_SIZE]]) { compress_inner(state, blocks); } diff --git a/sha1/src/compress/soft.rs b/sha1/src/compress/soft.rs index 0b9fb2701..0e28e5e2c 100644 --- a/sha1/src/compress/soft.rs +++ b/sha1/src/compress/soft.rs @@ -1,6 +1,5 @@ #![allow(clippy::many_single_char_names)] use super::BLOCK_SIZE; -use core::convert::TryInto; const K: [u32; 4] = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6]; diff --git a/sha1/src/compress/x86.rs b/sha1/src/compress/x86.rs index 4dcd56b8a..d59e7fd09 100644 --- a/sha1/src/compress/x86.rs +++ b/sha1/src/compress/x86.rs @@ -35,18 +35,12 @@ unsafe fn digest_blocks(state: &mut [u32; 5], blocks: &[[u8; 64]]) { #[allow(non_snake_case)] let MASK: __m128i = _mm_set_epi64x(0x0001_0203_0405_0607, 0x0809_0A0B_0C0D_0E0F); - let mut state_abcd = _mm_set_epi32( - state[0] as i32, - state[1] as i32, - state[2] as i32, - state[3] as i32, - ); + let mut state_abcd = _mm_loadu_si128(state.as_ptr().cast()); + state_abcd = _mm_shuffle_epi32(state_abcd, 0b00011011); let mut state_e = _mm_set_epi32(state[4] as i32, 0, 0, 0); for block in blocks { - // SAFETY: we use only unaligned loads with this pointer - #[allow(clippy::cast_ptr_alignment)] - let block_ptr = block.as_ptr() as *const __m128i; + let block_ptr: *const __m128i = block.as_ptr().cast(); let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(0)), MASK); let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.offset(1)), MASK); @@ -90,10 +84,8 @@ unsafe fn digest_blocks(state: &mut [u32; 5], blocks: &[[u8; 64]]) { state_e = _mm_sha1nexte_epu32(h1, state_e); } - state[0] = _mm_extract_epi32(state_abcd, 3) as u32; - state[1] = _mm_extract_epi32(state_abcd, 2) as u32; - state[2] = _mm_extract_epi32(state_abcd, 1) as u32; - state[3] = _mm_extract_epi32(state_abcd, 0) as u32; + state_abcd = _mm_shuffle_epi32(state_abcd, 0b00011011); + _mm_storeu_si128(state.as_mut_ptr().cast(), state_abcd); state[4] = _mm_extract_epi32(state_e, 3) as u32; } diff --git a/sha1/src/lib.rs b/sha1/src/lib.rs index 647f0ace0..8eff0ef03 100644 --- a/sha1/src/lib.rs +++ b/sha1/src/lib.rs @@ -13,6 +13,7 @@ use core::{fmt, slice::from_ref}; #[cfg(feature = "oid")] use digest::const_oid::{AssociatedOid, ObjectIdentifier}; use digest::{ + array::ArrayOps, block_buffer::Eager, core_api::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, @@ -30,6 +31,7 @@ pub use compress::compress; use compress::compress; const STATE_LEN: usize = 5; +const BLOCK_SIZE: usize = ::BlockSize::USIZE; /// Core SHA-1 hasher state. #[derive(Clone)] @@ -56,6 +58,7 @@ impl UpdateCore for Sha1Core { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { self.block_len += blocks.len() as u64; + let blocks = ArrayOps::cast_slice_to_core(blocks); compress(&mut self.h, blocks); } } @@ -67,7 +70,7 @@ impl FixedOutputCore for Sha1Core { let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); let mut h = self.h; - buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b))); + buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(&b.0))); for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) { chunk.copy_from_slice(&v.to_be_bytes()); } diff --git a/sha2/src/core_api.rs b/sha2/src/core_api.rs index cfec02a64..d492a79ac 100644 --- a/sha2/src/core_api.rs +++ b/sha2/src/core_api.rs @@ -1,6 +1,7 @@ use crate::{consts, sha256::compress256, sha512::compress512}; use core::{fmt, slice::from_ref}; use digest::{ + array::ArrayOps, block_buffer::Eager, core_api::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, OutputSizeUser, TruncSide, @@ -34,6 +35,7 @@ impl UpdateCore for Sha256VarCore { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { self.block_len += blocks.len() as u64; + let blocks = ArrayOps::cast_slice_to_core(blocks); compress256(&mut self.state, blocks); } } @@ -60,7 +62,7 @@ impl VariableOutputCore for Sha256VarCore { fn finalize_variable_core(&mut self, buffer: &mut Buffer, out: &mut Output) { let bs = Self::BlockSize::U64; let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); - buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(b))); + buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, from_ref(&b.0))); for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) { chunk.copy_from_slice(&v.to_be_bytes()); @@ -106,6 +108,7 @@ impl UpdateCore for Sha512VarCore { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { self.block_len += blocks.len() as u128; + let blocks = ArrayOps::cast_slice_to_core(blocks); compress512(&mut self.state, blocks); } } @@ -134,7 +137,7 @@ impl VariableOutputCore for Sha512VarCore { fn finalize_variable_core(&mut self, buffer: &mut Buffer, out: &mut Output) { let bs = Self::BlockSize::U64 as u128; let bit_len = 8 * (buffer.get_pos() as u128 + bs * self.block_len); - buffer.len128_padding_be(bit_len, |b| compress512(&mut self.state, from_ref(b))); + buffer.len128_padding_be(bit_len, |b| compress512(&mut self.state, from_ref(&b.0))); for (chunk, v) in out.chunks_exact_mut(8).zip(self.state.iter()) { chunk.copy_from_slice(&v.to_be_bytes()); diff --git a/sha2/src/sha256.rs b/sha2/src/sha256.rs index 7266137f0..44c02acfc 100644 --- a/sha2/src/sha256.rs +++ b/sha2/src/sha256.rs @@ -1,5 +1,3 @@ -use digest::{array::Array, typenum::U64}; - cfg_if::cfg_if! { if #[cfg(feature = "force-soft")] { mod soft; @@ -31,10 +29,6 @@ cfg_if::cfg_if! { /// This is a low-level "hazmat" API which provides direct access to the core /// functionality of SHA-256. #[cfg_attr(docsrs, doc(cfg(feature = "compress")))] -pub fn compress256(state: &mut [u32; 8], blocks: &[Array]) { - // SAFETY: Array and [u8; 64] have - // exactly the same memory layout - let p = blocks.as_ptr() as *const [u8; 64]; - let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) }; +pub fn compress256(state: &mut [u32; 8], blocks: &[[u8; 64]]) { compress(state, blocks) } diff --git a/sha2/src/sha256/soft.rs b/sha2/src/sha256/soft.rs index 69eb48894..315e5060a 100644 --- a/sha2/src/sha256/soft.rs +++ b/sha2/src/sha256/soft.rs @@ -1,6 +1,5 @@ #![allow(clippy::many_single_char_names)] use crate::consts::BLOCK_LEN; -use core::convert::TryInto; #[inline(always)] fn shr(v: [u32; 4], o: u32) -> [u32; 4] { diff --git a/sha2/src/sha256/x86.rs b/sha2/src/sha256/x86.rs index 46019388d..2f59dcf77 100644 --- a/sha2/src/sha256/x86.rs +++ b/sha2/src/sha256/x86.rs @@ -46,7 +46,7 @@ unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) { 0x0405_0607_0001_0203u64 as i64, ); - let state_ptr = state.as_ptr() as *const __m128i; + let state_ptr: *const __m128i = state.as_ptr().cast(); let dcba = _mm_loadu_si128(state_ptr.add(0)); let efgh = _mm_loadu_si128(state_ptr.add(1)); @@ -59,11 +59,11 @@ unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) { let abef_save = abef; let cdgh_save = cdgh; - let data_ptr = block.as_ptr() as *const __m128i; - let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(0)), MASK); - let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(1)), MASK); - let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(2)), MASK); - let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(data_ptr.add(3)), MASK); + let block_ptr: *const __m128i = block.as_ptr().cast(); + let mut w0 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(0)), MASK); + let mut w1 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(1)), MASK); + let mut w2 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(2)), MASK); + let mut w3 = _mm_shuffle_epi8(_mm_loadu_si128(block_ptr.add(3)), MASK); let mut w4; rounds4!(abef, cdgh, w0, 0); @@ -92,7 +92,7 @@ unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) { let dcba = _mm_blend_epi16(feba, dchg, 0xF0); let hgef = _mm_alignr_epi8(dchg, feba, 8); - let state_ptr_mut = state.as_mut_ptr() as *mut __m128i; + let state_ptr_mut: *mut __m128i = state.as_mut_ptr().cast(); _mm_storeu_si128(state_ptr_mut.add(0), dcba); _mm_storeu_si128(state_ptr_mut.add(1), hgef); } diff --git a/sha2/src/sha512.rs b/sha2/src/sha512.rs index 5c3590cf3..59f9cac0c 100644 --- a/sha2/src/sha512.rs +++ b/sha2/src/sha512.rs @@ -1,5 +1,3 @@ -use digest::{array::Array, typenum::U128}; - cfg_if::cfg_if! { if #[cfg(feature = "force-soft")] { mod soft; @@ -33,10 +31,6 @@ cfg_if::cfg_if! { /// This is a low-level "hazmat" API which provides direct access to the core /// functionality of SHA-512. #[cfg_attr(docsrs, doc(cfg(feature = "compress")))] -pub fn compress512(state: &mut [u64; 8], blocks: &[Array]) { - // SAFETY: Array and [u8; 64] have - // exactly the same memory layout - let p = blocks.as_ptr() as *const [u8; 128]; - let blocks = unsafe { core::slice::from_raw_parts(p, blocks.len()) }; +pub fn compress512(state: &mut [u64; 8], blocks: &[[u8; 128]]) { compress(state, blocks) } diff --git a/sha2/src/sha512/soft.rs b/sha2/src/sha512/soft.rs index ab6d56831..17405c5d5 100644 --- a/sha2/src/sha512/soft.rs +++ b/sha2/src/sha512/soft.rs @@ -1,6 +1,5 @@ #![allow(clippy::many_single_char_names)] use crate::consts::{BLOCK_LEN, K64X2}; -use core::convert::TryInto; fn add(a: [u64; 2], b: [u64; 2]) -> [u64; 2] { [a[0].wrapping_add(b[0]), a[1].wrapping_add(b[1])] diff --git a/sha2/src/sha512/x86.rs b/sha2/src/sha512/x86.rs index bb7904088..40a21f05d 100644 --- a/sha2/src/sha512/x86.rs +++ b/sha2/src/sha512/x86.rs @@ -39,7 +39,7 @@ unsafe fn sha512_compress_x86_64_avx2(state: &mut [u64; 8], blocks: &[[u8; 128]] let mut x = [_mm256_setzero_si256(); 8]; for i in (start_block..blocks.len()).step_by(2) { - load_data_avx2(&mut x, &mut ms, &mut t2, blocks.as_ptr().add(i) as *const _); + load_data_avx2(&mut x, &mut ms, &mut t2, blocks.as_ptr().add(i).cast()); // First block let mut current_state = *state; @@ -61,7 +61,7 @@ unsafe fn sha512_compress_x86_64_avx(state: &mut [u64; 8], block: &[u8; 128]) { // Reduced to single iteration let mut current_state = *state; - load_data_avx(&mut x, &mut ms, block.as_ptr() as *const _); + load_data_avx(&mut x, &mut ms, block.as_ptr().cast()); rounds_0_63_avx(&mut current_state, &mut x, &mut ms); rounds_64_79(&mut current_state, &ms); accumulate_state(state, ¤t_state); @@ -74,12 +74,12 @@ unsafe fn load_data_avx(x: &mut [__m128i; 8], ms: &mut MsgSchedule, data: *const macro_rules! unrolled_iterations { ($($i:literal),*) => {$( - x[$i] = _mm_loadu_si128(data.add($i) as *const _); + x[$i] = _mm_loadu_si128(data.add($i).cast()); x[$i] = _mm_shuffle_epi8(x[$i], MASK); let y = _mm_add_epi64( x[$i], - _mm_loadu_si128(&K64[2 * $i] as *const u64 as *const _), + _mm_loadu_si128(K64.as_ptr().add(2 * $i).cast()), ); ms[$i] = y; @@ -106,12 +106,12 @@ unsafe fn load_data_avx2( macro_rules! unrolled_iterations { ($($i:literal),*) => {$( - x[$i] = _mm256_insertf128_si256(x[$i], _mm_loadu_si128(data.add(8 + $i) as *const _), 1); - x[$i] = _mm256_insertf128_si256(x[$i], _mm_loadu_si128(data.add($i) as *const _), 0); + x[$i] = _mm256_insertf128_si256(x[$i], _mm_loadu_si128(data.add(8 + $i).cast()), 1); + x[$i] = _mm256_insertf128_si256(x[$i], _mm_loadu_si128(data.add($i).cast()), 0); x[$i] = _mm256_shuffle_epi8(x[$i], MASK); - let t = _mm_loadu_si128(K64.as_ptr().add($i * 2) as *const u64 as *const _); + let t = _mm_loadu_si128(K64.as_ptr().add($i * 2).cast()); let y = _mm256_add_epi64(x[$i], _mm256_set_m128i(t, t)); ms[$i] = _mm256_extracti128_si256(y, 0); @@ -128,7 +128,7 @@ unsafe fn rounds_0_63_avx(current_state: &mut State, x: &mut [__m128i; 8], ms: & for _ in 0..4 { for j in 0..8 { - let k64 = _mm_loadu_si128(&K64[k64_idx] as *const u64 as *const _); + let k64 = _mm_loadu_si128(K64.as_ptr().add(k64_idx).cast()); let y = sha512_update_x_avx(x, k64); { @@ -154,7 +154,7 @@ unsafe fn rounds_0_63_avx2( for i in 1..5 { for j in 0..8 { - let t = _mm_loadu_si128(K64.as_ptr().add(k64x4_idx) as *const u64 as *const _); + let t = _mm_loadu_si128(K64.as_ptr().add(k64x4_idx).cast()); let y = sha512_update_x_avx2(x, _mm256_set_m128i(t, t)); { @@ -338,12 +338,12 @@ fn_sha512_update_x!(sha512_update_x_avx2, __m256i, { #[inline(always)] fn cast_ms(ms: &MsgSchedule) -> &[u64; SHA512_BLOCK_WORDS_NUM] { - unsafe { &*(ms as *const MsgSchedule as *const _) } + unsafe { &*(ms.as_ptr().cast()) } } #[inline(always)] fn cast_rs(rs: &RoundStates) -> &[u64; SHA512_ROUNDS_NUM] { - unsafe { &*(rs as *const RoundStates as *const _) } + unsafe { &*(rs.as_ptr().cast()) } } type State = [u64; SHA512_HASH_WORDS_NUM]; diff --git a/sha3/src/state.rs b/sha3/src/state.rs index ce3785f75..b651cd3e8 100644 --- a/sha3/src/state.rs +++ b/sha3/src/state.rs @@ -1,4 +1,3 @@ -use core::convert::TryInto; #[cfg(feature = "zeroize")] use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/sha3/tests/turboshake.rs b/sha3/tests/turboshake.rs index 3d08df196..14308acf0 100644 --- a/sha3/tests/turboshake.rs +++ b/sha3/tests/turboshake.rs @@ -1,4 +1,4 @@ -use core::{convert::TryInto, fmt::Debug}; +use core::fmt::Debug; use digest::ExtendableOutput; pub(crate) fn turbo_shake_test( diff --git a/shabal/src/core_api.rs b/shabal/src/core_api.rs index ce5df75df..dc174268f 100644 --- a/shabal/src/core_api.rs +++ b/shabal/src/core_api.rs @@ -1,5 +1,5 @@ use crate::consts; -use core::{convert::TryInto, fmt, mem, num::Wrapping}; +use core::{fmt, mem, num::Wrapping}; use digest::{ array::Array, block_buffer::Eager, @@ -198,19 +198,12 @@ impl VariableOutputCore for ShabalVarCore { 64 => consts::INIT_512, _ => return Err(InvalidOutputSize), }; - let w = Wrapping(1); - // TODO: use `array::map` on MSRV bump - let mut a = [Wrapping(0u32); 12]; - let mut b = [Wrapping(0u32); 16]; - let mut c = [Wrapping(0u32); 16]; - for i in 0..12 { - a[i] = Wrapping(init.0[i]); - } - for i in 0..16 { - b[i] = Wrapping(init.1[i]); - c[i] = Wrapping(init.2[i]); - } - Ok(Self { a, b, c, w }) + Ok(Self { + a: init.0.map(Wrapping), + b: init.1.map(Wrapping), + c: init.2.map(Wrapping), + w: Wrapping(1), + }) } #[inline] diff --git a/sm3/src/compress.rs b/sm3/src/compress.rs index ea381e90b..c0155d58b 100644 --- a/sm3/src/compress.rs +++ b/sm3/src/compress.rs @@ -1,6 +1,5 @@ #![allow(clippy::many_single_char_names, clippy::too_many_arguments)] use crate::{consts::T32, Block, Sm3Core}; -use core::convert::TryInto; #[inline(always)] fn ff1(x: u32, y: u32, z: u32) -> u32 { diff --git a/streebog/src/core_api.rs b/streebog/src/core_api.rs index d143aedcf..b36c655b5 100644 --- a/streebog/src/core_api.rs +++ b/streebog/src/core_api.rs @@ -1,4 +1,4 @@ -use core::{convert::TryInto, fmt}; +use core::fmt; use digest::{ block_buffer::Eager, consts::U64, diff --git a/tiger/src/compress.rs b/tiger/src/compress.rs index 9f7024d7f..3ee461b1b 100644 --- a/tiger/src/compress.rs +++ b/tiger/src/compress.rs @@ -1,6 +1,5 @@ use super::tables::{T1, T2, T3, T4}; use super::State; -use core::convert::TryInto; #[inline(always)] fn round(a: &mut u64, b: &mut u64, c: &mut u64, x: &u64, mul: u8) { diff --git a/whirlpool/src/compress.rs b/whirlpool/src/compress.rs index 4f1664e30..f52ca62f1 100644 --- a/whirlpool/src/compress.rs +++ b/whirlpool/src/compress.rs @@ -1,11 +1,8 @@ -use crate::BLOCK_SIZE; -use core::convert::TryInto; - #[path = "consts.rs"] mod consts; use consts::*; -fn compress_block(state: &mut [u64; 8], b: &[u8; BLOCK_SIZE]) { +fn compress_block(state: &mut [u64; 8], b: &[u8; 64]) { let mut k = [0u64; 8]; let mut block = [0u64; 8]; let mut s = [0u64; 8]; @@ -53,7 +50,7 @@ fn compress_block(state: &mut [u64; 8], b: &[u8; BLOCK_SIZE]) { } } -pub(crate) fn compress(state: &mut [u64; 8], blocks: &[[u8; BLOCK_SIZE]]) { +pub(crate) fn compress(state: &mut [u64; 8], blocks: &[[u8; 64]]) { for block in blocks { compress_block(state, block); } diff --git a/whirlpool/src/lib.rs b/whirlpool/src/lib.rs index b091adca4..d29186690 100644 --- a/whirlpool/src/lib.rs +++ b/whirlpool/src/lib.rs @@ -4,6 +4,7 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] +#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] pub use digest::{self, Digest}; @@ -18,12 +19,13 @@ use compress::compress; use core::fmt; use digest::{ + array::ArrayOps, block_buffer::Eager, core_api::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore, OutputSizeUser, Reset, UpdateCore, }, - typenum::{Unsigned, U64}, + typenum::U64, HashMarker, Output, }; @@ -51,9 +53,10 @@ impl OutputSizeUser for WhirlpoolCore { impl UpdateCore for WhirlpoolCore { #[inline] fn update_blocks(&mut self, blocks: &[Block]) { - let block_bits = 8 * BLOCK_SIZE as u64; + let block_bits = 8 * Self::block_size() as u64; self.update_len(block_bits * (blocks.len() as u64)); - compress(&mut self.state, convert(blocks)); + let blocks = ArrayOps::cast_slice_to_core(blocks); + compress(&mut self.state, blocks); } } @@ -70,7 +73,7 @@ impl FixedOutputCore for WhirlpoolCore { let mut state = self.state; buffer.digest_pad(0x80, &buf, |block| { - compress(&mut state, convert(core::slice::from_ref(block))); + compress(&mut state, core::slice::from_ref(&block.0)); }); for (chunk, v) in out.chunks_exact_mut(8).zip(state.iter()) { @@ -129,13 +132,3 @@ fn adc(a: &mut u64, b: u64, carry: &mut u64) { *a = ret as u64; *carry = (ret >> 64) as u64; } - -const BLOCK_SIZE: usize = ::BlockSize::USIZE; - -#[inline(always)] -fn convert(blocks: &[Block]) -> &[[u8; BLOCK_SIZE]] { - // SAFETY: Array and [u8; 64] have - // exactly the same memory layout - let p = blocks.as_ptr() as *const [u8; BLOCK_SIZE]; - unsafe { core::slice::from_raw_parts(p, blocks.len()) } -}