1
+ /*!
2
+ * Implementation of SipHash 2-4
3
+ *
4
+ * See: http://131002.net/siphash/
5
+ *
6
+ * Consider this as a main "general-purpose" hash for all hashtables: it
7
+ * runs at good speed (competitive with spooky and city) and permits
8
+ * cryptographically strong _keyed_ hashing. Key your hashtables from a
9
+ * CPRNG like rand::rng.
10
+ */
11
+
12
+ pure fn hash_bytes ( buf : & [ const u8 ] ) -> u64 {
13
+ ret hash_bytes_keyed ( buf, 0u64 , 0u64 ) ;
14
+ }
15
+
16
+ pure fn hash_bytes_keyed ( buf : & [ const u8 ] , k0 : u64 , k1 : u64 ) -> u64 {
17
+
18
+ let mut v0 : u64 = k0 ^ 0x736f_6d65_7073_6575 ;
19
+ let mut v1 : u64 = k1 ^ 0x646f_7261_6e64_6f6d ;
20
+ let mut v2 : u64 = k0 ^ 0x6c79_6765_6e65_7261 ;
21
+ let mut v3 : u64 = k1 ^ 0x7465_6462_7974_6573 ;
22
+
23
+ #macro ( [ #u8to64_le ( buf, i) ,
24
+ ( buf[ 0 +i] as u64 |
25
+ buf[ 1 +i] as u64 << 8 |
26
+ buf[ 2 +i] as u64 << 16 |
27
+ buf[ 3 +i] as u64 << 24 |
28
+ buf[ 4 +i] as u64 << 32 |
29
+ buf[ 5 +i] as u64 << 40 |
30
+ buf[ 6 +i] as u64 << 48 |
31
+ buf[ 7 +i] as u64 << 56 ) ] ) ;
32
+
33
+ #macro ( [ #rotl ( x, b) , ( x << b) | ( x >> ( 64 - b) ) ] ) ;
34
+
35
+ #macro ( [ #compress ( ) , {
36
+ v0 += v1; v1 = #rotl ( v1, 13 ) ; v1 ^= v0; v0 = #rotl ( v0, 32 ) ;
37
+ v2 += v3; v3 = #rotl ( v3, 16 ) ; v3 ^= v2;
38
+ v0 += v3; v3 = #rotl ( v3, 21 ) ; v3 ^= v0;
39
+ v2 += v1; v1 = #rotl ( v1, 17 ) ; v1 ^= v2; v2 = #rotl ( v2, 32 ) ;
40
+ } ] ) ;
41
+
42
+ let len = vec:: len ( buf) ;
43
+ let end = len & ( !0x7 ) ;
44
+ let left = len & 0x7 ;
45
+
46
+ let mut i = 0 ;
47
+ while i < end {
48
+ let m = #u8to64_le ( buf, i) ;
49
+ v3 ^= m;
50
+ #compress ( ) ;
51
+ #compress ( ) ;
52
+ v0 ^= m;
53
+ i += 8 ;
54
+ }
55
+
56
+ let mut b : u64 = ( len as u64 & 0xff ) << 56 ;
57
+
58
+ if left > 0 { b |= buf[ i] as u64 ; }
59
+ if left > 1 { b |= buf[ i + 1 ] as u64 << 8 ; }
60
+ if left > 2 { b |= buf[ i + 2 ] as u64 << 16 ; }
61
+ if left > 3 { b |= buf[ i + 3 ] as u64 << 24 ; }
62
+ if left > 4 { b |= buf[ i + 4 ] as u64 << 32 ; }
63
+ if left > 5 { b |= buf[ i + 5 ] as u64 << 40 ; }
64
+ if left > 6 { b |= buf[ i + 6 ] as u64 << 48 ; }
65
+
66
+ v3 ^= b;
67
+ #compress ( ) ;
68
+ #compress ( ) ;
69
+ v0 ^= b;
70
+
71
+ v2 ^= 0xff ;
72
+ #compress ( ) ;
73
+ #compress ( ) ;
74
+ #compress ( ) ;
75
+ #compress ( ) ;
76
+
77
+ ret v0 ^ v1 ^ v2 ^ v3;
78
+ }
79
+
80
+ #[ test]
81
+ fn test_siphash ( ) {
82
+ let vecs : [ [ u8 ] /8 ] /64 = [
83
+ [ 0x31 , 0x0e , 0x0e , 0xdd , 0x47 , 0xdb , 0x6f , 0x72 , ] /_,
84
+ [ 0xfd , 0x67 , 0xdc , 0x93 , 0xc5 , 0x39 , 0xf8 , 0x74 , ] /_,
85
+ [ 0x5a , 0x4f , 0xa9 , 0xd9 , 0x09 , 0x80 , 0x6c , 0x0d , ] /_,
86
+ [ 0x2d , 0x7e , 0xfb , 0xd7 , 0x96 , 0x66 , 0x67 , 0x85 , ] /_,
87
+ [ 0xb7 , 0x87 , 0x71 , 0x27 , 0xe0 , 0x94 , 0x27 , 0xcf , ] /_,
88
+ [ 0x8d , 0xa6 , 0x99 , 0xcd , 0x64 , 0x55 , 0x76 , 0x18 , ] /_,
89
+ [ 0xce , 0xe3 , 0xfe , 0x58 , 0x6e , 0x46 , 0xc9 , 0xcb , ] /_,
90
+ [ 0x37 , 0xd1 , 0x01 , 0x8b , 0xf5 , 0x00 , 0x02 , 0xab , ] /_,
91
+ [ 0x62 , 0x24 , 0x93 , 0x9a , 0x79 , 0xf5 , 0xf5 , 0x93 , ] /_,
92
+ [ 0xb0 , 0xe4 , 0xa9 , 0x0b , 0xdf , 0x82 , 0x00 , 0x9e , ] /_,
93
+ [ 0xf3 , 0xb9 , 0xdd , 0x94 , 0xc5 , 0xbb , 0x5d , 0x7a , ] /_,
94
+ [ 0xa7 , 0xad , 0x6b , 0x22 , 0x46 , 0x2f , 0xb3 , 0xf4 , ] /_,
95
+ [ 0xfb , 0xe5 , 0x0e , 0x86 , 0xbc , 0x8f , 0x1e , 0x75 , ] /_,
96
+ [ 0x90 , 0x3d , 0x84 , 0xc0 , 0x27 , 0x56 , 0xea , 0x14 , ] /_,
97
+ [ 0xee , 0xf2 , 0x7a , 0x8e , 0x90 , 0xca , 0x23 , 0xf7 , ] /_,
98
+ [ 0xe5 , 0x45 , 0xbe , 0x49 , 0x61 , 0xca , 0x29 , 0xa1 , ] /_,
99
+ [ 0xdb , 0x9b , 0xc2 , 0x57 , 0x7f , 0xcc , 0x2a , 0x3f , ] /_,
100
+ [ 0x94 , 0x47 , 0xbe , 0x2c , 0xf5 , 0xe9 , 0x9a , 0x69 , ] /_,
101
+ [ 0x9c , 0xd3 , 0x8d , 0x96 , 0xf0 , 0xb3 , 0xc1 , 0x4b , ] /_,
102
+ [ 0xbd , 0x61 , 0x79 , 0xa7 , 0x1d , 0xc9 , 0x6d , 0xbb , ] /_,
103
+ [ 0x98 , 0xee , 0xa2 , 0x1a , 0xf2 , 0x5c , 0xd6 , 0xbe , ] /_,
104
+ [ 0xc7 , 0x67 , 0x3b , 0x2e , 0xb0 , 0xcb , 0xf2 , 0xd0 , ] /_,
105
+ [ 0x88 , 0x3e , 0xa3 , 0xe3 , 0x95 , 0x67 , 0x53 , 0x93 , ] /_,
106
+ [ 0xc8 , 0xce , 0x5c , 0xcd , 0x8c , 0x03 , 0x0c , 0xa8 , ] /_,
107
+ [ 0x94 , 0xaf , 0x49 , 0xf6 , 0xc6 , 0x50 , 0xad , 0xb8 , ] /_,
108
+ [ 0xea , 0xb8 , 0x85 , 0x8a , 0xde , 0x92 , 0xe1 , 0xbc , ] /_,
109
+ [ 0xf3 , 0x15 , 0xbb , 0x5b , 0xb8 , 0x35 , 0xd8 , 0x17 , ] /_,
110
+ [ 0xad , 0xcf , 0x6b , 0x07 , 0x63 , 0x61 , 0x2e , 0x2f , ] /_,
111
+ [ 0xa5 , 0xc9 , 0x1d , 0xa7 , 0xac , 0xaa , 0x4d , 0xde , ] /_,
112
+ [ 0x71 , 0x65 , 0x95 , 0x87 , 0x66 , 0x50 , 0xa2 , 0xa6 , ] /_,
113
+ [ 0x28 , 0xef , 0x49 , 0x5c , 0x53 , 0xa3 , 0x87 , 0xad , ] /_,
114
+ [ 0x42 , 0xc3 , 0x41 , 0xd8 , 0xfa , 0x92 , 0xd8 , 0x32 , ] /_,
115
+ [ 0xce , 0x7c , 0xf2 , 0x72 , 0x2f , 0x51 , 0x27 , 0x71 , ] /_,
116
+ [ 0xe3 , 0x78 , 0x59 , 0xf9 , 0x46 , 0x23 , 0xf3 , 0xa7 , ] /_,
117
+ [ 0x38 , 0x12 , 0x05 , 0xbb , 0x1a , 0xb0 , 0xe0 , 0x12 , ] /_,
118
+ [ 0xae , 0x97 , 0xa1 , 0x0f , 0xd4 , 0x34 , 0xe0 , 0x15 , ] /_,
119
+ [ 0xb4 , 0xa3 , 0x15 , 0x08 , 0xbe , 0xff , 0x4d , 0x31 , ] /_,
120
+ [ 0x81 , 0x39 , 0x62 , 0x29 , 0xf0 , 0x90 , 0x79 , 0x02 , ] /_,
121
+ [ 0x4d , 0x0c , 0xf4 , 0x9e , 0xe5 , 0xd4 , 0xdc , 0xca , ] /_,
122
+ [ 0x5c , 0x73 , 0x33 , 0x6a , 0x76 , 0xd8 , 0xbf , 0x9a , ] /_,
123
+ [ 0xd0 , 0xa7 , 0x04 , 0x53 , 0x6b , 0xa9 , 0x3e , 0x0e , ] /_,
124
+ [ 0x92 , 0x59 , 0x58 , 0xfc , 0xd6 , 0x42 , 0x0c , 0xad , ] /_,
125
+ [ 0xa9 , 0x15 , 0xc2 , 0x9b , 0xc8 , 0x06 , 0x73 , 0x18 , ] /_,
126
+ [ 0x95 , 0x2b , 0x79 , 0xf3 , 0xbc , 0x0a , 0xa6 , 0xd4 , ] /_,
127
+ [ 0xf2 , 0x1d , 0xf2 , 0xe4 , 0x1d , 0x45 , 0x35 , 0xf9 , ] /_,
128
+ [ 0x87 , 0x57 , 0x75 , 0x19 , 0x04 , 0x8f , 0x53 , 0xa9 , ] /_,
129
+ [ 0x10 , 0xa5 , 0x6c , 0xf5 , 0xdf , 0xcd , 0x9a , 0xdb , ] /_,
130
+ [ 0xeb , 0x75 , 0x09 , 0x5c , 0xcd , 0x98 , 0x6c , 0xd0 , ] /_,
131
+ [ 0x51 , 0xa9 , 0xcb , 0x9e , 0xcb , 0xa3 , 0x12 , 0xe6 , ] /_,
132
+ [ 0x96 , 0xaf , 0xad , 0xfc , 0x2c , 0xe6 , 0x66 , 0xc7 , ] /_,
133
+ [ 0x72 , 0xfe , 0x52 , 0x97 , 0x5a , 0x43 , 0x64 , 0xee , ] /_,
134
+ [ 0x5a , 0x16 , 0x45 , 0xb2 , 0x76 , 0xd5 , 0x92 , 0xa1 , ] /_,
135
+ [ 0xb2 , 0x74 , 0xcb , 0x8e , 0xbf , 0x87 , 0x87 , 0x0a , ] /_,
136
+ [ 0x6f , 0x9b , 0xb4 , 0x20 , 0x3d , 0xe7 , 0xb3 , 0x81 , ] /_,
137
+ [ 0xea , 0xec , 0xb2 , 0xa3 , 0x0b , 0x22 , 0xa8 , 0x7f , ] /_,
138
+ [ 0x99 , 0x24 , 0xa4 , 0x3c , 0xc1 , 0x31 , 0x57 , 0x24 , ] /_,
139
+ [ 0xbd , 0x83 , 0x8d , 0x3a , 0xaf , 0xbf , 0x8d , 0xb7 , ] /_,
140
+ [ 0x0b , 0x1a , 0x2a , 0x32 , 0x65 , 0xd5 , 0x1a , 0xea , ] /_,
141
+ [ 0x13 , 0x50 , 0x79 , 0xa3 , 0x23 , 0x1c , 0xe6 , 0x60 , ] /_,
142
+ [ 0x93 , 0x2b , 0x28 , 0x46 , 0xe4 , 0xd7 , 0x06 , 0x66 , ] /_,
143
+ [ 0xe1 , 0x91 , 0x5f , 0x5c , 0xb1 , 0xec , 0xa4 , 0x6c , ] /_,
144
+ [ 0xf3 , 0x25 , 0x96 , 0x5c , 0xa1 , 0x6d , 0x62 , 0x9f , ] /_,
145
+ [ 0x57 , 0x5f , 0xf2 , 0x8e , 0x60 , 0x38 , 0x1b , 0xe5 , ] /_,
146
+ [ 0x72 , 0x45 , 0x06 , 0xeb , 0x4c , 0x32 , 0x8a , 0x95 , ] /_
147
+ ] /_;
148
+
149
+ let k0 = 0x_07_06_05_04_03_02_01_00_u64 ;
150
+ let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64 ;
151
+ let mut buf : ~[ u8 ] = ~[ ] ;
152
+ let mut t = 0 ;
153
+ while t < 64 {
154
+ #debug ( "siphash test %?" , t) ;
155
+ let vec = #u8to64_le ( vecs[ t] , 0 ) ;
156
+ let out = hash_bytes_keyed ( buf, k0, k1) ;
157
+ #debug ( "got %?, expected %?" , out, vec) ;
158
+ assert vec == out;
159
+ buf += ~[ t as u8 ] ;
160
+ t += 1 ;
161
+ }
162
+
163
+ }
0 commit comments