2 *--------------------------------------------------------------------------------------
3 * The "hash seed" feature was added in Perl 5.8.1 to perturb the results
4 * to avoid "algorithmic complexity attacks".
6 * If USE_HASH_SEED is defined, hash randomisation is done by default
7 * If USE_HASH_SEED_EXPLICIT is defined, hash randomisation is done
8 * only if the environment variable PERL_HASH_SEED is set.
9 * (see also perl.c:perl_parse() and S_init_tls_and_interp() and util.c:get_hash_seed())
12 #ifndef PERL_SEEN_HV_FUNC_H /* compile once */
13 #define PERL_SEEN_HV_FUNC_H
16 || defined(PERL_HASH_FUNC_SIPHASH) \
17 || defined(PERL_HASH_FUNC_SIPHASH13) \
18 || defined(PERL_HASH_FUNC_HYBRID_OAATHU_SIPHASH13) \
19 || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) \
22 #define PERL_HASH_FUNC_HYBRID_OAATHU_SIPHASH13
24 #define PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
28 #if defined(PERL_HASH_FUNC_SIPHASH)
29 # define PERL_HASH_FUNC "SIPHASH_2_4"
30 # define PERL_HASH_SEED_BYTES 16
31 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_siphash_2_4((seed),(U8*)(str),(len))
32 #elif defined(PERL_HASH_FUNC_SIPHASH13)
33 # define PERL_HASH_FUNC "SIPHASH_1_3"
34 # define PERL_HASH_SEED_BYTES 16
35 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_siphash_1_3((seed),(U8*)(str),(len))
36 #elif defined(PERL_HASH_FUNC_HYBRID_OAATHU_SIPHASH13)
37 # define PERL_HASH_FUNC "HYBRID_OAATHU_SIPHASH_1_3"
38 # define PERL_HASH_SEED_BYTES 24
39 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_oaathu_siphash_1_3((seed),(U8*)(str),(len))
40 #elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD)
41 # define PERL_HASH_FUNC "ONE_AT_A_TIME_HARD"
42 # define PERL_HASH_SEED_BYTES 8
43 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_one_at_a_time_hard((seed),(U8*)(str),(len))
46 #ifndef PERL_HASH_WITH_SEED
47 #error "No hash function defined!"
49 #ifndef PERL_HASH_SEED_BYTES
50 #error "PERL_HASH_SEED_BYTES not defined"
52 #ifndef PERL_HASH_FUNC
53 #error "PERL_HASH_FUNC not defined"
56 #ifndef PERL_HASH_SEED
57 # if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)
58 # define PERL_HASH_SEED PL_hash_seed
59 # elif PERL_HASH_SEED_BYTES == 4
60 # define PERL_HASH_SEED ((const U8 *)"PeRl")
61 # elif PERL_HASH_SEED_BYTES == 8
62 # define PERL_HASH_SEED ((const U8 *)"PeRlHaSh")
63 # elif PERL_HASH_SEED_BYTES == 16
64 # define PERL_HASH_SEED ((const U8 *)"PeRlHaShhAcKpErl")
66 # error "No PERL_HASH_SEED definition for " PERL_HASH_FUNC
70 #define PERL_HASH(hash,str,len) PERL_HASH_WITH_SEED(PERL_HASH_SEED,hash,str,len)
72 /* legacy - only mod_perl should be doing this. */
73 #ifdef PERL_HASH_INTERNAL_ACCESS
74 #define PERL_HASH_INTERNAL(hash,str,len) PERL_HASH(hash,str,len)
77 /*-----------------------------------------------------------------------------
78 * Endianess, misalignment capabilities and util macros
80 * The following 3 macros are defined in this section. The other macros defined
81 * are only needed to help derive these 3.
83 * U8TO32_LE(x) Read a little endian unsigned 32-bit int
84 * UNALIGNED_SAFE Defined if unaligned access is safe
85 * ROTL32(x,r) Rotate x left by r bits
88 #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
89 || defined(_MSC_VER) || defined (__TURBOC__)
90 #define U8TO16_LE(d) (*((const U16 *) (d)))
93 #if !defined (U8TO16_LE)
94 #define U8TO16_LE(d) ((((const U8 *)(d))[1] << 8)\
95 +((const U8 *)(d))[0])
98 #if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678) && U32SIZE == 4
99 /* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
100 #define U8TO32_LE(ptr) (*((const U32*)(ptr)))
101 #elif BYTEORDER == 0x4321 || BYTEORDER == 0x87654321
102 /* TODO: Add additional cases below where a compiler provided bswap32 is available */
103 #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
104 #define U8TO32_LE(ptr) (__builtin_bswap32(*((U32*)(ptr))))
106 /* Without a known fast bswap32 we're just as well off doing this */
107 #define U8TO32_LE(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
108 #define UNALIGNED_SAFE
111 /* Unknown endianess so last resort is to read individual bytes */
112 #define U8TO32_LE(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
113 /* Since we're not doing word-reads we can skip the messing about with realignment */
114 #define UNALIGNED_SAFE
119 /* This probably isn't going to work, but failing with a compiler error due to
120 lack of uint64_t is no worse than failing right now with an #error. */
125 /* Find best way to ROTL32/ROTL64 */
126 #if defined(_MSC_VER)
127 #include <stdlib.h> /* Microsoft put _rotl declaration in here */
128 #define ROTL32(x,r) _rotl(x,r)
130 #define ROTL64(x,r) _rotl64(x,r)
133 /* gcc recognises this code and generates a rotate instruction for CPUs with one */
134 #define ROTL32(x,r) (((U32)x << r) | ((U32)x >> (32 - r)))
136 #define ROTL64(x,r) (((U64)x << r) | ((U64)x >> (64 - r)))
142 #define ROTL_UV(x,r) ROTL64(x,r)
144 #define ROTL_UV(x,r) ROTL32(x,r)
147 /* This is SipHash by Jean-Philippe Aumasson and Daniel J. Bernstein.
148 * The authors claim it is relatively secure compared to the alternatives
149 * and that performance wise it is a suitable hash for languages like Perl.
152 * https://www.131002.net/siphash/
154 * This implementation seems to perform slightly slower than one-at-a-time for
155 * short keys, but degrades slower for longer keys. Murmur Hash outperforms it
156 * regardless of keys size.
163 #define U8TO64_LE(p) \
164 (((U64)((p)[0]) ) | \
165 ((U64)((p)[1]) << 8) | \
166 ((U64)((p)[2]) << 16) | \
167 ((U64)((p)[3]) << 24) | \
168 ((U64)((p)[4]) << 32) | \
169 ((U64)((p)[5]) << 40) | \
170 ((U64)((p)[6]) << 48) | \
171 ((U64)((p)[7]) << 56))
175 v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
176 v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
177 v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
178 v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
184 #define PERL_SIPHASH_FNC(FNC,SIP_ROUNDS,SIP_FINAL_ROUNDS) \
185 PERL_STATIC_INLINE U32 \
186 FNC(const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) { \
187 /* "somepseudorandomlygeneratedbytes" */ \
188 U64 v0 = UINT64_C(0x736f6d6570736575); \
189 U64 v1 = UINT64_C(0x646f72616e646f6d); \
190 U64 v2 = UINT64_C(0x6c7967656e657261); \
191 U64 v3 = UINT64_C(0x7465646279746573); \
194 U64 k0 = ((const U64*)seed)[0]; \
195 U64 k1 = ((const U64*)seed)[1]; \
197 const int left = inlen & 7; \
198 const U8 *end = in + inlen - left; \
200 b = ( ( U64 )(inlen) ) << 56; \
206 for ( ; in != end; in += 8 ) \
208 m = U8TO64_LE( in ); \
218 case 7: b |= ( ( U64 )in[ 6] ) << 48; \
219 case 6: b |= ( ( U64 )in[ 5] ) << 40; \
220 case 5: b |= ( ( U64 )in[ 4] ) << 32; \
221 case 4: b |= ( ( U64 )in[ 3] ) << 24; \
222 case 3: b |= ( ( U64 )in[ 2] ) << 16; \
223 case 2: b |= ( ( U64 )in[ 1] ) << 8; \
224 case 1: b |= ( ( U64 )in[ 0] ); break; \
238 b = v0 ^ v1 ^ v2 ^ v3; \
239 return (U32)(b & U32_MAX); \
243 S_perl_hash_siphash_1_3
245 ,SIPROUND;SIPROUND;SIPROUND;
249 S_perl_hash_siphash_2_4
251 ,SIPROUND;SIPROUND;SIPROUND;SIPROUND;
254 #endif /* defined(HAS_QUAD) */
256 /* - ONE_AT_A_TIME_HARD is the 5.17+ recommend ONE_AT_A_TIME variant */
258 /* This is derived from the "One-at-a-Time" algorithm by Bob Jenkins
259 * from requirements by Colin Plumb.
260 * (http://burtleburtle.net/bob/hash/doobs.html)
261 * Modified by Yves Orton to increase security for Perl 5.17 and later.
263 PERL_STATIC_INLINE U32
264 S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
265 const unsigned char * const end = (const unsigned char *)str + len;
266 U32 hash = *((const U32*)seed) + (U32)len;
269 hash += (hash << 10);
274 hash += (hash << 10);
278 hash += (hash << 10);
282 hash += (hash << 10);
286 hash += (hash << 10);
290 hash += (hash << 10);
294 hash ^= (hash >> 11);
295 return (hash + (hash << 15));
300 /* Hybrid hash function
302 * For short strings, 16 bytes or shorter, we use an optimised variant
303 * of One At A Time Hard, and for longer strings, we use siphash_1_3.
305 * The optimisation of One At A Time Hard means we read the key in
306 * reverse from normal, but by doing so we avoid the loop overhead.
308 PERL_STATIC_INLINE U32
309 S_perl_hash_oaathu_siphash_1_3(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
310 U32 hash = *((const U32*)seed) + (U32)len;
313 hash += (hash << 10);
317 hash += (hash << 10);
321 hash += (hash << 10);
325 hash += (hash << 10);
329 hash += (hash << 10);
333 hash += (hash << 10);
337 hash += (hash << 10);
341 hash += (hash << 10);
345 hash += (hash << 10);
349 hash += (hash << 10);
353 hash += (hash << 10);
357 hash += (hash << 10);
361 hash += (hash << 10);
365 hash += (hash << 10);
369 hash += (hash << 10);
373 hash += (hash << 10);
377 hash += (hash << 10);
380 hash += (hash << 10);
383 hash += (hash << 10);
386 hash += (hash << 10);
389 hash += (hash << 10);
393 hash ^= (hash >> 11);
394 return (hash + (hash << 15));
396 return S_perl_hash_siphash_1_3(seed+8, str, len);
398 #endif /* defined(HAS_QUAD) */
401 #endif /*compile once*/
404 * ex: set ts=8 sts=4 sw=4 et: