Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/sha3/sph_haval.c
1201 views
1
/* $Id: haval.c 227 2010-06-16 17:28:38Z tp $ */
2
/*
3
* HAVAL implementation.
4
*
5
* The HAVAL reference paper is of questionable clarity with regards to
6
* some details such as endianness of bits within a byte, bytes within
7
* a 32-bit word, or the actual ordering of words within a stream of
8
* words. This implementation has been made compatible with the reference
9
* implementation available on: http://labs.calyptix.com/haval.php
10
*
11
* ==========================(LICENSE BEGIN)============================
12
*
13
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
14
*
15
* Permission is hereby granted, free of charge, to any person obtaining
16
* a copy of this software and associated documentation files (the
17
* "Software"), to deal in the Software without restriction, including
18
* without limitation the rights to use, copy, modify, merge, publish,
19
* distribute, sublicense, and/or sell copies of the Software, and to
20
* permit persons to whom the Software is furnished to do so, subject to
21
* the following conditions:
22
*
23
* The above copyright notice and this permission notice shall be
24
* included in all copies or substantial portions of the Software.
25
*
26
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
30
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
*
34
* ===========================(LICENSE END)=============================
35
*
36
* @author Thomas Pornin <[email protected]>
37
*/
38
39
#include <stddef.h>
40
#include <string.h>
41
42
#include "sph_haval.h"
43
44
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_HAVAL
45
#define SPH_SMALL_FOOTPRINT_HAVAL 1
46
#endif
47
48
/*
49
* Basic definition from the reference paper.
50
*
51
#define F1(x6, x5, x4, x3, x2, x1, x0) \
52
(((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)) ^ ((x0) & (x1)) ^ (x0))
53
*
54
*/
55
56
#define F1(x6, x5, x4, x3, x2, x1, x0) \
57
(((x1) & ((x0) ^ (x4))) ^ ((x2) & (x5)) ^ ((x3) & (x6)) ^ (x0))
58
59
/*
60
* Basic definition from the reference paper.
61
*
62
#define F2(x6, x5, x4, x3, x2, x1, x0) \
63
(((x1) & (x2) & (x3)) ^ ((x2) & (x4) & (x5)) ^ ((x1) & (x2)) \
64
^ ((x1) & (x4)) ^ ((x2) & (x6)) ^ ((x3) & (x5)) \
65
^ ((x4) & (x5)) ^ ((x0) & (x2)) ^ (x0))
66
*
67
*/
68
69
#define F2(x6, x5, x4, x3, x2, x1, x0) \
70
(((x2) & (((x1) & ~(x3)) ^ ((x4) & (x5)) ^ (x6) ^ (x0))) \
71
^ ((x4) & ((x1) ^ (x5))) ^ ((x3 & (x5)) ^ (x0)))
72
73
/*
74
* Basic definition from the reference paper.
75
*
76
#define F3(x6, x5, x4, x3, x2, x1, x0) \
77
(((x1) & (x2) & (x3)) ^ ((x1) & (x4)) ^ ((x2) & (x5)) \
78
^ ((x3) & (x6)) ^ ((x0) & (x3)) ^ (x0))
79
*
80
*/
81
82
#define F3(x6, x5, x4, x3, x2, x1, x0) \
83
(((x3) & (((x1) & (x2)) ^ (x6) ^ (x0))) \
84
^ ((x1) & (x4)) ^ ((x2) & (x5)) ^ (x0))
85
86
/*
87
* Basic definition from the reference paper.
88
*
89
#define F4(x6, x5, x4, x3, x2, x1, x0) \
90
(((x1) & (x2) & (x3)) ^ ((x2) & (x4) & (x5)) ^ ((x3) & (x4) & (x6)) \
91
^ ((x1) & (x4)) ^ ((x2) & (x6)) ^ ((x3) & (x4)) ^ ((x3) & (x5)) \
92
^ ((x3) & (x6)) ^ ((x4) & (x5)) ^ ((x4) & (x6)) ^ ((x0) & (x4)) ^ (x0))
93
*
94
*/
95
96
#define F4(x6, x5, x4, x3, x2, x1, x0) \
97
(((x3) & (((x1) & (x2)) ^ ((x4) | (x6)) ^ (x5))) \
98
^ ((x4) & ((~(x2) & (x5)) ^ (x1) ^ (x6) ^ (x0))) \
99
^ ((x2) & (x6)) ^ (x0))
100
101
/*
102
* Basic definition from the reference paper.
103
*
104
#define F5(x6, x5, x4, x3, x2, x1, x0) \
105
(((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)) \
106
^ ((x0) & (x1) & (x2) & (x3)) ^ ((x0) & (x5)) ^ (x0))
107
*
108
*/
109
110
#define F5(x6, x5, x4, x3, x2, x1, x0) \
111
(((x0) & ~(((x1) & (x2) & (x3)) ^ (x5))) \
112
^ ((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)))
113
114
/*
115
* The macros below integrate the phi() permutations, depending on the
116
* pass and the total number of passes.
117
*/
118
119
#define FP3_1(x6, x5, x4, x3, x2, x1, x0) \
120
F1(x1, x0, x3, x5, x6, x2, x4)
121
#define FP3_2(x6, x5, x4, x3, x2, x1, x0) \
122
F2(x4, x2, x1, x0, x5, x3, x6)
123
#define FP3_3(x6, x5, x4, x3, x2, x1, x0) \
124
F3(x6, x1, x2, x3, x4, x5, x0)
125
126
#define FP4_1(x6, x5, x4, x3, x2, x1, x0) \
127
F1(x2, x6, x1, x4, x5, x3, x0)
128
#define FP4_2(x6, x5, x4, x3, x2, x1, x0) \
129
F2(x3, x5, x2, x0, x1, x6, x4)
130
#define FP4_3(x6, x5, x4, x3, x2, x1, x0) \
131
F3(x1, x4, x3, x6, x0, x2, x5)
132
#define FP4_4(x6, x5, x4, x3, x2, x1, x0) \
133
F4(x6, x4, x0, x5, x2, x1, x3)
134
135
#define FP5_1(x6, x5, x4, x3, x2, x1, x0) \
136
F1(x3, x4, x1, x0, x5, x2, x6)
137
#define FP5_2(x6, x5, x4, x3, x2, x1, x0) \
138
F2(x6, x2, x1, x0, x3, x4, x5)
139
#define FP5_3(x6, x5, x4, x3, x2, x1, x0) \
140
F3(x2, x6, x0, x4, x3, x1, x5)
141
#define FP5_4(x6, x5, x4, x3, x2, x1, x0) \
142
F4(x1, x5, x3, x2, x0, x4, x6)
143
#define FP5_5(x6, x5, x4, x3, x2, x1, x0) \
144
F5(x2, x5, x0, x6, x4, x3, x1)
145
146
/*
147
* One step, for "n" passes, pass number "p" (1 <= p <= n), using
148
* input word number "w" and step constant "c".
149
*/
150
#define STEP(n, p, x7, x6, x5, x4, x3, x2, x1, x0, w, c) do { \
151
sph_u32 t = FP ## n ## _ ## p(x6, x5, x4, x3, x2, x1, x0); \
152
(x7) = SPH_T32(SPH_ROTR32(t, 7) + SPH_ROTR32((x7), 11) \
153
+ (w) + (c)); \
154
} while (0)
155
156
/*
157
* PASSy(n, in) computes pass number "y", for a total of "n", using the
158
* one-argument macro "in" to access input words. Current state is assumed
159
* to be held in variables "s0" to "s7".
160
*/
161
162
#if SPH_SMALL_FOOTPRINT_HAVAL
163
164
#define PASS1(n, in) do { \
165
unsigned pass_count; \
166
for (pass_count = 0; pass_count < 32; pass_count += 8) { \
167
STEP(n, 1, s7, s6, s5, s4, s3, s2, s1, s0, \
168
in(pass_count + 0), SPH_C32(0x00000000)); \
169
STEP(n, 1, s6, s5, s4, s3, s2, s1, s0, s7, \
170
in(pass_count + 1), SPH_C32(0x00000000)); \
171
STEP(n, 1, s5, s4, s3, s2, s1, s0, s7, s6, \
172
in(pass_count + 2), SPH_C32(0x00000000)); \
173
STEP(n, 1, s4, s3, s2, s1, s0, s7, s6, s5, \
174
in(pass_count + 3), SPH_C32(0x00000000)); \
175
STEP(n, 1, s3, s2, s1, s0, s7, s6, s5, s4, \
176
in(pass_count + 4), SPH_C32(0x00000000)); \
177
STEP(n, 1, s2, s1, s0, s7, s6, s5, s4, s3, \
178
in(pass_count + 5), SPH_C32(0x00000000)); \
179
STEP(n, 1, s1, s0, s7, s6, s5, s4, s3, s2, \
180
in(pass_count + 6), SPH_C32(0x00000000)); \
181
STEP(n, 1, s0, s7, s6, s5, s4, s3, s2, s1, \
182
in(pass_count + 7), SPH_C32(0x00000000)); \
183
} \
184
} while (0)
185
186
#define PASSG(p, n, in) do { \
187
unsigned pass_count; \
188
for (pass_count = 0; pass_count < 32; pass_count += 8) { \
189
STEP(n, p, s7, s6, s5, s4, s3, s2, s1, s0, \
190
in(MP ## p[pass_count + 0]), \
191
RK ## p[pass_count + 0]); \
192
STEP(n, p, s6, s5, s4, s3, s2, s1, s0, s7, \
193
in(MP ## p[pass_count + 1]), \
194
RK ## p[pass_count + 1]); \
195
STEP(n, p, s5, s4, s3, s2, s1, s0, s7, s6, \
196
in(MP ## p[pass_count + 2]), \
197
RK ## p[pass_count + 2]); \
198
STEP(n, p, s4, s3, s2, s1, s0, s7, s6, s5, \
199
in(MP ## p[pass_count + 3]), \
200
RK ## p[pass_count + 3]); \
201
STEP(n, p, s3, s2, s1, s0, s7, s6, s5, s4, \
202
in(MP ## p[pass_count + 4]), \
203
RK ## p[pass_count + 4]); \
204
STEP(n, p, s2, s1, s0, s7, s6, s5, s4, s3, \
205
in(MP ## p[pass_count + 5]), \
206
RK ## p[pass_count + 5]); \
207
STEP(n, p, s1, s0, s7, s6, s5, s4, s3, s2, \
208
in(MP ## p[pass_count + 6]), \
209
RK ## p[pass_count + 6]); \
210
STEP(n, p, s0, s7, s6, s5, s4, s3, s2, s1, \
211
in(MP ## p[pass_count + 7]), \
212
RK ## p[pass_count + 7]); \
213
} \
214
} while (0)
215
216
#define PASS2(n, in) PASSG(2, n, in)
217
#define PASS3(n, in) PASSG(3, n, in)
218
#define PASS4(n, in) PASSG(4, n, in)
219
#define PASS5(n, in) PASSG(5, n, in)
220
221
static const unsigned MP2[32] = {
222
5, 14, 26, 18, 11, 28, 7, 16,
223
0, 23, 20, 22, 1, 10, 4, 8,
224
30, 3, 21, 9, 17, 24, 29, 6,
225
19, 12, 15, 13, 2, 25, 31, 27
226
};
227
228
static const unsigned MP3[32] = {
229
19, 9, 4, 20, 28, 17, 8, 22,
230
29, 14, 25, 12, 24, 30, 16, 26,
231
31, 15, 7, 3, 1, 0, 18, 27,
232
13, 6, 21, 10, 23, 11, 5, 2
233
};
234
235
static const unsigned MP4[32] = {
236
24, 4, 0, 14, 2, 7, 28, 23,
237
26, 6, 30, 20, 18, 25, 19, 3,
238
22, 11, 31, 21, 8, 27, 12, 9,
239
1, 29, 5, 15, 17, 10, 16, 13
240
};
241
242
static const unsigned MP5[32] = {
243
27, 3, 21, 26, 17, 11, 20, 29,
244
19, 0, 12, 7, 13, 8, 31, 10,
245
5, 9, 14, 30, 18, 6, 28, 24,
246
2, 23, 16, 22, 4, 1, 25, 15
247
};
248
249
static const sph_u32 RK2[32] = {
250
SPH_C32(0x452821E6), SPH_C32(0x38D01377),
251
SPH_C32(0xBE5466CF), SPH_C32(0x34E90C6C),
252
SPH_C32(0xC0AC29B7), SPH_C32(0xC97C50DD),
253
SPH_C32(0x3F84D5B5), SPH_C32(0xB5470917),
254
SPH_C32(0x9216D5D9), SPH_C32(0x8979FB1B),
255
SPH_C32(0xD1310BA6), SPH_C32(0x98DFB5AC),
256
SPH_C32(0x2FFD72DB), SPH_C32(0xD01ADFB7),
257
SPH_C32(0xB8E1AFED), SPH_C32(0x6A267E96),
258
SPH_C32(0xBA7C9045), SPH_C32(0xF12C7F99),
259
SPH_C32(0x24A19947), SPH_C32(0xB3916CF7),
260
SPH_C32(0x0801F2E2), SPH_C32(0x858EFC16),
261
SPH_C32(0x636920D8), SPH_C32(0x71574E69),
262
SPH_C32(0xA458FEA3), SPH_C32(0xF4933D7E),
263
SPH_C32(0x0D95748F), SPH_C32(0x728EB658),
264
SPH_C32(0x718BCD58), SPH_C32(0x82154AEE),
265
SPH_C32(0x7B54A41D), SPH_C32(0xC25A59B5)
266
};
267
268
static const sph_u32 RK3[32] = {
269
SPH_C32(0x9C30D539), SPH_C32(0x2AF26013),
270
SPH_C32(0xC5D1B023), SPH_C32(0x286085F0),
271
SPH_C32(0xCA417918), SPH_C32(0xB8DB38EF),
272
SPH_C32(0x8E79DCB0), SPH_C32(0x603A180E),
273
SPH_C32(0x6C9E0E8B), SPH_C32(0xB01E8A3E),
274
SPH_C32(0xD71577C1), SPH_C32(0xBD314B27),
275
SPH_C32(0x78AF2FDA), SPH_C32(0x55605C60),
276
SPH_C32(0xE65525F3), SPH_C32(0xAA55AB94),
277
SPH_C32(0x57489862), SPH_C32(0x63E81440),
278
SPH_C32(0x55CA396A), SPH_C32(0x2AAB10B6),
279
SPH_C32(0xB4CC5C34), SPH_C32(0x1141E8CE),
280
SPH_C32(0xA15486AF), SPH_C32(0x7C72E993),
281
SPH_C32(0xB3EE1411), SPH_C32(0x636FBC2A),
282
SPH_C32(0x2BA9C55D), SPH_C32(0x741831F6),
283
SPH_C32(0xCE5C3E16), SPH_C32(0x9B87931E),
284
SPH_C32(0xAFD6BA33), SPH_C32(0x6C24CF5C)
285
};
286
287
static const sph_u32 RK4[32] = {
288
SPH_C32(0x7A325381), SPH_C32(0x28958677),
289
SPH_C32(0x3B8F4898), SPH_C32(0x6B4BB9AF),
290
SPH_C32(0xC4BFE81B), SPH_C32(0x66282193),
291
SPH_C32(0x61D809CC), SPH_C32(0xFB21A991),
292
SPH_C32(0x487CAC60), SPH_C32(0x5DEC8032),
293
SPH_C32(0xEF845D5D), SPH_C32(0xE98575B1),
294
SPH_C32(0xDC262302), SPH_C32(0xEB651B88),
295
SPH_C32(0x23893E81), SPH_C32(0xD396ACC5),
296
SPH_C32(0x0F6D6FF3), SPH_C32(0x83F44239),
297
SPH_C32(0x2E0B4482), SPH_C32(0xA4842004),
298
SPH_C32(0x69C8F04A), SPH_C32(0x9E1F9B5E),
299
SPH_C32(0x21C66842), SPH_C32(0xF6E96C9A),
300
SPH_C32(0x670C9C61), SPH_C32(0xABD388F0),
301
SPH_C32(0x6A51A0D2), SPH_C32(0xD8542F68),
302
SPH_C32(0x960FA728), SPH_C32(0xAB5133A3),
303
SPH_C32(0x6EEF0B6C), SPH_C32(0x137A3BE4)
304
};
305
306
static const sph_u32 RK5[32] = {
307
SPH_C32(0xBA3BF050), SPH_C32(0x7EFB2A98),
308
SPH_C32(0xA1F1651D), SPH_C32(0x39AF0176),
309
SPH_C32(0x66CA593E), SPH_C32(0x82430E88),
310
SPH_C32(0x8CEE8619), SPH_C32(0x456F9FB4),
311
SPH_C32(0x7D84A5C3), SPH_C32(0x3B8B5EBE),
312
SPH_C32(0xE06F75D8), SPH_C32(0x85C12073),
313
SPH_C32(0x401A449F), SPH_C32(0x56C16AA6),
314
SPH_C32(0x4ED3AA62), SPH_C32(0x363F7706),
315
SPH_C32(0x1BFEDF72), SPH_C32(0x429B023D),
316
SPH_C32(0x37D0D724), SPH_C32(0xD00A1248),
317
SPH_C32(0xDB0FEAD3), SPH_C32(0x49F1C09B),
318
SPH_C32(0x075372C9), SPH_C32(0x80991B7B),
319
SPH_C32(0x25D479D8), SPH_C32(0xF6E8DEF7),
320
SPH_C32(0xE3FE501A), SPH_C32(0xB6794C3B),
321
SPH_C32(0x976CE0BD), SPH_C32(0x04C006BA),
322
SPH_C32(0xC1A94FB6), SPH_C32(0x409F60C4)
323
};
324
325
#else
326
327
#define PASS1(n, in) do { \
328
STEP(n, 1, s7, s6, s5, s4, s3, s2, s1, s0, in( 0), SPH_C32(0x00000000)); \
329
STEP(n, 1, s6, s5, s4, s3, s2, s1, s0, s7, in( 1), SPH_C32(0x00000000)); \
330
STEP(n, 1, s5, s4, s3, s2, s1, s0, s7, s6, in( 2), SPH_C32(0x00000000)); \
331
STEP(n, 1, s4, s3, s2, s1, s0, s7, s6, s5, in( 3), SPH_C32(0x00000000)); \
332
STEP(n, 1, s3, s2, s1, s0, s7, s6, s5, s4, in( 4), SPH_C32(0x00000000)); \
333
STEP(n, 1, s2, s1, s0, s7, s6, s5, s4, s3, in( 5), SPH_C32(0x00000000)); \
334
STEP(n, 1, s1, s0, s7, s6, s5, s4, s3, s2, in( 6), SPH_C32(0x00000000)); \
335
STEP(n, 1, s0, s7, s6, s5, s4, s3, s2, s1, in( 7), SPH_C32(0x00000000)); \
336
\
337
STEP(n, 1, s7, s6, s5, s4, s3, s2, s1, s0, in( 8), SPH_C32(0x00000000)); \
338
STEP(n, 1, s6, s5, s4, s3, s2, s1, s0, s7, in( 9), SPH_C32(0x00000000)); \
339
STEP(n, 1, s5, s4, s3, s2, s1, s0, s7, s6, in(10), SPH_C32(0x00000000)); \
340
STEP(n, 1, s4, s3, s2, s1, s0, s7, s6, s5, in(11), SPH_C32(0x00000000)); \
341
STEP(n, 1, s3, s2, s1, s0, s7, s6, s5, s4, in(12), SPH_C32(0x00000000)); \
342
STEP(n, 1, s2, s1, s0, s7, s6, s5, s4, s3, in(13), SPH_C32(0x00000000)); \
343
STEP(n, 1, s1, s0, s7, s6, s5, s4, s3, s2, in(14), SPH_C32(0x00000000)); \
344
STEP(n, 1, s0, s7, s6, s5, s4, s3, s2, s1, in(15), SPH_C32(0x00000000)); \
345
\
346
STEP(n, 1, s7, s6, s5, s4, s3, s2, s1, s0, in(16), SPH_C32(0x00000000)); \
347
STEP(n, 1, s6, s5, s4, s3, s2, s1, s0, s7, in(17), SPH_C32(0x00000000)); \
348
STEP(n, 1, s5, s4, s3, s2, s1, s0, s7, s6, in(18), SPH_C32(0x00000000)); \
349
STEP(n, 1, s4, s3, s2, s1, s0, s7, s6, s5, in(19), SPH_C32(0x00000000)); \
350
STEP(n, 1, s3, s2, s1, s0, s7, s6, s5, s4, in(20), SPH_C32(0x00000000)); \
351
STEP(n, 1, s2, s1, s0, s7, s6, s5, s4, s3, in(21), SPH_C32(0x00000000)); \
352
STEP(n, 1, s1, s0, s7, s6, s5, s4, s3, s2, in(22), SPH_C32(0x00000000)); \
353
STEP(n, 1, s0, s7, s6, s5, s4, s3, s2, s1, in(23), SPH_C32(0x00000000)); \
354
\
355
STEP(n, 1, s7, s6, s5, s4, s3, s2, s1, s0, in(24), SPH_C32(0x00000000)); \
356
STEP(n, 1, s6, s5, s4, s3, s2, s1, s0, s7, in(25), SPH_C32(0x00000000)); \
357
STEP(n, 1, s5, s4, s3, s2, s1, s0, s7, s6, in(26), SPH_C32(0x00000000)); \
358
STEP(n, 1, s4, s3, s2, s1, s0, s7, s6, s5, in(27), SPH_C32(0x00000000)); \
359
STEP(n, 1, s3, s2, s1, s0, s7, s6, s5, s4, in(28), SPH_C32(0x00000000)); \
360
STEP(n, 1, s2, s1, s0, s7, s6, s5, s4, s3, in(29), SPH_C32(0x00000000)); \
361
STEP(n, 1, s1, s0, s7, s6, s5, s4, s3, s2, in(30), SPH_C32(0x00000000)); \
362
STEP(n, 1, s0, s7, s6, s5, s4, s3, s2, s1, in(31), SPH_C32(0x00000000)); \
363
} while (0)
364
365
#define PASS2(n, in) do { \
366
STEP(n, 2, s7, s6, s5, s4, s3, s2, s1, s0, in( 5), SPH_C32(0x452821E6)); \
367
STEP(n, 2, s6, s5, s4, s3, s2, s1, s0, s7, in(14), SPH_C32(0x38D01377)); \
368
STEP(n, 2, s5, s4, s3, s2, s1, s0, s7, s6, in(26), SPH_C32(0xBE5466CF)); \
369
STEP(n, 2, s4, s3, s2, s1, s0, s7, s6, s5, in(18), SPH_C32(0x34E90C6C)); \
370
STEP(n, 2, s3, s2, s1, s0, s7, s6, s5, s4, in(11), SPH_C32(0xC0AC29B7)); \
371
STEP(n, 2, s2, s1, s0, s7, s6, s5, s4, s3, in(28), SPH_C32(0xC97C50DD)); \
372
STEP(n, 2, s1, s0, s7, s6, s5, s4, s3, s2, in( 7), SPH_C32(0x3F84D5B5)); \
373
STEP(n, 2, s0, s7, s6, s5, s4, s3, s2, s1, in(16), SPH_C32(0xB5470917)); \
374
\
375
STEP(n, 2, s7, s6, s5, s4, s3, s2, s1, s0, in( 0), SPH_C32(0x9216D5D9)); \
376
STEP(n, 2, s6, s5, s4, s3, s2, s1, s0, s7, in(23), SPH_C32(0x8979FB1B)); \
377
STEP(n, 2, s5, s4, s3, s2, s1, s0, s7, s6, in(20), SPH_C32(0xD1310BA6)); \
378
STEP(n, 2, s4, s3, s2, s1, s0, s7, s6, s5, in(22), SPH_C32(0x98DFB5AC)); \
379
STEP(n, 2, s3, s2, s1, s0, s7, s6, s5, s4, in( 1), SPH_C32(0x2FFD72DB)); \
380
STEP(n, 2, s2, s1, s0, s7, s6, s5, s4, s3, in(10), SPH_C32(0xD01ADFB7)); \
381
STEP(n, 2, s1, s0, s7, s6, s5, s4, s3, s2, in( 4), SPH_C32(0xB8E1AFED)); \
382
STEP(n, 2, s0, s7, s6, s5, s4, s3, s2, s1, in( 8), SPH_C32(0x6A267E96)); \
383
\
384
STEP(n, 2, s7, s6, s5, s4, s3, s2, s1, s0, in(30), SPH_C32(0xBA7C9045)); \
385
STEP(n, 2, s6, s5, s4, s3, s2, s1, s0, s7, in( 3), SPH_C32(0xF12C7F99)); \
386
STEP(n, 2, s5, s4, s3, s2, s1, s0, s7, s6, in(21), SPH_C32(0x24A19947)); \
387
STEP(n, 2, s4, s3, s2, s1, s0, s7, s6, s5, in( 9), SPH_C32(0xB3916CF7)); \
388
STEP(n, 2, s3, s2, s1, s0, s7, s6, s5, s4, in(17), SPH_C32(0x0801F2E2)); \
389
STEP(n, 2, s2, s1, s0, s7, s6, s5, s4, s3, in(24), SPH_C32(0x858EFC16)); \
390
STEP(n, 2, s1, s0, s7, s6, s5, s4, s3, s2, in(29), SPH_C32(0x636920D8)); \
391
STEP(n, 2, s0, s7, s6, s5, s4, s3, s2, s1, in( 6), SPH_C32(0x71574E69)); \
392
\
393
STEP(n, 2, s7, s6, s5, s4, s3, s2, s1, s0, in(19), SPH_C32(0xA458FEA3)); \
394
STEP(n, 2, s6, s5, s4, s3, s2, s1, s0, s7, in(12), SPH_C32(0xF4933D7E)); \
395
STEP(n, 2, s5, s4, s3, s2, s1, s0, s7, s6, in(15), SPH_C32(0x0D95748F)); \
396
STEP(n, 2, s4, s3, s2, s1, s0, s7, s6, s5, in(13), SPH_C32(0x728EB658)); \
397
STEP(n, 2, s3, s2, s1, s0, s7, s6, s5, s4, in( 2), SPH_C32(0x718BCD58)); \
398
STEP(n, 2, s2, s1, s0, s7, s6, s5, s4, s3, in(25), SPH_C32(0x82154AEE)); \
399
STEP(n, 2, s1, s0, s7, s6, s5, s4, s3, s2, in(31), SPH_C32(0x7B54A41D)); \
400
STEP(n, 2, s0, s7, s6, s5, s4, s3, s2, s1, in(27), SPH_C32(0xC25A59B5)); \
401
} while (0)
402
403
#define PASS3(n, in) do { \
404
STEP(n, 3, s7, s6, s5, s4, s3, s2, s1, s0, in(19), SPH_C32(0x9C30D539)); \
405
STEP(n, 3, s6, s5, s4, s3, s2, s1, s0, s7, in( 9), SPH_C32(0x2AF26013)); \
406
STEP(n, 3, s5, s4, s3, s2, s1, s0, s7, s6, in( 4), SPH_C32(0xC5D1B023)); \
407
STEP(n, 3, s4, s3, s2, s1, s0, s7, s6, s5, in(20), SPH_C32(0x286085F0)); \
408
STEP(n, 3, s3, s2, s1, s0, s7, s6, s5, s4, in(28), SPH_C32(0xCA417918)); \
409
STEP(n, 3, s2, s1, s0, s7, s6, s5, s4, s3, in(17), SPH_C32(0xB8DB38EF)); \
410
STEP(n, 3, s1, s0, s7, s6, s5, s4, s3, s2, in( 8), SPH_C32(0x8E79DCB0)); \
411
STEP(n, 3, s0, s7, s6, s5, s4, s3, s2, s1, in(22), SPH_C32(0x603A180E)); \
412
\
413
STEP(n, 3, s7, s6, s5, s4, s3, s2, s1, s0, in(29), SPH_C32(0x6C9E0E8B)); \
414
STEP(n, 3, s6, s5, s4, s3, s2, s1, s0, s7, in(14), SPH_C32(0xB01E8A3E)); \
415
STEP(n, 3, s5, s4, s3, s2, s1, s0, s7, s6, in(25), SPH_C32(0xD71577C1)); \
416
STEP(n, 3, s4, s3, s2, s1, s0, s7, s6, s5, in(12), SPH_C32(0xBD314B27)); \
417
STEP(n, 3, s3, s2, s1, s0, s7, s6, s5, s4, in(24), SPH_C32(0x78AF2FDA)); \
418
STEP(n, 3, s2, s1, s0, s7, s6, s5, s4, s3, in(30), SPH_C32(0x55605C60)); \
419
STEP(n, 3, s1, s0, s7, s6, s5, s4, s3, s2, in(16), SPH_C32(0xE65525F3)); \
420
STEP(n, 3, s0, s7, s6, s5, s4, s3, s2, s1, in(26), SPH_C32(0xAA55AB94)); \
421
\
422
STEP(n, 3, s7, s6, s5, s4, s3, s2, s1, s0, in(31), SPH_C32(0x57489862)); \
423
STEP(n, 3, s6, s5, s4, s3, s2, s1, s0, s7, in(15), SPH_C32(0x63E81440)); \
424
STEP(n, 3, s5, s4, s3, s2, s1, s0, s7, s6, in( 7), SPH_C32(0x55CA396A)); \
425
STEP(n, 3, s4, s3, s2, s1, s0, s7, s6, s5, in( 3), SPH_C32(0x2AAB10B6)); \
426
STEP(n, 3, s3, s2, s1, s0, s7, s6, s5, s4, in( 1), SPH_C32(0xB4CC5C34)); \
427
STEP(n, 3, s2, s1, s0, s7, s6, s5, s4, s3, in( 0), SPH_C32(0x1141E8CE)); \
428
STEP(n, 3, s1, s0, s7, s6, s5, s4, s3, s2, in(18), SPH_C32(0xA15486AF)); \
429
STEP(n, 3, s0, s7, s6, s5, s4, s3, s2, s1, in(27), SPH_C32(0x7C72E993)); \
430
\
431
STEP(n, 3, s7, s6, s5, s4, s3, s2, s1, s0, in(13), SPH_C32(0xB3EE1411)); \
432
STEP(n, 3, s6, s5, s4, s3, s2, s1, s0, s7, in( 6), SPH_C32(0x636FBC2A)); \
433
STEP(n, 3, s5, s4, s3, s2, s1, s0, s7, s6, in(21), SPH_C32(0x2BA9C55D)); \
434
STEP(n, 3, s4, s3, s2, s1, s0, s7, s6, s5, in(10), SPH_C32(0x741831F6)); \
435
STEP(n, 3, s3, s2, s1, s0, s7, s6, s5, s4, in(23), SPH_C32(0xCE5C3E16)); \
436
STEP(n, 3, s2, s1, s0, s7, s6, s5, s4, s3, in(11), SPH_C32(0x9B87931E)); \
437
STEP(n, 3, s1, s0, s7, s6, s5, s4, s3, s2, in( 5), SPH_C32(0xAFD6BA33)); \
438
STEP(n, 3, s0, s7, s6, s5, s4, s3, s2, s1, in( 2), SPH_C32(0x6C24CF5C)); \
439
} while (0)
440
441
#define PASS4(n, in) do { \
442
STEP(n, 4, s7, s6, s5, s4, s3, s2, s1, s0, in(24), SPH_C32(0x7A325381)); \
443
STEP(n, 4, s6, s5, s4, s3, s2, s1, s0, s7, in( 4), SPH_C32(0x28958677)); \
444
STEP(n, 4, s5, s4, s3, s2, s1, s0, s7, s6, in( 0), SPH_C32(0x3B8F4898)); \
445
STEP(n, 4, s4, s3, s2, s1, s0, s7, s6, s5, in(14), SPH_C32(0x6B4BB9AF)); \
446
STEP(n, 4, s3, s2, s1, s0, s7, s6, s5, s4, in( 2), SPH_C32(0xC4BFE81B)); \
447
STEP(n, 4, s2, s1, s0, s7, s6, s5, s4, s3, in( 7), SPH_C32(0x66282193)); \
448
STEP(n, 4, s1, s0, s7, s6, s5, s4, s3, s2, in(28), SPH_C32(0x61D809CC)); \
449
STEP(n, 4, s0, s7, s6, s5, s4, s3, s2, s1, in(23), SPH_C32(0xFB21A991)); \
450
\
451
STEP(n, 4, s7, s6, s5, s4, s3, s2, s1, s0, in(26), SPH_C32(0x487CAC60)); \
452
STEP(n, 4, s6, s5, s4, s3, s2, s1, s0, s7, in( 6), SPH_C32(0x5DEC8032)); \
453
STEP(n, 4, s5, s4, s3, s2, s1, s0, s7, s6, in(30), SPH_C32(0xEF845D5D)); \
454
STEP(n, 4, s4, s3, s2, s1, s0, s7, s6, s5, in(20), SPH_C32(0xE98575B1)); \
455
STEP(n, 4, s3, s2, s1, s0, s7, s6, s5, s4, in(18), SPH_C32(0xDC262302)); \
456
STEP(n, 4, s2, s1, s0, s7, s6, s5, s4, s3, in(25), SPH_C32(0xEB651B88)); \
457
STEP(n, 4, s1, s0, s7, s6, s5, s4, s3, s2, in(19), SPH_C32(0x23893E81)); \
458
STEP(n, 4, s0, s7, s6, s5, s4, s3, s2, s1, in( 3), SPH_C32(0xD396ACC5)); \
459
\
460
STEP(n, 4, s7, s6, s5, s4, s3, s2, s1, s0, in(22), SPH_C32(0x0F6D6FF3)); \
461
STEP(n, 4, s6, s5, s4, s3, s2, s1, s0, s7, in(11), SPH_C32(0x83F44239)); \
462
STEP(n, 4, s5, s4, s3, s2, s1, s0, s7, s6, in(31), SPH_C32(0x2E0B4482)); \
463
STEP(n, 4, s4, s3, s2, s1, s0, s7, s6, s5, in(21), SPH_C32(0xA4842004)); \
464
STEP(n, 4, s3, s2, s1, s0, s7, s6, s5, s4, in( 8), SPH_C32(0x69C8F04A)); \
465
STEP(n, 4, s2, s1, s0, s7, s6, s5, s4, s3, in(27), SPH_C32(0x9E1F9B5E)); \
466
STEP(n, 4, s1, s0, s7, s6, s5, s4, s3, s2, in(12), SPH_C32(0x21C66842)); \
467
STEP(n, 4, s0, s7, s6, s5, s4, s3, s2, s1, in( 9), SPH_C32(0xF6E96C9A)); \
468
\
469
STEP(n, 4, s7, s6, s5, s4, s3, s2, s1, s0, in( 1), SPH_C32(0x670C9C61)); \
470
STEP(n, 4, s6, s5, s4, s3, s2, s1, s0, s7, in(29), SPH_C32(0xABD388F0)); \
471
STEP(n, 4, s5, s4, s3, s2, s1, s0, s7, s6, in( 5), SPH_C32(0x6A51A0D2)); \
472
STEP(n, 4, s4, s3, s2, s1, s0, s7, s6, s5, in(15), SPH_C32(0xD8542F68)); \
473
STEP(n, 4, s3, s2, s1, s0, s7, s6, s5, s4, in(17), SPH_C32(0x960FA728)); \
474
STEP(n, 4, s2, s1, s0, s7, s6, s5, s4, s3, in(10), SPH_C32(0xAB5133A3)); \
475
STEP(n, 4, s1, s0, s7, s6, s5, s4, s3, s2, in(16), SPH_C32(0x6EEF0B6C)); \
476
STEP(n, 4, s0, s7, s6, s5, s4, s3, s2, s1, in(13), SPH_C32(0x137A3BE4)); \
477
} while (0)
478
479
#define PASS5(n, in) do { \
480
STEP(n, 5, s7, s6, s5, s4, s3, s2, s1, s0, in(27), SPH_C32(0xBA3BF050)); \
481
STEP(n, 5, s6, s5, s4, s3, s2, s1, s0, s7, in( 3), SPH_C32(0x7EFB2A98)); \
482
STEP(n, 5, s5, s4, s3, s2, s1, s0, s7, s6, in(21), SPH_C32(0xA1F1651D)); \
483
STEP(n, 5, s4, s3, s2, s1, s0, s7, s6, s5, in(26), SPH_C32(0x39AF0176)); \
484
STEP(n, 5, s3, s2, s1, s0, s7, s6, s5, s4, in(17), SPH_C32(0x66CA593E)); \
485
STEP(n, 5, s2, s1, s0, s7, s6, s5, s4, s3, in(11), SPH_C32(0x82430E88)); \
486
STEP(n, 5, s1, s0, s7, s6, s5, s4, s3, s2, in(20), SPH_C32(0x8CEE8619)); \
487
STEP(n, 5, s0, s7, s6, s5, s4, s3, s2, s1, in(29), SPH_C32(0x456F9FB4)); \
488
\
489
STEP(n, 5, s7, s6, s5, s4, s3, s2, s1, s0, in(19), SPH_C32(0x7D84A5C3)); \
490
STEP(n, 5, s6, s5, s4, s3, s2, s1, s0, s7, in( 0), SPH_C32(0x3B8B5EBE)); \
491
STEP(n, 5, s5, s4, s3, s2, s1, s0, s7, s6, in(12), SPH_C32(0xE06F75D8)); \
492
STEP(n, 5, s4, s3, s2, s1, s0, s7, s6, s5, in( 7), SPH_C32(0x85C12073)); \
493
STEP(n, 5, s3, s2, s1, s0, s7, s6, s5, s4, in(13), SPH_C32(0x401A449F)); \
494
STEP(n, 5, s2, s1, s0, s7, s6, s5, s4, s3, in( 8), SPH_C32(0x56C16AA6)); \
495
STEP(n, 5, s1, s0, s7, s6, s5, s4, s3, s2, in(31), SPH_C32(0x4ED3AA62)); \
496
STEP(n, 5, s0, s7, s6, s5, s4, s3, s2, s1, in(10), SPH_C32(0x363F7706)); \
497
\
498
STEP(n, 5, s7, s6, s5, s4, s3, s2, s1, s0, in( 5), SPH_C32(0x1BFEDF72)); \
499
STEP(n, 5, s6, s5, s4, s3, s2, s1, s0, s7, in( 9), SPH_C32(0x429B023D)); \
500
STEP(n, 5, s5, s4, s3, s2, s1, s0, s7, s6, in(14), SPH_C32(0x37D0D724)); \
501
STEP(n, 5, s4, s3, s2, s1, s0, s7, s6, s5, in(30), SPH_C32(0xD00A1248)); \
502
STEP(n, 5, s3, s2, s1, s0, s7, s6, s5, s4, in(18), SPH_C32(0xDB0FEAD3)); \
503
STEP(n, 5, s2, s1, s0, s7, s6, s5, s4, s3, in( 6), SPH_C32(0x49F1C09B)); \
504
STEP(n, 5, s1, s0, s7, s6, s5, s4, s3, s2, in(28), SPH_C32(0x075372C9)); \
505
STEP(n, 5, s0, s7, s6, s5, s4, s3, s2, s1, in(24), SPH_C32(0x80991B7B)); \
506
\
507
STEP(n, 5, s7, s6, s5, s4, s3, s2, s1, s0, in( 2), SPH_C32(0x25D479D8)); \
508
STEP(n, 5, s6, s5, s4, s3, s2, s1, s0, s7, in(23), SPH_C32(0xF6E8DEF7)); \
509
STEP(n, 5, s5, s4, s3, s2, s1, s0, s7, s6, in(16), SPH_C32(0xE3FE501A)); \
510
STEP(n, 5, s4, s3, s2, s1, s0, s7, s6, s5, in(22), SPH_C32(0xB6794C3B)); \
511
STEP(n, 5, s3, s2, s1, s0, s7, s6, s5, s4, in( 4), SPH_C32(0x976CE0BD)); \
512
STEP(n, 5, s2, s1, s0, s7, s6, s5, s4, s3, in( 1), SPH_C32(0x04C006BA)); \
513
STEP(n, 5, s1, s0, s7, s6, s5, s4, s3, s2, in(25), SPH_C32(0xC1A94FB6)); \
514
STEP(n, 5, s0, s7, s6, s5, s4, s3, s2, s1, in(15), SPH_C32(0x409F60C4)); \
515
} while (0)
516
517
#endif
518
519
#define SAVE_STATE \
520
sph_u32 u0, u1, u2, u3, u4, u5, u6, u7; \
521
do { \
522
u0 = s0; \
523
u1 = s1; \
524
u2 = s2; \
525
u3 = s3; \
526
u4 = s4; \
527
u5 = s5; \
528
u6 = s6; \
529
u7 = s7; \
530
} while (0)
531
532
#define UPDATE_STATE do { \
533
s0 = SPH_T32(s0 + u0); \
534
s1 = SPH_T32(s1 + u1); \
535
s2 = SPH_T32(s2 + u2); \
536
s3 = SPH_T32(s3 + u3); \
537
s4 = SPH_T32(s4 + u4); \
538
s5 = SPH_T32(s5 + u5); \
539
s6 = SPH_T32(s6 + u6); \
540
s7 = SPH_T32(s7 + u7); \
541
} while (0)
542
543
/*
544
* COREn(in) performs the core HAVAL computation for "n" passes, using
545
* the one-argument macro "in" to access the input words. Running state
546
* is held in variable "s0" to "s7".
547
*/
548
549
#define CORE3(in) do { \
550
SAVE_STATE; \
551
PASS1(3, in); \
552
PASS2(3, in); \
553
PASS3(3, in); \
554
UPDATE_STATE; \
555
} while (0)
556
557
#define CORE4(in) do { \
558
SAVE_STATE; \
559
PASS1(4, in); \
560
PASS2(4, in); \
561
PASS3(4, in); \
562
PASS4(4, in); \
563
UPDATE_STATE; \
564
} while (0)
565
566
#define CORE5(in) do { \
567
SAVE_STATE; \
568
PASS1(5, in); \
569
PASS2(5, in); \
570
PASS3(5, in); \
571
PASS4(5, in); \
572
PASS5(5, in); \
573
UPDATE_STATE; \
574
} while (0)
575
576
/*
577
* DSTATE declares the state variables "s0" to "s7".
578
*/
579
#define DSTATE sph_u32 s0, s1, s2, s3, s4, s5, s6, s7
580
581
/*
582
* RSTATE fills the state variables from the context "sc".
583
*/
584
#define RSTATE do { \
585
s0 = sc->s0; \
586
s1 = sc->s1; \
587
s2 = sc->s2; \
588
s3 = sc->s3; \
589
s4 = sc->s4; \
590
s5 = sc->s5; \
591
s6 = sc->s6; \
592
s7 = sc->s7; \
593
} while (0)
594
595
/*
596
* WSTATE updates the context "sc" from the state variables.
597
*/
598
#define WSTATE do { \
599
sc->s0 = s0; \
600
sc->s1 = s1; \
601
sc->s2 = s2; \
602
sc->s3 = s3; \
603
sc->s4 = s4; \
604
sc->s5 = s5; \
605
sc->s6 = s6; \
606
sc->s7 = s7; \
607
} while (0)
608
609
/*
610
* Initialize a context. "olen" is the output length, in 32-bit words
611
* (between 4 and 8, inclusive). "passes" is the number of passes
612
* (3, 4 or 5).
613
*/
614
static void
615
haval_init(sph_haval_context *sc, unsigned olen, unsigned passes)
616
{
617
sc->s0 = SPH_C32(0x243F6A88);
618
sc->s1 = SPH_C32(0x85A308D3);
619
sc->s2 = SPH_C32(0x13198A2E);
620
sc->s3 = SPH_C32(0x03707344);
621
sc->s4 = SPH_C32(0xA4093822);
622
sc->s5 = SPH_C32(0x299F31D0);
623
sc->s6 = SPH_C32(0x082EFA98);
624
sc->s7 = SPH_C32(0xEC4E6C89);
625
sc->olen = olen;
626
sc->passes = passes;
627
#if SPH_64
628
sc->count = 0;
629
#else
630
sc->count_high = 0;
631
sc->count_low = 0;
632
#endif
633
}
634
635
/*
636
* IN_PREPARE(data) contains declarations and code to prepare for
637
* reading input words pointed to by "data".
638
* INW(i) reads the word number "i" (from 0 to 31).
639
*/
640
#if SPH_LITTLE_FAST
641
#define IN_PREPARE(indata) const unsigned char *const load_ptr = \
642
(const unsigned char *)(indata)
643
#define INW(i) sph_dec32le_aligned(load_ptr + 4 * (i))
644
#else
645
#define IN_PREPARE(indata) \
646
sph_u32 X_var[32]; \
647
int load_index; \
648
\
649
for (load_index = 0; load_index < 32; load_index ++) \
650
X_var[load_index] = sph_dec32le_aligned( \
651
(const unsigned char *)(indata) + 4 * load_index)
652
#define INW(i) X_var[i]
653
#endif
654
655
/*
656
* Mixing operation used for 128-bit output tailoring. This function
657
* takes the byte 0 from a0, byte 1 from a1, byte 2 from a2 and byte 3
658
* from a3, and combines them into a 32-bit word, which is then rotated
659
* to the left by n bits.
660
*/
661
static SPH_INLINE sph_u32
662
mix128(sph_u32 a0, sph_u32 a1, sph_u32 a2, sph_u32 a3, int n)
663
{
664
sph_u32 tmp;
665
666
tmp = (a0 & SPH_C32(0x000000FF))
667
| (a1 & SPH_C32(0x0000FF00))
668
| (a2 & SPH_C32(0x00FF0000))
669
| (a3 & SPH_C32(0xFF000000));
670
if (n > 0)
671
tmp = SPH_ROTL32(tmp, n);
672
return tmp;
673
}
674
675
/*
676
* Mixing operation used to compute output word 0 for 160-bit output.
677
*/
678
static SPH_INLINE sph_u32
679
mix160_0(sph_u32 x5, sph_u32 x6, sph_u32 x7)
680
{
681
sph_u32 tmp;
682
683
tmp = (x5 & SPH_C32(0x01F80000))
684
| (x6 & SPH_C32(0xFE000000))
685
| (x7 & SPH_C32(0x0000003F));
686
return SPH_ROTL32(tmp, 13);
687
}
688
689
/*
690
* Mixing operation used to compute output word 1 for 160-bit output.
691
*/
692
static SPH_INLINE sph_u32
693
mix160_1(sph_u32 x5, sph_u32 x6, sph_u32 x7)
694
{
695
sph_u32 tmp;
696
697
tmp = (x5 & SPH_C32(0xFE000000))
698
| (x6 & SPH_C32(0x0000003F))
699
| (x7 & SPH_C32(0x00000FC0));
700
return SPH_ROTL32(tmp, 7);
701
}
702
703
/*
704
* Mixing operation used to compute output word 2 for 160-bit output.
705
*/
706
static SPH_INLINE sph_u32
707
mix160_2(sph_u32 x5, sph_u32 x6, sph_u32 x7)
708
{
709
sph_u32 tmp;
710
711
tmp = (x5 & SPH_C32(0x0000003F))
712
| (x6 & SPH_C32(0x00000FC0))
713
| (x7 & SPH_C32(0x0007F000));
714
return tmp;
715
}
716
717
/*
718
* Mixing operation used to compute output word 3 for 160-bit output.
719
*/
720
static SPH_INLINE sph_u32
721
mix160_3(sph_u32 x5, sph_u32 x6, sph_u32 x7)
722
{
723
sph_u32 tmp;
724
725
tmp = (x5 & SPH_C32(0x00000FC0))
726
| (x6 & SPH_C32(0x0007F000))
727
| (x7 & SPH_C32(0x01F80000));
728
return tmp >> 6;
729
}
730
731
/*
732
* Mixing operation used to compute output word 4 for 160-bit output.
733
*/
734
static SPH_INLINE sph_u32
735
mix160_4(sph_u32 x5, sph_u32 x6, sph_u32 x7)
736
{
737
sph_u32 tmp;
738
739
tmp = (x5 & SPH_C32(0x0007F000))
740
| (x6 & SPH_C32(0x01F80000))
741
| (x7 & SPH_C32(0xFE000000));
742
return tmp >> 12;
743
}
744
745
/*
746
* Mixing operation used to compute output word 0 for 192-bit output.
747
*/
748
static SPH_INLINE sph_u32
749
mix192_0(sph_u32 x6, sph_u32 x7)
750
{
751
sph_u32 tmp;
752
753
tmp = (x6 & SPH_C32(0xFC000000)) | (x7 & SPH_C32(0x0000001F));
754
return SPH_ROTL32(tmp, 6);
755
}
756
757
/*
758
* Mixing operation used to compute output word 1 for 192-bit output.
759
*/
760
static SPH_INLINE sph_u32
761
mix192_1(sph_u32 x6, sph_u32 x7)
762
{
763
return (x6 & SPH_C32(0x0000001F)) | (x7 & SPH_C32(0x000003E0));
764
}
765
766
/*
767
* Mixing operation used to compute output word 2 for 192-bit output.
768
*/
769
static SPH_INLINE sph_u32
770
mix192_2(sph_u32 x6, sph_u32 x7)
771
{
772
return ((x6 & SPH_C32(0x000003E0)) | (x7 & SPH_C32(0x0000FC00))) >> 5;
773
}
774
775
/*
776
* Mixing operation used to compute output word 3 for 192-bit output.
777
*/
778
static SPH_INLINE sph_u32
779
mix192_3(sph_u32 x6, sph_u32 x7)
780
{
781
return ((x6 & SPH_C32(0x0000FC00)) | (x7 & SPH_C32(0x001F0000))) >> 10;
782
}
783
784
/*
785
* Mixing operation used to compute output word 4 for 192-bit output.
786
*/
787
static SPH_INLINE sph_u32
788
mix192_4(sph_u32 x6, sph_u32 x7)
789
{
790
return ((x6 & SPH_C32(0x001F0000)) | (x7 & SPH_C32(0x03E00000))) >> 16;
791
}
792
793
/*
794
* Mixing operation used to compute output word 5 for 192-bit output.
795
*/
796
static SPH_INLINE sph_u32
797
mix192_5(sph_u32 x6, sph_u32 x7)
798
{
799
return ((x6 & SPH_C32(0x03E00000)) | (x7 & SPH_C32(0xFC000000))) >> 21;
800
}
801
802
/*
803
* Write out HAVAL output. The output length is tailored to the requested
804
* length.
805
*/
806
static void
807
haval_out(sph_haval_context *sc, void *dst)
808
{
809
DSTATE;
810
unsigned char *buf;
811
812
buf = (unsigned char*)dst;
813
RSTATE;
814
switch (sc->olen) {
815
case 4:
816
sph_enc32le(buf, SPH_T32(s0 + mix128(s7, s4, s5, s6, 24)));
817
sph_enc32le(buf + 4, SPH_T32(s1 + mix128(s6, s7, s4, s5, 16)));
818
sph_enc32le(buf + 8, SPH_T32(s2 + mix128(s5, s6, s7, s4, 8)));
819
sph_enc32le(buf + 12, SPH_T32(s3 + mix128(s4, s5, s6, s7, 0)));
820
break;
821
case 5:
822
sph_enc32le(buf, SPH_T32(s0 + mix160_0(s5, s6, s7)));
823
sph_enc32le(buf + 4, SPH_T32(s1 + mix160_1(s5, s6, s7)));
824
sph_enc32le(buf + 8, SPH_T32(s2 + mix160_2(s5, s6, s7)));
825
sph_enc32le(buf + 12, SPH_T32(s3 + mix160_3(s5, s6, s7)));
826
sph_enc32le(buf + 16, SPH_T32(s4 + mix160_4(s5, s6, s7)));
827
break;
828
case 6:
829
sph_enc32le(buf, SPH_T32(s0 + mix192_0(s6, s7)));
830
sph_enc32le(buf + 4, SPH_T32(s1 + mix192_1(s6, s7)));
831
sph_enc32le(buf + 8, SPH_T32(s2 + mix192_2(s6, s7)));
832
sph_enc32le(buf + 12, SPH_T32(s3 + mix192_3(s6, s7)));
833
sph_enc32le(buf + 16, SPH_T32(s4 + mix192_4(s6, s7)));
834
sph_enc32le(buf + 20, SPH_T32(s5 + mix192_5(s6, s7)));
835
break;
836
case 7:
837
sph_enc32le(buf, SPH_T32(s0 + ((s7 >> 27) & 0x1F)));
838
sph_enc32le(buf + 4, SPH_T32(s1 + ((s7 >> 22) & 0x1F)));
839
sph_enc32le(buf + 8, SPH_T32(s2 + ((s7 >> 18) & 0x0F)));
840
sph_enc32le(buf + 12, SPH_T32(s3 + ((s7 >> 13) & 0x1F)));
841
sph_enc32le(buf + 16, SPH_T32(s4 + ((s7 >> 9) & 0x0F)));
842
sph_enc32le(buf + 20, SPH_T32(s5 + ((s7 >> 4) & 0x1F)));
843
sph_enc32le(buf + 24, SPH_T32(s6 + ((s7 ) & 0x0F)));
844
break;
845
case 8:
846
sph_enc32le(buf, s0);
847
sph_enc32le(buf + 4, s1);
848
sph_enc32le(buf + 8, s2);
849
sph_enc32le(buf + 12, s3);
850
sph_enc32le(buf + 16, s4);
851
sph_enc32le(buf + 20, s5);
852
sph_enc32le(buf + 24, s6);
853
sph_enc32le(buf + 28, s7);
854
break;
855
}
856
}
857
858
/*
859
* The main core functions inline the code with the COREx() macros. We
860
* use a helper file, included three times, which avoids code copying.
861
*/
862
863
#undef PASSES
864
#define PASSES 3
865
#include "haval_helper.c"
866
867
#undef PASSES
868
#define PASSES 4
869
#include "haval_helper.c"
870
871
#undef PASSES
872
#define PASSES 5
873
#include "haval_helper.c"
874
875
/* ====================================================================== */
876
877
#define API(xxx, y) \
878
void \
879
sph_haval ## xxx ## _ ## y ## _init(void *cc) \
880
{ \
881
haval_init((sph_haval_context*)cc, xxx >> 5, y); \
882
} \
883
\
884
void \
885
sph_haval ## xxx ## _ ## y (void *cc, const void *data, size_t len) \
886
{ \
887
haval ## y((sph_haval_context*)cc, data, len); \
888
} \
889
\
890
void \
891
sph_haval ## xxx ## _ ## y ## _close(void *cc, void *dst) \
892
{ \
893
haval ## y ## _close((sph_haval_context*)cc, 0, 0, dst); \
894
} \
895
\
896
void \
897
sph_haval ## xxx ## _ ## y ## addbits_and_close( \
898
void *cc, unsigned ub, unsigned n, void *dst) \
899
{ \
900
haval ## y ## _close((sph_haval_context*)cc, ub, n, dst); \
901
}
902
903
API(128, 3)
904
API(128, 4)
905
API(128, 5)
906
API(160, 3)
907
API(160, 4)
908
API(160, 5)
909
API(192, 3)
910
API(192, 4)
911
API(192, 5)
912
API(224, 3)
913
API(224, 4)
914
API(224, 5)
915
API(256, 3)
916
API(256, 4)
917
API(256, 5)
918
919
#define RVAL do { \
920
s0 = val[0]; \
921
s1 = val[1]; \
922
s2 = val[2]; \
923
s3 = val[3]; \
924
s4 = val[4]; \
925
s5 = val[5]; \
926
s6 = val[6]; \
927
s7 = val[7]; \
928
} while (0)
929
930
#define WVAL do { \
931
val[0] = s0; \
932
val[1] = s1; \
933
val[2] = s2; \
934
val[3] = s3; \
935
val[4] = s4; \
936
val[5] = s5; \
937
val[6] = s6; \
938
val[7] = s7; \
939
} while (0)
940
941
#define INMSG(i) msg[i]
942
943
/* see sph_haval.h */
944
void
945
sph_haval_3_comp(const sph_u32 msg[32], sph_u32 val[8])
946
{
947
DSTATE;
948
949
RVAL;
950
CORE3(INMSG);
951
WVAL;
952
}
953
954
/* see sph_haval.h */
955
void
956
sph_haval_4_comp(const sph_u32 msg[32], sph_u32 val[8])
957
{
958
DSTATE;
959
960
RVAL;
961
CORE4(INMSG);
962
WVAL;
963
}
964
965
/* see sph_haval.h */
966
void
967
sph_haval_5_comp(const sph_u32 msg[32], sph_u32 val[8])
968
{
969
DSTATE;
970
971
RVAL;
972
CORE5(INMSG);
973
WVAL;
974
}
975
976
977