blob: dbcc9744be35a7bba2b760840db4312d5b8cc08a [file] [log] [blame]
Christian Heimes985ecdc2013-11-20 11:46:18 +01001#ifndef Py_HASH_H
2
3#define Py_HASH_H
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8/* Helpers for hash functions */
9#ifndef Py_LIMITED_API
10PyAPI_FUNC(Py_hash_t) _Py_HashDouble(double);
11PyAPI_FUNC(Py_hash_t) _Py_HashPointer(void*);
12PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
13#endif
14
15/* Prime multiplier used in string and various other hashes. */
16#define _PyHASH_MULTIPLIER 1000003UL /* 0xf4243 */
17
18/* Parameters used for the numeric hash implementation. See notes for
Ned Batchelder01ae58d2017-11-09 11:55:34 -050019 _Py_HashDouble in Python/pyhash.c. Numeric hashes are based on
Christian Heimes985ecdc2013-11-20 11:46:18 +010020 reduction modulo the prime 2**_PyHASH_BITS - 1. */
21
22#if SIZEOF_VOID_P >= 8
23# define _PyHASH_BITS 61
24#else
25# define _PyHASH_BITS 31
26#endif
27
28#define _PyHASH_MODULUS (((size_t)1 << _PyHASH_BITS) - 1)
29#define _PyHASH_INF 314159
30#define _PyHASH_NAN 0
31#define _PyHASH_IMAG _PyHASH_MULTIPLIER
32
33
34/* hash secret
35 *
36 * memory layout on 64 bit systems
37 * cccccccc cccccccc cccccccc uc -- unsigned char[24]
38 * pppppppp ssssssss ........ fnv -- two Py_hash_t
Benjamin Peterson9b3d7702016-09-06 13:24:00 -070039 * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t
Christian Heimes985ecdc2013-11-20 11:46:18 +010040 * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t
41 * ........ ........ eeeeeeee pyexpat XML hash salt
42 *
43 * memory layout on 32 bit systems
44 * cccccccc cccccccc cccccccc uc
45 * ppppssss ........ ........ fnv -- two Py_hash_t
Benjamin Peterson9b3d7702016-09-06 13:24:00 -070046 * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*)
Christian Heimes985ecdc2013-11-20 11:46:18 +010047 * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t
48 * ........ ........ eeee.... pyexpat XML hash salt
49 *
50 * (*) The siphash member may not be available on 32 bit platforms without
51 * an unsigned int64 data type.
52 */
Martin v. Löwis1c0689c2014-01-03 21:36:49 +010053#ifndef Py_LIMITED_API
Christian Heimes985ecdc2013-11-20 11:46:18 +010054typedef union {
55 /* ensure 24 bytes */
56 unsigned char uc[24];
57 /* two Py_hash_t for FNV */
58 struct {
59 Py_hash_t prefix;
60 Py_hash_t suffix;
61 } fnv;
Christian Heimes985ecdc2013-11-20 11:46:18 +010062 /* two uint64 for SipHash24 */
63 struct {
Benjamin Peterson9b3d7702016-09-06 13:24:00 -070064 uint64_t k0;
65 uint64_t k1;
Christian Heimes985ecdc2013-11-20 11:46:18 +010066 } siphash;
Christian Heimes985ecdc2013-11-20 11:46:18 +010067 /* a different (!) Py_hash_t for small string optimization */
68 struct {
69 unsigned char padding[16];
70 Py_hash_t suffix;
71 } djbx33a;
72 struct {
73 unsigned char padding[16];
74 Py_hash_t hashsalt;
75 } expat;
76} _Py_HashSecret_t;
77PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret;
Martin v. Löwis1c0689c2014-01-03 21:36:49 +010078#endif
Christian Heimes985ecdc2013-11-20 11:46:18 +010079
80#ifdef Py_DEBUG
81PyAPI_DATA(int) _Py_HashSecret_Initialized;
82#endif
83
84
85/* hash function definition */
86#ifndef Py_LIMITED_API
87typedef struct {
88 Py_hash_t (*const hash)(const void *, Py_ssize_t);
89 const char *name;
90 const int hash_bits;
91 const int seed_bits;
92} PyHash_FuncDef;
93
94PyAPI_FUNC(PyHash_FuncDef*) PyHash_GetFuncDef(void);
95#endif
96
97
98/* cutoff for small string DJBX33A optimization in range [1, cutoff).
99 *
100 * About 50% of the strings in a typical Python application are smaller than
101 * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks.
102 * NEVER use DJBX33A for long strings!
103 *
104 * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms
105 * should use a smaller cutoff because it is easier to create colliding
106 * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should
107 * provide a decent safety margin.
108 */
109#ifndef Py_HASH_CUTOFF
110# define Py_HASH_CUTOFF 0
111#elif (Py_HASH_CUTOFF > 7 || Py_HASH_CUTOFF < 0)
112# error Py_HASH_CUTOFF must in range 0...7.
113#endif /* Py_HASH_CUTOFF */
114
115
116/* hash algorithm selection
117 *
118 * The values for Py_HASH_SIPHASH24 and Py_HASH_FNV are hard-coded in the
119 * configure script.
120 *
121 * - FNV is available on all platforms and architectures.
Miss Islington (bot)4bd1d052019-08-30 13:42:54 -0700122 * - SIPHASH24 only works on platforms that don't require aligned memory for integers.
Christian Heimes985ecdc2013-11-20 11:46:18 +0100123 * - With EXTERNAL embedders can provide an alternative implementation with::
124 *
125 * PyHash_FuncDef PyHash_Func = {...};
126 *
127 * XXX: Figure out __declspec() for extern PyHash_FuncDef.
128 */
129#define Py_HASH_EXTERNAL 0
130#define Py_HASH_SIPHASH24 1
131#define Py_HASH_FNV 2
132
133#ifndef Py_HASH_ALGORITHM
Benjamin Peterson9b3d7702016-09-06 13:24:00 -0700134# ifndef HAVE_ALIGNED_REQUIRED
Christian Heimes985ecdc2013-11-20 11:46:18 +0100135# define Py_HASH_ALGORITHM Py_HASH_SIPHASH24
136# else
137# define Py_HASH_ALGORITHM Py_HASH_FNV
138# endif /* uint64_t && uint32_t && aligned */
139#endif /* Py_HASH_ALGORITHM */
140
141#ifdef __cplusplus
142}
143#endif
144
145#endif /* !Py_HASH_H */