update binary chaff
[mobile-com.git] / DH-Keccak / assets / KremKeccak / KeccakF-1600-reference.c
CommitLineData
cc395669 1/*
2The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3Michaƫl Peeters and Gilles Van Assche. For more information, feedback or
4questions, please refer to our website: http://keccak.noekeon.org/
5
6Implementation by the designers,
7hereby denoted as "the implementer".
8
9To the extent possible under law, the implementer has waived all copyright
10and related or neighboring rights to the source code in this file.
11http://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
21typedef unsigned char UINT8;
22typedef unsigned long long int UINT64;
23
24#define nrRounds 24
25UINT64 KeccakRoundConstants[nrRounds];
26#define nrLanes 25
27unsigned int KeccakRhoOffsets[nrLanes];
28
29void KeccakPermutationOnWords(UINT64 *state);
30void theta(UINT64 *A);
31void rho(UINT64 *A);
32void pi(UINT64 *A);
33void chi(UINT64 *A);
34void iota(UINT64 *A, unsigned int indexRound);
35
36void 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
47void 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
56void 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
73void 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
82void 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
111void 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
128void 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
136void 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
147void 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
160void iota(UINT64 *A, unsigned int indexRound)
161{
162 A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
163}
164
165int 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
176void 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
191void 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
207void KeccakInitialize()
208{
209 KeccakInitializeRoundConstants();
210 KeccakInitializeRhoOffsets();
211}
212
213void 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
226void 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
238void KeccakInitializeState(unsigned char *state)
239{
240 memset(state, 0, KeccakPermutationSizeInBytes);
241}
242
243#ifdef ProvideFast576
244void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data)
245{
246 KeccakPermutationAfterXor(state, data, 72);
247}
248#endif
249
250#ifdef ProvideFast832
251void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data)
252{
253 KeccakPermutationAfterXor(state, data, 104);
254}
255#endif
256
257#ifdef ProvideFast1024
258void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data)
259{
260 KeccakPermutationAfterXor(state, data, 128);
261}
262#endif
263
264#ifdef ProvideFast1088
265void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data)
266{
267 KeccakPermutationAfterXor(state, data, 136);
268}
269#endif
270
271#ifdef ProvideFast1152
272void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data)
273{
274 KeccakPermutationAfterXor(state, data, 144);
275}
276#endif
277
278#ifdef ProvideFast1344
279void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data)
280{
281 KeccakPermutationAfterXor(state, data, 168);
282}
283#endif
284
285void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
286{
287 KeccakPermutationAfterXor(state, data, laneCount*8);
288}
289
290#ifdef ProvideFast1024
291void KeccakExtract1024bits(const unsigned char *state, unsigned char *data)
292{
293 memcpy(data, state, 128);
294}
295#endif
296
297void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
298{
299 memcpy(data, state, laneCount*8);
300}