3 use std::hash::{Hash, Hasher};
5 // Hash just the bytes of the slice, without length prefix
6 struct Bytes<'a>(&'a [u8]);
8 impl<'a> Hash for Bytes<'a> {
9 #[allow(unused_must_use)]
10 fn hash<H: Hasher>(&self, state: &mut H) {
12 state.write_u8(*byte);
17 fn hash_with<T: Hash>(mut st: SipHasher128, x: &T) -> (u64, u64) {
22 fn hash<T: Hash>(x: &T) -> (u64, u64) {
23 hash_with(SipHasher128::new_with_keys(0, 0), x)
26 const TEST_VECTOR: [[u8; 16]; 64] = [
28 0xa3, 0x81, 0x7f, 0x04, 0xba, 0x25, 0xa8, 0xe6, 0x6d, 0xf6, 0x72, 0x14, 0xc7, 0x55, 0x02,
32 0xda, 0x87, 0xc1, 0xd8, 0x6b, 0x99, 0xaf, 0x44, 0x34, 0x76, 0x59, 0x11, 0x9b, 0x22, 0xfc,
36 0x81, 0x77, 0x22, 0x8d, 0xa4, 0xa4, 0x5d, 0xc7, 0xfc, 0xa3, 0x8b, 0xde, 0xf6, 0x0a, 0xff,
40 0x9c, 0x70, 0xb6, 0x0c, 0x52, 0x67, 0xa9, 0x4e, 0x5f, 0x33, 0xb6, 0xb0, 0x29, 0x85, 0xed,
44 0xf8, 0x81, 0x64, 0xc1, 0x2d, 0x9c, 0x8f, 0xaf, 0x7d, 0x0f, 0x6e, 0x7c, 0x7b, 0xcd, 0x55,
48 0x13, 0x68, 0x87, 0x59, 0x80, 0x77, 0x6f, 0x88, 0x54, 0x52, 0x7a, 0x07, 0x69, 0x0e, 0x96,
52 0x14, 0xee, 0xca, 0x33, 0x8b, 0x20, 0x86, 0x13, 0x48, 0x5e, 0xa0, 0x30, 0x8f, 0xd7, 0xa1,
56 0xa1, 0xf1, 0xeb, 0xbe, 0xd8, 0xdb, 0xc1, 0x53, 0xc0, 0xb8, 0x4a, 0xa6, 0x1f, 0xf0, 0x82,
60 0x3b, 0x62, 0xa9, 0xba, 0x62, 0x58, 0xf5, 0x61, 0x0f, 0x83, 0xe2, 0x64, 0xf3, 0x14, 0x97,
64 0x26, 0x44, 0x99, 0x06, 0x0a, 0xd9, 0xba, 0xab, 0xc4, 0x7f, 0x8b, 0x02, 0xbb, 0x6d, 0x71,
68 0x00, 0x11, 0x0d, 0xc3, 0x78, 0x14, 0x69, 0x56, 0xc9, 0x54, 0x47, 0xd3, 0xf3, 0xd0, 0xfb,
72 0x01, 0x51, 0xc5, 0x68, 0x38, 0x6b, 0x66, 0x77, 0xa2, 0xb4, 0xdc, 0x6f, 0x81, 0xe5, 0xdc,
76 0xd6, 0x26, 0xb2, 0x66, 0x90, 0x5e, 0xf3, 0x58, 0x82, 0x63, 0x4d, 0xf6, 0x85, 0x32, 0xc1,
80 0x98, 0x69, 0xe2, 0x47, 0xe9, 0xc0, 0x8b, 0x10, 0xd0, 0x29, 0x93, 0x4f, 0xc4, 0xb9, 0x52,
84 0x31, 0xfc, 0xef, 0xac, 0x66, 0xd7, 0xde, 0x9c, 0x7e, 0xc7, 0x48, 0x5f, 0xe4, 0x49, 0x49,
88 0x54, 0x93, 0xe9, 0x99, 0x33, 0xb0, 0xa8, 0x11, 0x7e, 0x08, 0xec, 0x0f, 0x97, 0xcf, 0xc3,
92 0x6e, 0xe2, 0xa4, 0xca, 0x67, 0xb0, 0x54, 0xbb, 0xfd, 0x33, 0x15, 0xbf, 0x85, 0x23, 0x05,
96 0x47, 0x3d, 0x06, 0xe8, 0x73, 0x8d, 0xb8, 0x98, 0x54, 0xc0, 0x66, 0xc4, 0x7a, 0xe4, 0x77,
100 0xa4, 0x26, 0xe5, 0xe4, 0x23, 0xbf, 0x48, 0x85, 0x29, 0x4d, 0xa4, 0x81, 0xfe, 0xae, 0xf7,
104 0x78, 0x01, 0x77, 0x31, 0xcf, 0x65, 0xfa, 0xb0, 0x74, 0xd5, 0x20, 0x89, 0x52, 0x51, 0x2e,
108 0x9e, 0x25, 0xfc, 0x83, 0x3f, 0x22, 0x90, 0x73, 0x3e, 0x93, 0x44, 0xa5, 0xe8, 0x38, 0x39,
112 0x56, 0x8e, 0x49, 0x5a, 0xbe, 0x52, 0x5a, 0x21, 0x8a, 0x22, 0x14, 0xcd, 0x3e, 0x07, 0x1d,
116 0x4a, 0x29, 0xb5, 0x45, 0x52, 0xd1, 0x6b, 0x9a, 0x46, 0x9c, 0x10, 0x52, 0x8e, 0xff, 0x0a,
120 0xc9, 0xd1, 0x84, 0xdd, 0xd5, 0xa9, 0xf5, 0xe0, 0xcf, 0x8c, 0xe2, 0x9a, 0x9a, 0xbf, 0x69,
124 0x2d, 0xb4, 0x79, 0xae, 0x78, 0xbd, 0x50, 0xd8, 0x88, 0x2a, 0x8a, 0x17, 0x8a, 0x61, 0x32,
128 0x8e, 0xce, 0x5f, 0x04, 0x2d, 0x5e, 0x44, 0x7b, 0x50, 0x51, 0xb9, 0xea, 0xcb, 0x8d, 0x8f,
132 0x9c, 0x0b, 0x53, 0xb4, 0xb3, 0xc3, 0x07, 0xe8, 0x7e, 0xae, 0xe0, 0x86, 0x78, 0x14, 0x1f,
136 0xab, 0xf2, 0x48, 0xaf, 0x69, 0xa6, 0xea, 0xe4, 0xbf, 0xd3, 0xeb, 0x2f, 0x12, 0x9e, 0xeb,
140 0x06, 0x64, 0xda, 0x16, 0x68, 0x57, 0x4b, 0x88, 0xb9, 0x35, 0xf3, 0x02, 0x73, 0x58, 0xae,
144 0xaa, 0x4b, 0x9d, 0xc4, 0xbf, 0x33, 0x7d, 0xe9, 0x0c, 0xd4, 0xfd, 0x3c, 0x46, 0x7c, 0x6a,
148 0xea, 0x5c, 0x7f, 0x47, 0x1f, 0xaf, 0x6b, 0xde, 0x2b, 0x1a, 0xd7, 0xd4, 0x68, 0x6d, 0x22,
152 0x29, 0x39, 0xb0, 0x18, 0x32, 0x23, 0xfa, 0xfc, 0x17, 0x23, 0xde, 0x4f, 0x52, 0xc4, 0x3d,
156 0x7c, 0x39, 0x56, 0xca, 0x5e, 0xea, 0xfc, 0x3e, 0x36, 0x3e, 0x9d, 0x55, 0x65, 0x46, 0xeb,
160 0x77, 0xc6, 0x07, 0x71, 0x46, 0xf0, 0x1c, 0x32, 0xb6, 0xb6, 0x9d, 0x5f, 0x4e, 0xa9, 0xff,
164 0x37, 0xa6, 0x98, 0x6c, 0xb8, 0x84, 0x7e, 0xdf, 0x09, 0x25, 0xf0, 0xf1, 0x30, 0x9b, 0x54,
168 0xa7, 0x05, 0xf0, 0xe6, 0x9d, 0xa9, 0xa8, 0xf9, 0x07, 0x24, 0x1a, 0x2e, 0x92, 0x3c, 0x8c,
172 0x3d, 0xc4, 0x7d, 0x1f, 0x29, 0xc4, 0x48, 0x46, 0x1e, 0x9e, 0x76, 0xed, 0x90, 0x4f, 0x67,
176 0x0d, 0x62, 0xbf, 0x01, 0xe6, 0xfc, 0x0e, 0x1a, 0x0d, 0x3c, 0x47, 0x51, 0xc5, 0xd3, 0x69,
180 0x8c, 0x03, 0x46, 0x8b, 0xca, 0x7c, 0x66, 0x9e, 0xe4, 0xfd, 0x5e, 0x08, 0x4b, 0xbe, 0xe7,
184 0x52, 0x8a, 0x5b, 0xb9, 0x3b, 0xaf, 0x2c, 0x9c, 0x44, 0x73, 0xcc, 0xe5, 0xd0, 0xd2, 0x2b,
188 0xdf, 0x6a, 0x30, 0x1e, 0x95, 0xc9, 0x5d, 0xad, 0x97, 0xae, 0x0c, 0xc8, 0xc6, 0x91, 0x3b,
192 0x80, 0x11, 0x89, 0x90, 0x2c, 0x85, 0x7f, 0x39, 0xe7, 0x35, 0x91, 0x28, 0x5e, 0x70, 0xb6,
196 0xe6, 0x17, 0x34, 0x6a, 0xc9, 0xc2, 0x31, 0xbb, 0x36, 0x50, 0xae, 0x34, 0xcc, 0xca, 0x0c,
200 0x27, 0xd9, 0x34, 0x37, 0xef, 0xb7, 0x21, 0xaa, 0x40, 0x18, 0x21, 0xdc, 0xec, 0x5a, 0xdf,
204 0x89, 0x23, 0x7d, 0x9d, 0xed, 0x9c, 0x5e, 0x78, 0xd8, 0xb1, 0xc9, 0xb1, 0x66, 0xcc, 0x73,
208 0x4a, 0x6d, 0x80, 0x91, 0xbf, 0x5e, 0x7d, 0x65, 0x11, 0x89, 0xfa, 0x94, 0xa2, 0x50, 0xb1,
212 0x0e, 0x33, 0xf9, 0x60, 0x55, 0xe7, 0xae, 0x89, 0x3f, 0xfc, 0x0e, 0x3d, 0xcf, 0x49, 0x29,
216 0xe6, 0x1c, 0x43, 0x2b, 0x72, 0x0b, 0x19, 0xd1, 0x8e, 0xc8, 0xd8, 0x4b, 0xdc, 0x63, 0x15,
220 0xf7, 0xe5, 0xae, 0xf5, 0x49, 0xf7, 0x82, 0xcf, 0x37, 0x90, 0x55, 0xa6, 0x08, 0x26, 0x9b,
224 0x43, 0x8d, 0x03, 0x0f, 0xd0, 0xb7, 0xa5, 0x4f, 0xa8, 0x37, 0xf2, 0xad, 0x20, 0x1a, 0x64,
228 0xa5, 0x90, 0xd3, 0xee, 0x4f, 0xbf, 0x04, 0xe3, 0x24, 0x7e, 0x0d, 0x27, 0xf2, 0x86, 0x42,
232 0x5f, 0xe2, 0xc1, 0xa1, 0x72, 0xfe, 0x93, 0xc4, 0xb1, 0x5c, 0xd3, 0x7c, 0xae, 0xf9, 0xf5,
236 0x2c, 0x97, 0x32, 0x5c, 0xbd, 0x06, 0xb3, 0x6e, 0xb2, 0x13, 0x3d, 0xd0, 0x8b, 0x3a, 0x01,
240 0x92, 0xc8, 0x14, 0x22, 0x7a, 0x6b, 0xca, 0x94, 0x9f, 0xf0, 0x65, 0x9f, 0x00, 0x2a, 0xd3,
244 0xdc, 0xe8, 0x50, 0x11, 0x0b, 0xd8, 0x32, 0x8c, 0xfb, 0xd5, 0x08, 0x41, 0xd6, 0x91, 0x1d,
248 0x67, 0xf1, 0x49, 0x84, 0xc7, 0xda, 0x79, 0x12, 0x48, 0xe3, 0x2b, 0xb5, 0x92, 0x25, 0x83,
252 0x19, 0x38, 0xf2, 0xcf, 0x72, 0xd5, 0x4e, 0xe9, 0x7e, 0x94, 0x16, 0x6f, 0xa9, 0x1d, 0x2a,
256 0x74, 0x48, 0x1e, 0x96, 0x46, 0xed, 0x49, 0xfe, 0x0f, 0x62, 0x24, 0x30, 0x16, 0x04, 0x69,
260 0x57, 0xfc, 0xa5, 0xde, 0x98, 0xa9, 0xd6, 0xd8, 0x00, 0x64, 0x38, 0xd0, 0x58, 0x3d, 0x8a,
264 0x9f, 0xec, 0xde, 0x1c, 0xef, 0xdc, 0x1c, 0xbe, 0xd4, 0x76, 0x36, 0x74, 0xd9, 0x57, 0x53,
268 0xe3, 0x04, 0x0c, 0x00, 0xeb, 0x28, 0xf1, 0x53, 0x66, 0xca, 0x73, 0xcb, 0xd8, 0x72, 0xe7,
272 0x76, 0x97, 0x00, 0x9a, 0x6a, 0x83, 0x1d, 0xfe, 0xcc, 0xa9, 0x1c, 0x59, 0x93, 0x67, 0x0f,
276 0x58, 0x53, 0x54, 0x23, 0x21, 0xf5, 0x67, 0xa0, 0x05, 0xd5, 0x47, 0xa4, 0xf0, 0x47, 0x59,
280 0x51, 0x50, 0xd1, 0x77, 0x2f, 0x50, 0x83, 0x4a, 0x50, 0x3e, 0x06, 0x9a, 0x97, 0x3f, 0xbd,
285 // Test vector from reference implementation
287 fn test_siphash_2_4_test_vector() {
288 let k0 = 0x_07_06_05_04_03_02_01_00;
289 let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
291 let mut input: Vec<u8> = Vec::new();
294 let out = hash_with(SipHasher128::new_with_keys(k0, k1), &Bytes(&input[..]));
296 ((TEST_VECTOR[i][0] as u64) << 0)
297 | ((TEST_VECTOR[i][1] as u64) << 8)
298 | ((TEST_VECTOR[i][2] as u64) << 16)
299 | ((TEST_VECTOR[i][3] as u64) << 24)
300 | ((TEST_VECTOR[i][4] as u64) << 32)
301 | ((TEST_VECTOR[i][5] as u64) << 40)
302 | ((TEST_VECTOR[i][6] as u64) << 48)
303 | ((TEST_VECTOR[i][7] as u64) << 56),
304 ((TEST_VECTOR[i][8] as u64) << 0)
305 | ((TEST_VECTOR[i][9] as u64) << 8)
306 | ((TEST_VECTOR[i][10] as u64) << 16)
307 | ((TEST_VECTOR[i][11] as u64) << 24)
308 | ((TEST_VECTOR[i][12] as u64) << 32)
309 | ((TEST_VECTOR[i][13] as u64) << 40)
310 | ((TEST_VECTOR[i][14] as u64) << 48)
311 | ((TEST_VECTOR[i][15] as u64) << 56),
314 assert_eq!(out, expected);
320 #[cfg(target_arch = "arm")]
321 fn test_hash_usize() {
322 let val = 0xdeadbeef_deadbeef_u64;
323 assert!(hash(&(val as u64)) != hash(&(val as usize)));
324 assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
327 #[cfg(target_arch = "x86_64")]
328 fn test_hash_usize() {
329 let val = 0xdeadbeef_deadbeef_u64;
330 assert_eq!(hash(&(val as u64)), hash(&(val as usize)));
331 assert!(hash(&(val as u32)) != hash(&(val as usize)));
334 #[cfg(target_arch = "x86")]
335 fn test_hash_usize() {
336 let val = 0xdeadbeef_deadbeef_u64;
337 assert!(hash(&(val as u64)) != hash(&(val as usize)));
338 assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
342 fn test_hash_idempotent() {
343 let val64 = 0xdeadbeef_deadbeef_u64;
344 assert_eq!(hash(&val64), hash(&val64));
345 let val32 = 0xdeadbeef_u32;
346 assert_eq!(hash(&val32), hash(&val32));
350 fn test_hash_no_bytes_dropped_64() {
351 let val = 0xdeadbeef_deadbeef_u64;
353 assert!(hash(&val) != hash(&zero_byte(val, 0)));
354 assert!(hash(&val) != hash(&zero_byte(val, 1)));
355 assert!(hash(&val) != hash(&zero_byte(val, 2)));
356 assert!(hash(&val) != hash(&zero_byte(val, 3)));
357 assert!(hash(&val) != hash(&zero_byte(val, 4)));
358 assert!(hash(&val) != hash(&zero_byte(val, 5)));
359 assert!(hash(&val) != hash(&zero_byte(val, 6)));
360 assert!(hash(&val) != hash(&zero_byte(val, 7)));
362 fn zero_byte(val: u64, byte: usize) -> u64 {
364 val & !(0xff << (byte * 8))
369 fn test_hash_no_bytes_dropped_32() {
370 let val = 0xdeadbeef_u32;
372 assert!(hash(&val) != hash(&zero_byte(val, 0)));
373 assert!(hash(&val) != hash(&zero_byte(val, 1)));
374 assert!(hash(&val) != hash(&zero_byte(val, 2)));
375 assert!(hash(&val) != hash(&zero_byte(val, 3)));
377 fn zero_byte(val: u32, byte: usize) -> u32 {
379 val & !(0xff << (byte * 8))
384 fn test_hash_no_concat_alias() {
385 let s = ("aa", "bb");
386 let t = ("aabb", "");
387 let u = ("a", "abb");
389 assert!(s != t && t != u);
390 assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
392 let u = [1, 0, 0, 0];
393 let v = (&u[..1], &u[1..3], &u[3..]);
394 let w = (&u[..], &u[4..4], &u[4..4]);
397 assert!(hash(&v) != hash(&w));
401 fn test_short_write_works() {
402 let test_u8 = 0xFF_u8;
403 let test_u16 = 0x1122_u16;
404 let test_u32 = 0x22334455_u32;
405 let test_u64 = 0x33445566_778899AA_u64;
406 let test_u128 = 0x11223344_55667788_99AABBCC_DDEEFF77_u128;
407 let test_usize = 0xD0C0B0A0_usize;
410 let test_i16 = -2_i16;
411 let test_i32 = -3_i32;
412 let test_i64 = -4_i64;
413 let test_i128 = -5_i128;
414 let test_isize = -6_isize;
416 let mut h1 = SipHasher128::new_with_keys(0, 0);
419 h1.write_u8(test_u8);
420 h1.write_u16(test_u16);
421 h1.write_u32(test_u32);
422 h1.write_u64(test_u64);
423 h1.write_u128(test_u128);
424 h1.write_usize(test_usize);
425 h1.write_i8(test_i8);
426 h1.write_i16(test_i16);
427 h1.write_i32(test_i32);
428 h1.write_i64(test_i64);
429 h1.write_i128(test_i128);
430 h1.write_isize(test_isize);
432 let mut h2 = SipHasher128::new_with_keys(0, 0);
435 h2.write(&test_u8.to_ne_bytes());
436 h2.write(&test_u16.to_ne_bytes());
437 h2.write(&test_u32.to_ne_bytes());
438 h2.write(&test_u64.to_ne_bytes());
439 h2.write(&test_u128.to_ne_bytes());
440 h2.write(&test_usize.to_ne_bytes());
441 h2.write(&test_i8.to_ne_bytes());
442 h2.write(&test_i16.to_ne_bytes());
443 h2.write(&test_i32.to_ne_bytes());
444 h2.write(&test_i64.to_ne_bytes());
445 h2.write(&test_i128.to_ne_bytes());
446 h2.write(&test_isize.to_ne_bytes());
448 let h1_hash = h1.finish128();
449 let h2_hash = h2.finish128();
451 assert_eq!(h1_hash, h2_hash);
454 macro_rules! test_fill_buffer {
455 ($type:ty, $write_method:ident) => {{
456 // Test filling and overfilling the buffer from all possible offsets
457 // for a given integer type and its corresponding write method.
458 const SIZE: usize = std::mem::size_of::<$type>();
459 let input = [42; BUFFER_SIZE];
460 let x = 0x01234567_89ABCDEF_76543210_FEDCBA98_u128 as $type;
461 let x_bytes = &x.to_ne_bytes();
464 let s = &input[..BUFFER_SIZE - i];
466 let mut h1 = SipHasher128::new_with_keys(7, 13);
470 let mut h2 = SipHasher128::new_with_keys(7, 13);
474 let h1_hash = h1.finish128();
475 let h2_hash = h2.finish128();
477 assert_eq!(h1_hash, h2_hash);
483 fn test_fill_buffer() {
484 test_fill_buffer!(u8, write_u8);
485 test_fill_buffer!(u16, write_u16);
486 test_fill_buffer!(u32, write_u32);
487 test_fill_buffer!(u64, write_u64);
488 test_fill_buffer!(u128, write_u128);
489 test_fill_buffer!(usize, write_usize);
491 test_fill_buffer!(i8, write_i8);
492 test_fill_buffer!(i16, write_i16);
493 test_fill_buffer!(i32, write_i32);
494 test_fill_buffer!(i64, write_i64);
495 test_fill_buffer!(i128, write_i128);
496 test_fill_buffer!(isize, write_isize);