1 /*
2 * This code, as well as the Edon-R algorithm itself are public domain.
3 */
4
5 #include "fsys_zfs.h"
6 #include <string.h>
7
8 /* Specific algorithm definitions */
9 #define EdonR224_DIGEST_SIZE 28
10 #define EdonR224_BLOCK_SIZE 64
11 #define EdonR256_DIGEST_SIZE 32
12 #define EdonR256_BLOCK_SIZE 64
13 #define EdonR384_DIGEST_SIZE 48
14 #define EdonR384_BLOCK_SIZE 128
15 #define EdonR512_DIGEST_SIZE 64
16 #define EdonR512_BLOCK_SIZE 128
17
18 static void
19 my_memset(void *ptr, int c, size_t n)
20 {
21 uint8_t *p;
22 size_t i;
23
24 for (i = 0; i < n; i++)
25 p[i] = c;
26 }
27
28 typedef struct {
29 uint32_t DoublePipe[32];
30 uint8_t LastPart[EdonR256_BLOCK_SIZE * 2];
31 } EdonRData256;
32
33 typedef struct {
34 uint64_t DoublePipe[32];
35 uint8_t LastPart[EdonR512_BLOCK_SIZE * 2];
36 } EdonRData512;
37
38 typedef struct {
39 size_t hashbitlen;
40
41 /* algorithm specific parameters */
42 uint64_t bits_processed;
43 union {
44 EdonRData256 p256[1];
45 EdonRData512 p512[1];
46 } pipe[1];
47 int unprocessed_bits;
48 } EdonRHashState;
49
50 #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
51 #define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
52
53 #define rotl64(x,n) (((x) << n) | ((x) >> (64 - n)))
54 #define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
55
56 /* EdonR224 initial double chaining pipe */
57 static const uint32_t i224p2[16] = {
58 0x00010203ul, 0x04050607ul, 0x08090a0bul, 0x0c0d0e0ful,
59 0x10111213ul, 0x14151617ul, 0x18191a1bul, 0x1c1d1e1ful,
60 0x20212223ul, 0x24252627ul, 0x28292a2bul, 0x2c2d2e2ful,
61 0x30313233ul, 0x24353637ul, 0x38393a3bul, 0x3c3d3e3ful
62 };
63
64 /* EdonR256 initial double chaining pipe */
65 static const uint32_t i256p2[16] = {
66 0x40414243ul, 0x44454647ul, 0x48494a4bul, 0x4c4d4e4ful,
67 0x50515253ul, 0x54555657ul, 0x58595a5bul, 0x5c5d5e5ful,
68 0x60616263ul, 0x64656667ul, 0x68696a6bul, 0x6c6d6e6ful,
69 0x70717273ul, 0x74757677ul, 0x78797a7bul, 0x7c7d7e7ful
70 };
71
72 /* EdonR384 initial double chaining pipe */
73 static const uint64_t i384p2[16] = {
74 0x0001020304050607ull, 0x08090a0b0c0d0e0full,
75 0x1011121314151617ull, 0x18191a1b1c1d1e1full,
76 0x2021222324252627ull, 0x28292a2b2c2d2e2full,
77 0x3031323324353637ull, 0x38393a3b3c3d3e3full,
78 0x4041424344454647ull, 0x48494a4b4c4d4e4full,
79 0x5051525354555657ull, 0x58595a5b5c5d5e5full,
80 0x6061626364656667ull, 0x68696a6b6c6d6e6full,
81 0x7071727374757677ull, 0x78797a7b7c7d7e7full
82 };
83
84 /* EdonR512 initial double chaining pipe */
85 const uint64_t i512p2[16] = {
86 0x8081828384858687ull, 0x88898a8b8c8d8e8full,
87 0x9091929394959697ull, 0x98999a9b9c9d9e9full,
88 0xa0a1a2a3a4a5a6a7ull, 0xa8a9aaabacadaeafull,
89 0xb0b1b2b3b4b5b6b7ull, 0xb8b9babbbcbdbebfull,
90 0xc0c1c2c3c4c5c6c7ull, 0xc8c9cacbcccdcecfull,
91 0xd0d1d2d3d4d5d6d7ull, 0xd8d9dadbdcdddedfull,
92 0xe0e1e2e3e4e5e6e7ull, 0xe8e9eaebecedeeefull,
93 0xf0f1f2f3f4f5f6f7ull, 0xf8f9fafbfcfdfeffull
94 };
95
96 #define hashState224(x) ((x)->pipe->p256)
97 #define hashState256(x) ((x)->pipe->p256)
98 #define hashState384(x) ((x)->pipe->p512)
99 #define hashState512(x) ((x)->pipe->p512)
100
101 #define Q256(x0, x1, x2, x3, x4, x5, x6, x7, \
102 y0, y1, y2, y3, y4, y5, y6, y7, \
103 z0, z1, z2, z3, z4, z5, z6, z7) \
104 {\
105 /* First Latin Square\
106 0 7 1 3 2 4 6 5\
107 4 1 7 6 3 0 5 2\
108 7 0 4 2 5 3 1 6\
109 1 4 0 5 6 2 7 3\
110 2 3 6 7 1 5 0 4\
111 5 2 3 1 7 6 4 0\
112 3 6 5 0 4 7 2 1\
113 6 5 2 4 0 1 3 7\
114 */\
115 t8 = x0 + x4;\
116 t9 = x1 + x7;\
117 t12 = t8 + t9;\
118 t10 = x2 + x3;\
119 t11 = x5 + x6;\
120 t13 = t10 + t11;\
121 t0 = 0xaaaaaaaa + t12 + x2;\
122 t1 = t12 + x3;\
123 t1 = rotl32((t1), 5);\
124 t2 = t12 + x6;\
125 t2 = rotl32((t2),11);\
126 t3 = t13 + x7;\
127 t3 = rotl32((t3),13);\
128 t4 = x1 + t13;\
129 t4 = rotl32((t4),17);\
130 t5 = t8 + t10 + x5;\
131 t5 = rotl32((t5),19);\
132 t6 = x0 + t9 + t11;\
133 t6 = rotl32((t6),29);\
134 t7 = t13 +x4;\
135 t7 = rotl32((t7),31);\
136 \
137 t16 = t0 ^ t4;\
138 t17 = t1 ^ t7;\
139 t18 = t2 ^ t3;\
140 t19 = t5 ^ t6;\
141 t8 = t3 ^ t19;\
142 t9 = t2 ^ t19;\
143 t10 = t18 ^ t5;\
144 t11 = t16^ t1;\
145 t12 = t16 ^ t7;\
146 t13 = t17 ^ t6;\
147 t14 = t18 ^ t4;\
148 t15 = t0 ^ t17;\
149 \
150 /* Second Orthogonal Latin Square\
151 0 4 2 3 1 6 5 7\
152 7 6 3 2 5 4 1 0\
153 5 3 1 6 0 2 7 4\
154 1 0 5 4 3 7 2 6\
155 2 1 0 7 4 5 6 3\
156 3 5 7 0 6 1 4 2\
157 4 7 6 1 2 0 3 5\
158 6 2 4 5 7 3 0 1\
159 */\
160 t16 = y0 + y1;\
161 t17 = y2 + y5;\
162 t20 = t16 + t17;\
163 t18 = y3 + y4;\
164 t22 = t16 + t18;\
165 t19 = y6 + y7;\
166 t21 = t18 + t19;\
167 t23 = t17 + t19;\
168 t0 = 0x55555555 + t20 + y7;\
169 t1 = t22 + y6;\
170 t1 = rotl32((t1), 3);\
171 t2 = t20 + y3;\
172 t2 = rotl32((t2), 7);\
173 t3 = y2 + t21;\
174 t3 = rotl32((t3),11);\
175 t4 = t22 + y5;\
176 t4 = rotl32((t4),17);\
177 t5 = t23 + y4;\
178 t5 = rotl32((t5),19);\
179 t6 = y1 + t23;\
180 t6 = rotl32((t6),23);\
181 t7 = y0 + t21;\
182 t7 = rotl32((t7),29);\
183 \
184 t16 = t0 ^ t1;\
185 t17 = t2 ^ t5;\
186 t18 = t3 ^ t4;\
187 t19 = t6 ^ t7;\
188 z5 = t8 + (t18 ^ t6);\
189 z6 = t9 + (t17 ^ t7);\
190 z7 = t10 + (t4 ^ t19);\
191 z0 = t11 + (t16 ^ t5);\
192 z1 = t12 + (t2 ^ t19);\
193 z2 = t13 + (t16 ^ t3);\
194 z3 = t14 + (t0 ^ t18);\
195 z4 = t15 + (t1 ^ t17);\
196 }
197
198 #define Q512(x0, x1, x2, x3, x4, x5, x6, x7, \
199 y0, y1, y2, y3, y4, y5, y6, y7,\
200 z0, z1, z2, z3, z4, z5, z6, z7) \
201 {\
202 /* First Latin Square\
203 0 7 1 3 2 4 6 5\
204 4 1 7 6 3 0 5 2\
205 7 0 4 2 5 3 1 6\
206 1 4 0 5 6 2 7 3\
207 2 3 6 7 1 5 0 4\
208 5 2 3 1 7 6 4 0\
209 3 6 5 0 4 7 2 1\
210 6 5 2 4 0 1 3 7\
211 */\
212 tt8 = x0 + x4;\
213 tt9 = x1 + x7;\
214 tt12 = tt8 + tt9;\
215 tt10 = x2 + x3;\
216 tt11 = x5 + x6;\
217 tt13 = tt10 + tt11;\
218 tt0 = 0xaaaaaaaaaaaaaaaaull + tt12 + x2;\
219 tt1 = tt12 + x3;\
220 tt1 = rotl64((tt1), 5);\
221 tt2 = tt12 + x6;\
222 tt2 = rotl64((tt2),19);\
223 tt3 = tt13 + x7;\
224 tt3 = rotl64((tt3),29);\
225 tt4 = x1 + tt13;\
226 tt4 = rotl64((tt4),31);\
227 tt5 = tt8 + tt10 + x5;\
228 tt5 = rotl64((tt5),41);\
229 tt6 = x0 + tt9 + tt11;\
230 tt6 = rotl64((tt6),57);\
231 tt7 = tt13 + x4;\
232 tt7 = rotl64((tt7),61);\
233 \
234 tt16 = tt0 ^ tt4;\
235 tt17 = tt1 ^ tt7;\
236 tt18 = tt2 ^ tt3;\
237 tt19 = tt5 ^ tt6;\
238 tt8 = tt3 ^ tt19;\
239 tt9 = tt2 ^ tt19;\
240 tt10 = tt18 ^ tt5;\
241 tt11 = tt16 ^ tt1;\
242 tt12 = tt16 ^ tt7;\
243 tt13 = tt17 ^ tt6;\
244 tt14 = tt18 ^ tt4;\
245 tt15 = tt0 ^ tt17;\
246 \
247 /* Second Orthogonal Latin Square\
248 0 4 2 3 1 6 5 7\
249 7 6 3 2 5 4 1 0\
250 5 3 1 6 0 2 7 4\
251 1 0 5 4 3 7 2 6\
252 2 1 0 7 4 5 6 3\
253 3 5 7 0 6 1 4 2\
254 4 7 6 1 2 0 3 5\
255 6 2 4 5 7 3 0 1\
256 */\
257 tt16 = y0 + y1;\
258 tt17 = y2 + y5;\
259 tt20 = tt16 + tt17;\
260 tt18 = y3 + y4;\
261 tt22 = tt16 + tt18;\
262 tt19 = y6 + y7;\
263 tt21 = tt18 + tt19;\
264 tt23 = tt17 + tt19;\
265 tt0 = 0x5555555555555555ull + tt20 + y7;\
266 tt1 = tt22 + y6;\
267 tt1 = rotl64((tt1), 3);\
268 tt2 = tt20 + y3;\
269 tt2 = rotl64((tt2),17);\
270 tt3 = y2 + tt21;\
271 tt3 = rotl64((tt3),23);\
272 tt4 = tt22 + y5;\
273 tt4 = rotl64((tt4),31);\
274 tt5 = tt23+ y4;\
275 tt5 = rotl64((tt5),37);\
276 tt6 = y1 + tt23;\
277 tt6 = rotl64((tt6),45);\
278 tt7 = y0 + tt21;\
279 tt7 = rotl64((tt7),59);\
280 \
281 tt16 = tt0 ^ tt1;\
282 tt17 = tt2 ^ tt5;\
283 tt18 = tt3 ^ tt4;\
284 tt19 = tt6 ^ tt7;\
285 z5 = tt8 + (tt18 ^ tt6);\
286 z6 = tt9 + (tt17 ^ tt7);\
287 z7 = tt10 + (tt4 ^ tt19);\
288 z0 = tt11 + (tt16 ^ tt5);\
289 z1 = tt12 + (tt2 ^ tt19);\
290 z2 = tt13 + (tt16 ^ tt3);\
291 z3 = tt14 + (tt0 ^ tt18);\
292 z4 = tt15 + (tt1 ^ tt17);\
293 }
294
295 static void
296 EdonRInit(EdonRHashState *state, int hashbitlen)
297 {
298 switch (hashbitlen) {
299 case 224:
300 state->hashbitlen = 224;
301 state->bits_processed = 0;
302 state->unprocessed_bits = 0;
303 memcpy(hashState224(state)->DoublePipe, i224p2,
304 16 * sizeof (uint32_t));
305 break;
306
307 case 256:
308 state->hashbitlen = 256;
309 state->bits_processed = 0;
310 state->unprocessed_bits = 0;
311 memcpy(hashState256(state)->DoublePipe, i256p2,
312 16 * sizeof (uint32_t));
313 break;
314
315 case 384:
316 state->hashbitlen = 384;
317 state->bits_processed = 0;
318 state->unprocessed_bits = 0;
319 memcpy(hashState384(state)->DoublePipe, i384p2,
320 16 * sizeof (uint64_t));
321 break;
322
323 case 512:
324 state->hashbitlen = 512;
325 state->bits_processed = 0;
326 state->unprocessed_bits = 0;
327 memcpy(hashState224(state)->DoublePipe, i512p2,
328 16 * sizeof (uint64_t));
329 break;
330 }
331 }
332
333 static void
334 EdonRUpdate(EdonRHashState *state, const uint8_t *data, size_t databitlen)
335 {
336 uint32_t *data32, *p256;
337 uint32_t t0, t1, t2, t3, t4, t5, t6, t7;
338 uint32_t t8, t9, t10, t11, t12, t13, t14, t15;
339 uint32_t t16, t17, t18, t19, t20, t21, t22, t23;
340 uint32_t p16, p17, p18, p19, p20, p21, p22, p23;
341 uint32_t p24, p25, p26, p27, p28, p29, p30, p31;
342
343 uint64_t *data64, *p512;
344 uint64_t tt0, tt1, tt2, tt3, tt4, tt5, tt6, tt7;
345 uint64_t tt8, tt9, tt10, tt11, tt12, tt13, tt14, tt15;
346 uint64_t tt16, tt17, tt18, tt19, tt20, tt21, tt22, tt23;
347 uint64_t pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23;
348 uint64_t pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31;
349
350 int LastBytes;
351
352 switch (state->hashbitlen) {
353 case 224:
354 case 256:
355 if (state->unprocessed_bits > 0) {
356 /* LastBytes = databitlen / 8 */
357 LastBytes = (int) databitlen >> 3;
358 memcpy(hashState256(state)->LastPart +
359 (state->unprocessed_bits >> 3), data, LastBytes);
360 state->unprocessed_bits += (int) databitlen;
361 databitlen = state->unprocessed_bits;
362 data32 = (uint32_t *) hashState256(state)->LastPart;
363 } else
364 data32 = (uint32_t *) data;
365
366 p256 = hashState256(state)->DoublePipe;
367 while (databitlen >= EdonR256_BLOCK_SIZE * 8) {
368 databitlen -= EdonR256_BLOCK_SIZE * 8;
369
370 state->bits_processed += EdonR256_BLOCK_SIZE * 8;
371
372 /* First row of quasigroup e-transformations */
373 Q256(data32[15], data32[14], data32[13], data32[12],
374 data32[11], data32[10], data32[9], data32[8],
375 data32[0], data32[1], data32[2], data32[3],
376 data32[4], data32[5], data32[6], data32[7], p16,
377 p17, p18, p19, p20, p21, p22, p23);
378 Q256(p16, p17, p18, p19, p20, p21, p22, p23, data32[8],
379 data32[9], data32[10], data32[11], data32[12],
380 data32[13], data32[14], data32[15], p24, p25, p26,
381 p27, p28, p29, p30, p31);
382
383 /* Second row of quasigroup e-transformations */
384 Q256(p256[8], p256[9], p256[10], p256[11], p256[12],
385 p256[13], p256[14], p256[15], p16, p17, p18, p19,
386 p20, p21, p22, p23, p16, p17, p18, p19, p20, p21,
387 p22, p23);
388 Q256(p16, p17, p18, p19, p20, p21, p22, p23, p24, p25,
389 p26, p27, p28, p29, p30, p31, p24, p25, p26, p27,
390 p28, p29, p30, p31);
391
392 /* Third row of quasigroup e-transformations */
393 Q256(p16, p17, p18, p19, p20, p21, p22, p23,
394 p256[0], p256[1], p256[2], p256[3], p256[4],
395 p256[5], p256[6], p256[7], p16, p17, p18, p19, p20,
396 p21, p22, p23);
397 Q256(p24, p25, p26, p27, p28, p29, p30, p31, p16, p17,
398 p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
399 p28, p29, p30, p31);
400
401 /* Fourth row of quasigroup e-transformations */
402 Q256(data32[7], data32[6], data32[5], data32[4],
403 data32[3], data32[2], data32[1], data32[0], p16,
404 p17, p18, p19, p20, p21, p22, p23, p256[0], p256[1],
405 p256[2], p256[3], p256[4], p256[5], p256[6],
406 p256[7]);
407 Q256(p256[0], p256[1], p256[2], p256[3], p256[4],
408 p256[5], p256[6], p256[7], p24, p25, p26, p27, p28,
409 p29, p30, p31, p256[8], p256[9], p256[10], p256[11],
410 p256[12], p256[13], p256[14], p256[15]);
411
412 data32 += 16;
413 }
414 state->unprocessed_bits = (int) databitlen;
415 if (databitlen > 0) {
416 /* LastBytes = Ceil(databitlen / 8) */
417 LastBytes = ((~(((-(int) databitlen) >> 3) & 0x01ff)) +
418 1) & 0x01ff;
419 memcpy(hashState256(state)->LastPart, data32,
420 LastBytes);
421 }
422 break;
423
424
425 case 384:
426 case 512:
427 if (state->unprocessed_bits > 0) {
428 /* LastBytes = databitlen / 8 */
429 LastBytes = (int) databitlen >> 3;
430 memcpy(hashState512(state)->LastPart +
431 (state->unprocessed_bits >> 3), data, LastBytes);
432 state->unprocessed_bits += (int) databitlen;
433 databitlen = state->unprocessed_bits;
434 data64 = (uint64_t *) hashState512(state)->LastPart;
435 } else
436 data64 = (uint64_t *) data;
437
438 p512 = hashState512(state)->DoublePipe;
439 while (databitlen >= EdonR512_BLOCK_SIZE * 8) {
440 databitlen -= EdonR512_BLOCK_SIZE * 8;
441
442 state->bits_processed += EdonR512_BLOCK_SIZE * 8;
443
444 /* First row of quasigroup e-transformations */
445 Q512(data64[15], data64[14], data64[13], data64[12],
446 data64[11], data64[10], data64[9], data64[8],
447 data64[0], data64[1], data64[2], data64[3],
448 data64[4], data64[5], data64[6], data64[7], pp16,
449 pp17, pp18, pp19, pp20, pp21, pp22, pp23);
450 Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
451 data64[8], data64[9], data64[10], data64[11],
452 data64[12], data64[13], data64[14], data64[15],
453 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
454
455 /* Second row of quasigroup e-transformations */
456 Q512(p512[8], p512[9], p512[10], p512[11], p512[12],
457 p512[13], p512[14], p512[15], pp16, pp17, pp18,
458 pp19, pp20, pp21, pp22, pp23, pp16, pp17, pp18,
459 pp19, pp20, pp21, pp22, pp23);
460 Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
461 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
462 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
463
464 /* Third row of quasigroup e-transformations */
465 Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
466 p512[0], p512[1], p512[2], p512[3], p512[4],
467 p512[5], p512[6], p512[7], pp16, pp17, pp18, pp19,
468 pp20, pp21, pp22, pp23);
469 Q512(pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
470 pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
471 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
472
473 /* Fourth row of quasigroup e-transformations */
474 Q512(data64[7], data64[6], data64[5], data64[4],
475 data64[3], data64[2], data64[1], data64[0], pp16,
476 pp17, pp18, pp19, pp20, pp21, pp22, pp23, p512[0],
477 p512[1], p512[2], p512[3], p512[4], p512[5],
478 p512[6], p512[7]);
479 Q512(p512[0], p512[1], p512[2], p512[3], p512[4],
480 p512[5], p512[6], p512[7], pp24, pp25, pp26, pp27,
481 pp28, pp29, pp30, pp31, p512[8], p512[9], p512[10],
482 p512[11], p512[12], p512[13], p512[14], p512[15]);
483
484 data64 += 16;
485 }
486 state->unprocessed_bits = (int) databitlen;
487 if (databitlen > 0) {
488 /* LastBytes = Ceil(databitlen / 8) */
489 LastBytes = ((~(((-(int) databitlen) >> 3) & 0x03ff)) +
490 1) & 0x03ff;
491 memcpy(hashState512(state)->LastPart, data64,
492 LastBytes);
493 }
494 break;
495 }
496 }
497
498 static void
499 EdonRFinal(EdonRHashState * state, uint8_t *hashval)
500 {
501 uint32_t *data32, *p256;
502 uint32_t t0, t1, t2, t3, t4, t5, t6, t7;
503 uint32_t t8, t9, t10, t11, t12, t13, t14, t15;
504 uint32_t t16, t17, t18, t19, t20, t21, t22, t23;
505 uint32_t p16, p17, p18, p19, p20, p21, p22, p23;
506 uint32_t p24, p25, p26, p27, p28, p29, p30, p31;
507
508 uint64_t *data64, *p512;
509 uint64_t tt0, tt1, tt2, tt3, tt4, tt5, tt6, tt7;
510 uint64_t tt8, tt9, tt10, tt11, tt12, tt13, tt14, tt15;
511 uint64_t tt16, tt17, tt18, tt19, tt20, tt21, tt22, tt23;
512 uint64_t pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23;
513 uint64_t pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31;
514
515 size_t databitlen;
516
517 int LastByte, PadOnePosition;
518
519 switch (state->hashbitlen) {
520 case 224:
521 case 256:
522 LastByte = (int) state->unprocessed_bits >> 3;
523 PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
524 hashState256(state)->LastPart[LastByte] =
525 hashState256(state)->
526 LastPart[LastByte] & (0xff << (PadOnePosition + 1))
527 ^ (0x01 << PadOnePosition);
528 data64 = (uint64_t *) hashState256(state)->LastPart;
529
530 if (state->unprocessed_bits < 448) {
531 my_memset((hashState256(state)->LastPart) + LastByte +
532 1, 0x00, EdonR256_BLOCK_SIZE - LastByte - 9);
533 databitlen = EdonR256_BLOCK_SIZE * 8;
534 data64[7] =
535 state->bits_processed + state->unprocessed_bits;
536 } else {
537 my_memset((hashState256(state)->LastPart) + LastByte +
538 1, 0x00, EdonR256_BLOCK_SIZE * 2 - LastByte - 9);
539 databitlen = EdonR256_BLOCK_SIZE * 16;
540 data64[15] =
541 state->bits_processed + state->unprocessed_bits;
542 }
543
544 data32 = (uint32_t *) hashState256(state)->LastPart;
545 p256 = hashState256(state)->DoublePipe;
546 while (databitlen >= EdonR256_BLOCK_SIZE * 8) {
547 databitlen -= EdonR256_BLOCK_SIZE * 8;
548
549 /* First row of quasigroup e-transformations */
550 Q256(data32[15], data32[14], data32[13], data32[12],
551 data32[11], data32[10], data32[9], data32[8],
552 data32[0], data32[1], data32[2], data32[3],
553 data32[4], data32[5], data32[6], data32[7], p16,
554 p17, p18, p19, p20, p21, p22, p23);
555 Q256(p16, p17, p18, p19, p20, p21, p22, p23, data32[8],
556 data32[9], data32[10], data32[11], data32[12],
557 data32[13], data32[14], data32[15], p24, p25, p26,
558 p27, p28, p29, p30, p31);
559
560 /* Second row of quasigroup e-transformations */
561 Q256(p256[8], p256[9], p256[10], p256[11], p256[12],
562 p256[13], p256[14], p256[15], p16, p17, p18, p19,
563 p20, p21, p22, p23, p16, p17, p18, p19, p20, p21,
564 p22, p23);
565 Q256(p16, p17, p18, p19, p20, p21, p22, p23, p24, p25,
566 p26, p27, p28, p29, p30, p31, p24, p25, p26, p27,
567 p28, p29, p30, p31);
568
569 /* Third row of quasigroup e-transformations */
570 Q256(p16, p17, p18, p19, p20, p21, p22, p23,
571 p256[0], p256[1], p256[2], p256[3], p256[4],
572 p256[5], p256[6], p256[7], p16, p17, p18, p19, p20,
573 p21, p22, p23);
574 Q256(p24, p25, p26, p27, p28, p29, p30, p31, p16, p17,
575 p18, p19, p20, p21, p22, p23, p24, p25, p26, p27,
576 p28, p29, p30, p31);
577
578 /* Fourth row of quasigroup e-transformations */
579 Q256(data32[7], data32[6], data32[5], data32[4],
580 data32[3], data32[2], data32[1], data32[0], p16,
581 p17, p18, p19, p20, p21, p22, p23, p256[0], p256[1],
582 p256[2], p256[3], p256[4], p256[5], p256[6],
583 p256[7]);
584 Q256(p256[0], p256[1], p256[2], p256[3], p256[4],
585 p256[5], p256[6], p256[7], p24, p25, p26, p27, p28,
586 p29, p30, p31, p256[8], p256[9], p256[10], p256[11],
587 p256[12], p256[13], p256[14], p256[15]);
588
589
590 data32 += 16;
591 }
592 break;
593
594 case 384:
595 case 512:
596 LastByte = (int) state->unprocessed_bits >> 3;
597 PadOnePosition = 7 - (state->unprocessed_bits & 0x07);
598 hashState512(state)->LastPart[LastByte] =
599 hashState512(state)->
600 LastPart[LastByte] & (0xff << (PadOnePosition + 1))
601 ^ (0x01 << PadOnePosition);
602 data64 = (uint64_t *) hashState512(state)->LastPart;
603
604 if (state->unprocessed_bits < 960) {
605 my_memset((hashState512(state)->LastPart) + LastByte +
606 1, 0x00, EdonR512_BLOCK_SIZE - LastByte - 9);
607 databitlen = EdonR512_BLOCK_SIZE * 8;
608 data64[15] =
609 state->bits_processed + state->unprocessed_bits;
610 } else {
611 my_memset((hashState512(state)->LastPart) + LastByte +
612 1, 0x00, EdonR512_BLOCK_SIZE * 2 - LastByte - 9);
613 databitlen = EdonR512_BLOCK_SIZE * 16;
614 data64[31] =
615 state->bits_processed + state->unprocessed_bits;
616 }
617
618 p512 = hashState512(state)->DoublePipe;
619 while (databitlen >= EdonR512_BLOCK_SIZE * 8) {
620 databitlen -= EdonR512_BLOCK_SIZE * 8;
621 /* First row of quasigroup e-transformations */
622 Q512(data64[15], data64[14], data64[13], data64[12],
623 data64[11], data64[10], data64[9], data64[8],
624 data64[0], data64[1], data64[2], data64[3],
625 data64[4], data64[5], data64[6], data64[7], pp16,
626 pp17, pp18, pp19, pp20, pp21, pp22, pp23);
627 Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
628 data64[8], data64[9], data64[10], data64[11],
629 data64[12], data64[13], data64[14], data64[15],
630 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
631
632 /* Second row of quasigroup e-transformations */
633 Q512(p512[8], p512[9], p512[10], p512[11], p512[12],
634 p512[13], p512[14], p512[15], pp16, pp17, pp18,
635 pp19, pp20, pp21, pp22, pp23, pp16, pp17, pp18,
636 pp19, pp20, pp21, pp22, pp23);
637 Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
638 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
639 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
640
641 /* Third row of quasigroup e-transformations */
642 Q512(pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
643 p512[0], p512[1], p512[2], p512[3], p512[4],
644 p512[5], p512[6], p512[7], pp16, pp17, pp18, pp19,
645 pp20, pp21, pp22, pp23);
646 Q512(pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31,
647 pp16, pp17, pp18, pp19, pp20, pp21, pp22, pp23,
648 pp24, pp25, pp26, pp27, pp28, pp29, pp30, pp31);
649
650 /* Fourth row of quasigroup e-transformations */
651 Q512(data64[7], data64[6], data64[5], data64[4],
652 data64[3], data64[2], data64[1], data64[0], pp16,
653 pp17, pp18, pp19, pp20, pp21, pp22, pp23, p512[0],
654 p512[1], p512[2], p512[3], p512[4], p512[5],
655 p512[6], p512[7]);
656 Q512(p512[0], p512[1], p512[2], p512[3], p512[4],
657 p512[5], p512[6], p512[7], pp24, pp25, pp26, pp27,
658 pp28, pp29, pp30, pp31, p512[8], p512[9], p512[10],
659 p512[11], p512[12], p512[13], p512[14], p512[15]);
660
661 data64 += 16;
662 }
663 break;
664 }
665
666 switch (state->hashbitlen) {
667 case 224:
668 memcpy(hashval, p256 + 9, EdonR224_DIGEST_SIZE);
669 break;
670 case 256:
671 memcpy(hashval, p256 + 8, EdonR256_DIGEST_SIZE);
672 break;
673 case 384:
674 memcpy(hashval, p512 + 10, EdonR384_DIGEST_SIZE);
675 break;
676 case 512:
677 memcpy(hashval, p512 + 8, EdonR512_DIGEST_SIZE);
678 break;
679 }
680 }
681
682 static void
683 EdonRHash(size_t hashbitlen, const uint8_t* data, size_t databitlen,
684 uint8_t *hashval)
685 {
686 EdonRHashState state;
687
688 EdonRInit(&state, hashbitlen);
689 EdonRUpdate(&state, data, databitlen);
690 EdonRFinal(&state, hashval);
691 }
692
693 void
694 zio_checksum_EdonR512_256(const void *buf, uint64_t size, zio_cksum_t *zcp)
695 {
696 uint8_t hash[EdonR512_DIGEST_SIZE];
697
698 EdonRHash(512, buf, size * 8, hash);
699 memcpy(&zcp->zc_word[0], &hash[000], sizeof (zcp->zc_word[0]));
700 memcpy(&zcp->zc_word[1], &hash[010], sizeof (zcp->zc_word[1]));
701 memcpy(&zcp->zc_word[2], &hash[020], sizeof (zcp->zc_word[2]));
702 memcpy(&zcp->zc_word[3], &hash[030], sizeof (zcp->zc_word[3]));
703 }
704
705 void
706 zio_checksum_EdonR512_256_byteswap(const void *buf, uint64_t size,
707 zio_cksum_t *zcp)
708 {
709 zio_checksum_EdonR512_256(buf, size, zcp);
710 zcp->zc_word[0] = BSWAP_64(zcp->zc_word[0]);
711 zcp->zc_word[1] = BSWAP_64(zcp->zc_word[1]);
712 zcp->zc_word[2] = BSWAP_64(zcp->zc_word[2]);
713 zcp->zc_word[3] = BSWAP_64(zcp->zc_word[3]);
714 }