Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

cubehash.c
Go to the documentation of this file.
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 <thomas.pornin@cryptolog.com>
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
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;
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 ++) {
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
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);
633 }
634 
635 /* see sph_cubehash.h */
636 void
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);
662 }
663 
664 /* see sph_cubehash.h */
665 void
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);
691 }
692 
693 /* see sph_cubehash.h */
694 void
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);
720 }
721 #ifdef __cplusplus
722 }
723 #endif
void sph_cubehash384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
Add a few additional bits (0 to 7) to the current computation, then terminate it and output the resul...
Definition: cubehash.c:687
void sph_cubehash384_close(void *cc, void *dst)
Terminate the current CubeHash-384 computation and output the result into the provided buffer...
Definition: cubehash.c:680
void sph_cubehash512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
Add a few additional bits (0 to 7) to the current computation, then terminate it and output the resul...
Definition: cubehash.c:716
#define DECL_STATE
Definition: cubehash.c:178
static const sph_u32 IV384[]
Definition: cubehash.c:106
unsigned char buf[32]
Definition: sph_cubehash.h:79
void sph_cubehash384(void *cc, const void *data, size_t len)
Process some data bytes.
Definition: cubehash.c:673
#define INPUT_BLOCK
Definition: cubehash.c:256
void sph_cubehash256_init(void *cc)
Initialize a CubeHash-256 context.
Definition: cubehash.c:637
#define READ_STATE(cc)
Definition: cubehash.c:184
void sph_cubehash224_close(void *cc, void *dst)
Terminate the current CubeHash-224 computation and output the result into the provided buffer...
Definition: cubehash.c:622
static const sph_u32 IV256[]
Definition: cubehash.c:92
static void cubehash_core(sph_cubehash_context *sc, const void *data, size_t len)
Definition: cubehash.c:542
#define WRITE_STATE(cc)
Definition: cubehash.c:219
void sph_cubehash512(void *cc, const void *data, size_t len)
Process some data bytes.
Definition: cubehash.c:702
#define SIXTEEN_ROUNDS
Definition: cubehash.c:513
#define SPH_C32(x)
Definition: sph_types.h:873
void sph_cubehash256(void *cc, const void *data, size_t len)
Process some data bytes.
Definition: cubehash.c:644
void sph_cubehash256_close(void *cc, void *dst)
Terminate the current CubeHash-256 computation and output the result into the provided buffer...
Definition: cubehash.c:651
static void cubehash_close(sph_cubehash_context *sc, unsigned ub, unsigned n, void *dst, size_t out_size_w32)
Definition: cubehash.c:579
void sph_cubehash256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
Add a few additional bits (0 to 7) to the current computation, then terminate it and output the resul...
Definition: cubehash.c:658
void sph_cubehash512_close(void *cc, void *dst)
Terminate the current CubeHash-512 computation and output the result into the provided buffer...
Definition: cubehash.c:709
static SPH_INLINE void sph_enc32le(void *dst, sph_u32 val)
Encode a 32-bit value into the provided buffer (little endian convention).
Definition: sph_types.h:1485
static const sph_u32 IV224[]
Definition: cubehash.c:78
CubeHash interface.
static const sph_u32 IV512[]
Definition: cubehash.c:120
void sph_cubehash224(void *cc, const void *data, size_t len)
Process some data bytes.
Definition: cubehash.c:615
void sph_cubehash224_init(void *cc)
Initialize a CubeHash-224 context.
Definition: cubehash.c:608
void sph_cubehash384_init(void *cc)
Initialize a CubeHash-384 context.
Definition: cubehash.c:666
void * memcpy(void *a, const void *b, size_t c)
unsigned long sph_u32
Definition: sph_types.h:870
static void cubehash_init(sph_cubehash_context *sc, const sph_u32 *iv)
Definition: cubehash.c:535
void sph_cubehash224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
Add a few additional bits (0 to 7) to the current computation, then terminate it and output the resul...
Definition: cubehash.c:629
void sph_cubehash512_init(void *cc)
Initialize a CubeHash-512 context.
Definition: cubehash.c:695
This structure is a context for CubeHash computations: it contains the intermediate values and some d...
Definition: sph_cubehash.h:77
Released under the MIT license