66//
77// ===----------------------------------------------------------------------===//
88
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>
2414
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 ;
3217
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
3621
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))))
4223
4324#define SIPROUND \
4425 do { \
5839 v2 = ROTL (v2, 32 ); \
5940 } while (0 )
6041
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]) {
7154
7255 const unsigned char *ni = (const unsigned char *)in;
7356 const unsigned char *kk = (const unsigned char *)k;
7457
75- assert ((outlen == 8 ) || (outlen == 16 ));
58+ static_assert (outlen == 8 || outlen == 16 , " result should be 8 or 16 bytes" );
59+
7660 uint64_t v0 = UINT64_C (0x736f6d6570736575 );
7761 uint64_t v1 = UINT64_C (0x646f72616e646f6d );
7862 uint64_t v2 = UINT64_C (0x6c7967656e657261 );
7963 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 );
8266 uint64_t m;
8367 int i;
8468 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,
9377 v1 ^= 0xee ;
9478
9579 for (; ni != end; ni += 8 ) {
96- m = U8TO64_LE (ni);
80+ m = endian::read64le (ni);
9781 v3 ^= m;
9882
9983 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,
10589 switch (left) {
10690 case 7 :
10791 b |= ((uint64_t )ni[6 ]) << 48 ;
108- /* FALLTHRU */
92+ LLVM_FALLTHROUGH;
10993 case 6 :
11094 b |= ((uint64_t )ni[5 ]) << 40 ;
111- /* FALLTHRU */
95+ LLVM_FALLTHROUGH;
11296 case 5 :
11397 b |= ((uint64_t )ni[4 ]) << 32 ;
114- /* FALLTHRU */
98+ LLVM_FALLTHROUGH;
11599 case 4 :
116100 b |= ((uint64_t )ni[3 ]) << 24 ;
117- /* FALLTHRU */
101+ LLVM_FALLTHROUGH;
118102 case 3 :
119103 b |= ((uint64_t )ni[2 ]) << 16 ;
120- /* FALLTHRU */
104+ LLVM_FALLTHROUGH;
121105 case 2 :
122106 b |= ((uint64_t )ni[1 ]) << 8 ;
123- /* FALLTHRU */
107+ LLVM_FALLTHROUGH;
124108 case 1 :
125109 b |= ((uint64_t )ni[0 ]);
126110 break ;
@@ -144,18 +128,28 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
144128 SIPROUND;
145129
146130 b = v0 ^ v1 ^ v2 ^ v3;
147- U64TO8_LE (out, b);
131+ endian::write64le (out, b);
148132
149133 if (outlen == 8 )
150- return 0 ;
134+ return ;
151135
152136 v1 ^= 0xdd ;
153137
154138 for (i = 0 ; i < dROUNDS; ++i)
155139 SIPROUND;
156140
157141 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+ }
159151
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);
161155}
0 commit comments