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>
1311
1412// Lightly adapted from the SipHash reference C implementation by
1513// Jean-Philippe Aumasson and Daniel J. Bernstein.
1614
17- /* default: SipHash-2-4 */
18- #ifndef cROUNDS
19- #define cROUNDS 2
20- #endif
21- #ifndef dROUNDS
22- #define dROUNDS 4
23- #endif
24-
2515#define ROTL (x, b ) (uint64_t )(((x) << (b)) | ((x) >> (64 - (b))))
2616
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-
3717#define U8TO64_LE (p ) \
3818 (((uint64_t )((p)[0 ])) | ((uint64_t )((p)[1 ]) << 8 ) | \
3919 ((uint64_t )((p)[2 ]) << 16 ) | ((uint64_t )((p)[3 ]) << 24 ) | \
5838 v2 = ROTL (v2, 32 ); \
5939 } while (0 )
6040
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) {
41+ template <int cROUNDS, int dROUNDS, class ResultTy >
42+ static inline ResultTy siphash (const unsigned char *in, uint64_t inlen,
43+ const unsigned char (&k)[16]) {
7144
7245 const unsigned char *ni = (const unsigned char *)in;
7346 const unsigned char *kk = (const unsigned char *)k;
7447
75- assert ((outlen == 8 ) || (outlen == 16 ));
48+ static_assert (sizeof (ResultTy) == 8 || sizeof (ResultTy) == 16 ,
49+ " result type should be uint64_t or uint128_t" );
7650 uint64_t v0 = UINT64_C (0x736f6d6570736575 );
7751 uint64_t v1 = UINT64_C (0x646f72616e646f6d );
7852 uint64_t v2 = UINT64_C (0x6c7967656e657261 );
@@ -89,7 +63,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
8963 v1 ^= k1;
9064 v0 ^= k0;
9165
92- if (outlen == 16 )
66+ if (sizeof (ResultTy) == 16 )
9367 v1 ^= 0xee ;
9468
9569 for (; ni != end; ni += 8 ) {
@@ -105,22 +79,22 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
10579 switch (left) {
10680 case 7 :
10781 b |= ((uint64_t )ni[6 ]) << 48 ;
108- /* FALLTHRU */
82+ LLVM_FALLTHROUGH;
10983 case 6 :
11084 b |= ((uint64_t )ni[5 ]) << 40 ;
111- /* FALLTHRU */
85+ LLVM_FALLTHROUGH;
11286 case 5 :
11387 b |= ((uint64_t )ni[4 ]) << 32 ;
114- /* FALLTHRU */
88+ LLVM_FALLTHROUGH;
11589 case 4 :
11690 b |= ((uint64_t )ni[3 ]) << 24 ;
117- /* FALLTHRU */
91+ LLVM_FALLTHROUGH;
11892 case 3 :
11993 b |= ((uint64_t )ni[2 ]) << 16 ;
120- /* FALLTHRU */
94+ LLVM_FALLTHROUGH;
12195 case 2 :
12296 b |= ((uint64_t )ni[1 ]) << 8 ;
123- /* FALLTHRU */
97+ LLVM_FALLTHROUGH;
12498 case 1 :
12599 b |= ((uint64_t )ni[0 ]);
126100 break ;
@@ -135,7 +109,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
135109
136110 v0 ^= b;
137111
138- if (outlen == 16 )
112+ if (sizeof (ResultTy) == 16 )
139113 v2 ^= 0xee ;
140114 else
141115 v2 ^= 0xff ;
@@ -144,18 +118,18 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
144118 SIPROUND;
145119
146120 b = v0 ^ v1 ^ v2 ^ v3;
147- U64TO8_LE (out, b);
148121
149- if (outlen == 8 )
150- return 0 ;
122+ uint64_t firstHalf = b;
123+ if (sizeof (ResultTy) == 8 )
124+ return firstHalf;
151125
152126 v1 ^= 0xdd ;
153127
154128 for (i = 0 ; i < dROUNDS; ++i)
155129 SIPROUND;
156130
157131 b = v0 ^ v1 ^ v2 ^ v3;
158- U64TO8_LE (out + 8 , b) ;
132+ uint64_t secondHalf = b ;
159133
160- return 0 ;
134+ return firstHalf | ( ResultTy (secondHalf) << ( sizeof (ResultTy) == 8 ? 0 : 64 )) ;
161135}
0 commit comments