Line data Source code
1 : /* keccak_permute_64.h - Keccak permute function (simple 64bit)
2 : * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3 : *
4 : * This file is part of Libgcrypt.
5 : *
6 : * Libgcrypt is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser general Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * Libgcrypt is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : /* The code is based on public-domain/CC0 "keccakc1024/simple/Keccak-simple.c"
21 : * implementation by Ronny Van Keer from SUPERCOP toolkit package.
22 : */
23 :
24 : /* Function that computes the Keccak-f[1600] permutation on the given state. */
25 : static unsigned int
26 0 : KECCAK_F1600_PERMUTE_FUNC_NAME(KECCAK_STATE *hd)
27 : {
28 0 : const u64 *round_consts = _gcry_keccak_round_consts_64bit;
29 0 : const u64 *round_consts_end = _gcry_keccak_round_consts_64bit + 24;
30 : u64 Aba, Abe, Abi, Abo, Abu;
31 : u64 Aga, Age, Agi, Ago, Agu;
32 : u64 Aka, Ake, Aki, Ako, Aku;
33 : u64 Ama, Ame, Ami, Amo, Amu;
34 : u64 Asa, Ase, Asi, Aso, Asu;
35 : u64 BCa, BCe, BCi, BCo, BCu;
36 : u64 Da, De, Di, Do, Du;
37 : u64 Eba, Ebe, Ebi, Ebo, Ebu;
38 : u64 Ega, Ege, Egi, Ego, Egu;
39 : u64 Eka, Eke, Eki, Eko, Eku;
40 : u64 Ema, Eme, Emi, Emo, Emu;
41 : u64 Esa, Ese, Esi, Eso, Esu;
42 0 : u64 *state = hd->u.state64;
43 :
44 0 : Aba = state[0];
45 0 : Abe = state[1];
46 0 : Abi = state[2];
47 0 : Abo = state[3];
48 0 : Abu = state[4];
49 0 : Aga = state[5];
50 0 : Age = state[6];
51 0 : Agi = state[7];
52 0 : Ago = state[8];
53 0 : Agu = state[9];
54 0 : Aka = state[10];
55 0 : Ake = state[11];
56 0 : Aki = state[12];
57 0 : Ako = state[13];
58 0 : Aku = state[14];
59 0 : Ama = state[15];
60 0 : Ame = state[16];
61 0 : Ami = state[17];
62 0 : Amo = state[18];
63 0 : Amu = state[19];
64 0 : Asa = state[20];
65 0 : Ase = state[21];
66 0 : Asi = state[22];
67 0 : Aso = state[23];
68 0 : Asu = state[24];
69 :
70 : do
71 : {
72 : /* prepareTheta */
73 0 : BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
74 0 : BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
75 0 : BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
76 0 : BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
77 0 : BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
78 :
79 : /* thetaRhoPiChiIotaPrepareTheta(round , A, E) */
80 0 : Da = BCu ^ ROL64(BCe, 1);
81 0 : De = BCa ^ ROL64(BCi, 1);
82 0 : Di = BCe ^ ROL64(BCo, 1);
83 0 : Do = BCi ^ ROL64(BCu, 1);
84 0 : Du = BCo ^ ROL64(BCa, 1);
85 :
86 0 : Aba ^= Da;
87 0 : BCa = Aba;
88 0 : Age ^= De;
89 0 : BCe = ROL64(Age, 44);
90 0 : Aki ^= Di;
91 0 : BCi = ROL64(Aki, 43);
92 0 : Amo ^= Do;
93 0 : BCo = ROL64(Amo, 21);
94 0 : Asu ^= Du;
95 0 : BCu = ROL64(Asu, 14);
96 0 : Eba = BCa ^ ANDN64(BCe, BCi);
97 0 : Eba ^= *(round_consts++);
98 0 : Ebe = BCe ^ ANDN64(BCi, BCo);
99 0 : Ebi = BCi ^ ANDN64(BCo, BCu);
100 0 : Ebo = BCo ^ ANDN64(BCu, BCa);
101 0 : Ebu = BCu ^ ANDN64(BCa, BCe);
102 :
103 0 : Abo ^= Do;
104 0 : BCa = ROL64(Abo, 28);
105 0 : Agu ^= Du;
106 0 : BCe = ROL64(Agu, 20);
107 0 : Aka ^= Da;
108 0 : BCi = ROL64(Aka, 3);
109 0 : Ame ^= De;
110 0 : BCo = ROL64(Ame, 45);
111 0 : Asi ^= Di;
112 0 : BCu = ROL64(Asi, 61);
113 0 : Ega = BCa ^ ANDN64(BCe, BCi);
114 0 : Ege = BCe ^ ANDN64(BCi, BCo);
115 0 : Egi = BCi ^ ANDN64(BCo, BCu);
116 0 : Ego = BCo ^ ANDN64(BCu, BCa);
117 0 : Egu = BCu ^ ANDN64(BCa, BCe);
118 :
119 0 : Abe ^= De;
120 0 : BCa = ROL64(Abe, 1);
121 0 : Agi ^= Di;
122 0 : BCe = ROL64(Agi, 6);
123 0 : Ako ^= Do;
124 0 : BCi = ROL64(Ako, 25);
125 0 : Amu ^= Du;
126 0 : BCo = ROL64(Amu, 8);
127 0 : Asa ^= Da;
128 0 : BCu = ROL64(Asa, 18);
129 0 : Eka = BCa ^ ANDN64(BCe, BCi);
130 0 : Eke = BCe ^ ANDN64(BCi, BCo);
131 0 : Eki = BCi ^ ANDN64(BCo, BCu);
132 0 : Eko = BCo ^ ANDN64(BCu, BCa);
133 0 : Eku = BCu ^ ANDN64(BCa, BCe);
134 :
135 0 : Abu ^= Du;
136 0 : BCa = ROL64(Abu, 27);
137 0 : Aga ^= Da;
138 0 : BCe = ROL64(Aga, 36);
139 0 : Ake ^= De;
140 0 : BCi = ROL64(Ake, 10);
141 0 : Ami ^= Di;
142 0 : BCo = ROL64(Ami, 15);
143 0 : Aso ^= Do;
144 0 : BCu = ROL64(Aso, 56);
145 0 : Ema = BCa ^ ANDN64(BCe, BCi);
146 0 : Eme = BCe ^ ANDN64(BCi, BCo);
147 0 : Emi = BCi ^ ANDN64(BCo, BCu);
148 0 : Emo = BCo ^ ANDN64(BCu, BCa);
149 0 : Emu = BCu ^ ANDN64(BCa, BCe);
150 :
151 0 : Abi ^= Di;
152 0 : BCa = ROL64(Abi, 62);
153 0 : Ago ^= Do;
154 0 : BCe = ROL64(Ago, 55);
155 0 : Aku ^= Du;
156 0 : BCi = ROL64(Aku, 39);
157 0 : Ama ^= Da;
158 0 : BCo = ROL64(Ama, 41);
159 0 : Ase ^= De;
160 0 : BCu = ROL64(Ase, 2);
161 0 : Esa = BCa ^ ANDN64(BCe, BCi);
162 0 : Ese = BCe ^ ANDN64(BCi, BCo);
163 0 : Esi = BCi ^ ANDN64(BCo, BCu);
164 0 : Eso = BCo ^ ANDN64(BCu, BCa);
165 0 : Esu = BCu ^ ANDN64(BCa, BCe);
166 :
167 : /* prepareTheta */
168 0 : BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
169 0 : BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
170 0 : BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
171 0 : BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
172 0 : BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
173 :
174 : /* thetaRhoPiChiIotaPrepareTheta(round+1, E, A) */
175 0 : Da = BCu ^ ROL64(BCe, 1);
176 0 : De = BCa ^ ROL64(BCi, 1);
177 0 : Di = BCe ^ ROL64(BCo, 1);
178 0 : Do = BCi ^ ROL64(BCu, 1);
179 0 : Du = BCo ^ ROL64(BCa, 1);
180 :
181 0 : Eba ^= Da;
182 0 : BCa = Eba;
183 0 : Ege ^= De;
184 0 : BCe = ROL64(Ege, 44);
185 0 : Eki ^= Di;
186 0 : BCi = ROL64(Eki, 43);
187 0 : Emo ^= Do;
188 0 : BCo = ROL64(Emo, 21);
189 0 : Esu ^= Du;
190 0 : BCu = ROL64(Esu, 14);
191 0 : Aba = BCa ^ ANDN64(BCe, BCi);
192 0 : Aba ^= *(round_consts++);
193 0 : Abe = BCe ^ ANDN64(BCi, BCo);
194 0 : Abi = BCi ^ ANDN64(BCo, BCu);
195 0 : Abo = BCo ^ ANDN64(BCu, BCa);
196 0 : Abu = BCu ^ ANDN64(BCa, BCe);
197 :
198 0 : Ebo ^= Do;
199 0 : BCa = ROL64(Ebo, 28);
200 0 : Egu ^= Du;
201 0 : BCe = ROL64(Egu, 20);
202 0 : Eka ^= Da;
203 0 : BCi = ROL64(Eka, 3);
204 0 : Eme ^= De;
205 0 : BCo = ROL64(Eme, 45);
206 0 : Esi ^= Di;
207 0 : BCu = ROL64(Esi, 61);
208 0 : Aga = BCa ^ ANDN64(BCe, BCi);
209 0 : Age = BCe ^ ANDN64(BCi, BCo);
210 0 : Agi = BCi ^ ANDN64(BCo, BCu);
211 0 : Ago = BCo ^ ANDN64(BCu, BCa);
212 0 : Agu = BCu ^ ANDN64(BCa, BCe);
213 :
214 0 : Ebe ^= De;
215 0 : BCa = ROL64(Ebe, 1);
216 0 : Egi ^= Di;
217 0 : BCe = ROL64(Egi, 6);
218 0 : Eko ^= Do;
219 0 : BCi = ROL64(Eko, 25);
220 0 : Emu ^= Du;
221 0 : BCo = ROL64(Emu, 8);
222 0 : Esa ^= Da;
223 0 : BCu = ROL64(Esa, 18);
224 0 : Aka = BCa ^ ANDN64(BCe, BCi);
225 0 : Ake = BCe ^ ANDN64(BCi, BCo);
226 0 : Aki = BCi ^ ANDN64(BCo, BCu);
227 0 : Ako = BCo ^ ANDN64(BCu, BCa);
228 0 : Aku = BCu ^ ANDN64(BCa, BCe);
229 :
230 0 : Ebu ^= Du;
231 0 : BCa = ROL64(Ebu, 27);
232 0 : Ega ^= Da;
233 0 : BCe = ROL64(Ega, 36);
234 0 : Eke ^= De;
235 0 : BCi = ROL64(Eke, 10);
236 0 : Emi ^= Di;
237 0 : BCo = ROL64(Emi, 15);
238 0 : Eso ^= Do;
239 0 : BCu = ROL64(Eso, 56);
240 0 : Ama = BCa ^ ANDN64(BCe, BCi);
241 0 : Ame = BCe ^ ANDN64(BCi, BCo);
242 0 : Ami = BCi ^ ANDN64(BCo, BCu);
243 0 : Amo = BCo ^ ANDN64(BCu, BCa);
244 0 : Amu = BCu ^ ANDN64(BCa, BCe);
245 :
246 0 : Ebi ^= Di;
247 0 : BCa = ROL64(Ebi, 62);
248 0 : Ego ^= Do;
249 0 : BCe = ROL64(Ego, 55);
250 0 : Eku ^= Du;
251 0 : BCi = ROL64(Eku, 39);
252 0 : Ema ^= Da;
253 0 : BCo = ROL64(Ema, 41);
254 0 : Ese ^= De;
255 0 : BCu = ROL64(Ese, 2);
256 0 : Asa = BCa ^ ANDN64(BCe, BCi);
257 0 : Ase = BCe ^ ANDN64(BCi, BCo);
258 0 : Asi = BCi ^ ANDN64(BCo, BCu);
259 0 : Aso = BCo ^ ANDN64(BCu, BCa);
260 0 : Asu = BCu ^ ANDN64(BCa, BCe);
261 : }
262 0 : while (round_consts < round_consts_end);
263 :
264 0 : state[0] = Aba;
265 0 : state[1] = Abe;
266 0 : state[2] = Abi;
267 0 : state[3] = Abo;
268 0 : state[4] = Abu;
269 0 : state[5] = Aga;
270 0 : state[6] = Age;
271 0 : state[7] = Agi;
272 0 : state[8] = Ago;
273 0 : state[9] = Agu;
274 0 : state[10] = Aka;
275 0 : state[11] = Ake;
276 0 : state[12] = Aki;
277 0 : state[13] = Ako;
278 0 : state[14] = Aku;
279 0 : state[15] = Ama;
280 0 : state[16] = Ame;
281 0 : state[17] = Ami;
282 0 : state[18] = Amo;
283 0 : state[19] = Amu;
284 0 : state[20] = Asa;
285 0 : state[21] = Ase;
286 0 : state[22] = Asi;
287 0 : state[23] = Aso;
288 0 : state[24] = Asu;
289 :
290 0 : return sizeof(void *) * 4 + sizeof(u64) * 12 * 5;
291 : }
292 :
293 : static unsigned int
294 0 : KECCAK_F1600_ABSORB_FUNC_NAME(KECCAK_STATE *hd, int pos, const byte *lanes,
295 : unsigned int nlanes, int blocklanes)
296 : {
297 0 : unsigned int burn = 0;
298 :
299 0 : while (nlanes)
300 : {
301 0 : switch (blocklanes)
302 : {
303 : case 21:
304 : /* SHAKE128 */
305 0 : while (pos == 0 && nlanes >= 21)
306 : {
307 0 : nlanes -= 21;
308 0 : absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
309 0 : absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
310 0 : absorb_lanes64_4(&hd->u.state64[16], lanes); lanes += 8 * 4;
311 0 : absorb_lanes64_1(&hd->u.state64[20], lanes); lanes += 8 * 1;
312 :
313 0 : burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
314 : }
315 0 : break;
316 :
317 : case 18:
318 : /* SHA3-224 */
319 0 : while (pos == 0 && nlanes >= 18)
320 : {
321 0 : nlanes -= 18;
322 0 : absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
323 0 : absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
324 0 : absorb_lanes64_2(&hd->u.state64[16], lanes); lanes += 8 * 2;
325 :
326 0 : burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
327 : }
328 0 : break;
329 :
330 : case 17:
331 : /* SHA3-256 & SHAKE256 */
332 0 : while (pos == 0 && nlanes >= 17)
333 : {
334 0 : nlanes -= 17;
335 0 : absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
336 0 : absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
337 0 : absorb_lanes64_1(&hd->u.state64[16], lanes); lanes += 8 * 1;
338 :
339 0 : burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
340 : }
341 0 : break;
342 :
343 : case 13:
344 : /* SHA3-384 */
345 0 : while (pos == 0 && nlanes >= 13)
346 : {
347 0 : nlanes -= 13;
348 0 : absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
349 0 : absorb_lanes64_4(&hd->u.state64[8], lanes); lanes += 8 * 4;
350 0 : absorb_lanes64_1(&hd->u.state64[12], lanes); lanes += 8 * 1;
351 :
352 0 : burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
353 : }
354 0 : break;
355 :
356 : case 9:
357 : /* SHA3-512 */
358 0 : while (pos == 0 && nlanes >= 9)
359 : {
360 0 : nlanes -= 9;
361 0 : absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
362 0 : absorb_lanes64_1(&hd->u.state64[8], lanes); lanes += 8 * 1;
363 :
364 0 : burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
365 : }
366 0 : break;
367 : }
368 :
369 0 : while (nlanes)
370 : {
371 0 : hd->u.state64[pos] ^= buf_get_le64(lanes);
372 0 : lanes += 8;
373 0 : nlanes--;
374 :
375 0 : if (++pos == blocklanes)
376 : {
377 0 : burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
378 0 : pos = 0;
379 0 : break;
380 : }
381 : }
382 : }
383 :
384 0 : return burn;
385 : }
|