23 #include "KeccakCore.h"
25 #include "utility/EndianUtil.h"
26 #include "utility/RotateUtil.h"
27 #include "utility/ProgMemUtil.h"
42 #if !defined(CRYPTO_LITTLE_ENDIAN)
44 #error "KeccakCore is not supported on big-endian platforms yet - todo"
57 memset(state.A, 0,
sizeof(state.A));
78 return 1600 - ((size_t)_blockSize) * 8;
116 memset(state.A, 0,
sizeof(state.A));
118 state.outputSize = 0;
136 state.outputSize = 0;
139 const uint8_t *d = (
const uint8_t *)data;
141 uint8_t len = _blockSize - state.inputSize;
144 uint8_t *Abytes = ((uint8_t *)state.A) + state.inputSize;
145 for (uint8_t posn = 0; posn < len; ++posn)
146 Abytes[posn] ^= d[posn];
147 state.inputSize += len;
150 if (state.inputSize == _blockSize) {
174 uint8_t size = state.inputSize;
175 uint64_t *Awords = &(state.A[0][0]);
176 Awords[size / 8] ^= (((uint64_t)tag) << ((size % 8) * 8));
177 Awords[(_blockSize - 1) / 8] ^= 0x8000000000000000ULL;
180 state.outputSize = 0;
200 uint8_t *d = (uint8_t *)data;
204 if (state.outputSize >= _blockSize) {
206 state.outputSize = 0;
210 tempSize = _blockSize - state.outputSize;
215 memcpy(d, ((uint8_t *)(state.A)) + state.outputSize, tempSize);
216 state.outputSize += tempSize;
246 uint8_t *out = (uint8_t *)output;
247 const uint8_t *in = (
const uint8_t *)input;
251 if (state.outputSize >= _blockSize) {
253 state.outputSize = 0;
257 tempSize = _blockSize - state.outputSize;
262 const uint8_t *d = ((
const uint8_t *)(state.A)) + state.outputSize;
263 for (uint8_t index = 0; index < tempSize; ++index)
264 out[index] = in[index] ^ d[index];
265 state.outputSize += tempSize;
295 uint8_t *Abytes = (uint8_t *)state.A;
302 memcpy(Abytes, key, len);
310 memset(Abytes + hashSize,
pad, size - hashSize);
311 memset(Abytes + size, 0,
sizeof(state.A) - size);
324 void KeccakCore::keccakp()
331 for (uint8_t round = 0; round < 24; ++round) {
332 __asm__ __volatile__ (
353 "eor r8,__tmp_reg__\n"
354 "ldd __tmp_reg__,Z+1\n"
355 "eor r9,__tmp_reg__\n"
356 "ldd __tmp_reg__,Z+2\n"
357 "eor r10,__tmp_reg__\n"
358 "ldd __tmp_reg__,Z+3\n"
359 "eor r11,__tmp_reg__\n"
360 "ldd __tmp_reg__,Z+4\n"
361 "eor r12,__tmp_reg__\n"
362 "ldd __tmp_reg__,Z+5\n"
363 "eor r13,__tmp_reg__\n"
364 "ldd __tmp_reg__,Z+6\n"
365 "eor r14,__tmp_reg__\n"
366 "ldd __tmp_reg__,Z+7\n"
367 "eor r15,__tmp_reg__\n"
379 "sbc r31,__zero_reg__\n"
402 "adc r8, __zero_reg__\n"
403 "ldd __tmp_reg__,Y+32\n"
404 "eor r8,__tmp_reg__\n"
405 "ldd __tmp_reg__,Y+33\n"
406 "eor r9,__tmp_reg__\n"
407 "ldd __tmp_reg__,Y+34\n"
408 "eor r10,__tmp_reg__\n"
409 "ldd __tmp_reg__,Y+35\n"
410 "eor r11,__tmp_reg__\n"
411 "ldd __tmp_reg__,Y+36\n"
412 "eor r12,__tmp_reg__\n"
413 "ldd __tmp_reg__,Y+37\n"
414 "eor r13,__tmp_reg__\n"
415 "ldd __tmp_reg__,Y+38\n"
416 "eor r14,__tmp_reg__\n"
417 "ldd __tmp_reg__,Y+39\n"
418 "eor r15,__tmp_reg__\n"
422 "eor __tmp_reg__,r8\n"
424 "ldd __tmp_reg__,Z+1\n"
425 "eor __tmp_reg__,r9\n"
426 "std Z+1,__tmp_reg__\n"
427 "ldd __tmp_reg__,Z+2\n"
428 "eor __tmp_reg__,r10\n"
429 "std Z+2,__tmp_reg__\n"
430 "ldd __tmp_reg__,Z+3\n"
431 "eor __tmp_reg__,r11\n"
432 "std Z+3,__tmp_reg__\n"
433 "ldd __tmp_reg__,Z+4\n"
434 "eor __tmp_reg__,r12\n"
435 "std Z+4,__tmp_reg__\n"
436 "ldd __tmp_reg__,Z+5\n"
437 "eor __tmp_reg__,r13\n"
438 "std Z+5,__tmp_reg__\n"
439 "ldd __tmp_reg__,Z+6\n"
440 "eor __tmp_reg__,r14\n"
441 "std Z+6,__tmp_reg__\n"
442 "ldd __tmp_reg__,Z+7\n"
443 "eor __tmp_reg__,r15\n"
444 "std Z+7,__tmp_reg__\n"
449 "sbc r31,__zero_reg__\n"
466 "adc r8, __zero_reg__\n"
468 "eor r8,__tmp_reg__\n"
469 "ldd __tmp_reg__,Y+1\n"
470 "eor r9,__tmp_reg__\n"
471 "ldd __tmp_reg__,Y+2\n"
472 "eor r10,__tmp_reg__\n"
473 "ldd __tmp_reg__,Y+3\n"
474 "eor r11,__tmp_reg__\n"
475 "ldd __tmp_reg__,Y+4\n"
476 "eor r12,__tmp_reg__\n"
477 "ldd __tmp_reg__,Y+5\n"
478 "eor r13,__tmp_reg__\n"
479 "ldd __tmp_reg__,Y+6\n"
480 "eor r14,__tmp_reg__\n"
481 "ldd __tmp_reg__,Y+7\n"
482 "eor r15,__tmp_reg__\n"
486 "eor __tmp_reg__,r8\n"
488 "ldd __tmp_reg__,Z+1\n"
489 "eor __tmp_reg__,r9\n"
490 "std Z+1,__tmp_reg__\n"
491 "ldd __tmp_reg__,Z+2\n"
492 "eor __tmp_reg__,r10\n"
493 "std Z+2,__tmp_reg__\n"
494 "ldd __tmp_reg__,Z+3\n"
495 "eor __tmp_reg__,r11\n"
496 "std Z+3,__tmp_reg__\n"
497 "ldd __tmp_reg__,Z+4\n"
498 "eor __tmp_reg__,r12\n"
499 "std Z+4,__tmp_reg__\n"
500 "ldd __tmp_reg__,Z+5\n"
501 "eor __tmp_reg__,r13\n"
502 "std Z+5,__tmp_reg__\n"
503 "ldd __tmp_reg__,Z+6\n"
504 "eor __tmp_reg__,r14\n"
505 "std Z+6,__tmp_reg__\n"
506 "ldd __tmp_reg__,Z+7\n"
507 "eor __tmp_reg__,r15\n"
508 "std Z+7,__tmp_reg__\n"
513 "sbc r31,__zero_reg__\n"
530 "adc r8, __zero_reg__\n"
531 "ldd __tmp_reg__,Y+8\n"
532 "eor r8,__tmp_reg__\n"
533 "ldd __tmp_reg__,Y+9\n"
534 "eor r9,__tmp_reg__\n"
535 "ldd __tmp_reg__,Y+10\n"
536 "eor r10,__tmp_reg__\n"
537 "ldd __tmp_reg__,Y+11\n"
538 "eor r11,__tmp_reg__\n"
539 "ldd __tmp_reg__,Y+12\n"
540 "eor r12,__tmp_reg__\n"
541 "ldd __tmp_reg__,Y+13\n"
542 "eor r13,__tmp_reg__\n"
543 "ldd __tmp_reg__,Y+14\n"
544 "eor r14,__tmp_reg__\n"
545 "ldd __tmp_reg__,Y+15\n"
546 "eor r15,__tmp_reg__\n"
550 "eor __tmp_reg__,r8\n"
552 "ldd __tmp_reg__,Z+1\n"
553 "eor __tmp_reg__,r9\n"
554 "std Z+1,__tmp_reg__\n"
555 "ldd __tmp_reg__,Z+2\n"
556 "eor __tmp_reg__,r10\n"
557 "std Z+2,__tmp_reg__\n"
558 "ldd __tmp_reg__,Z+3\n"
559 "eor __tmp_reg__,r11\n"
560 "std Z+3,__tmp_reg__\n"
561 "ldd __tmp_reg__,Z+4\n"
562 "eor __tmp_reg__,r12\n"
563 "std Z+4,__tmp_reg__\n"
564 "ldd __tmp_reg__,Z+5\n"
565 "eor __tmp_reg__,r13\n"
566 "std Z+5,__tmp_reg__\n"
567 "ldd __tmp_reg__,Z+6\n"
568 "eor __tmp_reg__,r14\n"
569 "std Z+6,__tmp_reg__\n"
570 "ldd __tmp_reg__,Z+7\n"
571 "eor __tmp_reg__,r15\n"
572 "std Z+7,__tmp_reg__\n"
577 "sbc r31,__zero_reg__\n"
594 "adc r8, __zero_reg__\n"
595 "ldd __tmp_reg__,Y+16\n"
596 "eor r8,__tmp_reg__\n"
597 "ldd __tmp_reg__,Y+17\n"
598 "eor r9,__tmp_reg__\n"
599 "ldd __tmp_reg__,Y+18\n"
600 "eor r10,__tmp_reg__\n"
601 "ldd __tmp_reg__,Y+19\n"
602 "eor r11,__tmp_reg__\n"
603 "ldd __tmp_reg__,Y+20\n"
604 "eor r12,__tmp_reg__\n"
605 "ldd __tmp_reg__,Y+21\n"
606 "eor r13,__tmp_reg__\n"
607 "ldd __tmp_reg__,Y+22\n"
608 "eor r14,__tmp_reg__\n"
609 "ldd __tmp_reg__,Y+23\n"
610 "eor r15,__tmp_reg__\n"
614 "eor __tmp_reg__,r8\n"
616 "ldd __tmp_reg__,Z+1\n"
617 "eor __tmp_reg__,r9\n"
618 "std Z+1,__tmp_reg__\n"
619 "ldd __tmp_reg__,Z+2\n"
620 "eor __tmp_reg__,r10\n"
621 "std Z+2,__tmp_reg__\n"
622 "ldd __tmp_reg__,Z+3\n"
623 "eor __tmp_reg__,r11\n"
624 "std Z+3,__tmp_reg__\n"
625 "ldd __tmp_reg__,Z+4\n"
626 "eor __tmp_reg__,r12\n"
627 "std Z+4,__tmp_reg__\n"
628 "ldd __tmp_reg__,Z+5\n"
629 "eor __tmp_reg__,r13\n"
630 "std Z+5,__tmp_reg__\n"
631 "ldd __tmp_reg__,Z+6\n"
632 "eor __tmp_reg__,r14\n"
633 "std Z+6,__tmp_reg__\n"
634 "ldd __tmp_reg__,Z+7\n"
635 "eor __tmp_reg__,r15\n"
636 "std Z+7,__tmp_reg__\n"
641 "sbc r31,__zero_reg__\n"
658 "adc r8, __zero_reg__\n"
659 "ldd __tmp_reg__,Y+24\n"
660 "eor r8,__tmp_reg__\n"
661 "ldd __tmp_reg__,Y+25\n"
662 "eor r9,__tmp_reg__\n"
663 "ldd __tmp_reg__,Y+26\n"
664 "eor r10,__tmp_reg__\n"
665 "ldd __tmp_reg__,Y+27\n"
666 "eor r11,__tmp_reg__\n"
667 "ldd __tmp_reg__,Y+28\n"
668 "eor r12,__tmp_reg__\n"
669 "ldd __tmp_reg__,Y+29\n"
670 "eor r13,__tmp_reg__\n"
671 "ldd __tmp_reg__,Y+30\n"
672 "eor r14,__tmp_reg__\n"
673 "ldd __tmp_reg__,Y+31\n"
674 "eor r15,__tmp_reg__\n"
678 "eor __tmp_reg__,r8\n"
680 "ldd __tmp_reg__,Z+1\n"
681 "eor __tmp_reg__,r9\n"
682 "std Z+1,__tmp_reg__\n"
683 "ldd __tmp_reg__,Z+2\n"
684 "eor __tmp_reg__,r10\n"
685 "std Z+2,__tmp_reg__\n"
686 "ldd __tmp_reg__,Z+3\n"
687 "eor __tmp_reg__,r11\n"
688 "std Z+3,__tmp_reg__\n"
689 "ldd __tmp_reg__,Z+4\n"
690 "eor __tmp_reg__,r12\n"
691 "std Z+4,__tmp_reg__\n"
692 "ldd __tmp_reg__,Z+5\n"
693 "eor __tmp_reg__,r13\n"
694 "std Z+5,__tmp_reg__\n"
695 "ldd __tmp_reg__,Z+6\n"
696 "eor __tmp_reg__,r14\n"
697 "std Z+6,__tmp_reg__\n"
698 "ldd __tmp_reg__,Z+7\n"
699 "eor __tmp_reg__,r15\n"
700 "std Z+7,__tmp_reg__\n"
705 "sbc r31,__zero_reg__\n"
745 "adc r8, __zero_reg__\n"
754 "adc r8, __zero_reg__\n"
763 "adc r8, __zero_reg__\n"
772 "adc r8, __zero_reg__\n"
800 "adc r8, __zero_reg__\n"
828 "adc r8, __zero_reg__\n"
837 "adc r8, __zero_reg__\n"
846 "adc r8, __zero_reg__\n"
897 "sbc r27,__zero_reg__\n"
915 "adc r8, __zero_reg__\n"
924 "adc r8, __zero_reg__\n"
933 "adc r8, __zero_reg__\n"
942 "adc r8, __zero_reg__\n"
970 "adc r8, __zero_reg__\n"
979 "adc r8, __zero_reg__\n"
988 "adc r8, __zero_reg__\n"
997 "adc r8, __zero_reg__\n"
1064 "adc r8, __zero_reg__\n"
1073 "adc r8, __zero_reg__\n"
1082 "adc r8, __zero_reg__\n"
1091 "adc r8, __zero_reg__\n"
1132 "sbc r27,__zero_reg__\n"
1150 "adc r8, __zero_reg__\n"
1159 "adc r8, __zero_reg__\n"
1168 "adc r8, __zero_reg__\n"
1196 "adc r8, __zero_reg__\n"
1205 "adc r8, __zero_reg__\n"
1214 "adc r8, __zero_reg__\n"
1242 "adc r8, __zero_reg__\n"
1270 "adc r8, __zero_reg__\n"
1279 "adc r8, __zero_reg__\n"
1320 "sbc r27,__zero_reg__\n"
1484 "adc r8, __zero_reg__\n"
1496 "sbc r27,__zero_reg__\n"
1602 "adc r8, __zero_reg__\n"
1611 "adc r8, __zero_reg__\n"
1658 "adc r8, __zero_reg__\n"
1667 "adc r8, __zero_reg__\n"
1677 "sbc r27,__zero_reg__\n"
1679 "sbc r31,__zero_reg__\n"
1934 : :
"x"(B),
"z"(state.A)
1935 :
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
1936 "r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"memory"
1939 static const uint8_t addMod5Table[9] PROGMEM = {
1940 0, 1, 2, 3, 4, 0, 1, 2, 3
1942 #define addMod5(x, y) (pgm_read_byte(&(addMod5Table[(x) + (y)])))
1944 uint8_t index, index2;
1945 for (uint8_t round = 0; round < 24; ++round) {
1949 for (index = 0; index < 5; ++index) {
1950 B[0][index] = state.A[0][index] ^ state.A[1][index] ^
1951 state.A[2][index] ^ state.A[3][index] ^
1954 for (index = 0; index < 5; ++index) {
1955 D = B[0][addMod5(index, 4)] ^
1956 leftRotate1_64(B[0][addMod5(index, 1)]);
1957 for (index2 = 0; index2 < 5; ++index2)
1958 state.A[index2][index] ^= D;
1963 B[0][0] = state.A[0][0];
1964 B[1][0] = leftRotate28_64(state.A[0][3]);
1965 B[2][0] = leftRotate1_64 (state.A[0][1]);
1966 B[3][0] = leftRotate27_64(state.A[0][4]);
1967 B[4][0] = leftRotate62_64(state.A[0][2]);
1968 B[0][1] = leftRotate44_64(state.A[1][1]);
1969 B[1][1] = leftRotate20_64(state.A[1][4]);
1970 B[2][1] = leftRotate6_64 (state.A[1][2]);
1971 B[3][1] = leftRotate36_64(state.A[1][0]);
1972 B[4][1] = leftRotate55_64(state.A[1][3]);
1973 B[0][2] = leftRotate43_64(state.A[2][2]);
1974 B[1][2] = leftRotate3_64 (state.A[2][0]);
1975 B[2][2] = leftRotate25_64(state.A[2][3]);
1976 B[3][2] = leftRotate10_64(state.A[2][1]);
1977 B[4][2] = leftRotate39_64(state.A[2][4]);
1978 B[0][3] = leftRotate21_64(state.A[3][3]);
1979 B[1][3] = leftRotate45_64(state.A[3][1]);
1980 B[2][3] = leftRotate8_64 (state.A[3][4]);
1981 B[3][3] = leftRotate15_64(state.A[3][2]);
1982 B[4][3] = leftRotate41_64(state.A[3][0]);
1983 B[0][4] = leftRotate14_64(state.A[4][4]);
1984 B[1][4] = leftRotate61_64(state.A[4][2]);
1985 B[2][4] = leftRotate18_64(state.A[4][0]);
1986 B[3][4] = leftRotate56_64(state.A[4][3]);
1987 B[4][4] = leftRotate2_64 (state.A[4][1]);
1990 for (index = 0; index < 5; ++index) {
1991 for (index2 = 0; index2 < 5; ++index2) {
1992 state.A[index2][index] =
1994 ((~B[index2][addMod5(index, 1)]) &
1995 B[index2][addMod5(index, 2)]);
2001 static uint64_t
const RC[24] PROGMEM = {
2002 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL,
2003 0x8000000080008000ULL, 0x000000000000808BULL, 0x0000000080000001ULL,
2004 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008AULL,
2005 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL,
2006 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL,
2007 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
2008 0x000000000000800AULL, 0x800000008000000AULL, 0x8000000080008081ULL,
2009 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
2011 state.A[0][0] ^= pgm_read_qword(RC + round);
size_t blockSize() const
Returns the input block size for the sponge function in bytes.
~KeccakCore()
Destroys this Keccak sponge function after clearing all sensitive information.
void reset()
Resets the Keccak sponge function ready for a new session.
KeccakCore()
Constructs a new Keccak sponge function.
void pad(uint8_t tag)
Pads the last block of input data to blockSize().
size_t capacity() const
Returns the capacity of the sponge function in bits.
void update(const void *data, size_t size)
Updates the Keccak sponge function with more input data.
void extract(void *data, size_t size)
Extracts data from the Keccak sponge function.
void setCapacity(size_t capacity)
Sets the capacity of the Keccak sponge function in bits.
void encrypt(void *output, const void *input, size_t size)
Extracts data from the Keccak sponge function and uses it to encrypt a buffer.
void clear()
Clears all sensitive data from this object.
void setHMACKey(const void *key, size_t len, uint8_t pad, size_t hashSize)
Sets a HMAC key for a Keccak-based hash algorithm.