Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/sha3/sph_cubehash.c
1201 views
1
/* $Id: cubehash.c 227 2010-06-16 17:28:38Z tp $ */
2
/*
3
* CubeHash implementation.
4
*
5
* ==========================(LICENSE BEGIN)============================
6
*
7
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
8
*
9
* Permission is hereby granted, free of charge, to any person obtaining
10
* a copy of this software and associated documentation files (the
11
* "Software"), to deal in the Software without restriction, including
12
* without limitation the rights to use, copy, modify, merge, publish,
13
* distribute, sublicense, and/or sell copies of the Software, and to
14
* permit persons to whom the Software is furnished to do so, subject to
15
* the following conditions:
16
*
17
* The above copyright notice and this permission notice shall be
18
* included in all copies or substantial portions of the Software.
19
*
20
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
*
28
* ===========================(LICENSE END)=============================
29
*
30
* @author Thomas Pornin <[email protected]>
31
*/
32
33
#include <stddef.h>
34
#include <string.h>
35
#include <limits.h>
36
37
#include "sph_cubehash.h"
38
#ifdef __cplusplus
39
extern "C"{
40
#endif
41
42
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_CUBEHASH
43
#define SPH_SMALL_FOOTPRINT_CUBEHASH 1
44
#endif
45
46
/*
47
* Some tests were conducted on an Intel Core2 Q6600 (32-bit and 64-bit
48
* mode), a PowerPC G3, and a MIPS-compatible CPU (Broadcom BCM3302).
49
* It appears that the optimal settings are:
50
* -- full unroll, no state copy on the "big" systems (x86, PowerPC)
51
* -- unroll to 4 or 8, state copy on the "small" system (MIPS)
52
*/
53
54
#if SPH_SMALL_FOOTPRINT_CUBEHASH
55
56
#if !defined SPH_CUBEHASH_UNROLL
57
#define SPH_CUBEHASH_UNROLL 4
58
#endif
59
#if !defined SPH_CUBEHASH_NOCOPY
60
#define SPH_CUBEHASH_NOCOPY 1
61
#endif
62
63
#else
64
65
#if !defined SPH_CUBEHASH_UNROLL
66
#define SPH_CUBEHASH_UNROLL 0
67
#endif
68
#if !defined SPH_CUBEHASH_NOCOPY
69
#define SPH_CUBEHASH_NOCOPY 0
70
#endif
71
72
#endif
73
74
#ifdef _MSC_VER
75
#pragma warning (disable: 4146)
76
#endif
77
78
static const sph_u32 IV224[] = {
79
SPH_C32(0xB0FC8217), SPH_C32(0x1BEE1A90), SPH_C32(0x829E1A22),
80
SPH_C32(0x6362C342), SPH_C32(0x24D91C30), SPH_C32(0x03A7AA24),
81
SPH_C32(0xA63721C8), SPH_C32(0x85B0E2EF), SPH_C32(0xF35D13F3),
82
SPH_C32(0x41DA807D), SPH_C32(0x21A70CA6), SPH_C32(0x1F4E9774),
83
SPH_C32(0xB3E1C932), SPH_C32(0xEB0A79A8), SPH_C32(0xCDDAAA66),
84
SPH_C32(0xE2F6ECAA), SPH_C32(0x0A713362), SPH_C32(0xAA3080E0),
85
SPH_C32(0xD8F23A32), SPH_C32(0xCEF15E28), SPH_C32(0xDB086314),
86
SPH_C32(0x7F709DF7), SPH_C32(0xACD228A4), SPH_C32(0x704D6ECE),
87
SPH_C32(0xAA3EC95F), SPH_C32(0xE387C214), SPH_C32(0x3A6445FF),
88
SPH_C32(0x9CAB81C3), SPH_C32(0xC73D4B98), SPH_C32(0xD277AEBE),
89
SPH_C32(0xFD20151C), SPH_C32(0x00CB573E)
90
};
91
92
static const sph_u32 IV256[] = {
93
SPH_C32(0xEA2BD4B4), SPH_C32(0xCCD6F29F), SPH_C32(0x63117E71),
94
SPH_C32(0x35481EAE), SPH_C32(0x22512D5B), SPH_C32(0xE5D94E63),
95
SPH_C32(0x7E624131), SPH_C32(0xF4CC12BE), SPH_C32(0xC2D0B696),
96
SPH_C32(0x42AF2070), SPH_C32(0xD0720C35), SPH_C32(0x3361DA8C),
97
SPH_C32(0x28CCECA4), SPH_C32(0x8EF8AD83), SPH_C32(0x4680AC00),
98
SPH_C32(0x40E5FBAB), SPH_C32(0xD89041C3), SPH_C32(0x6107FBD5),
99
SPH_C32(0x6C859D41), SPH_C32(0xF0B26679), SPH_C32(0x09392549),
100
SPH_C32(0x5FA25603), SPH_C32(0x65C892FD), SPH_C32(0x93CB6285),
101
SPH_C32(0x2AF2B5AE), SPH_C32(0x9E4B4E60), SPH_C32(0x774ABFDD),
102
SPH_C32(0x85254725), SPH_C32(0x15815AEB), SPH_C32(0x4AB6AAD6),
103
SPH_C32(0x9CDAF8AF), SPH_C32(0xD6032C0A)
104
};
105
106
static const sph_u32 IV384[] = {
107
SPH_C32(0xE623087E), SPH_C32(0x04C00C87), SPH_C32(0x5EF46453),
108
SPH_C32(0x69524B13), SPH_C32(0x1A05C7A9), SPH_C32(0x3528DF88),
109
SPH_C32(0x6BDD01B5), SPH_C32(0x5057B792), SPH_C32(0x6AA7A922),
110
SPH_C32(0x649C7EEE), SPH_C32(0xF426309F), SPH_C32(0xCB629052),
111
SPH_C32(0xFC8E20ED), SPH_C32(0xB3482BAB), SPH_C32(0xF89E5E7E),
112
SPH_C32(0xD83D4DE4), SPH_C32(0x44BFC10D), SPH_C32(0x5FC1E63D),
113
SPH_C32(0x2104E6CB), SPH_C32(0x17958F7F), SPH_C32(0xDBEAEF70),
114
SPH_C32(0xB4B97E1E), SPH_C32(0x32C195F6), SPH_C32(0x6184A8E4),
115
SPH_C32(0x796C2543), SPH_C32(0x23DE176D), SPH_C32(0xD33BBAEC),
116
SPH_C32(0x0C12E5D2), SPH_C32(0x4EB95A7B), SPH_C32(0x2D18BA01),
117
SPH_C32(0x04EE475F), SPH_C32(0x1FC5F22E)
118
};
119
120
static const sph_u32 IV512[] = {
121
SPH_C32(0x2AEA2A61), SPH_C32(0x50F494D4), SPH_C32(0x2D538B8B),
122
SPH_C32(0x4167D83E), SPH_C32(0x3FEE2313), SPH_C32(0xC701CF8C),
123
SPH_C32(0xCC39968E), SPH_C32(0x50AC5695), SPH_C32(0x4D42C787),
124
SPH_C32(0xA647A8B3), SPH_C32(0x97CF0BEF), SPH_C32(0x825B4537),
125
SPH_C32(0xEEF864D2), SPH_C32(0xF22090C4), SPH_C32(0xD0E5CD33),
126
SPH_C32(0xA23911AE), SPH_C32(0xFCD398D9), SPH_C32(0x148FE485),
127
SPH_C32(0x1B017BEF), SPH_C32(0xB6444532), SPH_C32(0x6A536159),
128
SPH_C32(0x2FF5781C), SPH_C32(0x91FA7934), SPH_C32(0x0DBADEA9),
129
SPH_C32(0xD65C8A2B), SPH_C32(0xA5A70E75), SPH_C32(0xB1C62456),
130
SPH_C32(0xBC796576), SPH_C32(0x1921C8F7), SPH_C32(0xE7989AF1),
131
SPH_C32(0x7795D246), SPH_C32(0xD43E3B44)
132
};
133
134
#define T32 SPH_T32
135
#define ROTL32 SPH_ROTL32
136
137
#if SPH_CUBEHASH_NOCOPY
138
139
#define DECL_STATE
140
#define READ_STATE(cc)
141
#define WRITE_STATE(cc)
142
143
#define x0 ((sc)->state[ 0])
144
#define x1 ((sc)->state[ 1])
145
#define x2 ((sc)->state[ 2])
146
#define x3 ((sc)->state[ 3])
147
#define x4 ((sc)->state[ 4])
148
#define x5 ((sc)->state[ 5])
149
#define x6 ((sc)->state[ 6])
150
#define x7 ((sc)->state[ 7])
151
#define x8 ((sc)->state[ 8])
152
#define x9 ((sc)->state[ 9])
153
#define xa ((sc)->state[10])
154
#define xb ((sc)->state[11])
155
#define xc ((sc)->state[12])
156
#define xd ((sc)->state[13])
157
#define xe ((sc)->state[14])
158
#define xf ((sc)->state[15])
159
#define xg ((sc)->state[16])
160
#define xh ((sc)->state[17])
161
#define xi ((sc)->state[18])
162
#define xj ((sc)->state[19])
163
#define xk ((sc)->state[20])
164
#define xl ((sc)->state[21])
165
#define xm ((sc)->state[22])
166
#define xn ((sc)->state[23])
167
#define xo ((sc)->state[24])
168
#define xp ((sc)->state[25])
169
#define xq ((sc)->state[26])
170
#define xr ((sc)->state[27])
171
#define xs ((sc)->state[28])
172
#define xt ((sc)->state[29])
173
#define xu ((sc)->state[30])
174
#define xv ((sc)->state[31])
175
176
#else
177
178
#define DECL_STATE \
179
sph_u32 x0, x1, x2, x3, x4, x5, x6, x7; \
180
sph_u32 x8, x9, xa, xb, xc, xd, xe, xf; \
181
sph_u32 xg, xh, xi, xj, xk, xl, xm, xn; \
182
sph_u32 xo, xp, xq, xr, xs, xt, xu, xv;
183
184
#define READ_STATE(cc) do { \
185
x0 = (cc)->state[ 0]; \
186
x1 = (cc)->state[ 1]; \
187
x2 = (cc)->state[ 2]; \
188
x3 = (cc)->state[ 3]; \
189
x4 = (cc)->state[ 4]; \
190
x5 = (cc)->state[ 5]; \
191
x6 = (cc)->state[ 6]; \
192
x7 = (cc)->state[ 7]; \
193
x8 = (cc)->state[ 8]; \
194
x9 = (cc)->state[ 9]; \
195
xa = (cc)->state[10]; \
196
xb = (cc)->state[11]; \
197
xc = (cc)->state[12]; \
198
xd = (cc)->state[13]; \
199
xe = (cc)->state[14]; \
200
xf = (cc)->state[15]; \
201
xg = (cc)->state[16]; \
202
xh = (cc)->state[17]; \
203
xi = (cc)->state[18]; \
204
xj = (cc)->state[19]; \
205
xk = (cc)->state[20]; \
206
xl = (cc)->state[21]; \
207
xm = (cc)->state[22]; \
208
xn = (cc)->state[23]; \
209
xo = (cc)->state[24]; \
210
xp = (cc)->state[25]; \
211
xq = (cc)->state[26]; \
212
xr = (cc)->state[27]; \
213
xs = (cc)->state[28]; \
214
xt = (cc)->state[29]; \
215
xu = (cc)->state[30]; \
216
xv = (cc)->state[31]; \
217
} while (0)
218
219
#define WRITE_STATE(cc) do { \
220
(cc)->state[ 0] = x0; \
221
(cc)->state[ 1] = x1; \
222
(cc)->state[ 2] = x2; \
223
(cc)->state[ 3] = x3; \
224
(cc)->state[ 4] = x4; \
225
(cc)->state[ 5] = x5; \
226
(cc)->state[ 6] = x6; \
227
(cc)->state[ 7] = x7; \
228
(cc)->state[ 8] = x8; \
229
(cc)->state[ 9] = x9; \
230
(cc)->state[10] = xa; \
231
(cc)->state[11] = xb; \
232
(cc)->state[12] = xc; \
233
(cc)->state[13] = xd; \
234
(cc)->state[14] = xe; \
235
(cc)->state[15] = xf; \
236
(cc)->state[16] = xg; \
237
(cc)->state[17] = xh; \
238
(cc)->state[18] = xi; \
239
(cc)->state[19] = xj; \
240
(cc)->state[20] = xk; \
241
(cc)->state[21] = xl; \
242
(cc)->state[22] = xm; \
243
(cc)->state[23] = xn; \
244
(cc)->state[24] = xo; \
245
(cc)->state[25] = xp; \
246
(cc)->state[26] = xq; \
247
(cc)->state[27] = xr; \
248
(cc)->state[28] = xs; \
249
(cc)->state[29] = xt; \
250
(cc)->state[30] = xu; \
251
(cc)->state[31] = xv; \
252
} while (0)
253
254
#endif
255
256
#define INPUT_BLOCK do { \
257
x0 ^= sph_dec32le_aligned(buf + 0); \
258
x1 ^= sph_dec32le_aligned(buf + 4); \
259
x2 ^= sph_dec32le_aligned(buf + 8); \
260
x3 ^= sph_dec32le_aligned(buf + 12); \
261
x4 ^= sph_dec32le_aligned(buf + 16); \
262
x5 ^= sph_dec32le_aligned(buf + 20); \
263
x6 ^= sph_dec32le_aligned(buf + 24); \
264
x7 ^= sph_dec32le_aligned(buf + 28); \
265
} while (0)
266
267
#define ROUND_EVEN do { \
268
xg = T32(x0 + xg); \
269
x0 = ROTL32(x0, 7); \
270
xh = T32(x1 + xh); \
271
x1 = ROTL32(x1, 7); \
272
xi = T32(x2 + xi); \
273
x2 = ROTL32(x2, 7); \
274
xj = T32(x3 + xj); \
275
x3 = ROTL32(x3, 7); \
276
xk = T32(x4 + xk); \
277
x4 = ROTL32(x4, 7); \
278
xl = T32(x5 + xl); \
279
x5 = ROTL32(x5, 7); \
280
xm = T32(x6 + xm); \
281
x6 = ROTL32(x6, 7); \
282
xn = T32(x7 + xn); \
283
x7 = ROTL32(x7, 7); \
284
xo = T32(x8 + xo); \
285
x8 = ROTL32(x8, 7); \
286
xp = T32(x9 + xp); \
287
x9 = ROTL32(x9, 7); \
288
xq = T32(xa + xq); \
289
xa = ROTL32(xa, 7); \
290
xr = T32(xb + xr); \
291
xb = ROTL32(xb, 7); \
292
xs = T32(xc + xs); \
293
xc = ROTL32(xc, 7); \
294
xt = T32(xd + xt); \
295
xd = ROTL32(xd, 7); \
296
xu = T32(xe + xu); \
297
xe = ROTL32(xe, 7); \
298
xv = T32(xf + xv); \
299
xf = ROTL32(xf, 7); \
300
x8 ^= xg; \
301
x9 ^= xh; \
302
xa ^= xi; \
303
xb ^= xj; \
304
xc ^= xk; \
305
xd ^= xl; \
306
xe ^= xm; \
307
xf ^= xn; \
308
x0 ^= xo; \
309
x1 ^= xp; \
310
x2 ^= xq; \
311
x3 ^= xr; \
312
x4 ^= xs; \
313
x5 ^= xt; \
314
x6 ^= xu; \
315
x7 ^= xv; \
316
xi = T32(x8 + xi); \
317
x8 = ROTL32(x8, 11); \
318
xj = T32(x9 + xj); \
319
x9 = ROTL32(x9, 11); \
320
xg = T32(xa + xg); \
321
xa = ROTL32(xa, 11); \
322
xh = T32(xb + xh); \
323
xb = ROTL32(xb, 11); \
324
xm = T32(xc + xm); \
325
xc = ROTL32(xc, 11); \
326
xn = T32(xd + xn); \
327
xd = ROTL32(xd, 11); \
328
xk = T32(xe + xk); \
329
xe = ROTL32(xe, 11); \
330
xl = T32(xf + xl); \
331
xf = ROTL32(xf, 11); \
332
xq = T32(x0 + xq); \
333
x0 = ROTL32(x0, 11); \
334
xr = T32(x1 + xr); \
335
x1 = ROTL32(x1, 11); \
336
xo = T32(x2 + xo); \
337
x2 = ROTL32(x2, 11); \
338
xp = T32(x3 + xp); \
339
x3 = ROTL32(x3, 11); \
340
xu = T32(x4 + xu); \
341
x4 = ROTL32(x4, 11); \
342
xv = T32(x5 + xv); \
343
x5 = ROTL32(x5, 11); \
344
xs = T32(x6 + xs); \
345
x6 = ROTL32(x6, 11); \
346
xt = T32(x7 + xt); \
347
x7 = ROTL32(x7, 11); \
348
xc ^= xi; \
349
xd ^= xj; \
350
xe ^= xg; \
351
xf ^= xh; \
352
x8 ^= xm; \
353
x9 ^= xn; \
354
xa ^= xk; \
355
xb ^= xl; \
356
x4 ^= xq; \
357
x5 ^= xr; \
358
x6 ^= xo; \
359
x7 ^= xp; \
360
x0 ^= xu; \
361
x1 ^= xv; \
362
x2 ^= xs; \
363
x3 ^= xt; \
364
} while (0)
365
366
#define ROUND_ODD do { \
367
xj = T32(xc + xj); \
368
xc = ROTL32(xc, 7); \
369
xi = T32(xd + xi); \
370
xd = ROTL32(xd, 7); \
371
xh = T32(xe + xh); \
372
xe = ROTL32(xe, 7); \
373
xg = T32(xf + xg); \
374
xf = ROTL32(xf, 7); \
375
xn = T32(x8 + xn); \
376
x8 = ROTL32(x8, 7); \
377
xm = T32(x9 + xm); \
378
x9 = ROTL32(x9, 7); \
379
xl = T32(xa + xl); \
380
xa = ROTL32(xa, 7); \
381
xk = T32(xb + xk); \
382
xb = ROTL32(xb, 7); \
383
xr = T32(x4 + xr); \
384
x4 = ROTL32(x4, 7); \
385
xq = T32(x5 + xq); \
386
x5 = ROTL32(x5, 7); \
387
xp = T32(x6 + xp); \
388
x6 = ROTL32(x6, 7); \
389
xo = T32(x7 + xo); \
390
x7 = ROTL32(x7, 7); \
391
xv = T32(x0 + xv); \
392
x0 = ROTL32(x0, 7); \
393
xu = T32(x1 + xu); \
394
x1 = ROTL32(x1, 7); \
395
xt = T32(x2 + xt); \
396
x2 = ROTL32(x2, 7); \
397
xs = T32(x3 + xs); \
398
x3 = ROTL32(x3, 7); \
399
x4 ^= xj; \
400
x5 ^= xi; \
401
x6 ^= xh; \
402
x7 ^= xg; \
403
x0 ^= xn; \
404
x1 ^= xm; \
405
x2 ^= xl; \
406
x3 ^= xk; \
407
xc ^= xr; \
408
xd ^= xq; \
409
xe ^= xp; \
410
xf ^= xo; \
411
x8 ^= xv; \
412
x9 ^= xu; \
413
xa ^= xt; \
414
xb ^= xs; \
415
xh = T32(x4 + xh); \
416
x4 = ROTL32(x4, 11); \
417
xg = T32(x5 + xg); \
418
x5 = ROTL32(x5, 11); \
419
xj = T32(x6 + xj); \
420
x6 = ROTL32(x6, 11); \
421
xi = T32(x7 + xi); \
422
x7 = ROTL32(x7, 11); \
423
xl = T32(x0 + xl); \
424
x0 = ROTL32(x0, 11); \
425
xk = T32(x1 + xk); \
426
x1 = ROTL32(x1, 11); \
427
xn = T32(x2 + xn); \
428
x2 = ROTL32(x2, 11); \
429
xm = T32(x3 + xm); \
430
x3 = ROTL32(x3, 11); \
431
xp = T32(xc + xp); \
432
xc = ROTL32(xc, 11); \
433
xo = T32(xd + xo); \
434
xd = ROTL32(xd, 11); \
435
xr = T32(xe + xr); \
436
xe = ROTL32(xe, 11); \
437
xq = T32(xf + xq); \
438
xf = ROTL32(xf, 11); \
439
xt = T32(x8 + xt); \
440
x8 = ROTL32(x8, 11); \
441
xs = T32(x9 + xs); \
442
x9 = ROTL32(x9, 11); \
443
xv = T32(xa + xv); \
444
xa = ROTL32(xa, 11); \
445
xu = T32(xb + xu); \
446
xb = ROTL32(xb, 11); \
447
x0 ^= xh; \
448
x1 ^= xg; \
449
x2 ^= xj; \
450
x3 ^= xi; \
451
x4 ^= xl; \
452
x5 ^= xk; \
453
x6 ^= xn; \
454
x7 ^= xm; \
455
x8 ^= xp; \
456
x9 ^= xo; \
457
xa ^= xr; \
458
xb ^= xq; \
459
xc ^= xt; \
460
xd ^= xs; \
461
xe ^= xv; \
462
xf ^= xu; \
463
} while (0)
464
465
/*
466
* There is no need to unroll all 16 rounds. The word-swapping permutation
467
* is an involution, so we need to unroll an even number of rounds. On
468
* "big" systems, unrolling 4 rounds yields about 97% of the speed
469
* achieved with full unrolling; and it keeps the code more compact
470
* for small architectures.
471
*/
472
473
#if SPH_CUBEHASH_UNROLL == 2
474
475
#define SIXTEEN_ROUNDS do { \
476
int j; \
477
for (j = 0; j < 8; j ++) { \
478
ROUND_EVEN; \
479
ROUND_ODD; \
480
} \
481
} while (0)
482
483
#elif SPH_CUBEHASH_UNROLL == 4
484
485
#define SIXTEEN_ROUNDS do { \
486
int j; \
487
for (j = 0; j < 4; j ++) { \
488
ROUND_EVEN; \
489
ROUND_ODD; \
490
ROUND_EVEN; \
491
ROUND_ODD; \
492
} \
493
} while (0)
494
495
#elif SPH_CUBEHASH_UNROLL == 8
496
497
#define SIXTEEN_ROUNDS do { \
498
int j; \
499
for (j = 0; j < 2; j ++) { \
500
ROUND_EVEN; \
501
ROUND_ODD; \
502
ROUND_EVEN; \
503
ROUND_ODD; \
504
ROUND_EVEN; \
505
ROUND_ODD; \
506
ROUND_EVEN; \
507
ROUND_ODD; \
508
} \
509
} while (0)
510
511
#else
512
513
#define SIXTEEN_ROUNDS do { \
514
ROUND_EVEN; \
515
ROUND_ODD; \
516
ROUND_EVEN; \
517
ROUND_ODD; \
518
ROUND_EVEN; \
519
ROUND_ODD; \
520
ROUND_EVEN; \
521
ROUND_ODD; \
522
ROUND_EVEN; \
523
ROUND_ODD; \
524
ROUND_EVEN; \
525
ROUND_ODD; \
526
ROUND_EVEN; \
527
ROUND_ODD; \
528
ROUND_EVEN; \
529
ROUND_ODD; \
530
} while (0)
531
532
#endif
533
534
static void
535
cubehash_init(sph_cubehash_context *sc, const sph_u32 *iv)
536
{
537
memcpy(sc->state, iv, sizeof sc->state);
538
sc->ptr = 0;
539
}
540
541
static void
542
cubehash_core(sph_cubehash_context *sc, const void *data, size_t len)
543
{
544
unsigned char *buf;
545
size_t ptr;
546
DECL_STATE
547
548
buf = sc->buf;
549
ptr = sc->ptr;
550
if (len < (sizeof sc->buf) - ptr) {
551
memcpy(buf + ptr, data, len);
552
ptr += len;
553
sc->ptr = ptr;
554
return;
555
}
556
557
READ_STATE(sc);
558
while (len > 0) {
559
size_t clen;
560
561
clen = (sizeof sc->buf) - ptr;
562
if (clen > len)
563
clen = len;
564
memcpy(buf + ptr, data, clen);
565
ptr += clen;
566
data = (const unsigned char *)data + clen;
567
len -= clen;
568
if (ptr == sizeof sc->buf) {
569
INPUT_BLOCK;
570
SIXTEEN_ROUNDS;
571
ptr = 0;
572
}
573
}
574
WRITE_STATE(sc);
575
sc->ptr = ptr;
576
}
577
578
static void
579
cubehash_close(sph_cubehash_context *sc, unsigned ub, unsigned n,
580
void *dst, size_t out_size_w32)
581
{
582
unsigned char *buf, *out;
583
size_t ptr;
584
unsigned z;
585
int i;
586
DECL_STATE
587
588
buf = sc->buf;
589
ptr = sc->ptr;
590
z = 0x80 >> n;
591
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
592
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
593
READ_STATE(sc);
594
INPUT_BLOCK;
595
for (i = 0; i < 11; i ++) {
596
SIXTEEN_ROUNDS;
597
if (i == 0)
598
xv ^= SPH_C32(1);
599
}
600
WRITE_STATE(sc);
601
out = dst;
602
for (z = 0; z < out_size_w32; z ++)
603
sph_enc32le(out + (z << 2), sc->state[z]);
604
}
605
606
/* see sph_cubehash.h */
607
void
608
sph_cubehash224_init(void *cc)
609
{
610
cubehash_init(cc, IV224);
611
}
612
613
/* see sph_cubehash.h */
614
void
615
sph_cubehash224(void *cc, const void *data, size_t len)
616
{
617
cubehash_core(cc, data, len);
618
}
619
620
/* see sph_cubehash.h */
621
void
622
sph_cubehash224_close(void *cc, void *dst)
623
{
624
sph_cubehash224_addbits_and_close(cc, 0, 0, dst);
625
}
626
627
/* see sph_cubehash.h */
628
void
629
sph_cubehash224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
630
{
631
cubehash_close(cc, ub, n, dst, 7);
632
sph_cubehash224_init(cc);
633
}
634
635
/* see sph_cubehash.h */
636
void
637
sph_cubehash256_init(void *cc)
638
{
639
cubehash_init(cc, IV256);
640
}
641
642
/* see sph_cubehash.h */
643
void
644
sph_cubehash256(void *cc, const void *data, size_t len)
645
{
646
cubehash_core(cc, data, len);
647
}
648
649
/* see sph_cubehash.h */
650
void
651
sph_cubehash256_close(void *cc, void *dst)
652
{
653
sph_cubehash256_addbits_and_close(cc, 0, 0, dst);
654
}
655
656
/* see sph_cubehash.h */
657
void
658
sph_cubehash256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
659
{
660
cubehash_close(cc, ub, n, dst, 8);
661
sph_cubehash256_init(cc);
662
}
663
664
/* see sph_cubehash.h */
665
void
666
sph_cubehash384_init(void *cc)
667
{
668
cubehash_init(cc, IV384);
669
}
670
671
/* see sph_cubehash.h */
672
void
673
sph_cubehash384(void *cc, const void *data, size_t len)
674
{
675
cubehash_core(cc, data, len);
676
}
677
678
/* see sph_cubehash.h */
679
void
680
sph_cubehash384_close(void *cc, void *dst)
681
{
682
sph_cubehash384_addbits_and_close(cc, 0, 0, dst);
683
}
684
685
/* see sph_cubehash.h */
686
void
687
sph_cubehash384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
688
{
689
cubehash_close(cc, ub, n, dst, 12);
690
sph_cubehash384_init(cc);
691
}
692
693
/* see sph_cubehash.h */
694
void
695
sph_cubehash512_init(void *cc)
696
{
697
cubehash_init(cc, IV512);
698
}
699
700
/* see sph_cubehash.h */
701
void
702
sph_cubehash512(void *cc, const void *data, size_t len)
703
{
704
cubehash_core(cc, data, len);
705
}
706
707
/* see sph_cubehash.h */
708
void
709
sph_cubehash512_close(void *cc, void *dst)
710
{
711
sph_cubehash512_addbits_and_close(cc, 0, 0, dst);
712
}
713
714
/* see sph_cubehash.h */
715
void
716
sph_cubehash512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
717
{
718
cubehash_close(cc, ub, n, dst, 16);
719
sph_cubehash512_init(cc);
720
}
721
#ifdef __cplusplus
722
}
723
#endif
724
725