1111//! [`#[inline]`](https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute).
1212//!
1313//! An optional SIMD variant that computes multiple hashes in parallel is also implemented.
14-
1514pub fn buffer_size ( n : usize ) -> usize {
1615 ( n + 9 ) . next_multiple_of ( 64 )
1716}
1817
19- pub fn hash ( mut buffer : & mut [ u8 ] , size : usize ) -> ( u32 , u32 , u32 , u32 ) {
18+ #[ inline]
19+ pub fn hash ( buffer : & mut [ u8 ] , size : usize ) -> [ u32 ; 4 ] {
2020 let end = buffer. len ( ) - 8 ;
2121 let bits = size * 8 ;
2222
@@ -29,11 +29,8 @@ pub fn hash(mut buffer: &mut [u8], size: usize) -> (u32, u32, u32, u32) {
2929 let mut c0: u32 = 0x98badcfe ;
3030 let mut d0: u32 = 0x10325476 ;
3131
32- while !buffer. is_empty ( ) {
33- let ( prefix, suffix) = buffer. split_at_mut ( 64 ) ;
34- buffer = suffix;
35-
36- for ( i, chunk) in prefix. chunks_exact ( 4 ) . enumerate ( ) {
32+ for block in buffer. chunks_exact ( 64 ) {
33+ for ( i, chunk) in block. chunks_exact ( 4 ) . enumerate ( ) {
3734 m[ i] = u32:: from_le_bytes ( chunk. try_into ( ) . unwrap ( ) ) ;
3835 }
3936
@@ -116,7 +113,7 @@ pub fn hash(mut buffer: &mut [u8], size: usize) -> (u32, u32, u32, u32) {
116113 d0 = d0. wrapping_add ( d) ;
117114 }
118115
119- ( a0. to_be ( ) , b0. to_be ( ) , c0. to_be ( ) , d0. to_be ( ) )
116+ [ a0. to_be ( ) , b0. to_be ( ) , c0. to_be ( ) , d0. to_be ( ) ]
120117}
121118
122119#[ inline]
@@ -150,69 +147,62 @@ fn common(f: u32, a: u32, b: u32, m: u32, s: u32, k: u32) -> u32 {
150147
151148#[ cfg( feature = "simd" ) ]
152149pub mod simd {
153- use std:: array;
150+ use std:: array:: from_fn ;
154151 use std:: simd:: num:: SimdUint as _;
155152 use std:: simd:: { LaneCount , Simd , SupportedLaneCount } ;
156153
157154 #[ inline]
158155 #[ expect( clippy:: too_many_lines) ]
159- pub fn hash < const N : usize > (
160- buffers : & mut [ [ u8 ; 64 ] ] ,
161- size : usize ,
162- ) -> ( [ u32 ; N ] , [ u32 ; N ] , [ u32 ; N ] , [ u32 ; N ] )
156+ pub fn hash_fixed < const N : usize > ( buffers : & mut [ [ u8 ; 64 ] ; N ] , size : usize ) -> [ [ u32 ; N ] ; 4 ]
163157 where
164158 LaneCount < N > : SupportedLaneCount ,
165159 {
166160 // Assume all buffers are the same size.
167- let end = 64 - 8 ;
168- let bits = size * 8 ;
169-
170161 for buffer in buffers. iter_mut ( ) {
171162 buffer[ size] = 0x80 ;
172- buffer[ end..] . copy_from_slice ( & bits. to_le_bytes ( ) ) ;
173163 }
174164
175- let mut a0: Simd < u32 , N > = Simd :: splat ( 0x67452301 ) ;
176- let mut b0: Simd < u32 , N > = Simd :: splat ( 0xefcdab89 ) ;
177- let mut c0: Simd < u32 , N > = Simd :: splat ( 0x98badcfe ) ;
178- let mut d0: Simd < u32 , N > = Simd :: splat ( 0x10325476 ) ;
165+ let mut a0 = Simd :: splat ( 0x67452301 ) ;
166+ let mut b0 = Simd :: splat ( 0xefcdab89 ) ;
167+ let mut c0 = Simd :: splat ( 0x98badcfe ) ;
168+ let mut d0 = Simd :: splat ( 0x10325476 ) ;
179169
180170 let mut a = a0;
181171 let mut b = b0;
182172 let mut c = c0;
183173 let mut d = d0;
184174
185- let m0 = message ( buffers, 0 ) ;
175+ let m0 = message ( buffers, 0 , size ) ;
186176 a = round1 ( a, b, c, d, m0, 7 , 0xd76aa478 ) ;
187- let m1 = message ( buffers, 1 ) ;
177+ let m1 = message ( buffers, 4 , size ) ;
188178 d = round1 ( d, a, b, c, m1, 12 , 0xe8c7b756 ) ;
189- let m2 = message ( buffers, 2 ) ;
179+ let m2 = message ( buffers, 8 , size ) ;
190180 c = round1 ( c, d, a, b, m2, 17 , 0x242070db ) ;
191- let m3 = message ( buffers, 3 ) ;
181+ let m3 = message ( buffers, 12 , size ) ;
192182 b = round1 ( b, c, d, a, m3, 22 , 0xc1bdceee ) ;
193- let m4 = message ( buffers, 4 ) ;
183+ let m4 = message ( buffers, 16 , size ) ;
194184 a = round1 ( a, b, c, d, m4, 7 , 0xf57c0faf ) ;
195- let m5 = message ( buffers, 5 ) ;
185+ let m5 = message ( buffers, 20 , size ) ;
196186 d = round1 ( d, a, b, c, m5, 12 , 0x4787c62a ) ;
197- let m6 = message ( buffers, 6 ) ;
187+ let m6 = message ( buffers, 24 , size ) ;
198188 c = round1 ( c, d, a, b, m6, 17 , 0xa8304613 ) ;
199- let m7 = message ( buffers, 7 ) ;
189+ let m7 = message ( buffers, 28 , size ) ;
200190 b = round1 ( b, c, d, a, m7, 22 , 0xfd469501 ) ;
201- let m8 = message ( buffers, 8 ) ;
191+ let m8 = message ( buffers, 32 , size ) ;
202192 a = round1 ( a, b, c, d, m8, 7 , 0x698098d8 ) ;
203- let m9 = message ( buffers, 9 ) ;
193+ let m9 = message ( buffers, 36 , size ) ;
204194 d = round1 ( d, a, b, c, m9, 12 , 0x8b44f7af ) ;
205- let m10 = message ( buffers, 10 ) ;
195+ let m10 = message ( buffers, 40 , size ) ;
206196 c = round1 ( c, d, a, b, m10, 17 , 0xffff5bb1 ) ;
207- let m11 = message ( buffers, 11 ) ;
197+ let m11 = message ( buffers, 44 , size ) ;
208198 b = round1 ( b, c, d, a, m11, 22 , 0x895cd7be ) ;
209- let m12 = message ( buffers, 12 ) ;
199+ let m12 = message ( buffers, 48 , size ) ;
210200 a = round1 ( a, b, c, d, m12, 7 , 0x6b901122 ) ;
211- let m13 = message ( buffers, 13 ) ;
201+ let m13 = message ( buffers, 52 , size ) ;
212202 d = round1 ( d, a, b, c, m13, 12 , 0xfd987193 ) ;
213- let m14 = message ( buffers , 14 ) ;
203+ let m14 = Simd :: splat ( size as u32 * 8 ) ;
214204 c = round1 ( c, d, a, b, m14, 17 , 0xa679438e ) ;
215- let m15 = message ( buffers , 15 ) ;
205+ let m15 = Simd :: splat ( 0 ) ;
216206 b = round1 ( b, c, d, a, m15, 22 , 0x49b40821 ) ;
217207
218208 a = round2 ( a, b, c, d, m1, 5 , 0xf61e2562 ) ;
@@ -271,25 +261,27 @@ pub mod simd {
271261 c0 += c;
272262 d0 += d;
273263
274- (
264+ [
275265 a0. swap_bytes ( ) . to_array ( ) ,
276266 b0. swap_bytes ( ) . to_array ( ) ,
277267 c0. swap_bytes ( ) . to_array ( ) ,
278268 d0. swap_bytes ( ) . to_array ( ) ,
279- )
269+ ]
280270 }
281271
282272 #[ inline]
283- fn message < const N : usize > ( buffers : & mut [ [ u8 ; 64 ] ] , i : usize ) -> Simd < u32 , N >
273+ fn message < const N : usize > ( buffers : & [ [ u8 ; 64 ] ; N ] , i : usize , size : usize ) -> Simd < u32 , N >
284274 where
285275 LaneCount < N > : SupportedLaneCount ,
286276 {
287- let start = 4 * i;
288- let end = start + 4 ;
289- Simd :: from_array ( array:: from_fn ( |lane| {
290- let slice = & buffers[ lane] [ start..end] ;
291- u32:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
292- } ) )
277+ if i > size {
278+ Simd :: splat ( 0 )
279+ } else {
280+ Simd :: from_array ( from_fn ( |lane| {
281+ let slice = & buffers[ lane] [ i..i + 4 ] ;
282+ u32:: from_le_bytes ( slice. try_into ( ) . unwrap ( ) )
283+ } ) )
284+ }
293285 }
294286
295287 #[ inline]
0 commit comments