The Pedigree Project 0.1
SpookyV2.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20//
21// SpookyHash: a 128-bit noncryptographic hash function
22// By Bob Jenkins, public domain
23// Oct 31 2010: alpha, framework + SpookyHash::Mix appears right
24// Oct 31 2011: alpha again, Mix only good to 2^^69 but rest appears right
25// Dec 31 2011: beta, improved Mix, tested it for 2-bit deltas
26// Feb 2 2012: production, same bits as beta
27// Feb 5 2012: adjusted definitions of uint* to be more portable
28// Mar 30 2012: 3 bytes/cycle, not 4. Alpha was 4 but wasn't thorough enough.
29// August 5 2012: SpookyV2 (different results)
30//
31// Up to 3 bytes/cycle for long messages. Reasonably fast for short messages.
32// All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit.
33//
34// This was developed for and tested on 64-bit x86-compatible processors.
35// It assumes the processor is little-endian. There is a macro
36// controlling whether unaligned reads are allowed (by default they are).
37// This should be an equally good hash on big-endian machines, but it will
38// compute different results on them than on little-endian machines.
39//
40// Google's CityHash has similar specs to SpookyHash, and CityHash is faster
41// on new Intel boxes. MD4 and MD5 also have similar specs, but they are orders
42// of magnitude slower. CRCs are two or more times slower, but unlike
43// SpookyHash, they have nice math for combining the CRCs of pieces to form
44// the CRCs of wholes. There are also cryptographic hashes, but those are even
45// slower than MD5.
46//
47
48#include <stddef.h>
49
50#ifdef _MSC_VER
51#define INLINE __forceinline
52typedef unsigned __int64 uint64;
53typedef unsigned __int32 uint32;
54typedef unsigned __int16 uint16;
55typedef unsigned __int8 uint8;
56#else
57#include <stdint.h>
58#define INLINE inline
59typedef uint64_t uint64;
60typedef uint32_t uint32;
61typedef uint16_t uint16;
62typedef uint8_t uint8;
63#endif
64
66 public:
67 //
68 // SpookyHash: hash a single message in one call, produce 128-bit output
69 //
70 static void Hash128(const void* message, // message to hash
71 size_t length, // length of message in bytes
72 uint64* hash1, // in/out: in seed 1, out hash value 1
73 uint64* hash2); // in/out: in seed 2, out hash value 2
74
75 //
76 // Hash64: hash a single message in one call, return 64-bit output
77 //
78 static uint64 Hash64(const void* message, // message to hash
79 size_t length, // length of message in bytes
80 uint64 seed) // seed
81 {
82 uint64 hash1 = seed;
83 Hash128(message, length, &hash1, &seed);
84 return hash1;
85 }
86
87 //
88 // Hash32: hash a single message in one call, produce 32-bit output
89 //
90 static uint32 Hash32(const void* message, // message to hash
91 size_t length, // length of message in bytes
92 uint32 seed) // seed
93 {
94 uint64 hash1 = seed, hash2 = seed;
95 Hash128(message, length, &hash1, &hash2);
96 return (uint32)hash1;
97 }
98
99 //
100 // Init: initialize the context of a SpookyHash
101 //
102 void Init(uint64 seed1, // any 64-bit value will do, including 0
103 uint64 seed2); // different seeds produce independent hashes
104
105 //
106 // Update: add a piece of a message to a SpookyHash state
107 //
108 void Update(const void* message, // message fragment
109 size_t length); // length of message fragment in bytes
110
111 //
112 // Final: compute the hash for the current SpookyHash state
113 //
114 // This does not modify the state; you can keep updating it afterward
115 //
116 // The result is the same as if SpookyHash() had been called with
117 // all the pieces concatenated into one message.
118 //
119 void Final(uint64* hash1, // out only: first 64 bits of hash value.
120 uint64* hash2); // out only: second 64 bits of hash value.
121
122 //
123 // left rotate a 64-bit value by k bytes
124 //
125 static INLINE uint64 Rot64(uint64 x, int k) {
126 return (x << k) | (x >> (64 - k));
127 }
128
129 //
130 // This is used if the input is 96 bytes long or longer.
131 //
132 // The internal state is fully overwritten every 96 bytes.
133 // Every input bit appears to cause at least 128 bits of entropy
134 // before 96 other bytes are combined, when run forward or backward
135 // For every input bit,
136 // Two inputs differing in just that input bit
137 // Where "differ" means xor or subtraction
138 // And the base value is random
139 // When run forward or backwards one Mix
140 // I tried 3 pairs of each; they all differed by at least 212 bits.
141 //
142 static INLINE void Mix(const uint64* data, uint64& s0, uint64& s1, uint64& s2, uint64& s3,
143 uint64& s4, uint64& s5, uint64& s6, uint64& s7, uint64& s8, uint64& s9,
144 uint64& s10, uint64& s11) {
145 s0 += data[0];
146 s2 ^= s10;
147 s11 ^= s0;
148 s0 = Rot64(s0, 11);
149 s11 += s1;
150 s1 += data[1];
151 s3 ^= s11;
152 s0 ^= s1;
153 s1 = Rot64(s1, 32);
154 s0 += s2;
155 s2 += data[2];
156 s4 ^= s0;
157 s1 ^= s2;
158 s2 = Rot64(s2, 43);
159 s1 += s3;
160 s3 += data[3];
161 s5 ^= s1;
162 s2 ^= s3;
163 s3 = Rot64(s3, 31);
164 s2 += s4;
165 s4 += data[4];
166 s6 ^= s2;
167 s3 ^= s4;
168 s4 = Rot64(s4, 17);
169 s3 += s5;
170 s5 += data[5];
171 s7 ^= s3;
172 s4 ^= s5;
173 s5 = Rot64(s5, 28);
174 s4 += s6;
175 s6 += data[6];
176 s8 ^= s4;
177 s5 ^= s6;
178 s6 = Rot64(s6, 39);
179 s5 += s7;
180 s7 += data[7];
181 s9 ^= s5;
182 s6 ^= s7;
183 s7 = Rot64(s7, 57);
184 s6 += s8;
185 s8 += data[8];
186 s10 ^= s6;
187 s7 ^= s8;
188 s8 = Rot64(s8, 55);
189 s7 += s9;
190 s9 += data[9];
191 s11 ^= s7;
192 s8 ^= s9;
193 s9 = Rot64(s9, 54);
194 s8 += s10;
195 s10 += data[10];
196 s0 ^= s8;
197 s9 ^= s10;
198 s10 = Rot64(s10, 22);
199 s9 += s11;
200 s11 += data[11];
201 s1 ^= s9;
202 s10 ^= s11;
203 s11 = Rot64(s11, 46);
204 s10 += s0;
205 }
206
207 //
208 // Mix all 12 inputs together so that h0, h1 are a hash of them all.
209 //
210 // For two inputs differing in just the input bits
211 // Where "differ" means xor or subtraction
212 // And the base value is random, or a counting value starting at that bit
213 // The final result will have each bit of h0, h1 flip
214 // For every input bit,
215 // with probability 50 +- .3%
216 // For every pair of input bits,
217 // with probability 50 +- 3%
218 //
219 // This does not rely on the last Mix() call having already mixed some.
220 // Two iterations was almost good enough for a 64-bit result, but a
221 // 128-bit result is reported, so End() does three iterations.
222 //
223 static INLINE void EndPartial(uint64& h0, uint64& h1, uint64& h2, uint64& h3, uint64& h4,
224 uint64& h5, uint64& h6, uint64& h7, uint64& h8, uint64& h9,
225 uint64& h10, uint64& h11) {
226 h11 += h1;
227 h2 ^= h11;
228 h1 = Rot64(h1, 44);
229 h0 += h2;
230 h3 ^= h0;
231 h2 = Rot64(h2, 15);
232 h1 += h3;
233 h4 ^= h1;
234 h3 = Rot64(h3, 34);
235 h2 += h4;
236 h5 ^= h2;
237 h4 = Rot64(h4, 21);
238 h3 += h5;
239 h6 ^= h3;
240 h5 = Rot64(h5, 38);
241 h4 += h6;
242 h7 ^= h4;
243 h6 = Rot64(h6, 33);
244 h5 += h7;
245 h8 ^= h5;
246 h7 = Rot64(h7, 10);
247 h6 += h8;
248 h9 ^= h6;
249 h8 = Rot64(h8, 13);
250 h7 += h9;
251 h10 ^= h7;
252 h9 = Rot64(h9, 38);
253 h8 += h10;
254 h11 ^= h8;
255 h10 = Rot64(h10, 53);
256 h9 += h11;
257 h0 ^= h9;
258 h11 = Rot64(h11, 42);
259 h10 += h0;
260 h1 ^= h10;
261 h0 = Rot64(h0, 54);
262 }
263
264 static INLINE void End(const uint64* data, uint64& h0, uint64& h1, uint64& h2, uint64& h3,
265 uint64& h4, uint64& h5, uint64& h6, uint64& h7, uint64& h8, uint64& h9,
266 uint64& h10, uint64& h11) {
267 h0 += data[0];
268 h1 += data[1];
269 h2 += data[2];
270 h3 += data[3];
271 h4 += data[4];
272 h5 += data[5];
273 h6 += data[6];
274 h7 += data[7];
275 h8 += data[8];
276 h9 += data[9];
277 h10 += data[10];
278 h11 += data[11];
279 EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
280 EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
281 EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
282 }
283
284 //
285 // The goal is for each bit of the input to expand into 128 bits of
286 // apparent entropy before it is fully overwritten.
287 // n trials both set and cleared at least m bits of h0 h1 h2 h3
288 // n: 2 m: 29
289 // n: 3 m: 46
290 // n: 4 m: 57
291 // n: 5 m: 107
292 // n: 6 m: 146
293 // n: 7 m: 152
294 // when run forwards or backwards
295 // for all 1-bit and 2-bit diffs
296 // with diffs defined by either xor or subtraction
297 // with a base of all zeros plus a counter, or plus another bit, or random
298 //
299 static INLINE void ShortMix(uint64& h0, uint64& h1, uint64& h2, uint64& h3) {
300 h2 = Rot64(h2, 50);
301 h2 += h3;
302 h0 ^= h2;
303 h3 = Rot64(h3, 52);
304 h3 += h0;
305 h1 ^= h3;
306 h0 = Rot64(h0, 30);
307 h0 += h1;
308 h2 ^= h0;
309 h1 = Rot64(h1, 41);
310 h1 += h2;
311 h3 ^= h1;
312 h2 = Rot64(h2, 54);
313 h2 += h3;
314 h0 ^= h2;
315 h3 = Rot64(h3, 48);
316 h3 += h0;
317 h1 ^= h3;
318 h0 = Rot64(h0, 38);
319 h0 += h1;
320 h2 ^= h0;
321 h1 = Rot64(h1, 37);
322 h1 += h2;
323 h3 ^= h1;
324 h2 = Rot64(h2, 62);
325 h2 += h3;
326 h0 ^= h2;
327 h3 = Rot64(h3, 34);
328 h3 += h0;
329 h1 ^= h3;
330 h0 = Rot64(h0, 5);
331 h0 += h1;
332 h2 ^= h0;
333 h1 = Rot64(h1, 36);
334 h1 += h2;
335 h3 ^= h1;
336 }
337
338 //
339 // Mix all 4 inputs together so that h0, h1 are a hash of them all.
340 //
341 // For two inputs differing in just the input bits
342 // Where "differ" means xor or subtraction
343 // And the base value is random, or a counting value starting at that bit
344 // The final result will have each bit of h0, h1 flip
345 // For every input bit,
346 // with probability 50 +- .3% (it is probably better than that)
347 // For every pair of input bits,
348 // with probability 50 +- .75% (the worst case is approximately that)
349 //
350 static INLINE void ShortEnd(uint64& h0, uint64& h1, uint64& h2, uint64& h3) {
351 h3 ^= h2;
352 h2 = Rot64(h2, 15);
353 h3 += h2;
354 h0 ^= h3;
355 h3 = Rot64(h3, 52);
356 h0 += h3;
357 h1 ^= h0;
358 h0 = Rot64(h0, 26);
359 h1 += h0;
360 h2 ^= h1;
361 h1 = Rot64(h1, 51);
362 h2 += h1;
363 h3 ^= h2;
364 h2 = Rot64(h2, 28);
365 h3 += h2;
366 h0 ^= h3;
367 h3 = Rot64(h3, 9);
368 h0 += h3;
369 h1 ^= h0;
370 h0 = Rot64(h0, 47);
371 h1 += h0;
372 h2 ^= h1;
373 h1 = Rot64(h1, 54);
374 h2 += h1;
375 h3 ^= h2;
376 h2 = Rot64(h2, 32);
377 h3 += h2;
378 h0 ^= h3;
379 h3 = Rot64(h3, 25);
380 h0 += h3;
381 h1 ^= h0;
382 h0 = Rot64(h0, 63);
383 h1 += h0;
384 }
385
386 private:
387 //
388 // Short is used for messages under 192 bytes in length
389 // Short has a low startup cost, the normal mode is good for long
390 // keys, the cost crossover is at about 192 bytes. The two modes were
391 // held to the same quality bar.
392 //
393 static void Short(const void* message, // message (array of bytes, not necessarily aligned)
394 size_t length, // length of message (in bytes)
395 uint64* hash1, // in/out: in the seed, out the hash value
396 uint64* hash2); // in/out: in the seed, out the hash value
397
398 // number of uint64's in internal state
399 static const size_t sc_numVars = 12;
400
401 // size of the internal state
402 static const size_t sc_blockSize = sc_numVars * 8;
403
404 // size of buffer of unhashed data, in bytes
405 static const size_t sc_bufSize = 2 * sc_blockSize;
406
407 //
408 // sc_const: a constant which:
409 // * is not zero
410 // * is odd
411 // * is a not-very-regular mix of 1's and 0's
412 // * does not need any other special mathematical properties
413 //
414 static const uint64 sc_const = 0xdeadbeefdeadbeefLL;
415
416 uint64 m_data[2 * sc_numVars]; // unhashed data, for partial messages
417 uint64 m_state[sc_numVars]; // internal state of the hash
418 size_t m_length; // total length of the input so far
419 uint8 m_remainder; // length of unhashed data stashed in m_data
420};