1 /*
2 * SipHash reference C implementation
3 *
4 * Copyright (c) 2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
5 *
6 * To the extent possible under law, the author(s) have dedicated all
7 * copyright and related and neighboring rights to this software to the public
8 * domain worldwide. This software is distributed without any warranty.
9 *
10 * You should have received a copy of the CC0 Public Domain Dedication along
11 * with this software. If not, see
12 * <http://creativecommons.org/publicdomain/zero/1.0/>.
13 */
14
15 /*
16 * Originally taken from https://github.com/veorq/SipHash/
17 * Altered to match V8's use case.
18 */
19
20 #include "src/third_party/siphash/halfsiphash.h"
21
22 #include "src/base/logging.h"
23 #include "src/base/v8-fallthrough.h"
24
25 #define ROTL(x, b) (uint32_t)(((x) << (b)) | ((x) >> (32 - (b))))
26
27 #define SIPROUND \
28 do { \
29 v0 += v1; \
30 v1 = ROTL(v1, 5); \
31 v1 ^= v0; \
32 v0 = ROTL(v0, 16); \
33 v2 += v3; \
34 v3 = ROTL(v3, 8); \
35 v3 ^= v2; \
36 v0 += v3; \
37 v3 = ROTL(v3, 7); \
38 v3 ^= v0; \
39 v2 += v1; \
40 v1 = ROTL(v1, 13); \
41 v1 ^= v2; \
42 v2 = ROTL(v2, 16); \
43 } while (0)
44
45 // Simplified half-siphash-2-4 implementation for 4 byte input.
halfsiphash(const uint32_t value,const uint64_t seed)46 uint32_t halfsiphash(const uint32_t value, const uint64_t seed) {
47 uint32_t v0 = 0;
48 uint32_t v1 = 0;
49 uint32_t v2 = 0x6c796765;
50 uint32_t v3 = 0x74656462;
51 uint32_t k[2];
52 memcpy(k, &seed, sizeof(seed));
53 uint32_t b = 4 << 24;
54 v3 ^= k[1];
55 v2 ^= k[0];
56 v1 ^= k[1];
57 v0 ^= k[0];
58
59 v3 ^= value;
60
61 // 2 c-rounds
62 SIPROUND;
63 SIPROUND;
64
65 v0 ^= value;
66 v3 ^= b;
67
68 // 2 c-rounds
69 SIPROUND;
70 SIPROUND;
71
72 v0 ^= b;
73 v2 ^= 0xff;
74
75 // 4 d-rounds
76 SIPROUND;
77 SIPROUND;
78 SIPROUND;
79 SIPROUND;
80
81 b = v1 ^ v3;
82 return b;
83 }
84