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
20 || defined(PERL_HASH_FUNC_SIPHASH) \
21 || defined(PERL_HASH_FUNC_SIPHASH13) \
22 || defined(PERL_HASH_FUNC_HYBRID_OAATHU_SIPHASH13) \
23 || defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD) \
26 #define PERL_HASH_FUNC_HYBRID_OAATHU_SIPHASH13
28 #define PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
32 #if defined(PERL_HASH_FUNC_SIPHASH)
33 # define PERL_HASH_FUNC "SIPHASH_2_4"
34 # define PERL_HASH_SEED_BYTES 16
35 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_siphash_2_4((seed),(U8*)(str),(len))
36 #elif defined(PERL_HASH_FUNC_SIPHASH13)
37 # define PERL_HASH_FUNC "SIPHASH_1_3"
38 # define PERL_HASH_SEED_BYTES 16
39 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_siphash_1_3((seed),(U8*)(str),(len))
40 #elif defined(PERL_HASH_FUNC_HYBRID_OAATHU_SIPHASH13)
41 # define PERL_HASH_FUNC "HYBRID_OAATHU_SIPHASH_1_3"
42 # define PERL_HASH_SEED_BYTES 24
43 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_oaathu_siphash_1_3((seed),(U8*)(str),(len))
44 #elif defined(PERL_HASH_FUNC_ONE_AT_A_TIME_HARD)
45 # define PERL_HASH_FUNC "ONE_AT_A_TIME_HARD"
46 # define PERL_HASH_SEED_BYTES 8
47 # define PERL_HASH_WITH_SEED(seed,hash,str,len) (hash)= S_perl_hash_one_at_a_time_hard((seed),(U8*)(str),(len))
50 #ifndef PERL_HASH_WITH_SEED
51 #error "No hash function defined!"
53 #ifndef PERL_HASH_SEED_BYTES
54 #error "PERL_HASH_SEED_BYTES not defined"
56 #ifndef PERL_HASH_FUNC
57 #error "PERL_HASH_FUNC not defined"
60 #ifndef PERL_HASH_SEED
61 # if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)
62 # define PERL_HASH_SEED PL_hash_seed
63 # elif PERL_HASH_SEED_BYTES == 4
64 # define PERL_HASH_SEED ((const U8 *)"PeRl")
65 # elif PERL_HASH_SEED_BYTES == 8
66 # define PERL_HASH_SEED ((const U8 *)"PeRlHaSh")
67 # elif PERL_HASH_SEED_BYTES == 16
68 # define PERL_HASH_SEED ((const U8 *)"PeRlHaShhAcKpErl")
70 # error "No PERL_HASH_SEED definition for " PERL_HASH_FUNC
74 #define PERL_HASH(hash,str,len) PERL_HASH_WITH_SEED(PERL_HASH_SEED,hash,str,len)
76 /* legacy - only mod_perl should be doing this. */
77 #ifdef PERL_HASH_INTERNAL_ACCESS
78 #define PERL_HASH_INTERNAL(hash,str,len) PERL_HASH(hash,str,len)
81 /*-----------------------------------------------------------------------------
82 * Endianess, misalignment capabilities and util macros
84 * The following 3 macros are defined in this section. The other macros defined
85 * are only needed to help derive these 3.
87 * U8TO32_LE(x) Read a little endian unsigned 32-bit int
88 * UNALIGNED_SAFE Defined if unaligned access is safe
89 * ROTL32(x,r) Rotate x left by r bits
92 #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
93 || defined(_MSC_VER) || defined (__TURBOC__)
94 #define U8TO16_LE(d) (*((const U16 *) (d)))
97 #if !defined (U8TO16_LE)
98 #define U8TO16_LE(d) ((((const U8 *)(d))[1] << 8)\
99 +((const U8 *)(d))[0])
102 #if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678) && U32SIZE == 4
103 /* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
104 #define U8TO32_LE(ptr) (*((const U32*)(ptr)))
105 #elif BYTEORDER == 0x4321 || BYTEORDER == 0x87654321
106 /* TODO: Add additional cases below where a compiler provided bswap32 is available */
107 #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
108 #define U8TO32_LE(ptr) (__builtin_bswap32(*((U32*)(ptr))))
110 /* Without a known fast bswap32 we're just as well off doing this */
111 #define U8TO32_LE(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
112 #define UNALIGNED_SAFE
115 /* Unknown endianess so last resort is to read individual bytes */
116 #define U8TO32_LE(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24)
117 /* Since we're not doing word-reads we can skip the messing about with realignment */
118 #define UNALIGNED_SAFE
123 /* This probably isn't going to work, but failing with a compiler error due to
124 lack of uint64_t is no worse than failing right now with an #error. */
129 /* Find best way to ROTL32/ROTL64 */
130 #if defined(_MSC_VER)
131 #include <stdlib.h> /* Microsoft put _rotl declaration in here */
132 #define ROTL32(x,r) _rotl(x,r)
134 #define ROTL64(x,r) _rotl64(x,r)
137 /* gcc recognises this code and generates a rotate instruction for CPUs with one */
138 #define ROTL32(x,r) (((U32)x << r) | ((U32)x >> (32 - r)))
140 #define ROTL64(x,r) (((U64)x << r) | ((U64)x >> (64 - r)))
146 #define ROTL_UV(x,r) ROTL64(x,r)
148 #define ROTL_UV(x,r) ROTL32(x,r)
151 /* This is SipHash by Jean-Philippe Aumasson and Daniel J. Bernstein.
152 * The authors claim it is relatively secure compared to the alternatives
153 * and that performance wise it is a suitable hash for languages like Perl.
156 * https://www.131002.net/siphash/
158 * This implementation seems to perform slightly slower than one-at-a-time for
159 * short keys, but degrades slower for longer keys. Murmur Hash outperforms it
160 * regardless of keys size.
167 #define U8TO64_LE(p) \
168 (((U64)((p)[0]) ) | \
169 ((U64)((p)[1]) << 8) | \
170 ((U64)((p)[2]) << 16) | \
171 ((U64)((p)[3]) << 24) | \
172 ((U64)((p)[4]) << 32) | \
173 ((U64)((p)[5]) << 40) | \
174 ((U64)((p)[6]) << 48) | \
175 ((U64)((p)[7]) << 56))
179 v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
180 v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
181 v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
182 v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
188 #define PERL_SIPHASH_FNC(FNC,SIP_ROUNDS,SIP_FINAL_ROUNDS) \
189 PERL_STATIC_INLINE U32 \
190 FNC(const unsigned char * const seed, const unsigned char *in, const STRLEN inlen) { \
191 /* "somepseudorandomlygeneratedbytes" */ \
192 U64 v0 = UINT64_C(0x736f6d6570736575); \
193 U64 v1 = UINT64_C(0x646f72616e646f6d); \
194 U64 v2 = UINT64_C(0x6c7967656e657261); \
195 U64 v3 = UINT64_C(0x7465646279746573); \
198 U64 k0 = ((const U64*)seed)[0]; \
199 U64 k1 = ((const U64*)seed)[1]; \
201 const int left = inlen & 7; \
202 const U8 *end = in + inlen - left; \
204 b = ( ( U64 )(inlen) ) << 56; \
210 for ( ; in != end; in += 8 ) \
212 m = U8TO64_LE( in ); \
222 case 7: b |= ( ( U64 )in[ 6] ) << 48; \
223 case 6: b |= ( ( U64 )in[ 5] ) << 40; \
224 case 5: b |= ( ( U64 )in[ 4] ) << 32; \
225 case 4: b |= ( ( U64 )in[ 3] ) << 24; \
226 case 3: b |= ( ( U64 )in[ 2] ) << 16; \
227 case 2: b |= ( ( U64 )in[ 1] ) << 8; \
228 case 1: b |= ( ( U64 )in[ 0] ); break; \
242 b = v0 ^ v1 ^ v2 ^ v3; \
243 return (U32)(b & U32_MAX); \
247 S_perl_hash_siphash_1_3
249 ,SIPROUND;SIPROUND;SIPROUND;
253 S_perl_hash_siphash_2_4
255 ,SIPROUND;SIPROUND;SIPROUND;SIPROUND;
258 #endif /* defined(CAN64BITHASH) */
260 /* - ONE_AT_A_TIME_HARD is the 5.17+ recommend ONE_AT_A_TIME variant */
262 /* This is derived from the "One-at-a-Time" algorithm by Bob Jenkins
263 * from requirements by Colin Plumb.
264 * (http://burtleburtle.net/bob/hash/doobs.html)
265 * Modified by Yves Orton to increase security for Perl 5.17 and later.
267 PERL_STATIC_INLINE U32
268 S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
269 const unsigned char * const end = (const unsigned char *)str + len;
270 U32 hash = *((const U32*)seed) + (U32)len;
273 hash += (hash << 10);
278 hash += (hash << 10);
282 hash += (hash << 10);
286 hash += (hash << 10);
290 hash += (hash << 10);
294 hash += (hash << 10);
298 hash ^= (hash >> 11);
299 return (hash + (hash << 15));
304 /* Hybrid hash function
306 * For short strings, 16 bytes or shorter, we use an optimised variant
307 * of One At A Time Hard, and for longer strings, we use siphash_1_3.
309 * The optimisation of One At A Time Hard means we read the key in
310 * reverse from normal, but by doing so we avoid the loop overhead.
312 PERL_STATIC_INLINE U32
313 S_perl_hash_oaathu_siphash_1_3(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
314 U32 hash = *((const U32*)seed) + (U32)len;
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);
381 hash += (hash << 10);
384 hash += (hash << 10);
387 hash += (hash << 10);
390 hash += (hash << 10);
393 hash += (hash << 10);
397 hash ^= (hash >> 11);
398 return (hash + (hash << 15));
400 return S_perl_hash_siphash_1_3(seed+8, str, len);
402 #endif /* defined(CAN64BITHASH) */
405 #endif /*compile once*/
408 * ex: set ts=8 sts=4 sw=4 et: