2 The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3 Michaƫl Peeters and Gilles Van Assche. For more information, feedback or
4 questions, please refer to our website: http://keccak.noekeon.org/
6 Implementation by the designers,
7 hereby denoted as "the implementer".
9 To the extent possible under law, the implementer has waived all copyright
10 and related or neighboring rights to the source code in this file.
11 http://creativecommons.org/publicdomain/zero/1.0/
16 #include "brg_endian.h"
17 #include "displayIntermediateValues.h"
18 #include "KeccakNISTInterface.h"
19 #include "KeccakF-1600-interface.h"
21 typedef unsigned char UINT8
;
22 typedef unsigned long long int UINT64
;
25 UINT64 KeccakRoundConstants
[nrRounds
];
27 unsigned int KeccakRhoOffsets
[nrLanes
];
29 void KeccakPermutationOnWords(UINT64
*state
);
30 void theta(UINT64
*A
);
34 void iota(UINT64
*A
, unsigned int indexRound
);
36 void fromBytesToWords(UINT64
*stateAsWords
, const unsigned char *state
)
40 for(i
=0; i
<(KeccakPermutationSize
/64); i
++) {
42 for(j
=0; j
<(64/8); j
++)
43 stateAsWords
[i
] |= (UINT64
)(state
[i
*(64/8)+j
]) << (8*j
);
47 void fromWordsToBytes(unsigned char *state
, const UINT64
*stateAsWords
)
51 for(i
=0; i
<(KeccakPermutationSize
/64); i
++)
52 for(j
=0; j
<(64/8); j
++)
53 state
[i
*(64/8)+j
] = (stateAsWords
[i
] >> (8*j
)) & 0xFF;
56 void KeccakPermutation(unsigned char *state
)
58 #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
59 UINT64 stateAsWords
[KeccakPermutationSize
/64];
62 displayStateAsBytes(1, "Input of permutation", state
);
63 #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
64 KeccakPermutationOnWords((UINT64
*)state
);
66 fromBytesToWords(stateAsWords
, state
);
67 KeccakPermutationOnWords(stateAsWords
);
68 fromWordsToBytes(state
, stateAsWords
);
70 displayStateAsBytes(1, "State after permutation", state
);
73 void KeccakPermutationAfterXor(unsigned char *state
, const unsigned char *data
, unsigned int dataLengthInBytes
)
77 for(i
=0; i
<dataLengthInBytes
; i
++)
79 KeccakPermutation(state
);
82 void KeccakPermutationOnWords(UINT64
*state
)
86 displayStateAs64bitWords(3, "Same, with lanes as 64-bit words", state
);
88 for(i
=0; i
<nrRounds
; i
++) {
89 displayRoundNumber(3, i
);
92 displayStateAs64bitWords(3, "After theta", state
);
95 displayStateAs64bitWords(3, "After rho", state
);
98 displayStateAs64bitWords(3, "After pi", state
);
101 displayStateAs64bitWords(3, "After chi", state
);
104 displayStateAs64bitWords(3, "After iota", state
);
108 #define index(x, y) (((x)%5)+5*((y)%5))
109 #define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a)
111 void theta(UINT64
*A
)
119 C
[x
] ^= A
[index(x
, y
)];
122 D
[x
] = ROL64(C
[(x
+1)%5
], 1) ^ C
[(x
+4)%5
];
125 A
[index(x
, y
)] ^= D
[x
];
132 for(x
=0; x
<5; x
++) for(y
=0; y
<5; y
++)
133 A
[index(x
, y
)] = ROL64(A
[index(x
, y
)], KeccakRhoOffsets
[index(x
, y
)]);
141 for(x
=0; x
<5; x
++) for(y
=0; y
<5; y
++)
142 tempA
[index(x
, y
)] = A
[index(x
, y
)];
143 for(x
=0; x
<5; x
++) for(y
=0; y
<5; y
++)
144 A
[index(0*x
+1*y
, 2*x
+3*y
)] = tempA
[index(x
, y
)];
154 C
[x
] = A
[index(x
, y
)] ^ ((~A
[index(x
+1, y
)]) & A
[index(x
+2, y
)]);
156 A
[index(x
, y
)] = C
[x
];
160 void iota(UINT64
*A
, unsigned int indexRound
)
162 A
[index(0, 0)] ^= KeccakRoundConstants
[indexRound
];
165 int LFSR86540(UINT8
*LFSR
)
167 int result
= ((*LFSR
) & 0x01) != 0;
168 if (((*LFSR
) & 0x80) != 0)
169 // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
170 (*LFSR
) = ((*LFSR
) << 1) ^ 0x71;
176 void KeccakInitializeRoundConstants()
178 UINT8 LFSRstate
= 0x01;
179 unsigned int i
, j
, bitPosition
;
181 for(i
=0; i
<nrRounds
; i
++) {
182 KeccakRoundConstants
[i
] = 0;
184 bitPosition
= (1<<j
)-1; //2^j-1
185 if (LFSR86540(&LFSRstate
))
186 KeccakRoundConstants
[i
] ^= (UINT64
)1<<bitPosition
;
191 void KeccakInitializeRhoOffsets()
193 unsigned int x
, y
, t
, newX
, newY
;
195 KeccakRhoOffsets
[index(0, 0)] = 0;
198 for(t
=0; t
<24; t
++) {
199 KeccakRhoOffsets
[index(x
, y
)] = ((t
+1)*(t
+2)/2) % 64;
200 newX
= (0*x
+1*y
) % 5;
201 newY
= (2*x
+3*y
) % 5;
207 void KeccakInitialize()
209 KeccakInitializeRoundConstants();
210 KeccakInitializeRhoOffsets();
213 void displayRoundConstants(FILE *f
)
217 for(i
=0; i
<nrRounds
; i
++) {
218 fprintf(f
, "RC[%02i][0][0] = ", i
);
219 fprintf(f
, "%08X", (unsigned int)(KeccakRoundConstants
[i
] >> 32));
220 fprintf(f
, "%08X", (unsigned int)(KeccakRoundConstants
[i
] & 0xFFFFFFFFULL
));
226 void displayRhoOffsets(FILE *f
)
230 for(y
=0; y
<5; y
++) for(x
=0; x
<5; x
++) {
231 fprintf(f
, "RhoOffset[%i][%i] = ", x
, y
);
232 fprintf(f
, "%2i", KeccakRhoOffsets
[index(x
, y
)]);
238 void KeccakInitializeState(unsigned char *state
)
240 memset(state
, 0, KeccakPermutationSizeInBytes
);
243 #ifdef ProvideFast576
244 void KeccakAbsorb576bits(unsigned char *state
, const unsigned char *data
)
246 KeccakPermutationAfterXor(state
, data
, 72);
250 #ifdef ProvideFast832
251 void KeccakAbsorb832bits(unsigned char *state
, const unsigned char *data
)
253 KeccakPermutationAfterXor(state
, data
, 104);
257 #ifdef ProvideFast1024
258 void KeccakAbsorb1024bits(unsigned char *state
, const unsigned char *data
)
260 KeccakPermutationAfterXor(state
, data
, 128);
264 #ifdef ProvideFast1088
265 void KeccakAbsorb1088bits(unsigned char *state
, const unsigned char *data
)
267 KeccakPermutationAfterXor(state
, data
, 136);
271 #ifdef ProvideFast1152
272 void KeccakAbsorb1152bits(unsigned char *state
, const unsigned char *data
)
274 KeccakPermutationAfterXor(state
, data
, 144);
278 #ifdef ProvideFast1344
279 void KeccakAbsorb1344bits(unsigned char *state
, const unsigned char *data
)
281 KeccakPermutationAfterXor(state
, data
, 168);
285 void KeccakAbsorb(unsigned char *state
, const unsigned char *data
, unsigned int laneCount
)
287 KeccakPermutationAfterXor(state
, data
, laneCount
*8);
290 #ifdef ProvideFast1024
291 void KeccakExtract1024bits(const unsigned char *state
, unsigned char *data
)
293 memcpy(data
, state
, 128);
297 void KeccakExtract(const unsigned char *state
, unsigned char *data
, unsigned int laneCount
)
299 memcpy(data
, state
, laneCount
*8);