Skip to content

Commit

Permalink
Reduce amount of unsafe (#540)
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov authored Jan 10, 2024
1 parent 2dd1703 commit 4d7fb0e
Show file tree
Hide file tree
Showing 33 changed files with 65 additions and 127 deletions.
1 change: 0 additions & 1 deletion belt-hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
}

Expand Down
2 changes: 1 addition & 1 deletion blake2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
2 changes: 1 addition & 1 deletion gost94/src/gost94_core.rs
Original file line number Diff line number Diff line change
@@ -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::{
Expand Down
1 change: 0 additions & 1 deletion groestl/src/compress1024.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
1 change: 0 additions & 1 deletion groestl/src/compress512.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion jh/benches/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) });
Expand Down
2 changes: 1 addition & 1 deletion jh/src/compressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ union X2Bytes<M: Machine> {
#[doc(hidden)]
pub fn f8_impl<M: Machine>(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::<M>(
mach.unpack(state[0]),
mach.unpack(state[1]),
Expand Down
2 changes: 1 addition & 1 deletion md4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down
1 change: 0 additions & 1 deletion md5/src/compress/soft.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
18 changes: 4 additions & 14 deletions md5/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -49,7 +50,8 @@ impl UpdateCore for Md5Core {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
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)
}
}

Expand All @@ -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());
}
Expand Down Expand Up @@ -108,13 +108,3 @@ impl AssociatedOid for Md5Core {

/// MD5 hasher state.
pub type Md5 = CoreWrapper<Md5Core>;

const BLOCK_SIZE: usize = <Md5Core as BlockSizeUser>::BlockSize::USIZE;

#[inline(always)]
fn convert(blocks: &[Block<Md5Core>]) -> &[[u8; BLOCK_SIZE]] {
// SAFETY: Array<u8, U64> 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()) }
}
2 changes: 0 additions & 2 deletions ripemd/src/c128.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::convert::TryInto;

pub const DIGEST_BUF_LEN: usize = 4;
pub const WORK_BUF_LEN: usize = 16;

Expand Down
2 changes: 0 additions & 2 deletions ripemd/src/c160.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use core::convert::TryInto;

pub const DIGEST_BUF_LEN: usize = 5;
pub const WORK_BUF_LEN: usize = 16;

Expand Down
2 changes: 1 addition & 1 deletion ripemd/src/c256.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ripemd/src/c320.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
11 changes: 2 additions & 9 deletions sha1/src/compress.rs
Original file line number Diff line number Diff line change
@@ -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")] {
Expand Down Expand Up @@ -27,14 +26,8 @@ cfg_if::cfg_if! {
}
}

const BLOCK_SIZE: usize = <Sha1Core as BlockSizeUser>::BlockSize::USIZE;

/// SHA-1 compression function
#[cfg_attr(docsrs, doc(cfg(feature = "compress")))]
pub fn compress(state: &mut [u32; 5], blocks: &[Block<Sha1Core>]) {
// SAFETY: Array<u8, U64> 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);
}
1 change: 0 additions & 1 deletion sha1/src/compress/soft.rs
Original file line number Diff line number Diff line change
@@ -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];

Expand Down
18 changes: 5 additions & 13 deletions sha1/src/compress/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
5 changes: 4 additions & 1 deletion sha1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -30,6 +31,7 @@ pub use compress::compress;
use compress::compress;

const STATE_LEN: usize = 5;
const BLOCK_SIZE: usize = <Sha1Core as BlockSizeUser>::BlockSize::USIZE;

/// Core SHA-1 hasher state.
#[derive(Clone)]
Expand All @@ -56,6 +58,7 @@ impl UpdateCore for Sha1Core {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len += blocks.len() as u64;
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress(&mut self.h, blocks);
}
}
Expand All @@ -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());
}
Expand Down
7 changes: 5 additions & 2 deletions sha2/src/core_api.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -34,6 +35,7 @@ impl UpdateCore for Sha256VarCore {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len += blocks.len() as u64;
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress256(&mut self.state, blocks);
}
}
Expand All @@ -60,7 +62,7 @@ impl VariableOutputCore for Sha256VarCore {
fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
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());
Expand Down Expand Up @@ -106,6 +108,7 @@ impl UpdateCore for Sha512VarCore {
#[inline]
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
self.block_len += blocks.len() as u128;
let blocks = ArrayOps::cast_slice_to_core(blocks);
compress512(&mut self.state, blocks);
}
}
Expand Down Expand Up @@ -134,7 +137,7 @@ impl VariableOutputCore for Sha512VarCore {
fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
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());
Expand Down
8 changes: 1 addition & 7 deletions sha2/src/sha256.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use digest::{array::Array, typenum::U64};

cfg_if::cfg_if! {
if #[cfg(feature = "force-soft")] {
mod soft;
Expand Down Expand Up @@ -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<u8, U64>]) {
// SAFETY: Array<u8, U64> 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)
}
1 change: 0 additions & 1 deletion sha2/src/sha256/soft.rs
Original file line number Diff line number Diff line change
@@ -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] {
Expand Down
14 changes: 7 additions & 7 deletions sha2/src/sha256/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 1 addition & 7 deletions sha2/src/sha512.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use digest::{array::Array, typenum::U128};

cfg_if::cfg_if! {
if #[cfg(feature = "force-soft")] {
mod soft;
Expand Down Expand Up @@ -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<u8, U128>]) {
// SAFETY: Array<u8, U64> 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)
}
1 change: 0 additions & 1 deletion sha2/src/sha512/soft.rs
Original file line number Diff line number Diff line change
@@ -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])]
Expand Down
Loading

0 comments on commit 4d7fb0e

Please sign in to comment.