1 /* keccak_permute_64.h - Keccak permute function (simple 64bit)
2 * Copyright (C) 2015 Jussi Kivilinna <jussi.kivilinna@iki.fi>
4 * This file is part of Libgcrypt.
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.
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.
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/>.
20 /* The code is based on public-domain/CC0 "keccakc1024/simple/Keccak-simple.c"
21 * implementation by Ronny Van Keer from SUPERCOP toolkit package.
24 /* Function that computes the Keccak-f[1600] permutation on the given state. */
26 KECCAK_F1600_PERMUTE_FUNC_NAME(KECCAK_STATE *hd)
28 const u64 *round_consts = _gcry_keccak_round_consts_64bit;
29 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 u64 *state = hd->u.state64;
73 BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
74 BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
75 BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
76 BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
77 BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
79 /* thetaRhoPiChiIotaPrepareTheta(round , A, E) */
80 Da = BCu ^ ROL64(BCe, 1);
81 De = BCa ^ ROL64(BCi, 1);
82 Di = BCe ^ ROL64(BCo, 1);
83 Do = BCi ^ ROL64(BCu, 1);
84 Du = BCo ^ ROL64(BCa, 1);
96 Eba = BCa ^ ANDN64(BCe, BCi);
97 Eba ^= *(round_consts++);
98 Ebe = BCe ^ ANDN64(BCi, BCo);
99 Ebi = BCi ^ ANDN64(BCo, BCu);
100 Ebo = BCo ^ ANDN64(BCu, BCa);
101 Ebu = BCu ^ ANDN64(BCa, BCe);
104 BCa = ROL64(Abo, 28);
106 BCe = ROL64(Agu, 20);
110 BCo = ROL64(Ame, 45);
112 BCu = ROL64(Asi, 61);
113 Ega = BCa ^ ANDN64(BCe, BCi);
114 Ege = BCe ^ ANDN64(BCi, BCo);
115 Egi = BCi ^ ANDN64(BCo, BCu);
116 Ego = BCo ^ ANDN64(BCu, BCa);
117 Egu = BCu ^ ANDN64(BCa, BCe);
124 BCi = ROL64(Ako, 25);
128 BCu = ROL64(Asa, 18);
129 Eka = BCa ^ ANDN64(BCe, BCi);
130 Eke = BCe ^ ANDN64(BCi, BCo);
131 Eki = BCi ^ ANDN64(BCo, BCu);
132 Eko = BCo ^ ANDN64(BCu, BCa);
133 Eku = BCu ^ ANDN64(BCa, BCe);
136 BCa = ROL64(Abu, 27);
138 BCe = ROL64(Aga, 36);
140 BCi = ROL64(Ake, 10);
142 BCo = ROL64(Ami, 15);
144 BCu = ROL64(Aso, 56);
145 Ema = BCa ^ ANDN64(BCe, BCi);
146 Eme = BCe ^ ANDN64(BCi, BCo);
147 Emi = BCi ^ ANDN64(BCo, BCu);
148 Emo = BCo ^ ANDN64(BCu, BCa);
149 Emu = BCu ^ ANDN64(BCa, BCe);
152 BCa = ROL64(Abi, 62);
154 BCe = ROL64(Ago, 55);
156 BCi = ROL64(Aku, 39);
158 BCo = ROL64(Ama, 41);
161 Esa = BCa ^ ANDN64(BCe, BCi);
162 Ese = BCe ^ ANDN64(BCi, BCo);
163 Esi = BCi ^ ANDN64(BCo, BCu);
164 Eso = BCo ^ ANDN64(BCu, BCa);
165 Esu = BCu ^ ANDN64(BCa, BCe);
168 BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
169 BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
170 BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
171 BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
172 BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
174 /* thetaRhoPiChiIotaPrepareTheta(round+1, E, A) */
175 Da = BCu ^ ROL64(BCe, 1);
176 De = BCa ^ ROL64(BCi, 1);
177 Di = BCe ^ ROL64(BCo, 1);
178 Do = BCi ^ ROL64(BCu, 1);
179 Du = BCo ^ ROL64(BCa, 1);
184 BCe = ROL64(Ege, 44);
186 BCi = ROL64(Eki, 43);
188 BCo = ROL64(Emo, 21);
190 BCu = ROL64(Esu, 14);
191 Aba = BCa ^ ANDN64(BCe, BCi);
192 Aba ^= *(round_consts++);
193 Abe = BCe ^ ANDN64(BCi, BCo);
194 Abi = BCi ^ ANDN64(BCo, BCu);
195 Abo = BCo ^ ANDN64(BCu, BCa);
196 Abu = BCu ^ ANDN64(BCa, BCe);
199 BCa = ROL64(Ebo, 28);
201 BCe = ROL64(Egu, 20);
205 BCo = ROL64(Eme, 45);
207 BCu = ROL64(Esi, 61);
208 Aga = BCa ^ ANDN64(BCe, BCi);
209 Age = BCe ^ ANDN64(BCi, BCo);
210 Agi = BCi ^ ANDN64(BCo, BCu);
211 Ago = BCo ^ ANDN64(BCu, BCa);
212 Agu = BCu ^ ANDN64(BCa, BCe);
219 BCi = ROL64(Eko, 25);
223 BCu = ROL64(Esa, 18);
224 Aka = BCa ^ ANDN64(BCe, BCi);
225 Ake = BCe ^ ANDN64(BCi, BCo);
226 Aki = BCi ^ ANDN64(BCo, BCu);
227 Ako = BCo ^ ANDN64(BCu, BCa);
228 Aku = BCu ^ ANDN64(BCa, BCe);
231 BCa = ROL64(Ebu, 27);
233 BCe = ROL64(Ega, 36);
235 BCi = ROL64(Eke, 10);
237 BCo = ROL64(Emi, 15);
239 BCu = ROL64(Eso, 56);
240 Ama = BCa ^ ANDN64(BCe, BCi);
241 Ame = BCe ^ ANDN64(BCi, BCo);
242 Ami = BCi ^ ANDN64(BCo, BCu);
243 Amo = BCo ^ ANDN64(BCu, BCa);
244 Amu = BCu ^ ANDN64(BCa, BCe);
247 BCa = ROL64(Ebi, 62);
249 BCe = ROL64(Ego, 55);
251 BCi = ROL64(Eku, 39);
253 BCo = ROL64(Ema, 41);
256 Asa = BCa ^ ANDN64(BCe, BCi);
257 Ase = BCe ^ ANDN64(BCi, BCo);
258 Asi = BCi ^ ANDN64(BCo, BCu);
259 Aso = BCo ^ ANDN64(BCu, BCa);
260 Asu = BCu ^ ANDN64(BCa, BCe);
262 while (round_consts < round_consts_end);
290 return sizeof(void *) * 4 + sizeof(u64) * 12 * 5;
294 KECCAK_F1600_ABSORB_FUNC_NAME(KECCAK_STATE *hd, int pos, const byte *lanes,
295 unsigned int nlanes, int blocklanes)
297 unsigned int burn = 0;
305 while (pos == 0 && nlanes >= 21)
308 absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
309 absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
310 absorb_lanes64_4(&hd->u.state64[16], lanes); lanes += 8 * 4;
311 absorb_lanes64_1(&hd->u.state64[20], lanes); lanes += 8 * 1;
313 burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
319 while (pos == 0 && nlanes >= 18)
322 absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
323 absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
324 absorb_lanes64_2(&hd->u.state64[16], lanes); lanes += 8 * 2;
326 burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
331 /* SHA3-256 & SHAKE256 */
332 while (pos == 0 && nlanes >= 17)
335 absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
336 absorb_lanes64_8(&hd->u.state64[8], lanes); lanes += 8 * 8;
337 absorb_lanes64_1(&hd->u.state64[16], lanes); lanes += 8 * 1;
339 burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
345 while (pos == 0 && nlanes >= 13)
348 absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
349 absorb_lanes64_4(&hd->u.state64[8], lanes); lanes += 8 * 4;
350 absorb_lanes64_1(&hd->u.state64[12], lanes); lanes += 8 * 1;
352 burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
358 while (pos == 0 && nlanes >= 9)
361 absorb_lanes64_8(&hd->u.state64[0], lanes); lanes += 8 * 8;
362 absorb_lanes64_1(&hd->u.state64[8], lanes); lanes += 8 * 1;
364 burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);
371 hd->u.state64[pos] ^= buf_get_le64(lanes);
375 if (++pos == blocklanes)
377 burn = KECCAK_F1600_PERMUTE_FUNC_NAME(hd);