cc395669 |
1 | /* |
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/ |
5 | |
6 | Implementation by the designers, |
7 | hereby denoted as "the implementer". |
8 | |
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/ |
12 | */ |
13 | |
14 | #include <stdio.h> |
15 | #include <string.h> |
16 | #include "brg_endian.h" |
17 | #include "displayIntermediateValues.h" |
18 | #include "KeccakNISTInterface.h" |
19 | #include "KeccakF-1600-interface.h" |
20 | |
21 | typedef unsigned char UINT8; |
22 | typedef unsigned long long int UINT64; |
23 | |
24 | #define nrRounds 24 |
25 | UINT64 KeccakRoundConstants[nrRounds]; |
26 | #define nrLanes 25 |
27 | unsigned int KeccakRhoOffsets[nrLanes]; |
28 | |
29 | void KeccakPermutationOnWords(UINT64 *state); |
30 | void theta(UINT64 *A); |
31 | void rho(UINT64 *A); |
32 | void pi(UINT64 *A); |
33 | void chi(UINT64 *A); |
34 | void iota(UINT64 *A, unsigned int indexRound); |
35 | |
36 | void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state) |
37 | { |
38 | unsigned int i, j; |
39 | |
40 | for(i=0; i<(KeccakPermutationSize/64); i++) { |
41 | stateAsWords[i] = 0; |
42 | for(j=0; j<(64/8); j++) |
43 | stateAsWords[i] |= (UINT64)(state[i*(64/8)+j]) << (8*j); |
44 | } |
45 | } |
46 | |
47 | void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords) |
48 | { |
49 | unsigned int i, j; |
50 | |
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; |
54 | } |
55 | |
56 | void KeccakPermutation(unsigned char *state) |
57 | { |
58 | #if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) |
59 | UINT64 stateAsWords[KeccakPermutationSize/64]; |
60 | #endif |
61 | |
62 | displayStateAsBytes(1, "Input of permutation", state); |
63 | #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) |
64 | KeccakPermutationOnWords((UINT64*)state); |
65 | #else |
66 | fromBytesToWords(stateAsWords, state); |
67 | KeccakPermutationOnWords(stateAsWords); |
68 | fromWordsToBytes(state, stateAsWords); |
69 | #endif |
70 | displayStateAsBytes(1, "State after permutation", state); |
71 | } |
72 | |
73 | void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes) |
74 | { |
75 | unsigned int i; |
76 | |
77 | for(i=0; i<dataLengthInBytes; i++) |
78 | state[i] ^= data[i]; |
79 | KeccakPermutation(state); |
80 | } |
81 | |
82 | void KeccakPermutationOnWords(UINT64 *state) |
83 | { |
84 | unsigned int i; |
85 | |
86 | displayStateAs64bitWords(3, "Same, with lanes as 64-bit words", state); |
87 | |
88 | for(i=0; i<nrRounds; i++) { |
89 | displayRoundNumber(3, i); |
90 | |
91 | theta(state); |
92 | displayStateAs64bitWords(3, "After theta", state); |
93 | |
94 | rho(state); |
95 | displayStateAs64bitWords(3, "After rho", state); |
96 | |
97 | pi(state); |
98 | displayStateAs64bitWords(3, "After pi", state); |
99 | |
100 | chi(state); |
101 | displayStateAs64bitWords(3, "After chi", state); |
102 | |
103 | iota(state, i); |
104 | displayStateAs64bitWords(3, "After iota", state); |
105 | } |
106 | } |
107 | |
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) |
110 | |
111 | void theta(UINT64 *A) |
112 | { |
113 | unsigned int x, y; |
114 | UINT64 C[5], D[5]; |
115 | |
116 | for(x=0; x<5; x++) { |
117 | C[x] = 0; |
118 | for(y=0; y<5; y++) |
119 | C[x] ^= A[index(x, y)]; |
120 | } |
121 | for(x=0; x<5; x++) |
122 | D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5]; |
123 | for(x=0; x<5; x++) |
124 | for(y=0; y<5; y++) |
125 | A[index(x, y)] ^= D[x]; |
126 | } |
127 | |
128 | void rho(UINT64 *A) |
129 | { |
130 | unsigned int x, y; |
131 | |
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)]); |
134 | } |
135 | |
136 | void pi(UINT64 *A) |
137 | { |
138 | unsigned int x, y; |
139 | UINT64 tempA[25]; |
140 | |
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)]; |
145 | } |
146 | |
147 | void chi(UINT64 *A) |
148 | { |
149 | unsigned int x, y; |
150 | UINT64 C[5]; |
151 | |
152 | for(y=0; y<5; y++) { |
153 | for(x=0; x<5; x++) |
154 | C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]); |
155 | for(x=0; x<5; x++) |
156 | A[index(x, y)] = C[x]; |
157 | } |
158 | } |
159 | |
160 | void iota(UINT64 *A, unsigned int indexRound) |
161 | { |
162 | A[index(0, 0)] ^= KeccakRoundConstants[indexRound]; |
163 | } |
164 | |
165 | int LFSR86540(UINT8 *LFSR) |
166 | { |
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; |
171 | else |
172 | (*LFSR) <<= 1; |
173 | return result; |
174 | } |
175 | |
176 | void KeccakInitializeRoundConstants() |
177 | { |
178 | UINT8 LFSRstate = 0x01; |
179 | unsigned int i, j, bitPosition; |
180 | |
181 | for(i=0; i<nrRounds; i++) { |
182 | KeccakRoundConstants[i] = 0; |
183 | for(j=0; j<7; j++) { |
184 | bitPosition = (1<<j)-1; //2^j-1 |
185 | if (LFSR86540(&LFSRstate)) |
186 | KeccakRoundConstants[i] ^= (UINT64)1<<bitPosition; |
187 | } |
188 | } |
189 | } |
190 | |
191 | void KeccakInitializeRhoOffsets() |
192 | { |
193 | unsigned int x, y, t, newX, newY; |
194 | |
195 | KeccakRhoOffsets[index(0, 0)] = 0; |
196 | x = 1; |
197 | y = 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; |
202 | x = newX; |
203 | y = newY; |
204 | } |
205 | } |
206 | |
207 | void KeccakInitialize() |
208 | { |
209 | KeccakInitializeRoundConstants(); |
210 | KeccakInitializeRhoOffsets(); |
211 | } |
212 | |
213 | void displayRoundConstants(FILE *f) |
214 | { |
215 | unsigned int i; |
216 | |
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)); |
221 | fprintf(f, "\n"); |
222 | } |
223 | fprintf(f, "\n"); |
224 | } |
225 | |
226 | void displayRhoOffsets(FILE *f) |
227 | { |
228 | unsigned int x, y; |
229 | |
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)]); |
233 | fprintf(f, "\n"); |
234 | } |
235 | fprintf(f, "\n"); |
236 | } |
237 | |
238 | void KeccakInitializeState(unsigned char *state) |
239 | { |
240 | memset(state, 0, KeccakPermutationSizeInBytes); |
241 | } |
242 | |
243 | #ifdef ProvideFast576 |
244 | void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data) |
245 | { |
246 | KeccakPermutationAfterXor(state, data, 72); |
247 | } |
248 | #endif |
249 | |
250 | #ifdef ProvideFast832 |
251 | void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data) |
252 | { |
253 | KeccakPermutationAfterXor(state, data, 104); |
254 | } |
255 | #endif |
256 | |
257 | #ifdef ProvideFast1024 |
258 | void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data) |
259 | { |
260 | KeccakPermutationAfterXor(state, data, 128); |
261 | } |
262 | #endif |
263 | |
264 | #ifdef ProvideFast1088 |
265 | void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data) |
266 | { |
267 | KeccakPermutationAfterXor(state, data, 136); |
268 | } |
269 | #endif |
270 | |
271 | #ifdef ProvideFast1152 |
272 | void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data) |
273 | { |
274 | KeccakPermutationAfterXor(state, data, 144); |
275 | } |
276 | #endif |
277 | |
278 | #ifdef ProvideFast1344 |
279 | void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data) |
280 | { |
281 | KeccakPermutationAfterXor(state, data, 168); |
282 | } |
283 | #endif |
284 | |
285 | void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount) |
286 | { |
287 | KeccakPermutationAfterXor(state, data, laneCount*8); |
288 | } |
289 | |
290 | #ifdef ProvideFast1024 |
291 | void KeccakExtract1024bits(const unsigned char *state, unsigned char *data) |
292 | { |
293 | memcpy(data, state, 128); |
294 | } |
295 | #endif |
296 | |
297 | void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount) |
298 | { |
299 | memcpy(data, state, laneCount*8); |
300 | } |