66//
77// ===----------------------------------------------------------------------===//
88
9- #include " siphash.h"
10- #include < assert.h>
11- #include < stddef.h>
12- #include < stdint.h>
9+ #include " llvm/Support/Compiler.h"
10+ #include < cstdint>
11+ #include < cstring>
1312
1413// Lightly adapted from the SipHash reference C implementation by
1514// Jean-Philippe Aumasson and Daniel J. Bernstein.
1615
17- /* default: SipHash-2-4 */
18- #ifndef cROUNDS
19- #define cROUNDS 2
20- #endif
21- #ifndef dROUNDS
22- #define dROUNDS 4
23- #endif
24-
2516#define ROTL (x, b ) (uint64_t )(((x) << (b)) | ((x) >> (64 - (b))))
2617
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 );
32-
33- #define U64TO8_LE (p, v ) \
34- U32TO8_LE ((p), (uint32_t )((v))); \
35- U32TO8_LE ((p) + 4, (uint32_t )((v) >> 32));
36-
3718#define U8TO64_LE (p ) \
3819 (((uint64_t )((p)[0 ])) | ((uint64_t )((p)[1 ]) << 8 ) | \
3920 ((uint64_t )((p)[2 ]) << 16 ) | ((uint64_t )((p)[3 ]) << 24 ) | \
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+ template <int cROUNDS, int dROUNDS, class ResultTy >
43+ static inline ResultTy siphash (const unsigned char *in, uint64_t inlen,
44+ const unsigned char (&k)[16]) {
7145
7246 const unsigned char *ni = (const unsigned char *)in;
7347 const unsigned char *kk = (const unsigned char *)k;
7448
75- assert ((outlen == 8 ) || (outlen == 16 ));
49+ static_assert (sizeof (ResultTy) == 8 || sizeof (ResultTy) == 16 ,
50+ " result type should be uint64_t or uint128_t" );
7651 uint64_t v0 = UINT64_C (0x736f6d6570736575 );
7752 uint64_t v1 = UINT64_C (0x646f72616e646f6d );
7853 uint64_t v2 = UINT64_C (0x6c7967656e657261 );
@@ -89,7 +64,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
8964 v1 ^= k1;
9065 v0 ^= k0;
9166
92- if (outlen == 16 )
67+ if (sizeof (ResultTy) == 16 )
9368 v1 ^= 0xee ;
9469
9570 for (; ni != end; ni += 8 ) {
@@ -105,22 +80,22 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
10580 switch (left) {
10681 case 7 :
10782 b |= ((uint64_t )ni[6 ]) << 48 ;
108- /* FALLTHRU */
83+ LLVM_FALLTHROUGH;
10984 case 6 :
11085 b |= ((uint64_t )ni[5 ]) << 40 ;
111- /* FALLTHRU */
86+ LLVM_FALLTHROUGH;
11287 case 5 :
11388 b |= ((uint64_t )ni[4 ]) << 32 ;
114- /* FALLTHRU */
89+ LLVM_FALLTHROUGH;
11590 case 4 :
11691 b |= ((uint64_t )ni[3 ]) << 24 ;
117- /* FALLTHRU */
92+ LLVM_FALLTHROUGH;
11893 case 3 :
11994 b |= ((uint64_t )ni[2 ]) << 16 ;
120- /* FALLTHRU */
95+ LLVM_FALLTHROUGH;
12196 case 2 :
12297 b |= ((uint64_t )ni[1 ]) << 8 ;
123- /* FALLTHRU */
98+ LLVM_FALLTHROUGH;
12499 case 1 :
125100 b |= ((uint64_t )ni[0 ]);
126101 break ;
@@ -135,7 +110,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
135110
136111 v0 ^= b;
137112
138- if (outlen == 16 )
113+ if (sizeof (ResultTy) == 16 )
139114 v2 ^= 0xee ;
140115 else
141116 v2 ^= 0xff ;
@@ -144,18 +119,18 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
144119 SIPROUND;
145120
146121 b = v0 ^ v1 ^ v2 ^ v3;
147- U64TO8_LE (out, b);
148122
149- if (outlen == 8 )
150- return 0 ;
123+ uint64_t firstHalf = b;
124+ if (sizeof (ResultTy) == 8 )
125+ return firstHalf;
151126
152127 v1 ^= 0xdd ;
153128
154129 for (i = 0 ; i < dROUNDS; ++i)
155130 SIPROUND;
156131
157132 b = v0 ^ v1 ^ v2 ^ v3;
158- U64TO8_LE (out + 8 , b) ;
133+ uint64_t secondHalf = b ;
159134
160- return 0 ;
135+ return firstHalf | ( ResultTy (secondHalf) << ( sizeof (ResultTy) == 8 ? 0 : 64 )) ;
161136}
0 commit comments