1macro_rules! load_int_le {
30 ($buf:expr, $i:expr, $int_ty:ident) => {{
31 debug_assert!($i + core::mem::size_of::<$int_ty>() <= $buf.len());
32 let mut data = 0 as $int_ty;
33 core::ptr::copy_nonoverlapping(
34 $buf.as_ptr().add($i),
35 &mut data as *mut _ as *mut u8,
36 core::mem::size_of::<$int_ty>(),
37 );
38 data.to_le()
39 }};
40}
41
42#[inline]
48unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
49 debug_assert!(len < 8);
50 let mut i = 0; let mut out = 0;
52 if i + 3 < len {
53 out = load_int_le!(buf, start + i, u32) as u64;
54 i += 4;
55 }
56 if i + 1 < len {
57 out |= (load_int_le!(buf, start + i, u16) as u64) << (i * 8);
58 i += 2
59 }
60 if i < len {
61 out |= (*buf.get_unchecked(start + i) as u64) << (i * 8);
62 i += 1;
63 }
64 debug_assert_eq!(i, len);
65 out
66}
67
68#[derive(Debug, Clone, Copy)]
70#[repr(align(16), C)] pub struct Sip64Scalar<const C: usize, const D: usize> {
72 v0: u64,
74 v2: u64,
75 v1: u64,
76 v3: u64,
77 k0: u64,
78 k1: u64,
79 m: u64,
81 length: usize,
83 tail: u64,
85 ntail: usize,
87}
88
89impl<const C: usize, const D: usize> core::default::Default for Sip64Scalar<C, D> {
90 #[inline]
91 fn default() -> Self {
92 Self::new()
93 }
94}
95
96impl<const C: usize, const D: usize> Sip64Scalar<C, D> {
97 #[inline]
98 pub fn new() -> Self {
99 Self::new_with_key([0; 16])
101 }
102
103 #[inline(always)]
104 pub fn new_with_key(key: [u8; 16]) -> Self {
105 Self::new_with_key_and_state(
106 key,
107 [
108 0x736f6d6570736575,
109 0x646f72616e646f6d,
110 0x6c7967656e657261,
111 0x7465646279746573,
112 ],
113 )
114 }
115
116 #[inline(always)]
117 pub fn new_with_key_and_state(key: [u8; 16], state: [u64; 4]) -> Self {
118 let mut res = Self {
119 v0: state[0],
120 v1: state[1],
121 v2: state[2],
122 v3: state[3],
123 k0: u64::from_le_bytes(key[0..8].try_into().unwrap()),
124 k1: u64::from_le_bytes(key[8..16].try_into().unwrap()),
125 m: 0,
126 length: 0,
127 tail: 0,
128 ntail: 0,
129 };
130
131 res.v3 ^= res.k1;
132 res.v2 ^= res.k0;
133 res.v1 ^= res.k1;
134 res.v0 ^= res.k0;
135
136 res
137 }
138
139 #[inline(always)]
140 fn round(&mut self) {
141 self.v0 = self.v0.wrapping_add(self.v1);
142 self.v2 = self.v2.wrapping_add(self.v3);
143
144 self.v1 = self.v1.rotate_left(13);
145 self.v3 = self.v3.rotate_left(16);
146
147 self.v1 ^= self.v0;
148 self.v3 ^= self.v2;
149
150 self.v0 = self.v0.rotate_left(32);
151
152 self.v0 = self.v0.wrapping_add(self.v3);
153 self.v2 = self.v2.wrapping_add(self.v1);
154
155 self.v1 = self.v1.rotate_left(17);
156 self.v3 = self.v3.rotate_left(21);
157
158 self.v3 ^= self.v0;
159 self.v1 ^= self.v2;
160
161 self.v2 = self.v2.rotate_left(32);
162 }
163
164 #[inline]
176 pub fn short_write<T>(&mut self, _x: T, x: u64) {
177 let size = core::mem::size_of::<T>();
178 self.length += size;
179
180 debug_assert!(if size < 8 { x >> (8 * size) == 0 } else { true });
182
183 let needed = 8 - self.ntail;
185
186 self.tail |= x << (8 * self.ntail);
187 if size < needed {
188 self.ntail += size;
189 return;
190 }
191
192 self.v3 ^= self.tail;
194 for _ in 0..C {
195 self.round();
196 }
197 self.v0 ^= self.tail;
198
199 self.ntail = size - needed;
200 self.tail = if needed < 8 { x >> (8 * needed) } else { 0 };
201 }
202
203 pub fn finish_tuple(&self) -> (u64, u64) {
204 let mut state = *self;
205
206 let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
207
208 state.v3 ^= b;
209 for _ in 0..C {
210 state.round();
211 }
212 state.v0 ^= b;
213
214 state.v2 ^= 0xff;
215 for _ in 0..D {
216 state.round();
217 }
218
219 (state.v0 ^ state.v2, state.v1 ^ state.v3)
220 }
221}
222
223impl<const C: usize, const D: usize> core::hash::Hasher for Sip64Scalar<C, D> {
224 #[inline]
225 fn write(&mut self, msg: &[u8]) {
226 let length = msg.len();
227 self.length += length;
228
229 let mut needed = 0;
230
231 if self.ntail != 0 {
232 needed = 8 - self.ntail;
233 self.tail |=
234 unsafe { u8to64_le(msg, 0, core::cmp::min(length, needed)) } << (8 * self.ntail);
235 if length < needed {
236 self.ntail += length;
237 return;
238 } else {
239 self.v3 ^= self.tail;
240 for _ in 0..C {
241 self.round();
242 }
243 self.v0 ^= self.tail;
244 self.ntail = 0;
245 }
246 }
247
248 let len = length - needed;
250 let left = len & 0x7;
251
252 let mut i = needed;
253 while i < len - left {
254 let mi = unsafe { load_int_le!(msg, i, u64) };
255
256 self.v3 ^= mi;
257 for _ in 0..C {
258 self.round();
259 }
260 self.v0 ^= mi;
261
262 i += 8;
263 }
264
265 self.tail = unsafe { u8to64_le(msg, i, left) };
266 self.ntail = left;
267 }
268
269 #[inline]
270 fn finish(&self) -> u64 {
271 let (first, second) = self.finish_tuple();
272 first ^ second
273 }
274
275 #[inline]
276 fn write_usize(&mut self, i: usize) {
277 self.short_write(i, i.to_le() as u64);
278 }
279
280 #[inline]
281 fn write_u8(&mut self, i: u8) {
282 self.short_write(i, i as u64);
283 }
284
285 #[inline]
286 fn write_u32(&mut self, i: u32) {
287 self.short_write(i, i.to_le() as u64);
288 }
289
290 #[inline]
291 fn write_u64(&mut self, i: u64) {
292 self.short_write(i, i.to_le());
293 }
294}
295
296#[derive(Debug, Clone, Copy)]
298#[repr(transparent)]
299pub struct Sip128Scalar<const C: usize, const D: usize>(Sip64Scalar<C, D>);
300
301impl<const C: usize, const D: usize> core::default::Default for Sip128Scalar<C, D> {
302 #[inline]
303 fn default() -> Self {
304 Self::new()
305 }
306}
307
308impl<const C: usize, const D: usize> Sip128Scalar<C, D> {
309 #[inline]
310 pub fn new() -> Self {
311 Self(<Sip64Scalar<C, D>>::new())
312 }
313}
314
315impl<const C: usize, const D: usize> core::hash::Hasher for Sip128Scalar<C, D> {
316 #[inline(always)]
317 fn write(&mut self, msg: &[u8]) {
318 self.0.write(msg)
319 }
320
321 #[inline]
322 fn finish(&self) -> u64 {
323 let (high, low) = self.finish_tuple();
324
325 high ^ low
326 }
327
328 #[inline]
329 fn write_usize(&mut self, i: usize) {
330 self.0.write_usize(i);
331 }
332
333 #[inline]
334 fn write_u8(&mut self, i: u8) {
335 self.0.write_u8(i);
336 }
337
338 #[inline]
339 fn write_u32(&mut self, i: u32) {
340 self.0.write_u32(i);
341 }
342
343 #[inline]
344 fn write_u64(&mut self, i: u64) {
345 self.0.write_u64(i);
346 }
347}
348
349impl<const C: usize, const D: usize> Sip128Scalar<C, D> {
350 #[inline]
351 pub fn finish_tuple(&self) -> (u64, u64) {
352 let mut state = *self;
353
354 let b: u64 = ((self.0.length as u64 & 0xff) << 56) | self.0.tail;
355
356 state.0.v3 ^= b;
357 for _ in 0..C {
358 state.0.round();
359 }
360 state.0.v0 ^= b;
361
362 state.0.v2 ^= 0xff;
363 for _ in 0..D {
364 state.0.round();
365 }
366
367 let low = state.0.v0 ^ state.0.v1 ^ state.0.v2 ^ state.0.v3;
368
369 state.0.v1 ^= 0xdd;
370 for _ in 0..D {
371 state.0.round();
372 }
373
374 let high = state.0.v0 ^ state.0.v1 ^ state.0.v2 ^ state.0.v3;
375
376 (high, low)
377 }
378}
379
380#[cfg(test)]
381#[cfg(feature = "std")]
382mod test {
383 use core::hash::Hasher;
384
385 use super::*;
386 #[test]
387 fn test_siphasher() {
388 let data = (0..255_u8).collect::<Vec<_>>();
389 for i in 0..16 {
390 #[allow(deprecated)]
391 let mut sip =
392 core::hash::SipHasher::new_with_keys(0x0706050403020100, 0x0f0e0d0c0b0a0908);
393 sip.write(&data[..i]);
394 let truth = sip.finish();
395
396 let mut sip = <Sip64Scalar<2, 4>>::new_with_key([
397 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
398 ]);
399 sip.write(&data[..i]);
400 assert_eq!(sip.finish(), truth);
401 }
402 }
403 #[test]
404 fn test_default() {
405 let data = (0..255_u8).collect::<Vec<_>>();
406 for i in 0..16 {
407 #[allow(deprecated)]
408 let mut sip = std::collections::hash_map::DefaultHasher::new();
409 sip.write(&data[..i]);
410 let truth = sip.finish();
411
412 let mut sip = <Sip64Scalar<1, 3>>::new();
413 sip.write(&data[..i]);
414 assert_eq!(sip.finish(), truth);
415 }
416 }
417}