|
| 1 | +//! Utility functions. |
| 2 | +//! |
| 3 | +//! Note that support of big-endian targets is somewhat sub-optimal since we prioritized |
| 4 | +//! simplicity of the implementation. |
| 5 | +
|
| 6 | +#[inline(always)] |
| 7 | +pub(crate) fn absorb_full<const N: usize, const RATE: usize>( |
| 8 | + state: &mut [u64; N], |
| 9 | + block: &[u8; RATE], |
| 10 | +) { |
| 11 | + const { |
| 12 | + assert!(size_of::<[u8; RATE]>() <= size_of::<[u64; N]>()); |
| 13 | + assert!(RATE % size_of::<u64>() == 0); |
| 14 | + }; |
| 15 | + |
| 16 | + let chunks = block.chunks_exact(size_of::<u64>()); |
| 17 | + assert!(chunks.remainder().is_empty()); |
| 18 | + |
| 19 | + for (dst, chunk) in state.iter_mut().zip(chunks) { |
| 20 | + let chunk = chunk.try_into().expect("chunk has correct length"); |
| 21 | + *dst ^= u64::from_le_bytes(chunk); |
| 22 | + } |
| 23 | +} |
| 24 | + |
1 | 25 | #[inline(always)] |
2 | | -pub(crate) fn xor_into_state<const N: usize, const RATE: usize>( |
| 26 | +pub(crate) fn absorb_partial<const N: usize, const RATE: usize>( |
3 | 27 | state: &mut [u64; N], |
4 | 28 | offset: usize, |
5 | 29 | data: &[u8], |
@@ -61,22 +85,20 @@ pub(crate) fn squeeze_read_partial<const N: usize, const RATE: usize>( |
61 | 85 | assert!(RATE % size_of::<u64>() == 0); |
62 | 86 | }; |
63 | 87 |
|
64 | | - let (sub_state, mut buf); |
65 | | - if cfg!(target_endian = "little") { |
| 88 | + let mut buf = [0u8; RATE]; |
| 89 | + |
| 90 | + let sub_state: &[u8; RATE] = if cfg!(target_endian = "little") { |
66 | 91 | // SAFETY: casting of `&[u64; N]` into `&[u8; M]` is safe if |
67 | 92 | // `size_of::<[u8; M]>() <= size_of::<[u64; N]>())` |
68 | | - sub_state = unsafe { &*(state.as_ptr().cast::<[u8; RATE]>()) }; |
| 93 | + unsafe { &*(state.as_ptr().cast::<[u8; RATE]>()) } |
69 | 94 | } else { |
70 | | - buf = [0u8; RATE]; |
71 | | - |
72 | 95 | let mut chunks = buf.chunks_exact_mut(size_of::<u64>()); |
73 | 96 | for (src, dst) in state.iter().zip(&mut chunks) { |
74 | 97 | dst.copy_from_slice(&src.to_le_bytes()); |
75 | 98 | } |
76 | 99 | assert!(chunks.into_remainder().is_empty()); |
77 | | - |
78 | | - sub_state = &buf; |
79 | | - } |
| 100 | + &buf |
| 101 | + }; |
80 | 102 |
|
81 | 103 | let src = &sub_state[offset..][..dst.len()]; |
82 | 104 | dst.copy_from_slice(src); |
@@ -112,22 +134,20 @@ pub(crate) fn squeeze_xor_partial<const N: usize, const RATE: usize>( |
112 | 134 | assert!(RATE % size_of::<u64>() == 0); |
113 | 135 | }; |
114 | 136 |
|
115 | | - let (sub_state, mut buf); |
116 | | - if cfg!(target_endian = "little") { |
| 137 | + let mut buf = [0u8; RATE]; |
| 138 | + |
| 139 | + let sub_state: &[u8; RATE] = if cfg!(target_endian = "little") { |
117 | 140 | // SAFETY: casting of `&[u64; N]` into `&[u8; M]` is safe if |
118 | 141 | // `size_of::<[u8; M]>() <= size_of::<[u64; N]>())` |
119 | | - sub_state = unsafe { &*(state.as_ptr().cast::<[u8; RATE]>()) }; |
| 142 | + unsafe { &*(state.as_ptr().cast::<[u8; RATE]>()) } |
120 | 143 | } else { |
121 | | - buf = [0u8; RATE]; |
122 | | - |
123 | 144 | let mut chunks = buf.chunks_exact_mut(size_of::<u64>()); |
124 | 145 | for (src, dst) in state.iter().zip(&mut chunks) { |
125 | 146 | dst.copy_from_slice(&src.to_le_bytes()); |
126 | 147 | } |
127 | 148 | assert!(chunks.into_remainder().is_empty()); |
128 | | - |
129 | | - sub_state = &buf; |
130 | | - } |
| 149 | + &buf |
| 150 | + }; |
131 | 151 |
|
132 | 152 | let src = &sub_state[offset..][..dst.len()]; |
133 | 153 | for i in 0..dst.len() { |
|
0 commit comments