1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 * Implementation of SipHash 2-4
14 * See: http://131002.net/siphash/
16 * Consider this as a main "general-purpose" hash for all hashtables: it
17 * runs at good speed (competitive with spooky and city) and permits
18 * strong _keyed_ hashing. Key your hashtables from a strong RNG,
21 * Although the SipHash algorithm is considered to be cryptographically
22 * strong, this implementation has not been reviewed for such purposes.
23 * As such, all cryptographic uses of this implementation are strongly
27 #[allow(missing_doc)];
29 use container::Container;
31 use option::{Some, None};
34 use to_bytes::IterBytes;
35 use vec::ImmutableVector;
38 // Alias `SipState` to `State`.
39 pub use State = hash::SipState;
42 * Types that can meaningfully be hashed should implement this.
44 * Note that this trait is likely to change somewhat as it is
45 * closely related to `to_bytes::IterBytes` and in almost all
46 * cases presently the two are (and must be) used together.
48 * In general, most types only need to implement `IterBytes`,
49 * and the implementation of `Hash` below will take care of
50 * the rest. This is the recommended approach, since constructing
51 * good keyed hash functions is quite difficult.
55 * Compute a "keyed" hash of the value implementing the trait,
56 * taking `k0` and `k1` as "keying" parameters that randomize or
57 * otherwise perturb the hash function in such a way that a
58 * hash table built using such "keyed hash functions" cannot
59 * be made to perform linearly by an attacker controlling the
60 * hashtable's contents.
62 * In practical terms, we implement this using the SipHash 2-4
63 * function and require most types to only implement the
64 * IterBytes trait, that feeds SipHash.
66 fn hash_keyed(&self, k0: u64, k1: u64) -> u64;
69 fn hash(&self) -> u64 { self.hash_keyed(0,0) }
72 /// Streaming hash-functions should implement this.
74 fn input(&mut self, &[u8]);
75 // These can be refactored some when we have default methods.
76 fn result_bytes(&mut self) -> ~[u8];
77 fn result_str(&mut self) -> ~str;
78 fn result_u64(&mut self) -> u64;
82 impl<A:IterBytes> Hash for A {
84 fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
85 let mut s = State::new(k0, k1);
86 self.iter_bytes(true, |bytes| {
94 fn hash_keyed_2<A: IterBytes,
95 B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
96 let mut s = State::new(k0, k1);
97 a.iter_bytes(true, |bytes| {
101 b.iter_bytes(true, |bytes| {
108 fn hash_keyed_3<A: IterBytes,
110 C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
111 let mut s = State::new(k0, k1);
112 a.iter_bytes(true, |bytes| {
116 b.iter_bytes(true, |bytes| {
120 c.iter_bytes(true, |bytes| {
127 fn hash_keyed_4<A: IterBytes,
138 let mut s = State::new(k0, k1);
139 a.iter_bytes(true, |bytes| {
143 b.iter_bytes(true, |bytes| {
147 c.iter_bytes(true, |bytes| {
151 d.iter_bytes(true, |bytes| {
158 fn hash_keyed_5<A: IterBytes,
171 let mut s = State::new(k0, k1);
172 a.iter_bytes(true, |bytes| {
176 b.iter_bytes(true, |bytes| {
180 c.iter_bytes(true, |bytes| {
184 d.iter_bytes(true, |bytes| {
188 e.iter_bytes(true, |bytes| {
196 pub fn default_state() -> State {
203 length: uint, // how many bytes we've processed
204 v0: u64, // hash state
208 tail: [u8, ..8], // unprocessed bytes
209 ntail: uint, // how many bytes in tail are valid
214 fn new(key0: u64, key1: u64) -> SipState {
215 let mut state = SipState {
223 tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ],
231 // sadly, these macro definitions can't appear later,
232 // because they're needed in the following defs;
233 // this design could be improved.
235 macro_rules! u8to64_le (
236 ($buf:expr, $i:expr) =>
238 $buf[1+$i] as u64 << 8 |
239 $buf[2+$i] as u64 << 16 |
240 $buf[3+$i] as u64 << 24 |
241 $buf[4+$i] as u64 << 32 |
242 $buf[5+$i] as u64 << 40 |
243 $buf[6+$i] as u64 << 48 |
244 $buf[7+$i] as u64 << 56)
248 ($x:expr, $b:expr) =>
249 (($x << $b) | ($x >> (64 - $b)))
252 macro_rules! compress (
253 ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
255 $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
256 $v0 = rotl!($v0, 32);
257 $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
258 $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
259 $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
260 $v2 = rotl!($v2, 32);
265 impl Writer for SipState {
266 // Methods for io::writer
268 fn write(&mut self, msg: &[u8]) {
269 let length = msg.len();
270 self.length += length;
275 needed = 8 - self.ntail;
280 self.tail[self.ntail+t] = msg[t];
283 self.ntail += length;
289 self.tail[self.ntail+t] = msg[t];
293 let m = u8to64_le!(self.tail, 0);
296 compress!(self.v0, self.v1, self.v2, self.v3);
297 compress!(self.v0, self.v1, self.v2, self.v3);
303 // Buffered tail is now flushed, process new input.
304 let len = length - needed;
305 let end = len & (!0x7);
306 let left = len & 0x7;
310 let mi = u8to64_le!(msg, i);
313 compress!(self.v0, self.v1, self.v2, self.v3);
314 compress!(self.v0, self.v1, self.v2, self.v3);
322 self.tail[t] = msg[i+t];
328 fn flush(&mut self) {
333 impl Streaming for SipState {
335 fn input(&mut self, buf: &[u8]) {
340 fn result_u64(&mut self) -> u64 {
341 let mut v0 = self.v0;
342 let mut v1 = self.v1;
343 let mut v2 = self.v2;
344 let mut v3 = self.v3;
346 let mut b : u64 = (self.length as u64 & 0xff) << 56;
348 if self.ntail > 0 { b |= self.tail[0] as u64 << 0; }
349 if self.ntail > 1 { b |= self.tail[1] as u64 << 8; }
350 if self.ntail > 2 { b |= self.tail[2] as u64 << 16; }
351 if self.ntail > 3 { b |= self.tail[3] as u64 << 24; }
352 if self.ntail > 4 { b |= self.tail[4] as u64 << 32; }
353 if self.ntail > 5 { b |= self.tail[5] as u64 << 40; }
354 if self.ntail > 6 { b |= self.tail[6] as u64 << 48; }
357 compress!(v0, v1, v2, v3);
358 compress!(v0, v1, v2, v3);
362 compress!(v0, v1, v2, v3);
363 compress!(v0, v1, v2, v3);
364 compress!(v0, v1, v2, v3);
365 compress!(v0, v1, v2, v3);
367 return (v0 ^ v1 ^ v2 ^ v3);
370 fn result_bytes(&mut self) -> ~[u8] {
371 let h = self.result_u64();
383 fn result_str(&mut self) -> ~str {
384 let r = self.result_bytes();
387 s.push_str((*b as uint).to_str_radix(16u));
393 fn reset(&mut self) {
395 self.v0 = self.k0 ^ 0x736f6d6570736575;
396 self.v1 = self.k1 ^ 0x646f72616e646f6d;
397 self.v2 = self.k0 ^ 0x6c7967656e657261;
398 self.v3 = self.k1 ^ 0x7465646279746573;
408 // Hash just the bytes of the slice, without length prefix
409 struct Bytes<'self>(&'self [u8]);
410 impl<'self> IterBytes for Bytes<'self> {
411 fn iter_bytes(&self, _lsb0: bool, f: |&[u8]| -> bool) -> bool {
418 let vecs : [[u8, ..8], ..64] = [
419 [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
420 [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
421 [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
422 [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
423 [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
424 [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
425 [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
426 [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
427 [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
428 [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
429 [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
430 [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
431 [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
432 [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
433 [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
434 [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
435 [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
436 [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
437 [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
438 [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
439 [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
440 [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
441 [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
442 [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
443 [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
444 [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
445 [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
446 [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
447 [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
448 [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
449 [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
450 [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
451 [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
452 [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
453 [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
454 [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
455 [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
456 [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
457 [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
458 [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
459 [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
460 [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
461 [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
462 [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
463 [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
464 [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
465 [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
466 [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
467 [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
468 [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
469 [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
470 [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
471 [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
472 [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
473 [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
474 [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
475 [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
476 [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
477 [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
478 [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
479 [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
480 [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
481 [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
482 [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
485 let k0 = 0x_07_06_05_04_03_02_01_00_u64;
486 let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
487 let mut buf : ~[u8] = ~[];
489 let mut stream_inc = SipState::new(k0, k1);
490 let mut stream_full = SipState::new(k0, k1);
492 fn to_hex_str(r: &[u8, ..8]) -> ~str {
495 s.push_str((*b as uint).to_str_radix(16u));
501 debug!("siphash test {}", t);
502 let vec = u8to64_le!(vecs[t], 0);
503 let out = Bytes(buf.as_slice()).hash_keyed(k0, k1);
504 debug!("got {:?}, expected {:?}", out, vec);
505 assert_eq!(vec, out);
508 stream_full.input(buf);
509 let f = stream_full.result_str();
510 let i = stream_inc.result_str();
511 let v = to_hex_str(&vecs[t]);
512 debug!("{}: ({}) => inc={} full={}", t, v, i, f);
514 assert!(f == i && f == v);
517 stream_inc.input([t as u8]);
523 #[test] #[cfg(target_arch = "arm")]
524 fn test_hash_uint() {
525 let val = 0xdeadbeef_deadbeef_u64;
526 assert!((val as u64).hash() != (val as uint).hash());
527 assert_eq!((val as u32).hash(), (val as uint).hash());
529 #[test] #[cfg(target_arch = "x86_64")]
530 fn test_hash_uint() {
531 let val = 0xdeadbeef_deadbeef_u64;
532 assert_eq!((val as u64).hash(), (val as uint).hash());
533 assert!((val as u32).hash() != (val as uint).hash());
535 #[test] #[cfg(target_arch = "x86")]
536 fn test_hash_uint() {
537 let val = 0xdeadbeef_deadbeef_u64;
538 assert!((val as u64).hash() != (val as uint).hash());
539 assert_eq!((val as u32).hash(), (val as uint).hash());
543 fn test_hash_idempotent() {
544 let val64 = 0xdeadbeef_deadbeef_u64;
545 val64.hash() == val64.hash();
546 let val32 = 0xdeadbeef_u32;
547 val32.hash() == val32.hash();
551 fn test_hash_no_bytes_dropped_64() {
552 let val = 0xdeadbeef_deadbeef_u64;
554 assert!(val.hash() != zero_byte(val, 0).hash());
555 assert!(val.hash() != zero_byte(val, 1).hash());
556 assert!(val.hash() != zero_byte(val, 2).hash());
557 assert!(val.hash() != zero_byte(val, 3).hash());
558 assert!(val.hash() != zero_byte(val, 4).hash());
559 assert!(val.hash() != zero_byte(val, 5).hash());
560 assert!(val.hash() != zero_byte(val, 6).hash());
561 assert!(val.hash() != zero_byte(val, 7).hash());
563 fn zero_byte(val: u64, byte: uint) -> u64 {
565 val & !(0xff << (byte * 8))
570 fn test_hash_no_bytes_dropped_32() {
571 let val = 0xdeadbeef_u32;
573 assert!(val.hash() != zero_byte(val, 0).hash());
574 assert!(val.hash() != zero_byte(val, 1).hash());
575 assert!(val.hash() != zero_byte(val, 2).hash());
576 assert!(val.hash() != zero_byte(val, 3).hash());
578 fn zero_byte(val: u32, byte: uint) -> u32 {
580 val & !(0xff << (byte * 8))
585 fn test_float_hashes_differ() {
586 assert!(0.0.hash() != 1.0.hash());
587 assert!(1.0.hash() != (-1.0).hash());
591 fn test_float_hashes_of_zero() {
592 assert_eq!(0.0.hash(), (-0.0).hash());
596 fn test_hash_no_concat_alias() {
597 let s = ("aa", "bb");
598 let t = ("aabb", "");
599 let u = ("a", "abb");
601 let v = (&[1u8], &[0u8, 0], &[0u8]);
602 let w = (&[1u8, 0, 0, 0], &[], &[]);
605 assert!(s.hash() != t.hash() && s.hash() != u.hash());
606 assert!(v.hash() != w.hash());