23 #include "KeccakCore.h"
25 #include "utility/EndianUtil.h"
26 #include "utility/RotateUtil.h"
27 #include "utility/ProgMemUtil.h"
52 memset(state.A, 0,
sizeof(state.A));
73 return 1600 - ((size_t)_blockSize) * 8;
111 memset(state.A, 0,
sizeof(state.A));
113 state.outputSize = 0;
131 state.outputSize = 0;
134 const uint8_t *d = (
const uint8_t *)data;
135 #if !defined(CRYPTO_LITTLE_ENDIAN)
136 uint64_t *Awords = &(state.A[0][0]);
137 uint8_t index, index2;
140 uint8_t len = _blockSize - state.inputSize;
143 #if defined(CRYPTO_LITTLE_ENDIAN)
144 uint8_t *Abytes = ((uint8_t *)state.A) + state.inputSize;
145 for (uint8_t posn = 0; posn < len; ++posn)
146 Abytes[posn] ^= d[posn];
148 index2 = state.inputSize;
149 for (index = 0; index < len; ++index) {
150 Awords[index2 / 8] ^= (((uint64_t)d[index]) << ((index2 % 8) * 8));
154 state.inputSize += len;
157 if (state.inputSize == _blockSize) {
181 uint8_t size = state.inputSize;
182 uint64_t *Awords = &(state.A[0][0]);
183 Awords[size / 8] ^= (((uint64_t)tag) << ((size % 8) * 8));
184 Awords[(_blockSize - 1) / 8] ^= 0x8000000000000000ULL;
187 state.outputSize = 0;
203 #if !defined(CRYPTO_LITTLE_ENDIAN)
204 uint8_t index, index2;
205 const uint64_t *Awords = &(state.A[0][0]);
212 uint8_t *d = (uint8_t *)data;
216 if (state.outputSize >= _blockSize) {
218 state.outputSize = 0;
222 tempSize = _blockSize - state.outputSize;
227 #if defined(CRYPTO_LITTLE_ENDIAN)
228 memcpy(d, ((uint8_t *)(state.A)) + state.outputSize, tempSize);
230 index2 = state.outputSize;
231 for (index = 0; index < tempSize; ++index) {
232 d[index] = (uint8_t)(Awords[index2 / 8] >> ((index2 % 8) * 8));
236 state.outputSize += tempSize;
253 void KeccakCore::keccakp()
255 static const uint8_t addMod5Table[9] PROGMEM = {
256 0, 1, 2, 3, 4, 0, 1, 2, 3
258 #define addMod5(x, y) (pgm_read_byte(&(addMod5Table[(x) + (y)])))
260 uint8_t index, index2;
261 for (uint8_t round = 0; round < 24; ++round) {
265 for (index = 0; index < 5; ++index) {
266 state.B[0][index] = state.A[0][index] ^ state.A[1][index] ^
267 state.A[2][index] ^ state.A[3][index] ^
270 for (index = 0; index < 5; ++index) {
271 D = state.B[0][addMod5(index, 4)] ^
272 leftRotate1_64(state.B[0][addMod5(index, 1)]);
273 for (index2 = 0; index2 < 5; ++index2)
274 state.A[index2][index] ^= D;
279 state.B[0][0] = state.A[0][0];
280 state.B[1][0] = leftRotate28_64(state.A[0][3]);
281 state.B[2][0] = leftRotate1_64 (state.A[0][1]);
282 state.B[3][0] = leftRotate27_64(state.A[0][4]);
283 state.B[4][0] = leftRotate62_64(state.A[0][2]);
284 state.B[0][1] = leftRotate44_64(state.A[1][1]);
285 state.B[1][1] = leftRotate20_64(state.A[1][4]);
286 state.B[2][1] = leftRotate6_64 (state.A[1][2]);
287 state.B[3][1] = leftRotate36_64(state.A[1][0]);
288 state.B[4][1] = leftRotate55_64(state.A[1][3]);
289 state.B[0][2] = leftRotate43_64(state.A[2][2]);
290 state.B[1][2] = leftRotate3_64 (state.A[2][0]);
291 state.B[2][2] = leftRotate25_64(state.A[2][3]);
292 state.B[3][2] = leftRotate10_64(state.A[2][1]);
293 state.B[4][2] = leftRotate39_64(state.A[2][4]);
294 state.B[0][3] = leftRotate21_64(state.A[3][3]);
295 state.B[1][3] = leftRotate45_64(state.A[3][1]);
296 state.B[2][3] = leftRotate8_64 (state.A[3][4]);
297 state.B[3][3] = leftRotate15_64(state.A[3][2]);
298 state.B[4][3] = leftRotate41_64(state.A[3][0]);
299 state.B[0][4] = leftRotate14_64(state.A[4][4]);
300 state.B[1][4] = leftRotate61_64(state.A[4][2]);
301 state.B[2][4] = leftRotate18_64(state.A[4][0]);
302 state.B[3][4] = leftRotate56_64(state.A[4][3]);
303 state.B[4][4] = leftRotate2_64 (state.A[4][1]);
306 for (index = 0; index < 5; ++index) {
307 for (index2 = 0; index2 < 5; ++index2) {
308 state.A[index2][index] =
309 state.B[index2][index] ^
310 ((~state.B[index2][addMod5(index, 1)]) &
311 state.B[index2][addMod5(index, 2)]);
316 static uint64_t
const RC[24] PROGMEM = {
317 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL,
318 0x8000000080008000ULL, 0x000000000000808BULL, 0x0000000080000001ULL,
319 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008AULL,
320 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL,
321 0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL,
322 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
323 0x000000000000800AULL, 0x800000008000000AULL, 0x8000000080008081ULL,
324 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
326 state.A[0][0] ^= pgm_read_qword(RC + round);
void setCapacity(size_t capacity)
Sets the capacity of the Keccak sponge function in bits.
~KeccakCore()
Destroys this Keccak sponge function after clearing all sensitive information.
void extract(void *data, size_t size)
Extracts data from the 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.
KeccakCore()
Constructs a new Keccak sponge function.
void update(const void *data, size_t size)
Updates the Keccak sponge function with more input data.
void clear()
Clears all sensitive data from this object.
void reset()
Resets the Keccak sponge function ready for a new session.