xref: /aosp_15_r20/external/mksh/src/mirhash.h (revision 7c356e860f31eadd15fd599fcfdb9fd21f16a9d4)
1*7c356e86SAndroid Build Coastguard Worker /*-
2*7c356e86SAndroid Build Coastguard Worker  * Copyright © 2011, 2014, 2015
3*7c356e86SAndroid Build Coastguard Worker  *	mirabilos <[email protected]>
4*7c356e86SAndroid Build Coastguard Worker  *
5*7c356e86SAndroid Build Coastguard Worker  * Provided that these terms and disclaimer and all copyright notices
6*7c356e86SAndroid Build Coastguard Worker  * are retained or reproduced in an accompanying document, permission
7*7c356e86SAndroid Build Coastguard Worker  * is granted to deal in this work without restriction, including un‐
8*7c356e86SAndroid Build Coastguard Worker  * limited rights to use, publicly perform, distribute, sell, modify,
9*7c356e86SAndroid Build Coastguard Worker  * merge, give away, or sublicence.
10*7c356e86SAndroid Build Coastguard Worker  *
11*7c356e86SAndroid Build Coastguard Worker  * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
12*7c356e86SAndroid Build Coastguard Worker  * the utmost extent permitted by applicable law, neither express nor
13*7c356e86SAndroid Build Coastguard Worker  * implied; without malicious intent or gross negligence. In no event
14*7c356e86SAndroid Build Coastguard Worker  * may a licensor, author or contributor be held liable for indirect,
15*7c356e86SAndroid Build Coastguard Worker  * direct, other damage, loss, or other issues arising in any way out
16*7c356e86SAndroid Build Coastguard Worker  * of dealing in the work, even if advised of the possibility of such
17*7c356e86SAndroid Build Coastguard Worker  * damage or existence of a defect, except proven that it results out
18*7c356e86SAndroid Build Coastguard Worker  * of said person’s immediate fault when using the work as intended.
19*7c356e86SAndroid Build Coastguard Worker  *-
20*7c356e86SAndroid Build Coastguard Worker  * This file provides BAFH (Better Avalanche for the Jenkins Hash) as
21*7c356e86SAndroid Build Coastguard Worker  * inline macro bodies that operate on “register uint32_t” variables,
22*7c356e86SAndroid Build Coastguard Worker  * with variants that use their local intermediate registers.
23*7c356e86SAndroid Build Coastguard Worker  *
24*7c356e86SAndroid Build Coastguard Worker  * Usage note for BAFH with entropy distribution: input up to 4 bytes
25*7c356e86SAndroid Build Coastguard Worker  * is best combined into a 32-bit unsigned integer, which is then run
26*7c356e86SAndroid Build Coastguard Worker  * through BAFHFinish_reg for mixing and then used as context instead
27*7c356e86SAndroid Build Coastguard Worker  * of 0. Longer input should be handled the same: take the first four
28*7c356e86SAndroid Build Coastguard Worker  * bytes as IV after mixing then add subsequent bytes the same way.
29*7c356e86SAndroid Build Coastguard Worker  * This needs counting input bytes and is endian-dependent, thus not,
30*7c356e86SAndroid Build Coastguard Worker  * for speed reasons, specified for the regular stable hash, but very
31*7c356e86SAndroid Build Coastguard Worker  * much recommended if the actual output value may differ across runs
32*7c356e86SAndroid Build Coastguard Worker  * (so is using a random value instead of 0 for the IV).
33*7c356e86SAndroid Build Coastguard Worker  *-
34*7c356e86SAndroid Build Coastguard Worker  * Little quote gem:
35*7c356e86SAndroid Build Coastguard Worker  *	We are looking into it. Changing the core
36*7c356e86SAndroid Build Coastguard Worker  *	hash function in PHP isn't a trivial change
37*7c356e86SAndroid Build Coastguard Worker  *	and will take us some time.
38*7c356e86SAndroid Build Coastguard Worker  * -- Rasmus Lerdorf
39*7c356e86SAndroid Build Coastguard Worker  */
40*7c356e86SAndroid Build Coastguard Worker 
41*7c356e86SAndroid Build Coastguard Worker #ifndef SYSKERN_MIRHASH_H
42*7c356e86SAndroid Build Coastguard Worker #define SYSKERN_MIRHASH_H 1
43*7c356e86SAndroid Build Coastguard Worker #define SYSKERN_MIRHASH_BAFH
44*7c356e86SAndroid Build Coastguard Worker 
45*7c356e86SAndroid Build Coastguard Worker #include <sys/types.h>
46*7c356e86SAndroid Build Coastguard Worker 
47*7c356e86SAndroid Build Coastguard Worker __RCSID("$MirOS: src/bin/mksh/mirhash.h,v 1.6 2015/11/29 17:05:02 tg Exp $");
48*7c356e86SAndroid Build Coastguard Worker 
49*7c356e86SAndroid Build Coastguard Worker /*-
50*7c356e86SAndroid Build Coastguard Worker  * BAFH itself is defined by the following primitives:
51*7c356e86SAndroid Build Coastguard Worker  *
52*7c356e86SAndroid Build Coastguard Worker  * • BAFHInit(ctx) initialises the hash context, which consists of a
53*7c356e86SAndroid Build Coastguard Worker  *   sole 32-bit unsigned integer (ideally in a register), to 0.
54*7c356e86SAndroid Build Coastguard Worker  *   It is possible to use any initial value out of [0; 2³²[ – which
55*7c356e86SAndroid Build Coastguard Worker  *   is, in fact, recommended if using BAFH for entropy distribution
56*7c356e86SAndroid Build Coastguard Worker  *   – but for a regular stable hash, the IV 0 is needed.
57*7c356e86SAndroid Build Coastguard Worker  *
58*7c356e86SAndroid Build Coastguard Worker  * • BAFHUpdateOctet(ctx,val) compresses the unsigned 8-bit quantity
59*7c356e86SAndroid Build Coastguard Worker  *   into the hash context. The algorithm used is Jenkins’ one-at-a-
60*7c356e86SAndroid Build Coastguard Worker  *   time, except that an additional constant 1 is added so that, if
61*7c356e86SAndroid Build Coastguard Worker  *   the context is (still) zero, adding a NUL byte is not ignored.
62*7c356e86SAndroid Build Coastguard Worker  *
63*7c356e86SAndroid Build Coastguard Worker  * • BAFHror(eax,cl) evaluates to the unsigned 32-bit integer “eax”,
64*7c356e86SAndroid Build Coastguard Worker  *   rotated right by “cl” ∈ [0; 31] (no casting, be careful!) where
65*7c356e86SAndroid Build Coastguard Worker  *   “eax” must be uint32_t and “cl” an in-range integer.
66*7c356e86SAndroid Build Coastguard Worker  *
67*7c356e86SAndroid Build Coastguard Worker  * • BAFHFinish(ctx) avalanches the context around so every sub-byte
68*7c356e86SAndroid Build Coastguard Worker  *   depends on all input octets; afterwards, the context variable’s
69*7c356e86SAndroid Build Coastguard Worker  *   value is the hash output. BAFH does not use any padding, nor is
70*7c356e86SAndroid Build Coastguard Worker  *   the input length added; this is due to the common use case (for
71*7c356e86SAndroid Build Coastguard Worker  *   quick entropy distribution and use with a hashtable).
72*7c356e86SAndroid Build Coastguard Worker  *   Warning: BAFHFinish uses the MixColumn algorithm of AES – which
73*7c356e86SAndroid Build Coastguard Worker  *   is reversible (to avoid introducing funnels and reducing entro‐
74*7c356e86SAndroid Build Coastguard Worker  *   py), so blinding may need to be employed for some uses, e.g. in
75*7c356e86SAndroid Build Coastguard Worker  *   mksh, after a fork.
76*7c356e86SAndroid Build Coastguard Worker  *
77*7c356e86SAndroid Build Coastguard Worker  * The BAFHUpdateOctet and BAFHFinish are available in two flavours:
78*7c356e86SAndroid Build Coastguard Worker  * suffixed with _reg (assumes the context is in a register) or _mem
79*7c356e86SAndroid Build Coastguard Worker  * (which doesn’t).
80*7c356e86SAndroid Build Coastguard Worker  *
81*7c356e86SAndroid Build Coastguard Worker  * The following high-level macros (with _reg and _mem variants) are
82*7c356e86SAndroid Build Coastguard Worker  * available:
83*7c356e86SAndroid Build Coastguard Worker  *
84*7c356e86SAndroid Build Coastguard Worker  * • BAFHUpdateMem(ctx,buf,len) adds a memory block to a context.
85*7c356e86SAndroid Build Coastguard Worker  * • BAFHUpdateStr(ctx,buf) is equivalent to using len=strlen(buf).
86*7c356e86SAndroid Build Coastguard Worker  * • BAFHHostMem(ctx,buf,len) calculates the hash of the memory buf‐
87*7c356e86SAndroid Build Coastguard Worker  *   fer using the first 4 octets (mixed) for IV, as outlined above;
88*7c356e86SAndroid Build Coastguard Worker  *   the result is endian-dependent; “ctx” assumed to be a register.
89*7c356e86SAndroid Build Coastguard Worker  * • BAFHHostStr(ctx,buf) does the same for C strings.
90*7c356e86SAndroid Build Coastguard Worker  *
91*7c356e86SAndroid Build Coastguard Worker  * All macros may use ctx multiple times in their expansion, but all
92*7c356e86SAndroid Build Coastguard Worker  * other arguments are always evaluated at most once except BAFHror.
93*7c356e86SAndroid Build Coastguard Worker  *
94*7c356e86SAndroid Build Coastguard Worker  * To stay portable, never use the BAFHHost*() macros (these are for
95*7c356e86SAndroid Build Coastguard Worker  * host-local entropy shuffling), and encode numbers using ULEB128.
96*7c356e86SAndroid Build Coastguard Worker  */
97*7c356e86SAndroid Build Coastguard Worker 
98*7c356e86SAndroid Build Coastguard Worker #define BAFHInit(h) do {					\
99*7c356e86SAndroid Build Coastguard Worker 	(h) = 0;						\
100*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
101*7c356e86SAndroid Build Coastguard Worker 
102*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateOctet_reg(h,b) do {				\
103*7c356e86SAndroid Build Coastguard Worker 	(h) += (uint8_t)(b);					\
104*7c356e86SAndroid Build Coastguard Worker 	++(h);							\
105*7c356e86SAndroid Build Coastguard Worker 	(h) += (h) << 10;					\
106*7c356e86SAndroid Build Coastguard Worker 	(h) ^= (h) >> 6;					\
107*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
108*7c356e86SAndroid Build Coastguard Worker 
109*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateOctet_mem(m,b) do {				\
110*7c356e86SAndroid Build Coastguard Worker 	register uint32_t BAFH_h = (m);				\
111*7c356e86SAndroid Build Coastguard Worker 								\
112*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdateOctet_reg(BAFH_h, (b));			\
113*7c356e86SAndroid Build Coastguard Worker 	(m) = BAFH_h;						\
114*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
115*7c356e86SAndroid Build Coastguard Worker 
116*7c356e86SAndroid Build Coastguard Worker #define BAFHror(eax,cl) (((eax) >> (cl)) | ((eax) << (32 - (cl))))
117*7c356e86SAndroid Build Coastguard Worker 
118*7c356e86SAndroid Build Coastguard Worker #define BAFHFinish_reg(h) do {					\
119*7c356e86SAndroid Build Coastguard Worker 	register uint32_t BAFHFinish_v;				\
120*7c356e86SAndroid Build Coastguard Worker 								\
121*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v = ((h) >> 7) & 0x01010101U;		\
122*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v += BAFHFinish_v << 1;			\
123*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v += BAFHFinish_v << 3;			\
124*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= ((h) << 1) & 0xFEFEFEFEU;		\
125*7c356e86SAndroid Build Coastguard Worker 								\
126*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8);		\
127*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= ((h) = BAFHror((h), 8));		\
128*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= ((h) = BAFHror((h), 8));		\
129*7c356e86SAndroid Build Coastguard Worker 	(h) = BAFHror((h), 8) ^ BAFHFinish_v;			\
130*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
131*7c356e86SAndroid Build Coastguard Worker 
132*7c356e86SAndroid Build Coastguard Worker #define BAFHFinish_mem(m) do {					\
133*7c356e86SAndroid Build Coastguard Worker 	register uint32_t BAFHFinish_v, BAFH_h = (m);		\
134*7c356e86SAndroid Build Coastguard Worker 								\
135*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v = (BAFH_h >> 7) & 0x01010101U;		\
136*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v += BAFHFinish_v << 1;			\
137*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v += BAFHFinish_v << 3;			\
138*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= (BAFH_h << 1) & 0xFEFEFEFEU;		\
139*7c356e86SAndroid Build Coastguard Worker 								\
140*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= BAFHror(BAFHFinish_v, 8);		\
141*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8));		\
142*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_v ^= (BAFH_h = BAFHror(BAFH_h, 8));		\
143*7c356e86SAndroid Build Coastguard Worker 	(m) = BAFHror(BAFH_h, 8) ^ BAFHFinish_v;		\
144*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
145*7c356e86SAndroid Build Coastguard Worker 
146*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateMem_reg(h,p,z) do {				\
147*7c356e86SAndroid Build Coastguard Worker 	register const uint8_t *BAFHUpdate_p;			\
148*7c356e86SAndroid Build Coastguard Worker 	register size_t BAFHUpdate_z = (z);			\
149*7c356e86SAndroid Build Coastguard Worker 								\
150*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdate_p = (const void *)(p);			\
151*7c356e86SAndroid Build Coastguard Worker 	while (BAFHUpdate_z--)					\
152*7c356e86SAndroid Build Coastguard Worker 		BAFHUpdateOctet_reg((h), *BAFHUpdate_p++);	\
153*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
154*7c356e86SAndroid Build Coastguard Worker 
155*7c356e86SAndroid Build Coastguard Worker /* meh should have named them _r/m but that’s not valid C */
156*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateMem_mem(m,p,z) do {				\
157*7c356e86SAndroid Build Coastguard Worker 	register uint32_t BAFH_h = (m);				\
158*7c356e86SAndroid Build Coastguard Worker 								\
159*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdateMem_reg(BAFH_h, (p), (z));			\
160*7c356e86SAndroid Build Coastguard Worker 	(m) = BAFH_h;						\
161*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
162*7c356e86SAndroid Build Coastguard Worker 
163*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateStr_reg(h,s) do {				\
164*7c356e86SAndroid Build Coastguard Worker 	register const uint8_t *BAFHUpdate_s;			\
165*7c356e86SAndroid Build Coastguard Worker 	register uint8_t BAFHUpdate_c;				\
166*7c356e86SAndroid Build Coastguard Worker 								\
167*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdate_s = (const void *)(s);			\
168*7c356e86SAndroid Build Coastguard Worker 	while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0)		\
169*7c356e86SAndroid Build Coastguard Worker 		BAFHUpdateOctet_reg((h), BAFHUpdate_c);		\
170*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
171*7c356e86SAndroid Build Coastguard Worker 
172*7c356e86SAndroid Build Coastguard Worker #define BAFHUpdateStr_mem(m,s) do {				\
173*7c356e86SAndroid Build Coastguard Worker 	register uint32_t BAFH_h = (m);				\
174*7c356e86SAndroid Build Coastguard Worker 								\
175*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdateStr_reg(BAFH_h, (s));				\
176*7c356e86SAndroid Build Coastguard Worker 	(m) = BAFH_h;						\
177*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
178*7c356e86SAndroid Build Coastguard Worker 
179*7c356e86SAndroid Build Coastguard Worker #define BAFHHostMem(h,p,z) do {					\
180*7c356e86SAndroid Build Coastguard Worker 	register const uint8_t *BAFHUpdate_p;			\
181*7c356e86SAndroid Build Coastguard Worker 	register size_t BAFHUpdate_z = (z);			\
182*7c356e86SAndroid Build Coastguard Worker 	size_t BAFHHost_z;					\
183*7c356e86SAndroid Build Coastguard Worker 	union {							\
184*7c356e86SAndroid Build Coastguard Worker 		uint8_t as_u8[4];				\
185*7c356e86SAndroid Build Coastguard Worker 		uint32_t as_u32;				\
186*7c356e86SAndroid Build Coastguard Worker 	} BAFHHost_v;						\
187*7c356e86SAndroid Build Coastguard Worker 								\
188*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdate_p = (const void *)(p);			\
189*7c356e86SAndroid Build Coastguard Worker 	BAFHHost_v.as_u32 = 0;					\
190*7c356e86SAndroid Build Coastguard Worker 	BAFHHost_z = BAFHUpdate_z < 4 ? BAFHUpdate_z : 4;	\
191*7c356e86SAndroid Build Coastguard Worker 	memcpy(BAFHHost_v.as_u8, BAFHUpdate_p, BAFHHost_z);	\
192*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdate_p += BAFHHost_z;				\
193*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdate_z -= BAFHHost_z;				\
194*7c356e86SAndroid Build Coastguard Worker 	(h) = BAFHHost_v.as_u32;				\
195*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_reg(h);					\
196*7c356e86SAndroid Build Coastguard Worker 	while (BAFHUpdate_z--)					\
197*7c356e86SAndroid Build Coastguard Worker 		BAFHUpdateOctet_reg((h), *BAFHUpdate_p++);	\
198*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_reg(h);					\
199*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
200*7c356e86SAndroid Build Coastguard Worker 
201*7c356e86SAndroid Build Coastguard Worker #define BAFHHostStr(h,s) do {					\
202*7c356e86SAndroid Build Coastguard Worker 	register const uint8_t *BAFHUpdate_s;			\
203*7c356e86SAndroid Build Coastguard Worker 	register uint8_t BAFHUpdate_c;				\
204*7c356e86SAndroid Build Coastguard Worker 	union {							\
205*7c356e86SAndroid Build Coastguard Worker 		uint8_t as_u8[4];				\
206*7c356e86SAndroid Build Coastguard Worker 		uint32_t as_u32;				\
207*7c356e86SAndroid Build Coastguard Worker 	} BAFHHost_v;						\
208*7c356e86SAndroid Build Coastguard Worker 								\
209*7c356e86SAndroid Build Coastguard Worker 	BAFHUpdate_s = (const void *)(s);			\
210*7c356e86SAndroid Build Coastguard Worker 	BAFHHost_v.as_u32 = 0;					\
211*7c356e86SAndroid Build Coastguard Worker 	if ((BAFHHost_v.as_u8[0] = *BAFHUpdate_s) != 0)		\
212*7c356e86SAndroid Build Coastguard Worker 		++BAFHUpdate_s;					\
213*7c356e86SAndroid Build Coastguard Worker 	if ((BAFHHost_v.as_u8[1] = *BAFHUpdate_s) != 0)		\
214*7c356e86SAndroid Build Coastguard Worker 		++BAFHUpdate_s;					\
215*7c356e86SAndroid Build Coastguard Worker 	if ((BAFHHost_v.as_u8[2] = *BAFHUpdate_s) != 0)		\
216*7c356e86SAndroid Build Coastguard Worker 		++BAFHUpdate_s;					\
217*7c356e86SAndroid Build Coastguard Worker 	if ((BAFHHost_v.as_u8[3] = *BAFHUpdate_s) != 0)		\
218*7c356e86SAndroid Build Coastguard Worker 		++BAFHUpdate_s;					\
219*7c356e86SAndroid Build Coastguard Worker 	(h) = BAFHHost_v.as_u32;				\
220*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_reg(h);					\
221*7c356e86SAndroid Build Coastguard Worker 	while ((BAFHUpdate_c = *BAFHUpdate_s++) != 0)		\
222*7c356e86SAndroid Build Coastguard Worker 		BAFHUpdateOctet_reg((h), BAFHUpdate_c);		\
223*7c356e86SAndroid Build Coastguard Worker 	BAFHFinish_reg(h);					\
224*7c356e86SAndroid Build Coastguard Worker } while (/* CONSTCOND */ 0)
225*7c356e86SAndroid Build Coastguard Worker 
226*7c356e86SAndroid Build Coastguard Worker #endif
227