6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
- #include " siphash.h"
10
- #include < assert.h>
11
- #include < stddef.h>
12
- #include < stdint.h>
13
-
14
- // Lightly adapted from the SipHash reference C implementation by
15
- // Jean-Philippe Aumasson and Daniel J. Bernstein.
16
-
17
- /* default: SipHash-2-4 */
18
- #ifndef cROUNDS
19
- #define cROUNDS 2
20
- #endif
21
- #ifndef dROUNDS
22
- #define dROUNDS 4
23
- #endif
9
+ #include " llvm/Support/SipHash.h"
10
+ #include " llvm/ADT/ArrayRef.h"
11
+ #include " llvm/Support/Compiler.h"
12
+ #include " llvm/Support/Endian.h"
13
+ #include < cstdint>
24
14
25
- #define ROTL (x, b ) (uint64_t )(((x) << (b)) | ((x) >> (64 - (b))))
26
-
27
- #define U32TO8_LE (p, v ) \
28
- (p)[0 ] = (uint8_t )((v)); \
29
- (p)[1 ] = (uint8_t )((v) >> 8 ); \
30
- (p)[2 ] = (uint8_t )((v) >> 16 ); \
31
- (p)[3 ] = (uint8_t )((v) >> 24 );
15
+ using namespace llvm ;
16
+ using namespace support ;
32
17
33
- # define U64TO8_LE ( p, v ) \
34
- U32TO8_LE ((p), ( uint32_t )((v))); \
35
- U32TO8_LE ((p) + 4, ( uint32_t )((v) >> 32));
18
+ // Lightly adapted from the SipHash reference C implementation:
19
+ // https://github.com/veorq/SipHash
20
+ // by Jean-Philippe Aumasson and Daniel J. Bernstein
36
21
37
- #define U8TO64_LE (p ) \
38
- (((uint64_t )((p)[0 ])) | ((uint64_t )((p)[1 ]) << 8 ) | \
39
- ((uint64_t )((p)[2 ]) << 16 ) | ((uint64_t )((p)[3 ]) << 24 ) | \
40
- ((uint64_t )((p)[4 ]) << 32 ) | ((uint64_t )((p)[5 ]) << 40 ) | \
41
- ((uint64_t )((p)[6 ]) << 48 ) | ((uint64_t )((p)[7 ]) << 56 ))
22
+ #define ROTL (x, b ) (uint64_t )(((x) << (b)) | ((x) >> (64 - (b))))
42
23
43
24
#define SIPROUND \
44
25
do { \
58
39
v2 = ROTL (v2, 32 ); \
59
40
} while (0 )
60
41
61
- /*
62
- Computes a SipHash value
63
- *in: pointer to input data (read-only)
64
- inlen: input data length in bytes (any size_t value)
65
- *k: pointer to the key data (read-only), must be 16 bytes
66
- *out: pointer to output data (write-only), outlen bytes must be allocated
67
- outlen: length of the output in bytes, must be 8 or 16
68
- */
69
- int siphash (const void *in, const size_t inlen, const void *k, uint8_t *out,
70
- const size_t outlen) {
42
+ namespace {
43
+
44
+ // / Computes a SipHash value
45
+ // /
46
+ // / \param in: pointer to input data (read-only)
47
+ // / \param inlen: input data length in bytes (any size_t value)
48
+ // / \param k: reference to the key data 16-byte array (read-only)
49
+ // / \returns output data, must be 8 or 16 bytes
50
+ // /
51
+ template <int cROUNDS, int dROUNDS, size_t outlen>
52
+ void siphash (const unsigned char *in, uint64_t inlen,
53
+ const unsigned char (&k)[16], unsigned char (&out)[outlen]) {
71
54
72
55
const unsigned char *ni = (const unsigned char *)in;
73
56
const unsigned char *kk = (const unsigned char *)k;
74
57
75
- assert ((outlen == 8 ) || (outlen == 16 ));
58
+ static_assert (outlen == 8 || outlen == 16 , " result should be 8 or 16 bytes" );
59
+
76
60
uint64_t v0 = UINT64_C (0x736f6d6570736575 );
77
61
uint64_t v1 = UINT64_C (0x646f72616e646f6d );
78
62
uint64_t v2 = UINT64_C (0x6c7967656e657261 );
79
63
uint64_t v3 = UINT64_C (0x7465646279746573 );
80
- uint64_t k0 = U8TO64_LE (kk);
81
- uint64_t k1 = U8TO64_LE (kk + 8 );
64
+ uint64_t k0 = endian::read64le (kk);
65
+ uint64_t k1 = endian::read64le (kk + 8 );
82
66
uint64_t m;
83
67
int i;
84
68
const unsigned char *end = ni + inlen - (inlen % sizeof (uint64_t ));
@@ -93,7 +77,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
93
77
v1 ^= 0xee ;
94
78
95
79
for (; ni != end; ni += 8 ) {
96
- m = U8TO64_LE (ni);
80
+ m = endian::read64le (ni);
97
81
v3 ^= m;
98
82
99
83
for (i = 0 ; i < cROUNDS; ++i)
@@ -105,22 +89,22 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
105
89
switch (left) {
106
90
case 7 :
107
91
b |= ((uint64_t )ni[6 ]) << 48 ;
108
- /* FALLTHRU */
92
+ LLVM_FALLTHROUGH;
109
93
case 6 :
110
94
b |= ((uint64_t )ni[5 ]) << 40 ;
111
- /* FALLTHRU */
95
+ LLVM_FALLTHROUGH;
112
96
case 5 :
113
97
b |= ((uint64_t )ni[4 ]) << 32 ;
114
- /* FALLTHRU */
98
+ LLVM_FALLTHROUGH;
115
99
case 4 :
116
100
b |= ((uint64_t )ni[3 ]) << 24 ;
117
- /* FALLTHRU */
101
+ LLVM_FALLTHROUGH;
118
102
case 3 :
119
103
b |= ((uint64_t )ni[2 ]) << 16 ;
120
- /* FALLTHRU */
104
+ LLVM_FALLTHROUGH;
121
105
case 2 :
122
106
b |= ((uint64_t )ni[1 ]) << 8 ;
123
- /* FALLTHRU */
107
+ LLVM_FALLTHROUGH;
124
108
case 1 :
125
109
b |= ((uint64_t )ni[0 ]);
126
110
break ;
@@ -144,18 +128,28 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
144
128
SIPROUND;
145
129
146
130
b = v0 ^ v1 ^ v2 ^ v3;
147
- U64TO8_LE (out, b);
131
+ endian::write64le (out, b);
148
132
149
133
if (outlen == 8 )
150
- return 0 ;
134
+ return ;
151
135
152
136
v1 ^= 0xdd ;
153
137
154
138
for (i = 0 ; i < dROUNDS; ++i)
155
139
SIPROUND;
156
140
157
141
b = v0 ^ v1 ^ v2 ^ v3;
158
- U64TO8_LE (out + 8 , b);
142
+ endian::write64le (out + 8 , b);
143
+ }
144
+
145
+ } // end anonymous namespace
146
+
147
+ void llvm::getSipHash_2_4_64 (ArrayRef<uint8_t > In, const uint8_t (&K)[16],
148
+ uint8_t (&Out)[8]) {
149
+ siphash<2 , 4 >(In.data (), In.size (), K, Out);
150
+ }
159
151
160
- return 0 ;
152
+ void llvm::getSipHash_2_4_128 (ArrayRef<uint8_t > In, const uint8_t (&K)[16],
153
+ uint8_t (&Out)[16]) {
154
+ siphash<2 , 4 >(In.data (), In.size (), K, Out);
161
155
}
0 commit comments