/src/libgcrypt/cipher/mceliece6688128f.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* mceliece6688128f.c - Classic McEliece for libgcrypt |
2 | | * Copyright (C) 2023-2024 Simon Josefsson <simon@josefsson.org> |
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 <https://www.gnu.org/licenses/>. |
18 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
19 | | * |
20 | | */ |
21 | | |
22 | | /* This file is extracted from libmceliece. */ |
23 | | |
24 | | /* |
25 | | * libmceliece is hereby placed into the public domain. |
26 | | * |
27 | | * [SPDX-License-Identifier](https://spdx.dev/ids/): |
28 | | * [LicenseRef-PD-hp](https://cr.yp.to/spdx.html) |
29 | | * OR |
30 | | * [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) |
31 | | * OR |
32 | | * [0BSD](https://spdx.org/licenses/0BSD.html) |
33 | | * OR |
34 | | * [MIT-0](https://spdx.org/licenses/MIT-0.html) |
35 | | * OR |
36 | | * [MIT](https://spdx.org/licenses/MIT.html) |
37 | | * |
38 | | * libmceliece is based on the official Classic McEliece software, which |
39 | | * was written by Tung Chou. See the following papers for the major |
40 | | * algorithms used for speed inside that software: |
41 | | * |
42 | | * * Daniel J. Bernstein, Tung Chou, Peter Schwabe. "McBits: fast |
43 | | * constant-time code-based cryptography." CHES 2013. |
44 | | * [https://tungchou.github.io/papers/mcbits.pdf](https://tungchou.github.io/papers/mcbits.pdf) |
45 | | * |
46 | | * * Tung Chou. "McBits revisited." CHES 2017. |
47 | | * [https://tungchou.github.io/papers/mcbits_revisited.pdf](https://tungchou.github.io/papers/mcbits_revisited.pdf) |
48 | | * |
49 | | * The official Classic McEliece software includes `ref`, `vec`, `sse`, and |
50 | | * `avx` implementations; libmceliece includes only `vec` and `avx`. |
51 | | * |
52 | | * The following components of libmceliece are from Daniel J. Bernstein: |
53 | | * |
54 | | * * Small [changes](download.html#changelog) |
55 | | * for namespacing, portability, etc. |
56 | | * |
57 | | * * Software to compute control bits (also used in the official software). |
58 | | * See the following paper: Daniel J. Bernstein. "Verified fast formulas |
59 | | * for control bits for permutation networks." 2020. |
60 | | * [https://cr.yp.to/papers.html#controlbits](https://cr.yp.to/papers.html#controlbits) |
61 | | * |
62 | | * * `crypto_sort/int32`. See [https://sorting.cr.yp.to](https://sorting.cr.yp.to). |
63 | | * |
64 | | * * Infrastructure to build a library with automatic run-time selection of |
65 | | * implementations based on the run-time CPU and a database of |
66 | | * benchmarks. This infrastructure was introduced in |
67 | | * [`lib25519`](https://lib25519.cr.yp.to), with some extensions and |
68 | | * adaptations in libmceliece. |
69 | | * |
70 | | * * Various software for tests and benchmarks. This is based on |
71 | | * public-domain code in the SUPERCOP benchmarking framework. |
72 | | * |
73 | | * This file is generated by mceliece6688128f.sh from these files: |
74 | | * |
75 | | * libmceliece-20230612/include-build/crypto_declassify.h |
76 | | * libmceliece-20230612/crypto_kem/6688128f/vec/params.h |
77 | | * libmceliece-20230612/inttypes/crypto_intN.h |
78 | | * libmceliece-20230612/inttypes/crypto_intN.h |
79 | | * libmceliece-20230612/inttypes/crypto_intN.h |
80 | | * libmceliece-20230612/inttypes/crypto_uintN.h |
81 | | * libmceliece-20230612/inttypes/crypto_uintN.h |
82 | | * libmceliece-20230612/inttypes/crypto_uintN.h |
83 | | * libmceliece-20230612/crypto_kem/6688128f/vec/vec.h |
84 | | * libmceliece-20230612/crypto_kem/6688128f/vec/benes.h |
85 | | * libmceliece-20230612/crypto_kem/6688128f/vec/bm.h |
86 | | * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h |
87 | | * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h |
88 | | * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h |
89 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h |
90 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft.h |
91 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h |
92 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h |
93 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h |
94 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h |
95 | | * libmceliece-20230612/crypto_kem/6688128f/vec/gf.h |
96 | | * libmceliece-20230612/crypto_kem/6688128f/vec/hash.h |
97 | | * libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h |
98 | | * libmceliece-20230612/crypto_kem/6688128f/vec/operations.h |
99 | | * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h |
100 | | * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h |
101 | | * libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h |
102 | | * libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h |
103 | | * libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h |
104 | | * libmceliece-20230612/crypto_kem/6688128f/vec/util.h |
105 | | * libmceliece-20230612/crypto_kem/6688128f/vec/benes.c |
106 | | * libmceliece-20230612/crypto_kem/6688128f/vec/bm.c |
107 | | * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c |
108 | | * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c |
109 | | * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c |
110 | | * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c |
111 | | * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c |
112 | | * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c |
113 | | * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c |
114 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft.c |
115 | | * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c |
116 | | * libmceliece-20230612/crypto_kem/6688128f/vec/gf.c |
117 | | * libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c |
118 | | * libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c |
119 | | * libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c |
120 | | * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c |
121 | | * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c |
122 | | * libmceliece-20230612/crypto_kem/6688128f/vec/vec.c |
123 | | * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c |
124 | | * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c |
125 | | * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c |
126 | | * |
127 | | */ |
128 | | |
129 | | #ifdef HAVE_CONFIG_H |
130 | | #include <config.h> |
131 | | #endif |
132 | | |
133 | | #include "g10lib.h" |
134 | | #include "mceliece6688128f.h" |
135 | | |
136 | | #define int8 crypto_int8 |
137 | | #define uint8 crypto_uint8 |
138 | 0 | #define int16 crypto_int16 |
139 | | #define uint16 crypto_uint16 |
140 | 0 | #define int32 crypto_int32 |
141 | | #define uint32 crypto_uint32 |
142 | | #define int64 crypto_int64 |
143 | | #define uint64 crypto_uint64 |
144 | | |
145 | | static void |
146 | | randombytes (uint8_t *out, size_t outlen) |
147 | 0 | { |
148 | 0 | _gcry_randomize (out, outlen, GCRY_STRONG_RANDOM); |
149 | 0 | } |
150 | | |
151 | | /* from libmceliece-20230612/include-build/crypto_declassify.h */ |
152 | | #ifndef crypto_declassify_h |
153 | | #define crypto_declassify_h |
154 | | |
155 | 0 | static void crypto_declassify(void *crypto_declassify_v,long long crypto_declassify_vlen) { |
156 | 0 | (void) crypto_declassify_v; |
157 | 0 | (void) crypto_declassify_vlen; |
158 | 0 | } |
159 | | |
160 | | #endif |
161 | | |
162 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/params.h */ |
163 | | #ifndef PARAMS_H |
164 | | #define PARAMS_H |
165 | | |
166 | 0 | #define GFBITS 13 |
167 | 0 | #define SYS_N 6688 |
168 | 0 | #define SYS_T 128 |
169 | | |
170 | 0 | #define COND_BYTES ((1 << (GFBITS-4))*(2*GFBITS - 1)) |
171 | 0 | #define IRR_BYTES (SYS_T * 2) |
172 | | |
173 | 0 | #define PK_NROWS (SYS_T*GFBITS) |
174 | 0 | #define PK_NCOLS (SYS_N - PK_NROWS) |
175 | 0 | #define PK_ROW_BYTES ((PK_NCOLS + 7)/8) |
176 | | |
177 | 0 | #define SYND_BYTES ((PK_NROWS + 7)/8) |
178 | | |
179 | 0 | #define GFMASK ((1 << GFBITS) - 1) |
180 | | |
181 | | #endif |
182 | | |
183 | | |
184 | | /* from libmceliece-20230612/inttypes/crypto_intN.h */ |
185 | | #ifndef crypto_int64_h |
186 | | #define crypto_int64_h |
187 | | |
188 | | #define crypto_int64 int64_t |
189 | | |
190 | | GCC_ATTR_UNUSED |
191 | | static crypto_int64 crypto_int64_negative_mask(crypto_int64 crypto_int64_x) |
192 | 0 | { |
193 | 0 | return crypto_int64_x >> (64-1); |
194 | 0 | } |
195 | | |
196 | | GCC_ATTR_UNUSED |
197 | | static crypto_int64 crypto_int64_nonzero_mask(crypto_int64 crypto_int64_x) |
198 | 0 | { |
199 | 0 | return crypto_int64_negative_mask(crypto_int64_x) | crypto_int64_negative_mask(-crypto_int64_x); |
200 | 0 | } |
201 | | |
202 | | GCC_ATTR_UNUSED |
203 | | static crypto_int64 crypto_int64_zero_mask(crypto_int64 crypto_int64_x) |
204 | 0 | { |
205 | 0 | return ~crypto_int64_nonzero_mask(crypto_int64_x); |
206 | 0 | } |
207 | | |
208 | | GCC_ATTR_UNUSED |
209 | | static crypto_int64 crypto_int64_positive_mask(crypto_int64 crypto_int64_x) |
210 | 0 | { |
211 | 0 | crypto_int64 crypto_int64_z = -crypto_int64_x; |
212 | 0 | crypto_int64_z ^= crypto_int64_x & crypto_int64_z; |
213 | 0 | return crypto_int64_negative_mask(crypto_int64_z); |
214 | 0 | } |
215 | | |
216 | | GCC_ATTR_UNUSED |
217 | | static crypto_int64 crypto_int64_unequal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) |
218 | 0 | { |
219 | 0 | crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y; |
220 | 0 | return crypto_int64_nonzero_mask(crypto_int64_xy); |
221 | 0 | } |
222 | | |
223 | | GCC_ATTR_UNUSED |
224 | | static crypto_int64 crypto_int64_equal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) |
225 | 0 | { |
226 | 0 | return ~crypto_int64_unequal_mask(crypto_int64_x,crypto_int64_y); |
227 | 0 | } |
228 | | |
229 | | GCC_ATTR_UNUSED |
230 | | static crypto_int64 crypto_int64_smaller_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) |
231 | 0 | { |
232 | 0 | crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y; |
233 | 0 | crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y; |
234 | 0 | crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_x); |
235 | 0 | return crypto_int64_negative_mask(crypto_int64_z); |
236 | 0 | } |
237 | | |
238 | | GCC_ATTR_UNUSED |
239 | | static crypto_int64 crypto_int64_min(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) |
240 | 0 | { |
241 | 0 | crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x; |
242 | 0 | crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; |
243 | 0 | crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y); |
244 | 0 | crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); |
245 | 0 | crypto_int64_z &= crypto_int64_xy; |
246 | 0 | return crypto_int64_x ^ crypto_int64_z; |
247 | 0 | } |
248 | | |
249 | | GCC_ATTR_UNUSED |
250 | | static crypto_int64 crypto_int64_max(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) |
251 | 0 | { |
252 | 0 | crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x; |
253 | 0 | crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; |
254 | 0 | crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y); |
255 | 0 | crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); |
256 | 0 | crypto_int64_z &= crypto_int64_xy; |
257 | 0 | return crypto_int64_y ^ crypto_int64_z; |
258 | 0 | } |
259 | | |
260 | | GCC_ATTR_UNUSED |
261 | | static void crypto_int64_minmax(crypto_int64 *crypto_int64_a,crypto_int64 *crypto_int64_b) |
262 | 0 | { |
263 | 0 | crypto_int64 crypto_int64_x = *crypto_int64_a; |
264 | 0 | crypto_int64 crypto_int64_y = *crypto_int64_b; |
265 | 0 | crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x; |
266 | 0 | crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; |
267 | 0 | crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y); |
268 | 0 | crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); |
269 | 0 | crypto_int64_z &= crypto_int64_xy; |
270 | 0 | *crypto_int64_a = crypto_int64_x ^ crypto_int64_z; |
271 | 0 | *crypto_int64_b = crypto_int64_y ^ crypto_int64_z; |
272 | 0 | } |
273 | | |
274 | | #endif |
275 | | |
276 | | /* from libmceliece-20230612/inttypes/crypto_intN.h */ |
277 | | #ifndef crypto_int16_h |
278 | | #define crypto_int16_h |
279 | | |
280 | 0 | #define crypto_int16 int16_t |
281 | | |
282 | | GCC_ATTR_UNUSED |
283 | | static crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x) |
284 | 0 | { |
285 | 0 | return crypto_int16_x >> (16-1); |
286 | 0 | } |
287 | | |
288 | | GCC_ATTR_UNUSED |
289 | | static crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x) |
290 | 0 | { |
291 | 0 | return crypto_int16_negative_mask(crypto_int16_x) | crypto_int16_negative_mask(-crypto_int16_x); |
292 | 0 | } |
293 | | |
294 | | GCC_ATTR_UNUSED |
295 | | static crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x) |
296 | 0 | { |
297 | 0 | return ~crypto_int16_nonzero_mask(crypto_int16_x); |
298 | 0 | } |
299 | | |
300 | | GCC_ATTR_UNUSED |
301 | | static crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x) |
302 | 0 | { |
303 | 0 | crypto_int16 crypto_int16_z = -crypto_int16_x; |
304 | 0 | crypto_int16_z ^= crypto_int16_x & crypto_int16_z; |
305 | 0 | return crypto_int16_negative_mask(crypto_int16_z); |
306 | 0 | } |
307 | | |
308 | | GCC_ATTR_UNUSED |
309 | | static crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) |
310 | 0 | { |
311 | 0 | crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y; |
312 | 0 | return crypto_int16_nonzero_mask(crypto_int16_xy); |
313 | 0 | } |
314 | | |
315 | | GCC_ATTR_UNUSED |
316 | | static crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) |
317 | 0 | { |
318 | 0 | return ~crypto_int16_unequal_mask(crypto_int16_x,crypto_int16_y); |
319 | 0 | } |
320 | | |
321 | | GCC_ATTR_UNUSED |
322 | | static crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) |
323 | 0 | { |
324 | 0 | crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y; |
325 | 0 | crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; |
326 | 0 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_x); |
327 | 0 | return crypto_int16_negative_mask(crypto_int16_z); |
328 | 0 | } |
329 | | |
330 | | GCC_ATTR_UNUSED |
331 | | static crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) |
332 | 0 | { |
333 | 0 | crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; |
334 | 0 | crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; |
335 | 0 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); |
336 | 0 | crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); |
337 | 0 | crypto_int16_z &= crypto_int16_xy; |
338 | 0 | return crypto_int16_x ^ crypto_int16_z; |
339 | 0 | } |
340 | | |
341 | | GCC_ATTR_UNUSED |
342 | | static crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) |
343 | 0 | { |
344 | 0 | crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; |
345 | 0 | crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; |
346 | 0 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); |
347 | 0 | crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); |
348 | 0 | crypto_int16_z &= crypto_int16_xy; |
349 | 0 | return crypto_int16_y ^ crypto_int16_z; |
350 | 0 | } |
351 | | |
352 | | GCC_ATTR_UNUSED |
353 | | static void crypto_int16_minmax(crypto_int16 *crypto_int16_a,crypto_int16 *crypto_int16_b) |
354 | 0 | { |
355 | 0 | crypto_int16 crypto_int16_x = *crypto_int16_a; |
356 | 0 | crypto_int16 crypto_int16_y = *crypto_int16_b; |
357 | 0 | crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; |
358 | 0 | crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; |
359 | 0 | crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); |
360 | 0 | crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); |
361 | 0 | crypto_int16_z &= crypto_int16_xy; |
362 | 0 | *crypto_int16_a = crypto_int16_x ^ crypto_int16_z; |
363 | 0 | *crypto_int16_b = crypto_int16_y ^ crypto_int16_z; |
364 | 0 | } |
365 | | |
366 | | #endif |
367 | | |
368 | | /* from libmceliece-20230612/inttypes/crypto_intN.h */ |
369 | | #ifndef crypto_int32_h |
370 | | #define crypto_int32_h |
371 | | |
372 | 0 | #define crypto_int32 int32_t |
373 | | |
374 | | GCC_ATTR_UNUSED |
375 | | static crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x) |
376 | 0 | { |
377 | 0 | return crypto_int32_x >> (32-1); |
378 | 0 | } |
379 | | |
380 | | GCC_ATTR_UNUSED |
381 | | static crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x) |
382 | 0 | { |
383 | 0 | return crypto_int32_negative_mask(crypto_int32_x) | crypto_int32_negative_mask(-crypto_int32_x); |
384 | 0 | } |
385 | | |
386 | | GCC_ATTR_UNUSED |
387 | | static crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x) |
388 | 0 | { |
389 | 0 | return ~crypto_int32_nonzero_mask(crypto_int32_x); |
390 | 0 | } |
391 | | |
392 | | GCC_ATTR_UNUSED |
393 | | static crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x) |
394 | 0 | { |
395 | 0 | crypto_int32 crypto_int32_z = -crypto_int32_x; |
396 | 0 | crypto_int32_z ^= crypto_int32_x & crypto_int32_z; |
397 | 0 | return crypto_int32_negative_mask(crypto_int32_z); |
398 | 0 | } |
399 | | |
400 | | GCC_ATTR_UNUSED |
401 | | static crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) |
402 | 0 | { |
403 | 0 | crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y; |
404 | 0 | return crypto_int32_nonzero_mask(crypto_int32_xy); |
405 | 0 | } |
406 | | |
407 | | GCC_ATTR_UNUSED |
408 | | static crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) |
409 | 0 | { |
410 | 0 | return ~crypto_int32_unequal_mask(crypto_int32_x,crypto_int32_y); |
411 | 0 | } |
412 | | |
413 | | GCC_ATTR_UNUSED |
414 | | static crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) |
415 | 0 | { |
416 | 0 | crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y; |
417 | 0 | crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; |
418 | 0 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_x); |
419 | 0 | return crypto_int32_negative_mask(crypto_int32_z); |
420 | 0 | } |
421 | | |
422 | | GCC_ATTR_UNUSED |
423 | | static crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) |
424 | 0 | { |
425 | 0 | crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; |
426 | 0 | crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; |
427 | 0 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); |
428 | 0 | crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); |
429 | 0 | crypto_int32_z &= crypto_int32_xy; |
430 | 0 | return crypto_int32_x ^ crypto_int32_z; |
431 | 0 | } |
432 | | |
433 | | GCC_ATTR_UNUSED |
434 | | static crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) |
435 | 0 | { |
436 | 0 | crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; |
437 | 0 | crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; |
438 | 0 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); |
439 | 0 | crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); |
440 | 0 | crypto_int32_z &= crypto_int32_xy; |
441 | 0 | return crypto_int32_y ^ crypto_int32_z; |
442 | 0 | } |
443 | | |
444 | | GCC_ATTR_UNUSED |
445 | | static void crypto_int32_minmax(crypto_int32 *crypto_int32_a,crypto_int32 *crypto_int32_b) |
446 | 0 | { |
447 | 0 | crypto_int32 crypto_int32_x = *crypto_int32_a; |
448 | 0 | crypto_int32 crypto_int32_y = *crypto_int32_b; |
449 | 0 | crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; |
450 | 0 | crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; |
451 | 0 | crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); |
452 | 0 | crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); |
453 | 0 | crypto_int32_z &= crypto_int32_xy; |
454 | 0 | *crypto_int32_a = crypto_int32_x ^ crypto_int32_z; |
455 | 0 | *crypto_int32_b = crypto_int32_y ^ crypto_int32_z; |
456 | 0 | } |
457 | | |
458 | | #endif |
459 | | |
460 | | /* from libmceliece-20230612/inttypes/crypto_uintN.h */ |
461 | | #ifndef crypto_uint64_h |
462 | | #define crypto_uint64_h |
463 | | |
464 | 0 | #define crypto_uint64 uint64_t |
465 | | #define crypto_uint64_signed int64_t |
466 | | |
467 | | GCC_ATTR_UNUSED |
468 | | static crypto_uint64_signed crypto_uint64_signed_negative_mask(crypto_uint64_signed crypto_uint64_signed_x) |
469 | 0 | { |
470 | 0 | return crypto_uint64_signed_x >> (64-1); |
471 | 0 | } |
472 | | |
473 | | GCC_ATTR_UNUSED |
474 | | static crypto_uint64 crypto_uint64_nonzero_mask(crypto_uint64 crypto_uint64_x) |
475 | 0 | { |
476 | 0 | return crypto_uint64_signed_negative_mask(crypto_uint64_x) | crypto_uint64_signed_negative_mask(-crypto_uint64_x); |
477 | 0 | } |
478 | | |
479 | | GCC_ATTR_UNUSED |
480 | | static crypto_uint64 crypto_uint64_zero_mask(crypto_uint64 crypto_uint64_x) |
481 | 0 | { |
482 | 0 | return ~crypto_uint64_nonzero_mask(crypto_uint64_x); |
483 | 0 | } |
484 | | |
485 | | GCC_ATTR_UNUSED |
486 | | static crypto_uint64 crypto_uint64_unequal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) |
487 | 0 | { |
488 | 0 | crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y; |
489 | 0 | return crypto_uint64_nonzero_mask(crypto_uint64_xy); |
490 | 0 | } |
491 | | |
492 | | GCC_ATTR_UNUSED |
493 | | static crypto_uint64 crypto_uint64_equal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) |
494 | 0 | { |
495 | 0 | return ~crypto_uint64_unequal_mask(crypto_uint64_x,crypto_uint64_y); |
496 | 0 | } |
497 | | |
498 | | GCC_ATTR_UNUSED |
499 | | static crypto_uint64 crypto_uint64_smaller_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) |
500 | 0 | { |
501 | 0 | crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y; |
502 | 0 | crypto_uint64 crypto_uint64_z = crypto_uint64_x - crypto_uint64_y; |
503 | 0 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_x ^ (((crypto_uint64) 1) << (64-1))); |
504 | 0 | return crypto_uint64_signed_negative_mask(crypto_uint64_z); |
505 | 0 | } |
506 | | |
507 | | GCC_ATTR_UNUSED |
508 | | static crypto_uint64 crypto_uint64_min(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) |
509 | 0 | { |
510 | 0 | crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; |
511 | 0 | crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; |
512 | 0 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1))); |
513 | 0 | crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); |
514 | 0 | crypto_uint64_z &= crypto_uint64_xy; |
515 | 0 | return crypto_uint64_x ^ crypto_uint64_z; |
516 | 0 | } |
517 | | |
518 | | GCC_ATTR_UNUSED |
519 | | static crypto_uint64 crypto_uint64_max(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) |
520 | 0 | { |
521 | 0 | crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; |
522 | 0 | crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; |
523 | 0 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1))); |
524 | 0 | crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); |
525 | 0 | crypto_uint64_z &= crypto_uint64_xy; |
526 | 0 | return crypto_uint64_y ^ crypto_uint64_z; |
527 | 0 | } |
528 | | |
529 | | GCC_ATTR_UNUSED |
530 | | static void crypto_uint64_minmax(crypto_uint64 *crypto_uint64_a,crypto_uint64 *crypto_uint64_b) |
531 | 0 | { |
532 | 0 | crypto_uint64 crypto_uint64_x = *crypto_uint64_a; |
533 | 0 | crypto_uint64 crypto_uint64_y = *crypto_uint64_b; |
534 | 0 | crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; |
535 | 0 | crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; |
536 | 0 | crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1))); |
537 | 0 | crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); |
538 | 0 | crypto_uint64_z &= crypto_uint64_xy; |
539 | 0 | *crypto_uint64_a = crypto_uint64_x ^ crypto_uint64_z; |
540 | 0 | *crypto_uint64_b = crypto_uint64_y ^ crypto_uint64_z; |
541 | 0 | } |
542 | | |
543 | | #endif |
544 | | |
545 | | /* from libmceliece-20230612/inttypes/crypto_uintN.h */ |
546 | | #ifndef crypto_uint16_h |
547 | | #define crypto_uint16_h |
548 | | |
549 | 0 | #define crypto_uint16 uint16_t |
550 | | #define crypto_uint16_signed int16_t |
551 | | |
552 | | GCC_ATTR_UNUSED |
553 | | static crypto_uint16_signed crypto_uint16_signed_negative_mask(crypto_uint16_signed crypto_uint16_signed_x) |
554 | 0 | { |
555 | 0 | return crypto_uint16_signed_x >> (16-1); |
556 | 0 | } |
557 | | |
558 | | GCC_ATTR_UNUSED |
559 | | static crypto_uint16 crypto_uint16_nonzero_mask(crypto_uint16 crypto_uint16_x) |
560 | 0 | { |
561 | 0 | return crypto_uint16_signed_negative_mask(crypto_uint16_x) | crypto_uint16_signed_negative_mask(-crypto_uint16_x); |
562 | 0 | } |
563 | | |
564 | | GCC_ATTR_UNUSED |
565 | | static crypto_uint16 crypto_uint16_zero_mask(crypto_uint16 crypto_uint16_x) |
566 | 0 | { |
567 | 0 | return ~crypto_uint16_nonzero_mask(crypto_uint16_x); |
568 | 0 | } |
569 | | |
570 | | GCC_ATTR_UNUSED |
571 | | static crypto_uint16 crypto_uint16_unequal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) |
572 | 0 | { |
573 | 0 | crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y; |
574 | 0 | return crypto_uint16_nonzero_mask(crypto_uint16_xy); |
575 | 0 | } |
576 | | |
577 | | GCC_ATTR_UNUSED |
578 | | static crypto_uint16 crypto_uint16_equal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) |
579 | 0 | { |
580 | 0 | return ~crypto_uint16_unequal_mask(crypto_uint16_x,crypto_uint16_y); |
581 | 0 | } |
582 | | |
583 | | GCC_ATTR_UNUSED |
584 | | static crypto_uint16 crypto_uint16_smaller_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) |
585 | 0 | { |
586 | 0 | crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y; |
587 | 0 | crypto_uint16 crypto_uint16_z = crypto_uint16_x - crypto_uint16_y; |
588 | 0 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_x ^ (((crypto_uint16) 1) << (16-1))); |
589 | 0 | return crypto_uint16_signed_negative_mask(crypto_uint16_z); |
590 | 0 | } |
591 | | |
592 | | GCC_ATTR_UNUSED |
593 | | static crypto_uint16 crypto_uint16_min(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) |
594 | 0 | { |
595 | 0 | crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; |
596 | 0 | crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; |
597 | 0 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1))); |
598 | 0 | crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); |
599 | 0 | crypto_uint16_z &= crypto_uint16_xy; |
600 | 0 | return crypto_uint16_x ^ crypto_uint16_z; |
601 | 0 | } |
602 | | |
603 | | GCC_ATTR_UNUSED |
604 | | static crypto_uint16 crypto_uint16_max(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) |
605 | 0 | { |
606 | 0 | crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; |
607 | 0 | crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; |
608 | 0 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1))); |
609 | 0 | crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); |
610 | 0 | crypto_uint16_z &= crypto_uint16_xy; |
611 | 0 | return crypto_uint16_y ^ crypto_uint16_z; |
612 | 0 | } |
613 | | |
614 | | GCC_ATTR_UNUSED |
615 | | static void crypto_uint16_minmax(crypto_uint16 *crypto_uint16_a,crypto_uint16 *crypto_uint16_b) |
616 | 0 | { |
617 | 0 | crypto_uint16 crypto_uint16_x = *crypto_uint16_a; |
618 | 0 | crypto_uint16 crypto_uint16_y = *crypto_uint16_b; |
619 | 0 | crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; |
620 | 0 | crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; |
621 | 0 | crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1))); |
622 | 0 | crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); |
623 | 0 | crypto_uint16_z &= crypto_uint16_xy; |
624 | 0 | *crypto_uint16_a = crypto_uint16_x ^ crypto_uint16_z; |
625 | 0 | *crypto_uint16_b = crypto_uint16_y ^ crypto_uint16_z; |
626 | 0 | } |
627 | | |
628 | | #endif |
629 | | |
630 | | /* from libmceliece-20230612/inttypes/crypto_uintN.h */ |
631 | | #ifndef crypto_uint32_h |
632 | | #define crypto_uint32_h |
633 | | |
634 | 0 | #define crypto_uint32 uint32_t |
635 | | #define crypto_uint32_signed int32_t |
636 | | |
637 | | GCC_ATTR_UNUSED |
638 | | static crypto_uint32_signed crypto_uint32_signed_negative_mask(crypto_uint32_signed crypto_uint32_signed_x) |
639 | 0 | { |
640 | 0 | return crypto_uint32_signed_x >> (32-1); |
641 | 0 | } |
642 | | |
643 | | GCC_ATTR_UNUSED |
644 | | static crypto_uint32 crypto_uint32_nonzero_mask(crypto_uint32 crypto_uint32_x) |
645 | 0 | { |
646 | 0 | return crypto_uint32_signed_negative_mask(crypto_uint32_x) | crypto_uint32_signed_negative_mask(-crypto_uint32_x); |
647 | 0 | } |
648 | | |
649 | | GCC_ATTR_UNUSED |
650 | | static crypto_uint32 crypto_uint32_zero_mask(crypto_uint32 crypto_uint32_x) |
651 | 0 | { |
652 | 0 | return ~crypto_uint32_nonzero_mask(crypto_uint32_x); |
653 | 0 | } |
654 | | |
655 | | GCC_ATTR_UNUSED |
656 | | static crypto_uint32 crypto_uint32_unequal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) |
657 | 0 | { |
658 | 0 | crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y; |
659 | 0 | return crypto_uint32_nonzero_mask(crypto_uint32_xy); |
660 | 0 | } |
661 | | |
662 | | GCC_ATTR_UNUSED |
663 | | static crypto_uint32 crypto_uint32_equal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) |
664 | 0 | { |
665 | 0 | return ~crypto_uint32_unequal_mask(crypto_uint32_x,crypto_uint32_y); |
666 | 0 | } |
667 | | |
668 | | GCC_ATTR_UNUSED |
669 | | static crypto_uint32 crypto_uint32_smaller_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) |
670 | 0 | { |
671 | 0 | crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y; |
672 | 0 | crypto_uint32 crypto_uint32_z = crypto_uint32_x - crypto_uint32_y; |
673 | 0 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_x ^ (((crypto_uint32) 1) << (32-1))); |
674 | 0 | return crypto_uint32_signed_negative_mask(crypto_uint32_z); |
675 | 0 | } |
676 | | |
677 | | GCC_ATTR_UNUSED |
678 | | static crypto_uint32 crypto_uint32_min(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) |
679 | 0 | { |
680 | 0 | crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; |
681 | 0 | crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; |
682 | 0 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1))); |
683 | 0 | crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); |
684 | 0 | crypto_uint32_z &= crypto_uint32_xy; |
685 | 0 | return crypto_uint32_x ^ crypto_uint32_z; |
686 | 0 | } |
687 | | |
688 | | GCC_ATTR_UNUSED |
689 | | static crypto_uint32 crypto_uint32_max(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) |
690 | 0 | { |
691 | 0 | crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; |
692 | 0 | crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; |
693 | 0 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1))); |
694 | 0 | crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); |
695 | 0 | crypto_uint32_z &= crypto_uint32_xy; |
696 | 0 | return crypto_uint32_y ^ crypto_uint32_z; |
697 | 0 | } |
698 | | |
699 | | GCC_ATTR_UNUSED |
700 | | static void crypto_uint32_minmax(crypto_uint32 *crypto_uint32_a,crypto_uint32 *crypto_uint32_b) |
701 | 0 | { |
702 | 0 | crypto_uint32 crypto_uint32_x = *crypto_uint32_a; |
703 | 0 | crypto_uint32 crypto_uint32_y = *crypto_uint32_b; |
704 | 0 | crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; |
705 | 0 | crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; |
706 | 0 | crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1))); |
707 | 0 | crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); |
708 | 0 | crypto_uint32_z &= crypto_uint32_xy; |
709 | 0 | *crypto_uint32_a = crypto_uint32_x ^ crypto_uint32_z; |
710 | 0 | *crypto_uint32_b = crypto_uint32_y ^ crypto_uint32_z; |
711 | 0 | } |
712 | | |
713 | | #endif |
714 | | |
715 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.h */ |
716 | | #ifndef VEC_H |
717 | | #define VEC_H |
718 | | |
719 | | |
720 | | |
721 | | typedef uint64_t vec; |
722 | | |
723 | | static inline vec vec_setbits(vec b) |
724 | 0 | { |
725 | 0 | vec ret = -b; |
726 | |
|
727 | 0 | return ret; |
728 | 0 | } |
729 | | |
730 | | static inline vec vec_set1_16b(uint16_t v) |
731 | 0 | { |
732 | 0 | vec ret; |
733 | |
|
734 | 0 | ret = v; |
735 | 0 | ret |= ret << 16; |
736 | 0 | ret |= ret << 32; |
737 | |
|
738 | 0 | return ret; |
739 | 0 | } |
740 | | |
741 | | static inline void vec_copy(vec * out, vec * in) |
742 | 0 | { |
743 | 0 | int i; |
744 | |
|
745 | 0 | for (i = 0; i < GFBITS; i++) |
746 | 0 | out[i] = in[i]; |
747 | 0 | } |
748 | | |
749 | | static inline vec vec_or_reduce(vec * a) |
750 | 0 | { |
751 | 0 | int i; |
752 | 0 | vec ret; |
753 | |
|
754 | 0 | ret = a[0]; |
755 | 0 | for (i = 1; i < GFBITS; i++) |
756 | 0 | ret |= a[i]; |
757 | |
|
758 | 0 | return ret; |
759 | 0 | } |
760 | | |
761 | | static inline int vec_testz(vec a) |
762 | 0 | { |
763 | 0 | a |= a >> 32; |
764 | 0 | a |= a >> 16; |
765 | 0 | a |= a >> 8; |
766 | 0 | a |= a >> 4; |
767 | 0 | a |= a >> 2; |
768 | 0 | a |= a >> 1; |
769 | |
|
770 | 0 | return (a&1)^1; |
771 | 0 | } |
772 | | |
773 | | static void vec_mul(vec *, const vec *, const vec *); |
774 | | static void vec_sq(vec *, vec *); |
775 | | static void vec_inv(vec *, vec *); |
776 | | |
777 | | #endif |
778 | | |
779 | | |
780 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.h */ |
781 | | /* |
782 | | This file is for Benes network related functions |
783 | | */ |
784 | | |
785 | | #ifndef BENES_H |
786 | | #define BENES_H |
787 | | |
788 | | |
789 | | static void benes(vec *, const unsigned char *, int); |
790 | | |
791 | | #endif |
792 | | |
793 | | |
794 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.h */ |
795 | | /* |
796 | | This file is for the inversion-free Berlekamp-Massey algorithm |
797 | | see https://ieeexplore.ieee.org/document/87857 |
798 | | */ |
799 | | |
800 | | #ifndef BM_H |
801 | | #define BM_H |
802 | | |
803 | | |
804 | | static void bm(vec [][GFBITS], vec [][ GFBITS ]); |
805 | | |
806 | | #endif |
807 | | |
808 | | |
809 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h */ |
810 | | /* This file is for implementing the Nassimi-Sahni algorithm */ |
811 | | /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */ |
812 | | /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */ |
813 | | |
814 | | #ifndef CONTROLBITS_H |
815 | | #define CONTROLBITS_H |
816 | | |
817 | | |
818 | | |
819 | | |
820 | | #endif |
821 | | |
822 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h */ |
823 | | /* |
824 | | This file is for Nieddereiter decryption |
825 | | */ |
826 | | |
827 | | #ifndef DECRYPT_H |
828 | | #define DECRYPT_H |
829 | | |
830 | | static int decrypt(unsigned char *, const unsigned char *, const unsigned char *); |
831 | | |
832 | | #endif |
833 | | |
834 | | |
835 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h */ |
836 | | /* |
837 | | This file is for Niederreiter encryption |
838 | | */ |
839 | | /* 20230102 djb: rename encrypt() as pke_encrypt() */ |
840 | | |
841 | | #ifndef ENCRYPT_H |
842 | | #define ENCRYPT_H |
843 | | |
844 | | static void pke_encrypt(unsigned char *, const unsigned char *, unsigned char *); |
845 | | |
846 | | #endif |
847 | | |
848 | | |
849 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h */ |
850 | | #ifndef fft_consts_h |
851 | | #define fft_consts_h |
852 | | |
853 | | |
854 | | |
855 | | |
856 | | #endif |
857 | | |
858 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.h */ |
859 | | /* |
860 | | This file is for the Gao-Mateer FFT |
861 | | sse http://www.math.clemson.edu/~sgao/papers/GM10.pdf |
862 | | */ |
863 | | |
864 | | #ifndef FFT_H |
865 | | #define FFT_H |
866 | | |
867 | | |
868 | | static void fft(vec [][GFBITS], vec [][GFBITS]); |
869 | | |
870 | | #endif |
871 | | |
872 | | |
873 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h */ |
874 | | #ifndef fft_powers_h |
875 | | #define fft_powers_h |
876 | | |
877 | | |
878 | | |
879 | | |
880 | | #endif |
881 | | |
882 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h */ |
883 | | #ifndef fft_scalars_2x_h |
884 | | #define fft_scalars_2x_h |
885 | | |
886 | | |
887 | | |
888 | | |
889 | | #endif |
890 | | |
891 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h */ |
892 | | #ifndef fft_scalars_4x_h |
893 | | #define fft_scalars_4x_h |
894 | | |
895 | | |
896 | | |
897 | | |
898 | | #endif |
899 | | |
900 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h */ |
901 | | /* |
902 | | This file is for transpose of the Gao-Mateer FFT |
903 | | */ |
904 | | |
905 | | #ifndef FFT_TR_H |
906 | | #define FFT_TR_H |
907 | | |
908 | | |
909 | | static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ]); |
910 | | |
911 | | #endif |
912 | | |
913 | | |
914 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.h */ |
915 | | /* |
916 | | This file is for functions for field arithmetic |
917 | | */ |
918 | | /* 20221231 djb: const for GF_mul */ |
919 | | |
920 | | #ifndef GF_H |
921 | | #define GF_H |
922 | | |
923 | | |
924 | | |
925 | | typedef uint16_t gf; |
926 | | |
927 | | gf gf_iszero(gf); |
928 | | gf gf_mul(gf, gf); |
929 | | gf gf_frac(gf, gf); |
930 | | gf gf_inv(gf); |
931 | | |
932 | | static void GF_mul(gf *, const gf *, const gf *); |
933 | | |
934 | | /* 2 field multiplications */ |
935 | | static inline uint64_t gf_mul2(gf a, gf b0, gf b1) |
936 | 0 | { |
937 | 0 | int i; |
938 | |
|
939 | 0 | uint64_t tmp=0; |
940 | 0 | uint64_t t0; |
941 | 0 | uint64_t t1; |
942 | 0 | uint64_t t; |
943 | 0 | uint64_t mask = 0x0000000100000001; |
944 | |
|
945 | 0 | t0 = a; |
946 | 0 | t1 = b1; |
947 | 0 | t1 = (t1 << 32) | b0; |
948 | |
|
949 | 0 | for (i = 0; i < GFBITS; i++) |
950 | 0 | { |
951 | 0 | tmp ^= t0 * (t1 & mask); |
952 | 0 | mask += mask; |
953 | 0 | } |
954 | | |
955 | | /**/ |
956 | |
|
957 | 0 | t = tmp & 0x01FF000001FF0000; |
958 | 0 | tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
959 | |
|
960 | 0 | t = tmp & 0x0000E0000000E000; |
961 | 0 | tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
962 | |
|
963 | 0 | return tmp & 0x00001FFF00001FFF; |
964 | 0 | } |
965 | | |
966 | | #endif |
967 | | |
968 | | |
969 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/hash.h */ |
970 | | |
971 | 0 | #define shake crypto_xof_shake256 |
972 | | |
973 | | #define crypto_hash_32b(out,in,inlen) \ |
974 | 0 | shake(out,32,in,inlen) |
975 | | |
976 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h */ |
977 | | #ifndef int32_sort_h |
978 | | #define int32_sort_h |
979 | | |
980 | | |
981 | | |
982 | 0 | #define int32_MINMAX(a,b) \ |
983 | 0 | do { \ |
984 | 0 | int64_t ab = (int64_t)b ^ (int64_t)a; \ |
985 | 0 | int64_t c = (int64_t)b - (int64_t)a; \ |
986 | 0 | c ^= ab & (c ^ b); \ |
987 | 0 | c >>= 31; \ |
988 | 0 | c &= ab; \ |
989 | 0 | a ^= c; \ |
990 | 0 | b ^= c; \ |
991 | 0 | } while(0) |
992 | | |
993 | | static void int32_sort(int32_t *x,long long n) |
994 | 0 | { |
995 | 0 | long long top,p,q,r,i; |
996 | |
|
997 | 0 | if (n < 2) return; |
998 | 0 | top = 1; |
999 | 0 | while (top < n - top) top += top; |
1000 | |
|
1001 | 0 | for (p = top;p > 0;p >>= 1) { |
1002 | 0 | for (i = 0;i < n - p;++i) |
1003 | 0 | if (!(i & p)) |
1004 | 0 | int32_MINMAX(x[i],x[i+p]); |
1005 | 0 | i = 0; |
1006 | 0 | for (q = top;q > p;q >>= 1) { |
1007 | 0 | for (;i < n - q;++i) { |
1008 | 0 | if (!(i & p)) { |
1009 | 0 | int32_t a = x[i + p]; |
1010 | 0 | for (r = q;r > p;r >>= 1) |
1011 | 0 | int32_MINMAX(a,x[i+r]); |
1012 | 0 | x[i + p] = a; |
1013 | 0 | } |
1014 | 0 | } |
1015 | 0 | } |
1016 | 0 | } |
1017 | 0 | } |
1018 | | |
1019 | | #endif |
1020 | | |
1021 | | |
1022 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/operations.h */ |
1023 | | #ifndef OPERATIONS_H |
1024 | | #define OPERATIONS_H |
1025 | | |
1026 | | |
1027 | | static void operation_enc( |
1028 | | unsigned char *c, |
1029 | | unsigned char *key, |
1030 | | const unsigned char *pk |
1031 | | ); |
1032 | | |
1033 | | static void operation_dec( |
1034 | | unsigned char *key, |
1035 | | const unsigned char *c, |
1036 | | const unsigned char *sk |
1037 | | ); |
1038 | | |
1039 | | static void operation_keypair |
1040 | | ( |
1041 | | unsigned char *pk, |
1042 | | unsigned char *sk |
1043 | | ); |
1044 | | |
1045 | | #endif |
1046 | | |
1047 | | |
1048 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h */ |
1049 | | /* |
1050 | | This file is for public-key generation |
1051 | | */ |
1052 | | |
1053 | | #ifndef PK_GEN_H |
1054 | | #define PK_GEN_H |
1055 | | |
1056 | | |
1057 | | static int pk_gen(unsigned char *, const unsigned char *, uint32_t *, int16_t *, uint64_t *); |
1058 | | |
1059 | | #endif |
1060 | | |
1061 | | |
1062 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h */ |
1063 | | /* |
1064 | | This file is for secret-key generation |
1065 | | */ |
1066 | | |
1067 | | #ifndef SK_GEN_H |
1068 | | #define SK_GEN_H |
1069 | | |
1070 | | |
1071 | | |
1072 | | static int genpoly_gen(gf *, gf *); |
1073 | | |
1074 | | #endif |
1075 | | |
1076 | | |
1077 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h */ |
1078 | | /* |
1079 | | This file is for matrix transposition |
1080 | | */ |
1081 | | |
1082 | | #ifndef TRANSPOSE_H |
1083 | | #define TRANSPOSE_H |
1084 | | |
1085 | | /* input: in, a 64x64 matrix over GF(2) */ |
1086 | | /* output: out, transpose of in */ |
1087 | | static inline void transpose_64x64(uint64_t * out, uint64_t * in) |
1088 | 0 | { |
1089 | 0 | int i, j, s, d; |
1090 | |
|
1091 | 0 | uint64_t x, y; |
1092 | 0 | uint64_t masks[6][2] = { |
1093 | 0 | {0x5555555555555555, 0xAAAAAAAAAAAAAAAA}, |
1094 | 0 | {0x3333333333333333, 0xCCCCCCCCCCCCCCCC}, |
1095 | 0 | {0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0}, |
1096 | 0 | {0x00FF00FF00FF00FF, 0xFF00FF00FF00FF00}, |
1097 | 0 | {0x0000FFFF0000FFFF, 0xFFFF0000FFFF0000}, |
1098 | 0 | {0x00000000FFFFFFFF, 0xFFFFFFFF00000000} |
1099 | 0 | }; |
1100 | |
|
1101 | 0 | for (i = 0; i < 64; i++) |
1102 | 0 | out[i] = in[i]; |
1103 | |
|
1104 | 0 | for (d = 5; d >= 0; d--) |
1105 | 0 | { |
1106 | 0 | s = 1 << d; |
1107 | |
|
1108 | 0 | for (i = 0; i < 64; i += s*2) |
1109 | 0 | for (j = i; j < i+s; j++) |
1110 | 0 | { |
1111 | 0 | x = (out[j] & masks[d][0]) | ((out[j+s] & masks[d][0]) << s); |
1112 | 0 | y = ((out[j] & masks[d][1]) >> s) | (out[j+s] & masks[d][1]); |
1113 | |
|
1114 | 0 | out[j+0] = x; |
1115 | 0 | out[j+s] = y; |
1116 | 0 | } |
1117 | 0 | } |
1118 | 0 | } |
1119 | | |
1120 | | #endif |
1121 | | |
1122 | | |
1123 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h */ |
1124 | | #ifndef uint16_sort_h |
1125 | | #define uint16_sort_h |
1126 | | |
1127 | | |
1128 | | |
1129 | 0 | #define uint16_MINMAX(a,b) \ |
1130 | 0 | do { \ |
1131 | 0 | uint16_t c = b - a; \ |
1132 | 0 | c >>= 15; \ |
1133 | 0 | c = -c; \ |
1134 | 0 | c &= a ^ b; \ |
1135 | 0 | a ^= c; \ |
1136 | 0 | b ^= c; \ |
1137 | 0 | } while(0) |
1138 | | |
1139 | | static void uint16_sort(uint16_t *x,long long n) |
1140 | 0 | { |
1141 | 0 | long long top,p,q,r,i; |
1142 | |
|
1143 | 0 | if (n < 2) return; |
1144 | 0 | top = 1; |
1145 | 0 | while (top < n - top) top += top; |
1146 | |
|
1147 | 0 | for (p = top;p > 0;p >>= 1) { |
1148 | 0 | for (i = 0;i < n - p;++i) |
1149 | 0 | if (!(i & p)) |
1150 | 0 | uint16_MINMAX(x[i],x[i+p]); |
1151 | 0 | i = 0; |
1152 | 0 | for (q = top;q > p;q >>= 1) { |
1153 | 0 | for (;i < n - q;++i) { |
1154 | 0 | if (!(i & p)) { |
1155 | 0 | int16_t a = x[i + p]; |
1156 | 0 | for (r = q;r > p;r >>= 1) |
1157 | 0 | uint16_MINMAX(a,x[i+r]); |
1158 | 0 | x[i + p] = a; |
1159 | 0 | } |
1160 | 0 | } |
1161 | 0 | } |
1162 | 0 | } |
1163 | 0 | } |
1164 | | |
1165 | | #endif |
1166 | | |
1167 | | |
1168 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h */ |
1169 | | #ifndef uint64_sort_h |
1170 | | #define uint64_sort_h |
1171 | | |
1172 | | |
1173 | | |
1174 | 0 | #define uint64_MINMAX(a,b) \ |
1175 | 0 | do { \ |
1176 | 0 | uint64_t c = b - a; \ |
1177 | 0 | c >>= 63; \ |
1178 | 0 | c = -c; \ |
1179 | 0 | c &= a ^ b; \ |
1180 | 0 | a ^= c; \ |
1181 | 0 | b ^= c; \ |
1182 | 0 | } while(0) |
1183 | | |
1184 | | static void uint64_sort(uint64_t *x,long long n) |
1185 | 0 | { |
1186 | 0 | long long top,p,q,r,i; |
1187 | |
|
1188 | 0 | if (n < 2) return; |
1189 | 0 | top = 1; |
1190 | 0 | while (top < n - top) top += top; |
1191 | |
|
1192 | 0 | for (p = top;p > 0;p >>= 1) { |
1193 | 0 | for (i = 0;i < n - p;++i) |
1194 | 0 | if (!(i & p)) |
1195 | 0 | uint64_MINMAX(x[i],x[i+p]); |
1196 | 0 | i = 0; |
1197 | 0 | for (q = top;q > p;q >>= 1) { |
1198 | 0 | for (;i < n - q;++i) { |
1199 | 0 | if (!(i & p)) { |
1200 | 0 | uint64_t a = x[i + p]; |
1201 | 0 | for (r = q;r > p;r >>= 1) |
1202 | 0 | uint64_MINMAX(a,x[i+r]); |
1203 | 0 | x[i + p] = a; |
1204 | 0 | } |
1205 | 0 | } |
1206 | 0 | } |
1207 | 0 | } |
1208 | 0 | } |
1209 | | |
1210 | | #endif |
1211 | | |
1212 | | |
1213 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/util.h */ |
1214 | | /* |
1215 | | This file is for loading/storing data in a little-endian fashion |
1216 | | */ |
1217 | | |
1218 | | #ifndef UTIL_H |
1219 | | #define UTIL_H |
1220 | | |
1221 | | |
1222 | | |
1223 | | static inline void store_i(unsigned char *out, uint64_t in, int i) |
1224 | 0 | { |
1225 | 0 | int j; |
1226 | |
|
1227 | 0 | for (j = 0; j < i; j++) |
1228 | 0 | out[j] = (in >> (j * 8)) & 0xFF; |
1229 | 0 | } |
1230 | | |
1231 | | static inline void store_gf(unsigned char *dest, uint16_t a) |
1232 | 0 | { |
1233 | 0 | dest[0] = a & 0xFF; |
1234 | 0 | dest[1] = a >> 8; |
1235 | 0 | } |
1236 | | |
1237 | | static inline uint16_t load_gf(const unsigned char *src) |
1238 | 0 | { |
1239 | 0 | uint16_t a; |
1240 | |
|
1241 | 0 | a = src[1]; |
1242 | 0 | a <<= 8; |
1243 | 0 | a |= src[0]; |
1244 | |
|
1245 | 0 | return a & GFMASK; |
1246 | 0 | } |
1247 | | |
1248 | | static inline uint32_t load4(const unsigned char *src) |
1249 | 0 | { |
1250 | 0 | uint32_t a; |
1251 | |
|
1252 | 0 | a = src[3]; a <<= 8; |
1253 | 0 | a |= src[2]; a <<= 8; |
1254 | 0 | a |= src[1]; a <<= 8; |
1255 | 0 | a |= src[0]; |
1256 | |
|
1257 | 0 | return a; |
1258 | 0 | } |
1259 | | |
1260 | | static inline void irr_load(vec out[][GFBITS], const unsigned char * in) |
1261 | 0 | { |
1262 | 0 | int i, j; |
1263 | 0 | uint64_t v0 = 0, v1 = 0; |
1264 | 0 | uint16_t irr[ SYS_T ]; |
1265 | |
|
1266 | 0 | for (i = 0; i < SYS_T; i++) |
1267 | 0 | irr[i] = load_gf(in + i*2); |
1268 | |
|
1269 | 0 | for (i = 0; i < GFBITS; i++) |
1270 | 0 | { |
1271 | 0 | for (j = 63; j >= 0; j--) |
1272 | 0 | { |
1273 | 0 | v0 <<= 1; |
1274 | 0 | v1 <<= 1; |
1275 | 0 | v0 |= (irr[j] >> i) & 1; |
1276 | 0 | v1 |= (irr[j+64] >> i) & 1; |
1277 | 0 | } |
1278 | |
|
1279 | 0 | out[0][i] = v0; |
1280 | 0 | out[1][i] = v1; |
1281 | 0 | } |
1282 | 0 | } |
1283 | | |
1284 | | static inline void store8(unsigned char *out, uint64_t in) |
1285 | 0 | { |
1286 | 0 | out[0] = (in >> 0x00) & 0xFF; |
1287 | 0 | out[1] = (in >> 0x08) & 0xFF; |
1288 | 0 | out[2] = (in >> 0x10) & 0xFF; |
1289 | 0 | out[3] = (in >> 0x18) & 0xFF; |
1290 | 0 | out[4] = (in >> 0x20) & 0xFF; |
1291 | 0 | out[5] = (in >> 0x28) & 0xFF; |
1292 | 0 | out[6] = (in >> 0x30) & 0xFF; |
1293 | 0 | out[7] = (in >> 0x38) & 0xFF; |
1294 | 0 | } |
1295 | | |
1296 | | static inline uint64_t load8(const unsigned char * in) |
1297 | 0 | { |
1298 | 0 | int i; |
1299 | 0 | uint64_t ret = in[7]; |
1300 | |
|
1301 | 0 | for (i = 6; i >= 0; i--) |
1302 | 0 | { |
1303 | 0 | ret <<= 8; |
1304 | 0 | ret |= in[i]; |
1305 | 0 | } |
1306 | |
|
1307 | 0 | return ret; |
1308 | 0 | } |
1309 | | |
1310 | | #endif |
1311 | | |
1312 | | |
1313 | | static void crypto_xof_shake256(unsigned char *h,long long hlen, |
1314 | | const unsigned char *m,long long mlen) |
1315 | 0 | { |
1316 | 0 | gcry_md_hd_t mdh; |
1317 | 0 | gcry_err_code_t ec; |
1318 | |
|
1319 | 0 | ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0); |
1320 | 0 | if (ec) |
1321 | 0 | log_fatal ("internal md_open failed: %d\n", ec); |
1322 | 0 | _gcry_md_write (mdh, m, mlen); |
1323 | 0 | _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen); |
1324 | 0 | _gcry_md_close (mdh); |
1325 | 0 | } |
1326 | | |
1327 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.c */ |
1328 | | /* |
1329 | | This file is for Benes network related functions |
1330 | | |
1331 | | For the implementation strategy, see |
1332 | | https://eprint.iacr.org/2017/793.pdf |
1333 | | */ |
1334 | | /* 20221230 djb: add linker lines */ |
1335 | | |
1336 | | /* linker define benes */ |
1337 | | |
1338 | | |
1339 | | /* middle layers of the benes network */ |
1340 | | static void layer_in(uint64_t data[2][64], uint64_t * bits, int lgs) |
1341 | 0 | { |
1342 | 0 | int i, j, s; |
1343 | |
|
1344 | 0 | uint64_t d; |
1345 | |
|
1346 | 0 | s = 1 << lgs; |
1347 | |
|
1348 | 0 | for (i = 0; i < 64; i += s*2) |
1349 | 0 | for (j = i; j < i+s; j++) |
1350 | 0 | { |
1351 | |
|
1352 | 0 | d = (data[0][j+0] ^ data[0][j+s]); |
1353 | 0 | d &= (*bits++); |
1354 | 0 | data[0][j+0] ^= d; |
1355 | 0 | data[0][j+s] ^= d; |
1356 | |
|
1357 | 0 | d = (data[1][j+0] ^ data[1][j+s]); |
1358 | 0 | d &= (*bits++); |
1359 | 0 | data[1][j+0] ^= d; |
1360 | 0 | data[1][j+s] ^= d; |
1361 | 0 | } |
1362 | 0 | } |
1363 | | |
1364 | | /* first and last layers of the benes network */ |
1365 | | static void layer_ex(uint64_t * data, uint64_t * bits, int lgs) |
1366 | 0 | { |
1367 | 0 | int i, j, s; |
1368 | |
|
1369 | 0 | uint64_t d; |
1370 | |
|
1371 | 0 | s = 1 << lgs; |
1372 | |
|
1373 | 0 | for (i = 0; i < 128; i += s*2) |
1374 | 0 | for (j = i; j < i+s; j++) |
1375 | 0 | { |
1376 | |
|
1377 | 0 | d = (data[j+0] ^ data[j+s]); |
1378 | 0 | d &= (*bits++); |
1379 | 0 | data[j+0] ^= d; |
1380 | 0 | data[j+s] ^= d; |
1381 | 0 | } |
1382 | 0 | } |
1383 | | |
1384 | | /* input: r, sequence of bits to be permuted */ |
1385 | | /* bits, condition bits of the Benes network */ |
1386 | | /* rev, 0 for normal application; !0 for inverse */ |
1387 | | /* output: r, permuted bits */ |
1388 | | static void benes(vec * r, const unsigned char * bits, int rev) |
1389 | 0 | { |
1390 | 0 | int i, iter, inc; |
1391 | |
|
1392 | 0 | const unsigned char *bits_ptr; |
1393 | |
|
1394 | 0 | uint64_t r_int_v[2][64]; |
1395 | 0 | uint64_t r_int_h[2][64]; |
1396 | 0 | uint64_t b_int_v[64]; |
1397 | 0 | uint64_t b_int_h[64]; |
1398 | | |
1399 | | /**/ |
1400 | |
|
1401 | 0 | if (rev) { bits_ptr = bits + 12288; inc = -1024; } |
1402 | 0 | else { bits_ptr = bits; inc = 0; } |
1403 | |
|
1404 | 0 | for (i = 0; i < 64; i++) |
1405 | 0 | { |
1406 | 0 | r_int_v[0][i] = r[i*2 + 0]; |
1407 | 0 | r_int_v[1][i] = r[i*2 + 1]; |
1408 | 0 | } |
1409 | |
|
1410 | 0 | transpose_64x64(r_int_h[0], r_int_v[0]); |
1411 | 0 | transpose_64x64(r_int_h[1], r_int_v[1]); |
1412 | |
|
1413 | 0 | for (iter = 0; iter <= 6; iter++) |
1414 | 0 | { |
1415 | 0 | for (i = 0; i < 64; i++) |
1416 | 0 | { |
1417 | 0 | b_int_v[i] = load8(bits_ptr); bits_ptr += 8; |
1418 | 0 | } |
1419 | |
|
1420 | 0 | bits_ptr += inc; |
1421 | |
|
1422 | 0 | transpose_64x64(b_int_h, b_int_v); |
1423 | |
|
1424 | 0 | layer_ex(r_int_h[0], b_int_h, iter); |
1425 | 0 | } |
1426 | |
|
1427 | 0 | transpose_64x64(r_int_v[0], r_int_h[0]); |
1428 | 0 | transpose_64x64(r_int_v[1], r_int_h[1]); |
1429 | |
|
1430 | 0 | for (iter = 0; iter <= 5; iter++) |
1431 | 0 | { |
1432 | 0 | for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; } |
1433 | 0 | bits_ptr += inc; |
1434 | |
|
1435 | 0 | layer_in(r_int_v, b_int_v, iter); |
1436 | 0 | } |
1437 | |
|
1438 | 0 | for (iter = 4; iter >= 0; iter--) |
1439 | 0 | { |
1440 | 0 | for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; } |
1441 | 0 | bits_ptr += inc; |
1442 | |
|
1443 | 0 | layer_in(r_int_v, b_int_v, iter); |
1444 | 0 | } |
1445 | |
|
1446 | 0 | transpose_64x64(r_int_h[0], r_int_v[0]); |
1447 | 0 | transpose_64x64(r_int_h[1], r_int_v[1]); |
1448 | |
|
1449 | 0 | for (iter = 6; iter >= 0; iter--) |
1450 | 0 | { |
1451 | 0 | for (i = 0; i < 64; i++) |
1452 | 0 | { |
1453 | 0 | b_int_v[i] = load8(bits_ptr); bits_ptr += 8; |
1454 | 0 | } |
1455 | |
|
1456 | 0 | bits_ptr += inc; |
1457 | |
|
1458 | 0 | transpose_64x64(b_int_h, b_int_v); |
1459 | |
|
1460 | 0 | layer_ex(r_int_h[0], b_int_h, iter); |
1461 | 0 | } |
1462 | |
|
1463 | 0 | transpose_64x64(r_int_v[0], r_int_h[0]); |
1464 | 0 | transpose_64x64(r_int_v[1], r_int_h[1]); |
1465 | |
|
1466 | 0 | for (i = 0; i < 64; i++) |
1467 | 0 | { |
1468 | 0 | r[i*2+0] = r_int_v[0][i]; |
1469 | 0 | r[i*2+1] = r_int_v[1][i]; |
1470 | 0 | } |
1471 | 0 | } |
1472 | | |
1473 | | |
1474 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.c */ |
1475 | | /* |
1476 | | This file is for implementating the inversion-free Berlekamp-Massey algorithm |
1477 | | see https://ieeexplore.ieee.org/document/87857 |
1478 | | |
1479 | | For the implementation strategy, see |
1480 | | https://eprint.iacr.org/2017/793.pdf |
1481 | | */ |
1482 | | /* 20221230 djb: add linker lines */ |
1483 | | |
1484 | | /* linker define bm */ |
1485 | | /* linker use vec_mul */ |
1486 | | /* linker use gf_inv */ |
1487 | | |
1488 | | |
1489 | | |
1490 | | static inline uint16_t mask_nonzero(gf a) |
1491 | 0 | { |
1492 | 0 | uint32_t ret = a; |
1493 | |
|
1494 | 0 | ret -= 1; |
1495 | 0 | ret >>= 31; |
1496 | 0 | ret -= 1; |
1497 | |
|
1498 | 0 | return ret; |
1499 | 0 | } |
1500 | | |
1501 | | static inline uint16_t mask_leq(uint16_t a, uint16_t b) |
1502 | 0 | { |
1503 | 0 | uint32_t a_tmp = a; |
1504 | 0 | uint32_t b_tmp = b; |
1505 | 0 | uint32_t ret = b_tmp - a_tmp; |
1506 | |
|
1507 | 0 | ret >>= 31; |
1508 | 0 | ret -= 1; |
1509 | |
|
1510 | 0 | return ret; |
1511 | 0 | } |
1512 | | |
1513 | | static inline void vec_cmov(vec * out, vec * in, uint16_t mask) |
1514 | 0 | { |
1515 | 0 | int i; |
1516 | |
|
1517 | 0 | vec m0, m1; |
1518 | |
|
1519 | 0 | m0 = vec_set1_16b(mask); |
1520 | 0 | m1 = ~m0; |
1521 | |
|
1522 | 0 | for (i = 0; i < GFBITS; i++) |
1523 | 0 | { |
1524 | 0 | out[i] = (in[i] & m0) | (out[i] & m1); |
1525 | 0 | out[i] = (in[i] & m0) | (out[i] & m1); |
1526 | 0 | } |
1527 | 0 | } |
1528 | | |
1529 | | static inline void interleave(vec *in, int idx0, int idx1, vec *mask, int b) |
1530 | 0 | { |
1531 | 0 | int s = 1 << b; |
1532 | |
|
1533 | 0 | vec x, y; |
1534 | |
|
1535 | 0 | x = (in[idx0] & mask[0]) | ((in[idx1] & mask[0]) << s); |
1536 | 0 | y = ((in[idx0] & mask[1]) >> s) | (in[idx1] & mask[1]); |
1537 | |
|
1538 | 0 | in[idx0] = x; |
1539 | 0 | in[idx1] = y; |
1540 | 0 | } |
1541 | | |
1542 | | /* input: in, field elements in bitsliced form */ |
1543 | | /* output: out, field elements in non-bitsliced form */ |
1544 | | static inline void get_coefs(gf *out, vec *in) |
1545 | 0 | { |
1546 | 0 | int i, k; |
1547 | |
|
1548 | 0 | vec mask[4][2]; |
1549 | 0 | vec buf[16]; |
1550 | |
|
1551 | 0 | for (i = 0; i < 13; i++) buf[i] = in[i]; |
1552 | 0 | for (i = 13; i < 16; i++) buf[i] = 0; |
1553 | |
|
1554 | 0 | mask[0][0] = vec_set1_16b(0x5555); |
1555 | 0 | mask[0][1] = vec_set1_16b(0xAAAA); |
1556 | 0 | mask[1][0] = vec_set1_16b(0x3333); |
1557 | 0 | mask[1][1] = vec_set1_16b(0xCCCC); |
1558 | 0 | mask[2][0] = vec_set1_16b(0x0F0F); |
1559 | 0 | mask[2][1] = vec_set1_16b(0xF0F0); |
1560 | 0 | mask[3][0] = vec_set1_16b(0x00FF); |
1561 | 0 | mask[3][1] = vec_set1_16b(0xFF00); |
1562 | |
|
1563 | 0 | interleave(buf, 0, 8, mask[3], 3); |
1564 | 0 | interleave(buf, 1, 9, mask[3], 3); |
1565 | 0 | interleave(buf, 2, 10, mask[3], 3); |
1566 | 0 | interleave(buf, 3, 11, mask[3], 3); |
1567 | 0 | interleave(buf, 4, 12, mask[3], 3); |
1568 | 0 | interleave(buf, 5, 13, mask[3], 3); |
1569 | 0 | interleave(buf, 6, 14, mask[3], 3); |
1570 | 0 | interleave(buf, 7, 15, mask[3], 3); |
1571 | |
|
1572 | 0 | interleave(buf, 0, 4, mask[2], 2); |
1573 | 0 | interleave(buf, 1, 5, mask[2], 2); |
1574 | 0 | interleave(buf, 2, 6, mask[2], 2); |
1575 | 0 | interleave(buf, 3, 7, mask[2], 2); |
1576 | 0 | interleave(buf, 8, 12, mask[2], 2); |
1577 | 0 | interleave(buf, 9, 13, mask[2], 2); |
1578 | 0 | interleave(buf, 10, 14, mask[2], 2); |
1579 | 0 | interleave(buf, 11, 15, mask[2], 2); |
1580 | |
|
1581 | 0 | interleave(buf, 0, 2, mask[1], 1); |
1582 | 0 | interleave(buf, 1, 3, mask[1], 1); |
1583 | 0 | interleave(buf, 4, 6, mask[1], 1); |
1584 | 0 | interleave(buf, 5, 7, mask[1], 1); |
1585 | 0 | interleave(buf, 8, 10, mask[1], 1); |
1586 | 0 | interleave(buf, 9, 11, mask[1], 1); |
1587 | 0 | interleave(buf, 12, 14, mask[1], 1); |
1588 | 0 | interleave(buf, 13, 15, mask[1], 1); |
1589 | |
|
1590 | 0 | interleave(buf, 0, 1, mask[0], 0); |
1591 | 0 | interleave(buf, 2, 3, mask[0], 0); |
1592 | 0 | interleave(buf, 4, 5, mask[0], 0); |
1593 | 0 | interleave(buf, 6, 7, mask[0], 0); |
1594 | 0 | interleave(buf, 8, 9, mask[0], 0); |
1595 | 0 | interleave(buf, 10, 11, mask[0], 0); |
1596 | 0 | interleave(buf, 12, 13, mask[0], 0); |
1597 | 0 | interleave(buf, 14, 15, mask[0], 0); |
1598 | |
|
1599 | 0 | for (i = 0; i < 16; i++) |
1600 | 0 | for (k = 0; k < 4; k++) |
1601 | 0 | out[ k*16 + i ] = (buf[i] >> (k*16)) & GFMASK; |
1602 | 0 | } |
1603 | | |
1604 | | static void update(vec in[][GFBITS], const gf e) |
1605 | 0 | { |
1606 | 0 | int i; |
1607 | 0 | vec tmp; |
1608 | |
|
1609 | 0 | for (i = 0; i < GFBITS; i++) |
1610 | 0 | { |
1611 | 0 | tmp = (e >> i) & 1; |
1612 | |
|
1613 | 0 | in[0][i] = (in[0][i] >> 1) | (in[1][i] << 63); |
1614 | 0 | in[1][i] = (in[1][i] >> 1) | (tmp << 63); |
1615 | 0 | } |
1616 | 0 | } |
1617 | | |
1618 | | static inline gf vec_reduce(vec in[][GFBITS]) |
1619 | 0 | { |
1620 | 0 | int i; |
1621 | 0 | vec tmp; |
1622 | 0 | gf ret = 0; |
1623 | |
|
1624 | 0 | for (i = GFBITS-1; i >= 0; i--) |
1625 | 0 | { |
1626 | 0 | tmp = in[0][i] ^ in[1][i]; |
1627 | |
|
1628 | 0 | tmp ^= tmp >> 32; |
1629 | 0 | tmp ^= tmp >> 16; |
1630 | 0 | tmp ^= tmp >> 8; |
1631 | 0 | tmp ^= tmp >> 4; |
1632 | 0 | tmp ^= tmp >> 2; |
1633 | 0 | tmp ^= tmp >> 1; |
1634 | |
|
1635 | 0 | ret <<= 1; |
1636 | 0 | ret |= tmp & 1; |
1637 | 0 | } |
1638 | |
|
1639 | 0 | return ret; |
1640 | 0 | } |
1641 | | |
1642 | | /* input: in, sequence of field elements */ |
1643 | | /* output: out, minimal polynomial of in */ |
1644 | | static void bm(vec out[][ GFBITS ], vec in[][ GFBITS ]) |
1645 | 0 | { |
1646 | 0 | int i; |
1647 | 0 | uint16_t N, L; |
1648 | 0 | uint16_t mask; |
1649 | 0 | uint64_t one = 1, t; |
1650 | |
|
1651 | 0 | vec prod[2][GFBITS]; |
1652 | 0 | vec interval[2][GFBITS]; |
1653 | 0 | vec dd[2][GFBITS], bb[2][GFBITS]; |
1654 | 0 | vec B[2][GFBITS], C[2][GFBITS]; |
1655 | 0 | vec B_tmp[2][GFBITS], C_tmp[2][GFBITS]; |
1656 | 0 | vec v[GFBITS]; |
1657 | |
|
1658 | 0 | gf d, b, c0 = 1; |
1659 | 0 | gf coefs[256]; |
1660 | | |
1661 | | /* initialization */ |
1662 | |
|
1663 | 0 | get_coefs(&coefs[ 0], in[0]); |
1664 | 0 | get_coefs(&coefs[ 64], in[1]); |
1665 | 0 | get_coefs(&coefs[128], in[2]); |
1666 | 0 | get_coefs(&coefs[192], in[3]); |
1667 | |
|
1668 | 0 | C[0][0] = 0; |
1669 | 0 | C[1][0] = 0; |
1670 | 0 | B[0][0] = 0; |
1671 | 0 | B[1][0] = one << 63; |
1672 | |
|
1673 | 0 | for (i = 1; i < GFBITS; i++) |
1674 | 0 | C[0][i] = C[1][i] = B[0][i] = B[1][i] = 0; |
1675 | |
|
1676 | 0 | b = 1; |
1677 | 0 | L = 0; |
1678 | | |
1679 | | /**/ |
1680 | |
|
1681 | 0 | for (i = 0; i < GFBITS; i++) |
1682 | 0 | interval[0][i] = interval[1][i] = 0; |
1683 | |
|
1684 | 0 | for (N = 0; N < 256; N++) |
1685 | 0 | { |
1686 | 0 | vec_mul(prod[0], C[0], interval[0]); |
1687 | 0 | vec_mul(prod[1], C[1], interval[1]); |
1688 | 0 | update(interval, coefs[N]); |
1689 | 0 | d = vec_reduce(prod); |
1690 | |
|
1691 | 0 | t = gf_mul2(c0, coefs[N], b); |
1692 | 0 | d ^= t & 0xFFFFFFFF; |
1693 | |
|
1694 | 0 | mask = mask_nonzero(d) & mask_leq(L*2, N); |
1695 | |
|
1696 | 0 | for (i = 0; i < GFBITS; i++) |
1697 | 0 | { |
1698 | 0 | dd[0][i] = dd[1][i] = vec_setbits((d >> i) & 1); |
1699 | 0 | bb[0][i] = bb[1][i] = vec_setbits((b >> i) & 1); |
1700 | 0 | } |
1701 | |
|
1702 | 0 | vec_mul(B_tmp[0], dd[0], B[0]); |
1703 | 0 | vec_mul(B_tmp[1], dd[1], B[1]); |
1704 | 0 | vec_mul(C_tmp[0], bb[0], C[0]); |
1705 | 0 | vec_mul(C_tmp[1], bb[1], C[1]); |
1706 | |
|
1707 | 0 | vec_cmov(B[0], C[0], mask); |
1708 | 0 | vec_cmov(B[1], C[1], mask); |
1709 | 0 | update(B, c0 & mask); |
1710 | |
|
1711 | 0 | for (i = 0; i < GFBITS; i++) |
1712 | 0 | { |
1713 | 0 | C[0][i] = B_tmp[0][i] ^ C_tmp[0][i]; |
1714 | 0 | C[1][i] = B_tmp[1][i] ^ C_tmp[1][i]; |
1715 | 0 | } |
1716 | |
|
1717 | 0 | c0 = t >> 32; |
1718 | 0 | b = (d & mask) | (b & ~mask); |
1719 | 0 | L = ((N+1-L) & mask) | (L & ~mask); |
1720 | 0 | } |
1721 | |
|
1722 | 0 | c0 = gf_inv(c0); |
1723 | |
|
1724 | 0 | for (i = 0; i < GFBITS; i++) |
1725 | 0 | v[i] = vec_setbits((c0 >> i) & 1); |
1726 | |
|
1727 | 0 | vec_mul(out[0], C[0], v); |
1728 | 0 | vec_mul(out[1], C[1], v); |
1729 | 0 | } |
1730 | | |
1731 | | |
1732 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c */ |
1733 | | /* This file is for implementing the Nassimi-Sahni algorithm */ |
1734 | | /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */ |
1735 | | /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */ |
1736 | | |
1737 | | /* 20221230 djb: add linker line */ |
1738 | | |
1739 | | /* linker define controlbitsfrompermutation */ |
1740 | | |
1741 | | typedef int16_t int16; |
1742 | | typedef int32_t int32; |
1743 | 0 | #define int32_min crypto_int32_min |
1744 | | |
1745 | | /* parameters: 1 <= w <= 14; n = 2^w */ |
1746 | | /* input: permutation pi of {0,1,...,n-1} */ |
1747 | | /* output: (2m-1)n/2 control bits at positions pos,pos+step,... */ |
1748 | | /* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */ |
1749 | | /* caller must 0-initialize positions first */ |
1750 | | /* temp must have space for int32[2*n] */ |
1751 | | static void cbrecursion(unsigned char *out,long long pos,long long step,const int16 *pi,long long w,long long n,int32 *temp) |
1752 | 0 | { |
1753 | 0 | #define A temp |
1754 | 0 | #define B (temp+n) |
1755 | 0 | #define q ((int16 *) (temp+n+n/4)) |
1756 | | /* q can start anywhere between temp+n and temp+n/2 */ |
1757 | |
|
1758 | 0 | long long x,i,j,k; |
1759 | |
|
1760 | 0 | if (w == 1) { |
1761 | 0 | out[pos>>3] ^= pi[0]<<(pos&7); |
1762 | 0 | return; |
1763 | 0 | } |
1764 | | |
1765 | 0 | for (x = 0;x < n;++x) A[x] = ((pi[x]^1)<<16)|pi[x^1]; |
1766 | 0 | int32_sort(A,n); /* A = (id<<16)+pibar */ |
1767 | |
|
1768 | 0 | for (x = 0;x < n;++x) { |
1769 | 0 | int32 Ax = A[x]; |
1770 | 0 | int32 px = Ax&0xffff; |
1771 | 0 | int32 cx = int32_min(px,x); |
1772 | 0 | B[x] = (px<<16)|cx; |
1773 | 0 | } |
1774 | | /* B = (p<<16)+c */ |
1775 | |
|
1776 | 0 | for (x = 0;x < n;++x) A[x] = (A[x]<<16)|x; /* A = (pibar<<16)+id */ |
1777 | 0 | int32_sort(A,n); /* A = (id<<16)+pibar^-1 */ |
1778 | |
|
1779 | 0 | for (x = 0;x < n;++x) A[x] = (A[x]<<16)+(B[x]>>16); /* A = (pibar^(-1)<<16)+pibar */ |
1780 | 0 | int32_sort(A,n); /* A = (id<<16)+pibar^2 */ |
1781 | |
|
1782 | 0 | if (w <= 10) { |
1783 | 0 | for (x = 0;x < n;++x) B[x] = ((A[x]&0xffff)<<10)|(B[x]&0x3ff); |
1784 | |
|
1785 | 0 | for (i = 1;i < w-1;++i) { |
1786 | | /* B = (p<<10)+c */ |
1787 | |
|
1788 | 0 | for (x = 0;x < n;++x) A[x] = ((B[x]&~0x3ff)<<6)|x; /* A = (p<<16)+id */ |
1789 | 0 | int32_sort(A,n); /* A = (id<<16)+p^{-1} */ |
1790 | |
|
1791 | 0 | for (x = 0;x < n;++x) A[x] = (A[x]<<20)|B[x]; /* A = (p^{-1}<<20)+(p<<10)+c */ |
1792 | 0 | int32_sort(A,n); /* A = (id<<20)+(pp<<10)+cp */ |
1793 | |
|
1794 | 0 | for (x = 0;x < n;++x) { |
1795 | 0 | int32 ppcpx = A[x]&0xfffff; |
1796 | 0 | int32 ppcx = (A[x]&0xffc00)|(B[x]&0x3ff); |
1797 | 0 | B[x] = int32_min(ppcx,ppcpx); |
1798 | 0 | } |
1799 | 0 | } |
1800 | 0 | for (x = 0;x < n;++x) B[x] &= 0x3ff; |
1801 | 0 | } else { |
1802 | 0 | for (x = 0;x < n;++x) B[x] = (A[x]<<16)|(B[x]&0xffff); |
1803 | |
|
1804 | 0 | for (i = 1;i < w-1;++i) { |
1805 | | /* B = (p<<16)+c */ |
1806 | |
|
1807 | 0 | for (x = 0;x < n;++x) A[x] = (B[x]&~0xffff)|x; |
1808 | 0 | int32_sort(A,n); /* A = (id<<16)+p^(-1) */ |
1809 | |
|
1810 | 0 | for (x = 0;x < n;++x) A[x] = (A[x]<<16)|(B[x]&0xffff); |
1811 | | /* A = p^(-1)<<16+c */ |
1812 | |
|
1813 | 0 | if (i < w-2) { |
1814 | 0 | for (x = 0;x < n;++x) B[x] = (A[x]&~0xffff)|(B[x]>>16); |
1815 | | /* B = (p^(-1)<<16)+p */ |
1816 | 0 | int32_sort(B,n); /* B = (id<<16)+p^(-2) */ |
1817 | 0 | for (x = 0;x < n;++x) B[x] = (B[x]<<16)|(A[x]&0xffff); |
1818 | | /* B = (p^(-2)<<16)+c */ |
1819 | 0 | } |
1820 | |
|
1821 | 0 | int32_sort(A,n); |
1822 | | /* A = id<<16+cp */ |
1823 | 0 | for (x = 0;x < n;++x) { |
1824 | 0 | int32 cpx = (B[x]&~0xffff)|(A[x]&0xffff); |
1825 | 0 | B[x] = int32_min(B[x],cpx); |
1826 | 0 | } |
1827 | 0 | } |
1828 | 0 | for (x = 0;x < n;++x) B[x] &= 0xffff; |
1829 | 0 | } |
1830 | |
|
1831 | 0 | for (x = 0;x < n;++x) A[x] = (((int32)pi[x])<<16)+x; |
1832 | 0 | int32_sort(A,n); /* A = (id<<16)+pi^(-1) */ |
1833 | |
|
1834 | 0 | for (j = 0;j < n/2;++j) { |
1835 | 0 | long long lx = 2*j; |
1836 | 0 | int32 fj = B[lx]&1; /* f[j] */ |
1837 | 0 | int32 Fx = lx+fj; /* F[x] */ |
1838 | 0 | int32 Fx1 = Fx^1; /* F[x+1] */ |
1839 | |
|
1840 | 0 | out[pos>>3] ^= fj<<(pos&7); |
1841 | 0 | pos += step; |
1842 | |
|
1843 | 0 | B[lx] = (A[lx]<<16)|Fx; |
1844 | 0 | B[lx+1] = (A[lx+1]<<16)|Fx1; |
1845 | 0 | } |
1846 | | /* B = (pi^(-1)<<16)+F */ |
1847 | |
|
1848 | 0 | int32_sort(B,n); /* B = (id<<16)+F(pi) */ |
1849 | |
|
1850 | 0 | pos += (2*w-3)*step*(n/2); |
1851 | |
|
1852 | 0 | for (k = 0;k < n/2;++k) { |
1853 | 0 | long long y = 2*k; |
1854 | 0 | int32 lk = B[y]&1; /* l[k] */ |
1855 | 0 | int32 Ly = y+lk; /* L[y] */ |
1856 | 0 | int32 Ly1 = Ly^1; /* L[y+1] */ |
1857 | |
|
1858 | 0 | out[pos>>3] ^= lk<<(pos&7); |
1859 | 0 | pos += step; |
1860 | |
|
1861 | 0 | A[y] = (Ly<<16)|(B[y]&0xffff); |
1862 | 0 | A[y+1] = (Ly1<<16)|(B[y+1]&0xffff); |
1863 | 0 | } |
1864 | | /* A = (L<<16)+F(pi) */ |
1865 | |
|
1866 | 0 | int32_sort(A,n); /* A = (id<<16)+F(pi(L)) = (id<<16)+M */ |
1867 | |
|
1868 | 0 | pos -= (2*w-2)*step*(n/2); |
1869 | |
|
1870 | 0 | for (j = 0;j < n/2;++j) { |
1871 | 0 | q[j] = (A[2*j]&0xffff)>>1; |
1872 | 0 | q[j+n/2] = (A[2*j+1]&0xffff)>>1; |
1873 | 0 | } |
1874 | |
|
1875 | 0 | cbrecursion(out,pos,step*2,q,w-1,n/2,temp); |
1876 | 0 | cbrecursion(out,pos+step,step*2,q+n/2,w-1,n/2,temp); |
1877 | 0 | } |
1878 | | |
1879 | | /* input: p, an array of int16 */ |
1880 | | /* input: n, length of p */ |
1881 | | /* input: s, meaning that stride-2^s cswaps are performed */ |
1882 | | /* input: cb, the control bits */ |
1883 | | /* output: the result of apply the control bits to p */ |
1884 | | static void layer(int16_t *p, const unsigned char *cb, int s, int n) |
1885 | 0 | { |
1886 | 0 | int i, j; |
1887 | 0 | int stride = 1 << s; |
1888 | 0 | int index = 0; |
1889 | 0 | int16_t d, m; |
1890 | |
|
1891 | 0 | for (i = 0; i < n; i += stride*2) |
1892 | 0 | { |
1893 | 0 | for (j = 0; j < stride; j++) |
1894 | 0 | { |
1895 | 0 | d = p[ i+j ] ^ p[ i+j+stride ]; |
1896 | 0 | m = (cb[ index >> 3 ] >> (index & 7)) & 1; |
1897 | 0 | m = -m; |
1898 | 0 | d &= m; |
1899 | 0 | p[ i+j ] ^= d; |
1900 | 0 | p[ i+j+stride ] ^= d; |
1901 | 0 | index++; |
1902 | 0 | } |
1903 | 0 | } |
1904 | 0 | } |
1905 | | |
1906 | | /* parameters: 1 <= w <= 14; n = 2^w */ |
1907 | | /* input: permutation pi of {0,1,...,n-1} */ |
1908 | | /* output: (2m-1)n/2 control bits at positions 0,1,... */ |
1909 | | /* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */ |
1910 | | static void controlbitsfrompermutation(unsigned char *out,const int16 *pi,long long w,long long n) |
1911 | 0 | { |
1912 | 0 | int32 temp[2*n]; |
1913 | 0 | int16 pi_test[n], diff; |
1914 | 0 | int i; |
1915 | 0 | unsigned char *ptr; |
1916 | |
|
1917 | 0 | while (1) |
1918 | 0 | { |
1919 | 0 | memset(out,0,(((2*w-1)*n/2)+7)/8); |
1920 | 0 | cbrecursion(out,0,1,pi,w,n,temp); |
1921 | | |
1922 | | /* check for correctness */ |
1923 | |
|
1924 | 0 | for (i = 0; i < n; i++) |
1925 | 0 | pi_test[i] = i; |
1926 | |
|
1927 | 0 | ptr = out; |
1928 | 0 | for (i = 0; i < w; i++) |
1929 | 0 | { |
1930 | 0 | layer(pi_test, ptr, i, n); |
1931 | 0 | ptr += n >> 4; |
1932 | 0 | } |
1933 | |
|
1934 | 0 | for (i = w-2; i >= 0; i--) |
1935 | 0 | { |
1936 | 0 | layer(pi_test, ptr, i, n); |
1937 | 0 | ptr += n >> 4; |
1938 | 0 | } |
1939 | |
|
1940 | 0 | diff = 0; |
1941 | 0 | for (i = 0; i < n; i++) |
1942 | 0 | diff |= pi[i] ^ pi_test[i]; |
1943 | |
|
1944 | 0 | diff = crypto_int16_nonzero_mask(diff); |
1945 | 0 | crypto_declassify(&diff,sizeof diff); |
1946 | 0 | if (diff == 0) |
1947 | 0 | break; |
1948 | 0 | } |
1949 | 0 | } |
1950 | | |
1951 | | #undef A |
1952 | | #undef B |
1953 | | #undef q |
1954 | | |
1955 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c */ |
1956 | | /* |
1957 | | This file is for Niederreiter decryption |
1958 | | */ |
1959 | | /* 20221230 djb: add linker lines */ |
1960 | | |
1961 | | /* linker define decrypt */ |
1962 | | /* linker use benes bm fft fft_tr */ |
1963 | | /* linker use vec_mul vec_sq vec_inv */ |
1964 | | |
1965 | | |
1966 | | |
1967 | | |
1968 | | static void scaling(vec out[][GFBITS], vec inv[][GFBITS], const unsigned char *sk, vec *recv) |
1969 | 0 | { |
1970 | 0 | int i, j; |
1971 | |
|
1972 | 0 | vec irr_int[2][ GFBITS ]; |
1973 | 0 | vec eval[128][ GFBITS ]; |
1974 | 0 | vec tmp[ GFBITS ]; |
1975 | | |
1976 | | /**/ |
1977 | |
|
1978 | 0 | irr_load(irr_int, sk); |
1979 | |
|
1980 | 0 | fft(eval, irr_int); |
1981 | |
|
1982 | 0 | for (i = 0; i < 128; i++) |
1983 | 0 | vec_sq(eval[i], eval[i]); |
1984 | |
|
1985 | 0 | vec_copy(inv[0], eval[0]); |
1986 | |
|
1987 | 0 | for (i = 1; i < 128; i++) |
1988 | 0 | vec_mul(inv[i], inv[i-1], eval[i]); |
1989 | |
|
1990 | 0 | vec_inv(tmp, inv[127]); |
1991 | |
|
1992 | 0 | for (i = 126; i >= 0; i--) |
1993 | 0 | { |
1994 | 0 | vec_mul(inv[i+1], tmp, inv[i]); |
1995 | 0 | vec_mul(tmp, tmp, eval[i+1]); |
1996 | 0 | } |
1997 | |
|
1998 | 0 | vec_copy(inv[0], tmp); |
1999 | | |
2000 | | /**/ |
2001 | |
|
2002 | 0 | for (i = 0; i < 128; i++) |
2003 | 0 | for (j = 0; j < GFBITS; j++) |
2004 | 0 | out[i][j] = inv[i][j] & recv[i]; |
2005 | 0 | } |
2006 | | |
2007 | | static void preprocess(vec *recv, const unsigned char *s) |
2008 | 0 | { |
2009 | 0 | int i; |
2010 | 0 | unsigned char r[ 1024 ]; |
2011 | |
|
2012 | 0 | for (i = 0; i < SYND_BYTES; i++) |
2013 | 0 | r[i] = s[i]; |
2014 | |
|
2015 | 0 | for (i = SYND_BYTES; i < 1024; i++) |
2016 | 0 | r[i] = 0; |
2017 | |
|
2018 | 0 | for (i = 0; i < 128; i++) |
2019 | 0 | recv[i] = load8(r + i*8); |
2020 | 0 | } |
2021 | | |
2022 | | static void postprocess(unsigned char * e, vec * err) |
2023 | 0 | { |
2024 | 0 | int i; |
2025 | 0 | unsigned char error8[ (1 << GFBITS)/8 ]; |
2026 | |
|
2027 | 0 | for (i = 0; i < 128; i++) |
2028 | 0 | store8(error8 + i*8, err[i]); |
2029 | |
|
2030 | 0 | for (i = 0; i < SYS_N/8; i++) |
2031 | 0 | e[i] = error8[i]; |
2032 | 0 | } |
2033 | | |
2034 | | static void scaling_inv(vec out[][GFBITS], vec inv[][GFBITS], vec *recv) |
2035 | 0 | { |
2036 | 0 | int i, j; |
2037 | |
|
2038 | 0 | for (i = 0; i < 128; i++) |
2039 | 0 | for (j = 0; j < GFBITS; j++) |
2040 | 0 | out[i][j] = inv[i][j] & recv[i]; |
2041 | 0 | } |
2042 | | |
2043 | | static int weight_check(unsigned char * e, vec * error) |
2044 | 0 | { |
2045 | 0 | int i; |
2046 | 0 | uint16_t w0 = 0; |
2047 | 0 | uint16_t w1 = 0; |
2048 | 0 | uint16_t check; |
2049 | |
|
2050 | 0 | for (i = 0; i < (1 << GFBITS); i++) |
2051 | 0 | w0 += (error[i/64] >> (i%64)) & 1; |
2052 | |
|
2053 | 0 | for (i = 0; i < SYS_N; i++) |
2054 | 0 | w1 += (e[i/8] >> (i%8)) & 1; |
2055 | |
|
2056 | 0 | check = (w0 ^ SYS_T) | (w1 ^ SYS_T); |
2057 | 0 | check -= 1; |
2058 | 0 | check >>= 15; |
2059 | |
|
2060 | 0 | return check; |
2061 | 0 | } |
2062 | | |
2063 | | static uint16_t synd_cmp(vec s0[][ GFBITS ] , vec s1[][ GFBITS ]) |
2064 | 0 | { |
2065 | 0 | int i, j; |
2066 | 0 | vec diff = 0; |
2067 | |
|
2068 | 0 | for (i = 0; i < 4; i++) |
2069 | 0 | for (j = 0; j < GFBITS; j++) |
2070 | 0 | diff |= (s0[i][j] ^ s1[i][j]); |
2071 | |
|
2072 | 0 | return vec_testz(diff); |
2073 | 0 | } |
2074 | | |
2075 | | /* Niederreiter decryption with the Berlekamp decoder */ |
2076 | | /* intput: sk, secret key */ |
2077 | | /* s, ciphertext (syndrome) */ |
2078 | | /* output: e, error vector */ |
2079 | | /* return: 0 for success; 1 for failure */ |
2080 | | static int decrypt(unsigned char *e, const unsigned char *sk, const unsigned char *s) |
2081 | 0 | { |
2082 | 0 | int i; |
2083 | |
|
2084 | 0 | uint16_t check_synd; |
2085 | 0 | uint16_t check_weight; |
2086 | |
|
2087 | 0 | vec inv[ 128 ][ GFBITS ]; |
2088 | 0 | vec scaled[ 128 ][ GFBITS ]; |
2089 | 0 | vec eval[ 128 ][ GFBITS ]; |
2090 | |
|
2091 | 0 | vec error[ 128 ]; |
2092 | |
|
2093 | 0 | vec s_priv[ 4 ][ GFBITS ]; |
2094 | 0 | vec s_priv_cmp[ 4 ][ GFBITS ]; |
2095 | 0 | vec locator[2][ GFBITS ]; |
2096 | |
|
2097 | 0 | vec recv[ 128 ]; |
2098 | 0 | vec allone; |
2099 | | |
2100 | | /* Berlekamp decoder */ |
2101 | |
|
2102 | 0 | preprocess(recv, s); |
2103 | |
|
2104 | 0 | benes(recv, sk + IRR_BYTES, 1); |
2105 | 0 | scaling(scaled, inv, sk, recv); |
2106 | 0 | fft_tr(s_priv, scaled); |
2107 | 0 | bm(locator, s_priv); |
2108 | |
|
2109 | 0 | fft(eval, locator); |
2110 | | |
2111 | | /* reencryption and weight check */ |
2112 | |
|
2113 | 0 | allone = vec_setbits(1); |
2114 | |
|
2115 | 0 | for (i = 0; i < 128; i++) |
2116 | 0 | { |
2117 | 0 | error[i] = vec_or_reduce(eval[i]); |
2118 | 0 | error[i] ^= allone; |
2119 | 0 | } |
2120 | |
|
2121 | 0 | scaling_inv(scaled, inv, error); |
2122 | 0 | fft_tr(s_priv_cmp, scaled); |
2123 | |
|
2124 | 0 | check_synd = synd_cmp(s_priv, s_priv_cmp); |
2125 | | |
2126 | | /**/ |
2127 | |
|
2128 | 0 | benes(error, sk + IRR_BYTES, 0); |
2129 | |
|
2130 | 0 | postprocess(e, error); |
2131 | |
|
2132 | 0 | check_weight = weight_check(e, error); |
2133 | |
|
2134 | | #ifdef KAT |
2135 | | { |
2136 | | int k; |
2137 | | printf("decrypt e: positions"); |
2138 | | for (k = 0;k < SYS_N;++k) |
2139 | | if (e[k/8] & (1 << (k&7))) |
2140 | | printf(" %d",k); |
2141 | | printf("\n"); |
2142 | | } |
2143 | | #endif |
2144 | |
|
2145 | 0 | return 1 - (check_synd & check_weight); |
2146 | 0 | } |
2147 | | |
2148 | | |
2149 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c */ |
2150 | | /* 20230102 djb: rename encrypt() as pke_encrypt() */ |
2151 | | /* 20221231 djb: move encrypt.h last for macos portability; tnx thom wiggers */ |
2152 | | /* 20221230 djb: add linker line */ |
2153 | | |
2154 | | /* linker define pke_encrypt */ |
2155 | | |
2156 | | /* |
2157 | | This file is for Niederreiter encryption |
2158 | | */ |
2159 | | |
2160 | | |
2161 | | |
2162 | | |
2163 | | |
2164 | | static inline crypto_uint16 uint16_is_smaller_declassify(uint16_t t,uint16_t u) |
2165 | 0 | { |
2166 | 0 | crypto_uint16 mask = crypto_uint16_smaller_mask(t,u); |
2167 | 0 | crypto_declassify(&mask,sizeof mask); |
2168 | 0 | return mask; |
2169 | 0 | } |
2170 | | |
2171 | | static inline crypto_uint32 uint32_is_equal_declassify(uint32_t t,uint32_t u) |
2172 | 0 | { |
2173 | 0 | crypto_uint32 mask = crypto_uint32_equal_mask(t,u); |
2174 | 0 | crypto_declassify(&mask,sizeof mask); |
2175 | 0 | return mask; |
2176 | 0 | } |
2177 | | |
2178 | | /* output: e, an error vector of weight t */ |
2179 | | static void gen_e(unsigned char *e) |
2180 | 0 | { |
2181 | 0 | int i, j, eq, count; |
2182 | |
|
2183 | 0 | union |
2184 | 0 | { |
2185 | 0 | uint16_t nums[ SYS_T*2 ]; |
2186 | 0 | unsigned char bytes[ SYS_T*2 * sizeof(uint16_t) ]; |
2187 | 0 | } buf; |
2188 | |
|
2189 | 0 | uint16_t ind[ SYS_T ]; |
2190 | 0 | uint64_t e_int[ (SYS_N+63)/64 ]; |
2191 | 0 | uint64_t one = 1; |
2192 | 0 | uint64_t mask; |
2193 | 0 | uint64_t val[ SYS_T ]; |
2194 | |
|
2195 | 0 | while (1) |
2196 | 0 | { |
2197 | 0 | randombytes(buf.bytes, sizeof(buf)); |
2198 | |
|
2199 | 0 | for (i = 0; i < SYS_T*2; i++) |
2200 | 0 | buf.nums[i] = load_gf(buf.bytes + i*2); |
2201 | | |
2202 | | /* moving and counting indices in the correct range */ |
2203 | |
|
2204 | 0 | count = 0; |
2205 | 0 | for (i = 0; i < SYS_T*2 && count < SYS_T; i++) |
2206 | 0 | if (uint16_is_smaller_declassify(buf.nums[i],SYS_N)) |
2207 | 0 | ind[ count++ ] = buf.nums[i]; |
2208 | |
|
2209 | 0 | if (count < SYS_T) continue; |
2210 | | |
2211 | | /* check for repetition */ |
2212 | | |
2213 | 0 | uint16_sort(ind, SYS_T); |
2214 | |
|
2215 | 0 | eq = 0; |
2216 | 0 | for (i = 1; i < SYS_T; i++) |
2217 | 0 | if (uint32_is_equal_declassify(ind[i-1],ind[i])) |
2218 | 0 | eq = 1; |
2219 | |
|
2220 | 0 | if (eq == 0) |
2221 | 0 | break; |
2222 | 0 | } |
2223 | |
|
2224 | 0 | for (j = 0; j < SYS_T; j++) |
2225 | 0 | val[j] = one << (ind[j] & 63); |
2226 | |
|
2227 | 0 | for (i = 0; i < (SYS_N+63)/64; i++) |
2228 | 0 | { |
2229 | 0 | e_int[i] = 0; |
2230 | |
|
2231 | 0 | for (j = 0; j < SYS_T; j++) |
2232 | 0 | { |
2233 | 0 | mask = i ^ (ind[j] >> 6); |
2234 | 0 | mask -= 1; |
2235 | 0 | mask >>= 63; |
2236 | 0 | mask = -mask; |
2237 | |
|
2238 | 0 | e_int[i] |= val[j] & mask; |
2239 | 0 | } |
2240 | 0 | } |
2241 | |
|
2242 | 0 | for (i = 0; i < (SYS_N+63)/64 - 1; i++) |
2243 | 0 | { store8(e, e_int[i]); e += 8; } |
2244 | |
|
2245 | 0 | for (j = 0; j < (SYS_N % 64); j+=8) |
2246 | 0 | e[ j/8 ] = (e_int[i] >> j) & 0xFF; |
2247 | 0 | } |
2248 | | |
2249 | | /* input: public key pk, error vector e */ |
2250 | | /* output: syndrome s */ |
2251 | | static void syndrome(unsigned char *s, const unsigned char *pk, unsigned char *e) |
2252 | 0 | { |
2253 | 0 | uint64_t b; |
2254 | |
|
2255 | 0 | const uint64_t *pk_ptr; |
2256 | 0 | const uint64_t *e_ptr = ((uint64_t *) (e + SYND_BYTES)); |
2257 | |
|
2258 | 0 | int i, j; |
2259 | | |
2260 | | /**/ |
2261 | |
|
2262 | 0 | for (i = 0; i < SYND_BYTES; i++) |
2263 | 0 | s[i] = e[i]; |
2264 | |
|
2265 | 0 | for (i = 0; i < PK_NROWS; i++) |
2266 | 0 | { |
2267 | 0 | pk_ptr = ((uint64_t *) (pk + PK_ROW_BYTES * i)); |
2268 | |
|
2269 | 0 | b = 0; |
2270 | 0 | for (j = 0; j < PK_NCOLS/64; j++) |
2271 | 0 | b ^= pk_ptr[j] & e_ptr[j]; |
2272 | |
|
2273 | 0 | b ^= ((uint32_t *) &pk_ptr[j])[0] & ((uint32_t *) &e_ptr[j])[0]; |
2274 | |
|
2275 | 0 | b ^= b >> 32; |
2276 | 0 | b ^= b >> 16; |
2277 | 0 | b ^= b >> 8; |
2278 | 0 | b ^= b >> 4; |
2279 | 0 | b ^= b >> 2; |
2280 | 0 | b ^= b >> 1; |
2281 | 0 | b &= 1; |
2282 | |
|
2283 | 0 | s[ i/8 ] ^= (b << (i%8)); |
2284 | 0 | } |
2285 | 0 | } |
2286 | | |
2287 | | /* input: public key pk */ |
2288 | | /* output: error vector e, syndrome s */ |
2289 | | static void pke_encrypt(unsigned char *s, const unsigned char *pk, unsigned char *e) |
2290 | 0 | { |
2291 | 0 | gen_e(e); |
2292 | |
|
2293 | | #ifdef KAT |
2294 | | { |
2295 | | int k; |
2296 | | printf("encrypt e: positions"); |
2297 | | for (k = 0;k < SYS_N;++k) |
2298 | | if (e[k/8] & (1 << (k&7))) |
2299 | | printf(" %d",k); |
2300 | | printf("\n"); |
2301 | | } |
2302 | | #endif |
2303 | |
|
2304 | 0 | syndrome(s, pk, e); |
2305 | 0 | } |
2306 | | |
2307 | | |
2308 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c */ |
2309 | | /* linker define fft_consts */ |
2310 | | |
2311 | | |
2312 | | const vec fft_consts[128][GFBITS] = { |
2313 | | { 0x6969969669699696, 0x9966669966999966, 0x9966669966999966, 0xFF0000FF00FFFF00, 0xCC3333CCCC3333CC, 0x9966669966999966, 0x6666666666666666, 0xA55AA55AA55AA55A, 0xCCCC33333333CCCC, 0x5A5A5A5A5A5A5A5A, 0x55AAAA55AA5555AA, 0x0FF0F00FF00F0FF0, 0x5AA55AA5A55AA55A }, { 0x6969969669699696, 0x9966669966999966, 0x9966669966999966, 0xFF0000FF00FFFF00, 0xCC3333CCCC3333CC, 0x9966669966999966, 0x6666666666666666, 0xA55AA55AA55AA55A, 0xCCCC33333333CCCC, 0x5A5A5A5A5A5A5A5A, 0x55AAAA55AA5555AA, 0x0FF0F00FF00F0FF0, 0x5AA55AA5A55AA55A }, { 0xA55A5AA55AA5A55A, 0x6969696996969696, 0x5AA55AA5A55AA55A, 0x9999999966666666, 0x3C3CC3C3C3C33C3C, 0xFFFF0000FFFF0000, 0x0000000000000000, 0xCC33CC3333CC33CC, 0x0000000000000000, 0x3C3C3C3C3C3C3C3C, 0xAA5555AAAA5555AA, 0xC33C3CC33CC3C33C, 0x00FFFF0000FFFF00 }, { 0xA55A5AA55AA5A55A, 0x6969696996969696, 0x5AA55AA5A55AA55A, 0x6666666699999999, 0xC3C33C3C3C3CC3C3, 0x0000FFFF0000FFFF, 0x0000000000000000, 0x33CC33CCCC33CC33, 0x0000000000000000, 0x3C3C3C3C3C3C3C3C, 0xAA5555AAAA5555AA, 0xC33C3CC33CC3C33C, 0xFF0000FFFF0000FF }, { 0xFFFFFFFF00000000, 0xA5A5A5A55A5A5A5A, 0x0FF0F00FF00F0FF0, 0x9669966969966996, 0x0000FFFFFFFF0000, 0x33333333CCCCCCCC, 0xA55A5AA55AA5A55A, 0x00FFFF0000FFFF00, 0x0000000000000000, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAA55555555AAAA }, { 0xFFFFFFFF00000000, 0xA5A5A5A55A5A5A5A, 0x0FF0F00FF00F0FF0, 0x6996699696699669, 0xFFFF00000000FFFF, 0x33333333CCCCCCCC, 0x5AA5A55AA55A5AA5, 0xFF0000FFFF0000FF, 0xFFFFFFFFFFFFFFFF, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0x5555AAAAAAAA5555 }, { 0xFFFFFFFF00000000, 0x5A5A5A5AA5A5A5A5, 0xF00F0FF00FF0F00F, 0x6996699696699669, 0x0000FFFFFFFF0000, 0x33333333CCCCCCCC, 0x5AA5A55AA55A5AA5, 0xFF0000FFFF0000FF, 0xFFFFFFFFFFFFFFFF, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAA55555555AAAA }, { 0xFFFFFFFF00000000, 0x5A5A5A5AA5A5A5A5, 0xF00F0FF00FF0F00F, 0x9669966969966996, 0xFFFF00000000FFFF, 0x33333333CCCCCCCC, 0xA55A5AA55AA5A55A, 0x00FFFF0000FFFF00, 0x0000000000000000, 0xC33CC33CC33CC33C, 0x0F0FF0F00F0FF0F0, 0xCCCCCCCCCCCCCCCC, 0x5555AAAAAAAA5555 }, { 0xC33C3CC33CC3C33C, 0x9966669966999966, 0x9966996699669966, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x9966996699669966, 0x5AA5A55A5AA5A55A, 0xC3C3C3C33C3C3C3C, 0x3CC33CC3C33CC33C, 0x3333CCCC3333CCCC, 0x9999999966666666, 0xC33CC33CC33CC33C, 0x6666999999996666 }, { 0x3CC3C33CC33C3CC3, 0x6699996699666699, 0x6699669966996699, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x9966996699669966, 0xA55A5AA5A55A5AA5, 0xC3C3C3C33C3C3C3C, 0x3CC33CC3C33CC33C, 0x3333CCCC3333CCCC, 0x6666666699999999, 0x3CC33CC33CC33CC3, 0x9999666666669999 }, { 0xC33C3CC33CC3C33C, 0x9966669966999966, 0x6699669966996699, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x6699669966996699, 0x5AA5A55A5AA5A55A, 0x3C3C3C3CC3C3C3C3, 0xC33CC33C3CC33CC3, 0xCCCC3333CCCC3333, 0x6666666699999999, 0xC33CC33CC33CC33C, 0x9999666666669999 }, { 0x3CC3C33CC33C3CC3, 0x6699996699666699, 0x9966996699669966, 0x6969969669699696, 0xAA55AA5555AA55AA, 0x6699669966996699, 0xA55A5AA5A55A5AA5, 0x3C3C3C3CC3C3C3C3, 0xC33CC33C3CC33CC3, 0xCCCC3333CCCC3333, 0x9999999966666666, 0x3CC33CC33CC33CC3, 0x6666999999996666 }, { 0xC33C3CC33CC3C33C, 0x6699996699666699, 0x6699669966996699, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x9966996699669966, 0x5AA5A55A5AA5A55A, 0xC3C3C3C33C3C3C3C, 0xC33CC33C3CC33CC3, 0x3333CCCC3333CCCC, 0x9999999966666666, 0xC33CC33CC33CC33C, 0x6666999999996666 }, { 0x3CC3C33CC33C3CC3, 0x9966669966999966, 0x9966996699669966, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x9966996699669966, 0xA55A5AA5A55A5AA5, 0xC3C3C3C33C3C3C3C, 0xC33CC33C3CC33CC3, 0x3333CCCC3333CCCC, 0x6666666699999999, 0x3CC33CC33CC33CC3, 0x9999666666669999 }, { 0xC33C3CC33CC3C33C, 0x6699996699666699, 0x9966996699669966, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x6699669966996699, 0x5AA5A55A5AA5A55A, 0x3C3C3C3CC3C3C3C3, 0x3CC33CC3C33CC33C, 0xCCCC3333CCCC3333, 0x6666666699999999, 0xC33CC33CC33CC33C, 0x9999666666669999 }, { 0x3CC3C33CC33C3CC3, 0x9966669966999966, 0x6699669966996699, 0x6969969669699696, 0x55AA55AAAA55AA55, 0x6699669966996699, 0xA55A5AA5A55A5AA5, 0x3C3C3C3CC3C3C3C3, 0x3CC33CC3C33CC33C, 0xCCCC3333CCCC3333, 0x9999999966666666, 0x3CC33CC33CC33CC3, 0x6666999999996666 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0xAA5555AA55AAAA55, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0x55555555AAAAAAAA, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0x55555555AAAAAAAA, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0x55AAAA55AA5555AA, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x9669699696696996, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0xA55AA55AA55AA55A, 0xAAAAAAAA55555555, 0xCCCC33333333CCCC, 0x0000FFFFFFFF0000, 0xFF0000FF00FFFF00, 0x6996699669966996 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0xA55AA55A5AA55AA5, 0x55AAAA55AA5555AA, 0x0FF0F00F0FF0F00F, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0xAAAAAAAA55555555, 0x3333CCCCCCCC3333, 0x0000FFFFFFFF0000, 0x00FFFF00FF0000FF, 0x9669966996699669 }, { 0x3C3CC3C3C3C33C3C, 0xAAAAAAAA55555555, 0xF00FF00F0FF00FF0, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0x5AA55AA55AA55AA5, 0x55555555AAAAAAAA, 0x3333CCCCCCCC3333, 0xFFFF00000000FFFF, 0xFF0000FF00FFFF00, 0x9669966996699669 }, { 0xC3C33C3C3C3CC3C3, 0xAAAAAAAA55555555, 0x0FF00FF0F00FF00F, 0x5AA55AA5A55AA55A, 0xAA5555AA55AAAA55, 0xF00F0FF0F00F0FF0, 0x6996966969969669, 0xA55AA55AA55AA55A, 0x55555555AAAAAAAA, 0xCCCC33333333CCCC, 0xFFFF00000000FFFF, 0x00FFFF00FF0000FF, 0x6996699669966996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0xAAAAAAAAAAAAAAAA, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0x0000FFFF0000FFFF, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0xC33C3CC3C33C3CC3, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0x55AA55AA55AA55AA, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0xFFFF0000FFFF0000, 0x0F0F0F0FF0F0F0F0, 0x00FFFF00FF0000FF, 0xCC3333CC33CCCC33, 0xFF0000FF00FFFF00, 0x6996966996696996, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x3CC3C33C3CC3C33C, 0x5555555555555555, 0xFFFF0000FFFF0000, 0x3CC3C33C3CC3C33C, 0xAA55AA55AA55AA55, 0x0000FFFF0000FFFF, 0xF0F0F0F00F0F0F0F, 0xFF0000FF00FFFF00, 0x33CCCC33CC3333CC, 0x00FFFF00FF0000FF, 0x9669699669969669, 0xA55A5AA55AA5A55A, 0x6996966996696996 }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF0000FFFF0000, 0xFF00FF00FF00FF00, 0xF0F0F0F0F0F0F0F0, 0xCCCCCCCCCCCCCCCC, 0xAAAAAAAAAAAAAAAA }, |
2314 | | }; |
2315 | | |
2316 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c */ |
2317 | | /* linker define fft_powers */ |
2318 | | |
2319 | | |
2320 | | const vec fft_powers[128][GFBITS] = { |
2321 | | { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0x00000000FFFFFFFF, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0x5A5A5A5A5A5A5A5A, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0xCC33CC33CC33CC33, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0xCC33CC33CC33CC33, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x9696969669696969, 0xA5A5A5A5A5A5A5A5, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0x0F0FF0F00F0FF0F0 }, { 0xA55AA55A5AA55AA5, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0x5A5A5A5A5A5A5A5A, 0xA5A5A5A55A5A5A5A, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0x3CC33CC3C33CC33C, 0xA5A55A5AA5A55A5A, 0x0000FFFF0000FFFF, 0x33CC33CC33CC33CC, 0xF00FF00F0FF00FF0, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0x5555AAAAAAAA5555, 0xF00FF00FF00FF00F, 0xF0F00F0FF0F00F0F }, { 0x5AA55AA5A55AA55A, 0xC33CC33C3CC33CC3, 0xA5A55A5AA5A55A5A, 0xFFFF0000FFFF0000, 0x33CC33CC33CC33CC, 0x0FF00FF0F00FF00F, 0xFFFFFFFF00000000, 0x6969696996969696, 0xA5A5A5A5A5A5A5A5, 0x5A5A5A5AA5A5A5A5, 0xAAAA55555555AAAA, 0x0FF00FF00FF00FF0, 0x0F0FF0F00F0FF0F0 } |
2322 | | }; |
2323 | | |
2324 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c */ |
2325 | | /* linker define fft_scalars_2x */ |
2326 | | |
2327 | | |
2328 | | const vec fft_scalars_2x[5][2][GFBITS] = { |
2329 | | {{ 0X3C3CF30C0000C003, 0X0CCCC3F333C0000C, 0X03C33F33FCC0C03C, 0X0003000F3C03C0C0, 0XF33FF33030CF03F0, 0X0CF0303300F0CCC0, 0XFF3F0C0CC0FF3CC0, 0XCF3CF0FF003FC000, 0XC00FF3CF0303F300, 0X3CCC0CC00CF0CC00, 0XF30FFC3C3FCCFC00, 0X3F0FC3F0CCF0C000, 0X3000FF33CCF0F000 }, { 0X0C0F0FCF0F0CF330, 0XF0000FC33C3CCF3C, 0X3C0F3F00C3C300FC, 0X3C33CCC0F0F3CC30, 0XC0CFFFFFCCCC30CC, 0X3FC3F3CCFFFC033F, 0XFC3030CCCCC0CFCF, 0X0FCF0C00CCF333C3, 0XCFFCF33000CFF030, 0X00CFFCC330F30FCC, 0X3CCC3FCCC0F3FFF3, 0XF00F0C3FC003C0FF, 0X330CCFCC03C0FC33 }}, {{ 0X0F0F0FF0F000000F, 0X00FFFFFFFF0000F0, 0XFFFF00FF00000F00, 0XFFF000F00F0FF000, 0XFFF0000F0FF000F0, 0X00FF000FFF000000, 0XFF0F0FFF0F0FF000, 0X0FFF0000000F0000, 0X00F000F0FFF00F00, 0X00F00FF00F00F000, 0XFFF000F000F00000, 0X00F00F000FF00000, 0X0000FF0F0000F000 }, { 0XF0FFFFFFF0F00F00, 0X00FFF0FFFF0000FF, 0X00FF00000F0F0FFF, 0XF000F0000F00FF0F, 0XFF000000FFF00000, 0XF0FF000FF00F0FF0, 0X0F0F0F00FF000F0F, 0X0F0F00F0F0F0F000, 0X00F00F00F00F000F, 0X00F0F0F00000FFF0, 0XFFFFFF0FF00F0FFF, 0X0F0FFFF00FFFFFFF, 0XFFFF0F0FFF0FFF00 }}, {{ 0X00FF0000000000FF, 0XFFFFFFFFFF00FF00, 0XFF0000FF00FF0000, 0XFFFF000000FF0000, 0XFF00000000FF0000, 0X00FFFFFFFF000000, 0XFF0000FFFFFF0000, 0XFF00FF00FFFF0000, 0X00FFFFFFFF00FF00, 0XFFFF000000000000, 0X00FF0000FF000000, 0XFF00FF00FF000000, 0X00FF00FFFF000000 }, { 0X00FF00FF00FF0000, 0XFF00FFFF000000FF, 0X0000FFFF000000FF, 0X00FFFF00FF000000, 0XFFFFFF0000FF00FF, 0X0000FFFF00FFFF00, 0XFF00FF0000FFFF00, 0X00000000FFFFFFFF, 0X0000FF0000000000, 0XFF00FFFF00FFFF00, 0X00FFFF00000000FF, 0X0000FF00FF00FFFF, 0XFF0000FFFFFF0000 }}, {{ 0X000000000000FFFF, 0XFFFFFFFFFFFF0000, 0X0000000000000000, 0XFFFF0000FFFF0000, 0XFFFFFFFFFFFF0000, 0X0000FFFF00000000, 0X0000FFFFFFFF0000, 0XFFFF0000FFFF0000, 0X0000FFFF00000000, 0XFFFF000000000000, 0XFFFF000000000000, 0XFFFF000000000000, 0XFFFFFFFF00000000 }, { 0X0000FFFF00000000, 0XFFFFFFFF0000FFFF, 0X00000000FFFFFFFF, 0X0000000000000000, 0X0000FFFF00000000, 0XFFFF0000FFFF0000, 0X0000FFFFFFFF0000, 0X0000FFFF0000FFFF, 0XFFFFFFFF0000FFFF, 0X00000000FFFF0000, 0XFFFF0000FFFFFFFF, 0XFFFF0000FFFFFFFF, 0X0000000000000000 }}, {{ 0X00000000FFFFFFFF, 0X0000000000000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFF00000000, 0XFFFFFFFF00000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFF00000000, 0X0000000000000000, 0X0000000000000000, 0X0000000000000000, 0XFFFFFFFF00000000 }, { 0X0000000000000000, 0XFFFFFFFFFFFFFFFF, 0X0000000000000000, 0X0000000000000000, 0X00000000FFFFFFFF, 0XFFFFFFFF00000000, 0X0000000000000000, 0XFFFFFFFFFFFFFFFF, 0X00000000FFFFFFFF, 0XFFFFFFFF00000000, 0XFFFFFFFFFFFFFFFF, 0XFFFFFFFFFFFFFFFF, 0XFFFFFFFF00000000 }} |
2330 | | }; |
2331 | | |
2332 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c */ |
2333 | | /* linker define fft_scalars_4x */ |
2334 | | |
2335 | | |
2336 | | const vec fft_scalars_4x[6][4][GFBITS] = { |
2337 | | {{ 0x3C3CF30C0000C003, 0x0CCCC3F333C0000C, 0x03C33F33FCC0C03C, 0x0003000F3C03C0C0, 0xF33FF33030CF03F0, 0x0CF0303300F0CCC0, 0xFF3F0C0CC0FF3CC0, 0xCF3CF0FF003FC000, 0xC00FF3CF0303F300, 0x3CCC0CC00CF0CC00, 0xF30FFC3C3FCCFC00, 0x3F0FC3F0CCF0C000, 0x3000FF33CCF0F000 }, { 0x0C0F0FCF0F0CF330, 0xF0000FC33C3CCF3C, 0x3C0F3F00C3C300FC, 0x3C33CCC0F0F3CC30, 0xC0CFFFFFCCCC30CC, 0x3FC3F3CCFFFC033F, 0xFC3030CCCCC0CFCF, 0x0FCF0C00CCF333C3, 0xCFFCF33000CFF030, 0x00CFFCC330F30FCC, 0x3CCC3FCCC0F3FFF3, 0xF00F0C3FC003C0FF, 0x330CCFCC03C0FC33 }, { 0xF0F30C33CF03F03F, 0x00F30FC00C3300FF, 0xF3CC3CF3F3FCF33F, 0x3C0FC0FC303C3F3C, 0xFC30CF303F3FF00F, 0x33300C0CC3300CF3, 0x3C030CF3F03FF3F3, 0x3CCC03FCCC3FFC03, 0x033C3C3CF0003FC3, 0xFFC0FF00F0FF0F03, 0xF3F30CF003FCC303, 0x30CFCFC3CC0F3000, 0x0CF30CCF3FCFCC0F }, { 0x3F30CC0C000F3FCC, 0xFC3CF030FC3FFF03, 0x33FFFCFF0CCF3CC3, 0x003CFF33C3CC30CF, 0xCFF3CF33C00F3003, 0x00F3CC0CF3003CCF, 0x3C000CFCCC3C3333, 0xF3CF03C0FCF03FF0, 0x3F3C3CF0C330330C, 0x33CCFCC0FF0033F0, 0x33C300C0F0C003F3, 0x003FF0003F00C00C, 0xCFF3C3033F030FFF }}, {{ 0x0F0F0FF0F000000F, 0x00FFFFFFFF0000F0, 0xFFFF00FF00000F00, 0xFFF000F00F0FF000, 0xFFF0000F0FF000F0, 0x00FF000FFF000000, 0xFF0F0FFF0F0FF000, 0x0FFF0000000F0000, 0x00F000F0FFF00F00, 0x00F00FF00F00F000, 0xFFF000F000F00000, 0x00F00F000FF00000, 0x0000FF0F0000F000 }, { 0xF0FFFFFFF0F00F00, 0x00FFF0FFFF0000FF, 0x00FF00000F0F0FFF, 0xF000F0000F00FF0F, 0xFF000000FFF00000, 0xF0FF000FF00F0FF0, 0x0F0F0F00FF000F0F, 0x0F0F00F0F0F0F000, 0x00F00F00F00F000F, 0x00F0F0F00000FFF0, 0xFFFFFF0FF00F0FFF, 0x0F0FFFF00FFFFFFF, 0xFFFF0F0FFF0FFF00 }, { 0x0F0F00FF0FF0FFFF, 0xF000F0F00F00FF0F, 0x000FFFF0FFF0FF0F, 0x00F00FFF00000FF0, 0xFFFFF0000FFFF00F, 0xFFF0FFF0000FFFF0, 0xF0F0F0000F0F0F00, 0x00F000F0F00FFF00, 0xF0FF0F0FFF00F0FF, 0xF0FF0FFFF0F0F0FF, 0x00FFFFFFFFFFFFF0, 0x00FFF0F0FF000F0F, 0x000FFFF0000FFF00 }, { 0xFF0F0F00F000F0FF, 0x0FFFFFFFFF00000F, 0xF0FFFF000F00F0FF, 0x0F0000F00FFF0FFF, 0x0F0F0F00FF0F000F, 0x000F0F0FFFF0F000, 0xF0FFFF0F00F0FF0F, 0x0F0F000F0F00F0FF, 0x0000F0FF00FF0F0F, 0x00FFFF0FF0FFF0F0, 0x0000000F00F0FFF0, 0xF0F00000FF00F0F0, 0x0F0F0FFFFFFFFFFF }}, {{ 0x00FF0000000000FF, 0xFFFFFFFFFF00FF00, 0xFF0000FF00FF0000, 0xFFFF000000FF0000, 0xFF00000000FF0000, 0x00FFFFFFFF000000, 0xFF0000FFFFFF0000, 0xFF00FF00FFFF0000, 0x00FFFFFFFF00FF00, 0xFFFF000000000000, 0x00FF0000FF000000, 0xFF00FF00FF000000, 0x00FF00FFFF000000 }, { 0x00FF00FF00FF0000, 0xFF00FFFF000000FF, 0x0000FFFF000000FF, 0x00FFFF00FF000000, 0xFFFFFF0000FF00FF, 0x0000FFFF00FFFF00, 0xFF00FF0000FFFF00, 0x00000000FFFFFFFF, 0x0000FF0000000000, 0xFF00FFFF00FFFF00, 0x00FFFF00000000FF, 0x0000FF00FF00FFFF, 0xFF0000FFFFFF0000 }, { 0xFFFF00FF00FF00FF, 0x00FFFF000000FF00, 0xFFFF00FFFFFFFF00, 0x0000FFFF00FFFFFF, 0x00FF0000FF0000FF, 0xFFFF0000FF00FFFF, 0xFF000000FFFFFF00, 0x000000000000FFFF, 0xFF00FF00FFFF0000, 0xFFFF00FFFF00FFFF, 0xFFFFFFFFFF00FF00, 0xFFFF00FFFF0000FF, 0x0000FF00000000FF }, { 0xFF0000FFFFFF00FF, 0xFFFF0000FFFFFFFF, 0xFFFF000000FFFFFF, 0x00FFFF00FF0000FF, 0xFFFFFF00FFFFFF00, 0x00FFFF00FFFF00FF, 0x0000FFFF00FF0000, 0x000000FFFF000000, 0xFF00FF0000FF00FF, 0x00FF0000000000FF, 0xFF00FFFF00FF00FF, 0xFFFFFFFFFFFFFFFF, 0x0000FF000000FFFF }}, {{ 0x000000000000FFFF, 0xFFFFFFFFFFFF0000, 0x0000000000000000, 0xFFFF0000FFFF0000, 0xFFFFFFFFFFFF0000, 0x0000FFFF00000000, 0x0000FFFFFFFF0000, 0xFFFF0000FFFF0000, 0x0000FFFF00000000, 0xFFFF000000000000, 0xFFFF000000000000, 0xFFFF000000000000, 0xFFFFFFFF00000000 }, { 0x0000FFFF00000000, 0xFFFFFFFF0000FFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0x0000FFFF00000000, 0xFFFF0000FFFF0000, 0x0000FFFFFFFF0000, 0x0000FFFF0000FFFF, 0xFFFFFFFF0000FFFF, 0x00000000FFFF0000, 0xFFFF0000FFFFFFFF, 0xFFFF0000FFFFFFFF, 0x0000000000000000 }, { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x0000FFFFFFFFFFFF, 0x0000FFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x000000000000FFFF, 0x000000000000FFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFF0000FFFF, 0xFFFF0000FFFFFFFF }, { 0x0000FFFFFFFFFFFF, 0x0000FFFF0000FFFF, 0x0000FFFFFFFF0000, 0xFFFF0000FFFFFFFF, 0x00000000FFFF0000, 0xFFFF00000000FFFF, 0x0000FFFF0000FFFF, 0xFFFF00000000FFFF, 0x0000FFFF0000FFFF, 0x0000FFFF00000000, 0xFFFFFFFF00000000, 0x0000FFFFFFFF0000, 0x0000FFFFFFFFFFFF }}, {{ 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFF00000000 }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000 }, { 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }, { 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFF00000000 }}, {{ 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 }, { 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000 }, { 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }, { 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF }}, |
2338 | | }; |
2339 | | |
2340 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.c */ |
2341 | | /* |
2342 | | This file is for implementing the Gao-Mateer FFT, see |
2343 | | http://www.math.clemson.edu/~sgao/papers/GM10.pdf |
2344 | | |
2345 | | For the implementation strategy, see |
2346 | | https://eprint.iacr.org/2017/793.pdf |
2347 | | */ |
2348 | | /* 20221230 djb: split these arrays into separate .c files */ |
2349 | | /* 20221230 djb: rename powers array as fft_powers */ |
2350 | | /* 20221230 djb: rename consts array as fft_consts */ |
2351 | | /* 20221230 djb: rename s array as fft_scalars_2x */ |
2352 | | /* 20221230 djb: add linker lines */ |
2353 | | |
2354 | | /* linker define fft */ |
2355 | | /* linker use vec_mul */ |
2356 | | /* linker use fft_scalars_2x fft_consts fft_powers */ |
2357 | | |
2358 | | |
2359 | | |
2360 | | |
2361 | | /* input: in, polynomial in bitsliced form */ |
2362 | | /* output: in, result of applying the radix conversions on in */ |
2363 | | static void radix_conversions(vec in[][GFBITS]) |
2364 | 0 | { |
2365 | 0 | int i, j, k; |
2366 | |
|
2367 | 0 | const vec mask[5][2] = |
2368 | 0 | { |
2369 | 0 | {0x8888888888888888, 0x4444444444444444}, |
2370 | 0 | {0xC0C0C0C0C0C0C0C0, 0x3030303030303030}, |
2371 | 0 | {0xF000F000F000F000, 0x0F000F000F000F00}, |
2372 | 0 | {0xFF000000FF000000, 0x00FF000000FF0000}, |
2373 | 0 | {0xFFFF000000000000, 0x0000FFFF00000000} |
2374 | 0 | }; |
2375 | |
|
2376 | 0 | for (j = 0; j <= 5; j++) |
2377 | 0 | { |
2378 | 0 | for (i = 0; i < GFBITS; i++) |
2379 | 0 | { |
2380 | 0 | in[1][i] ^= in[1][i] >> 32; |
2381 | 0 | in[0][i] ^= in[1][i] << 32; |
2382 | 0 | } |
2383 | |
|
2384 | 0 | for (i = 0; i < GFBITS; i++) |
2385 | 0 | for (k = 4; k >= j; k--) |
2386 | 0 | { |
2387 | 0 | in[0][i] ^= (in[0][i] & mask[k][0]) >> (1 << k); |
2388 | 0 | in[0][i] ^= (in[0][i] & mask[k][1]) >> (1 << k); |
2389 | 0 | in[1][i] ^= (in[1][i] & mask[k][0]) >> (1 << k); |
2390 | 0 | in[1][i] ^= (in[1][i] & mask[k][1]) >> (1 << k); |
2391 | 0 | } |
2392 | |
|
2393 | 0 | if (j < 5) |
2394 | 0 | { |
2395 | 0 | vec_mul(in[0], in[0], fft_scalars_2x[j][0]); |
2396 | 0 | vec_mul(in[1], in[1], fft_scalars_2x[j][1]); |
2397 | 0 | } |
2398 | 0 | } |
2399 | 0 | } |
2400 | | |
2401 | | /* input: in, result of applying the radix conversions to the input polynomial */ |
2402 | | /* output: out, evaluation results (by applying the FFT butterflies) */ |
2403 | | static void butterflies(vec out[][ GFBITS ], vec in[][ GFBITS ]) |
2404 | 0 | { |
2405 | 0 | int i, j, k, s, b; |
2406 | |
|
2407 | 0 | vec tmp[ GFBITS ]; |
2408 | 0 | vec pre[8][ GFBITS ]; |
2409 | 0 | vec buf[128]; |
2410 | |
|
2411 | 0 | uint64_t consts_ptr = 2; |
2412 | |
|
2413 | 0 | const unsigned char reversal[128] = |
2414 | 0 | { |
2415 | 0 | 0, 64, 32, 96, 16, 80, 48, 112, |
2416 | 0 | 8, 72, 40, 104, 24, 88, 56, 120, |
2417 | 0 | 4, 68, 36, 100, 20, 84, 52, 116, |
2418 | 0 | 12, 76, 44, 108, 28, 92, 60, 124, |
2419 | 0 | 2, 66, 34, 98, 18, 82, 50, 114, |
2420 | 0 | 10, 74, 42, 106, 26, 90, 58, 122, |
2421 | 0 | 6, 70, 38, 102, 22, 86, 54, 118, |
2422 | 0 | 14, 78, 46, 110, 30, 94, 62, 126, |
2423 | 0 | 1, 65, 33, 97, 17, 81, 49, 113, |
2424 | 0 | 9, 73, 41, 105, 25, 89, 57, 121, |
2425 | 0 | 5, 69, 37, 101, 21, 85, 53, 117, |
2426 | 0 | 13, 77, 45, 109, 29, 93, 61, 125, |
2427 | 0 | 3, 67, 35, 99, 19, 83, 51, 115, |
2428 | 0 | 11, 75, 43, 107, 27, 91, 59, 123, |
2429 | 0 | 7, 71, 39, 103, 23, 87, 55, 119, |
2430 | 0 | 15, 79, 47, 111, 31, 95, 63, 127 |
2431 | 0 | }; |
2432 | |
|
2433 | 0 | const uint16_t beta[7] = {2522, 7827, 7801, 8035, 6897, 8167, 3476}; |
2434 | | |
2435 | | /**/ |
2436 | |
|
2437 | 0 | for (i = 0; i < 7; i++) |
2438 | 0 | { |
2439 | 0 | for (j = 0; j < GFBITS; j++) |
2440 | 0 | { |
2441 | 0 | pre[i][j] = (beta[i] >> j) & 1; |
2442 | 0 | pre[i][j] = -pre[i][j]; |
2443 | 0 | } |
2444 | |
|
2445 | 0 | vec_mul(pre[i], in[1], pre[i]); |
2446 | 0 | } |
2447 | |
|
2448 | 0 | for (i = 0; i < GFBITS; i++) |
2449 | 0 | { |
2450 | 0 | buf[0] = in[0][i]; |
2451 | |
|
2452 | 0 | buf[1] = buf[0] ^ pre[0][i]; buf[32] = in[0][i] ^ pre[5][i]; |
2453 | 0 | buf[3] = buf[1] ^ pre[1][i]; buf[96] = buf[32] ^ pre[6][i]; |
2454 | 0 | buf[97] = buf[96] ^ pre[0][i]; |
2455 | 0 | buf[2] = in[0][i] ^ pre[1][i]; buf[99] = buf[97] ^ pre[1][i]; |
2456 | 0 | buf[6] = buf[2] ^ pre[2][i]; buf[98] = buf[99] ^ pre[0][i]; |
2457 | 0 | buf[7] = buf[6] ^ pre[0][i]; buf[102] = buf[98] ^ pre[2][i]; |
2458 | 0 | buf[5] = buf[7] ^ pre[1][i]; buf[103] = buf[102] ^ pre[0][i]; |
2459 | 0 | buf[101] = buf[103] ^ pre[1][i]; |
2460 | 0 | buf[4] = in[0][i] ^ pre[2][i]; buf[100] = buf[101] ^ pre[0][i]; |
2461 | 0 | buf[12] = buf[4] ^ pre[3][i]; buf[108] = buf[100] ^ pre[3][i]; |
2462 | 0 | buf[13] = buf[12] ^ pre[0][i]; buf[109] = buf[108] ^ pre[0][i]; |
2463 | 0 | buf[15] = buf[13] ^ pre[1][i]; buf[111] = buf[109] ^ pre[1][i]; |
2464 | 0 | buf[14] = buf[15] ^ pre[0][i]; buf[110] = buf[111] ^ pre[0][i]; |
2465 | 0 | buf[10] = buf[14] ^ pre[2][i]; buf[106] = buf[110] ^ pre[2][i]; |
2466 | 0 | buf[11] = buf[10] ^ pre[0][i]; buf[107] = buf[106] ^ pre[0][i]; |
2467 | 0 | buf[9] = buf[11] ^ pre[1][i]; buf[105] = buf[107] ^ pre[1][i]; |
2468 | 0 | buf[104] = buf[105] ^ pre[0][i]; |
2469 | 0 | buf[8] = in[0][i] ^ pre[3][i]; buf[120] = buf[104] ^ pre[4][i]; |
2470 | 0 | buf[24] = buf[8] ^ pre[4][i]; buf[121] = buf[120] ^ pre[0][i]; |
2471 | 0 | buf[25] = buf[24] ^ pre[0][i]; buf[123] = buf[121] ^ pre[1][i]; |
2472 | 0 | buf[27] = buf[25] ^ pre[1][i]; buf[122] = buf[123] ^ pre[0][i]; |
2473 | 0 | buf[26] = buf[27] ^ pre[0][i]; buf[126] = buf[122] ^ pre[2][i]; |
2474 | 0 | buf[30] = buf[26] ^ pre[2][i]; buf[127] = buf[126] ^ pre[0][i]; |
2475 | 0 | buf[31] = buf[30] ^ pre[0][i]; buf[125] = buf[127] ^ pre[1][i]; |
2476 | 0 | buf[29] = buf[31] ^ pre[1][i]; buf[124] = buf[125] ^ pre[0][i]; |
2477 | 0 | buf[28] = buf[29] ^ pre[0][i]; buf[116] = buf[124] ^ pre[3][i]; |
2478 | 0 | buf[20] = buf[28] ^ pre[3][i]; buf[117] = buf[116] ^ pre[0][i]; |
2479 | 0 | buf[21] = buf[20] ^ pre[0][i]; buf[119] = buf[117] ^ pre[1][i]; |
2480 | 0 | buf[23] = buf[21] ^ pre[1][i]; buf[118] = buf[119] ^ pre[0][i]; |
2481 | 0 | buf[22] = buf[23] ^ pre[0][i]; buf[114] = buf[118] ^ pre[2][i]; |
2482 | 0 | buf[18] = buf[22] ^ pre[2][i]; buf[115] = buf[114] ^ pre[0][i]; |
2483 | 0 | buf[19] = buf[18] ^ pre[0][i]; buf[113] = buf[115] ^ pre[1][i]; |
2484 | 0 | buf[17] = buf[19] ^ pre[1][i]; buf[112] = buf[113] ^ pre[0][i]; |
2485 | 0 | buf[80] = buf[112] ^ pre[5][i]; |
2486 | 0 | buf[16] = in[0][i] ^ pre[4][i]; buf[81] = buf[80] ^ pre[0][i]; |
2487 | 0 | buf[48] = buf[16] ^ pre[5][i]; buf[83] = buf[81] ^ pre[1][i]; |
2488 | 0 | buf[49] = buf[48] ^ pre[0][i]; buf[82] = buf[83] ^ pre[0][i]; |
2489 | 0 | buf[51] = buf[49] ^ pre[1][i]; buf[86] = buf[82] ^ pre[2][i]; |
2490 | 0 | buf[50] = buf[51] ^ pre[0][i]; buf[87] = buf[86] ^ pre[0][i]; |
2491 | 0 | buf[54] = buf[50] ^ pre[2][i]; buf[85] = buf[87] ^ pre[1][i]; |
2492 | 0 | buf[55] = buf[54] ^ pre[0][i]; buf[84] = buf[85] ^ pre[0][i]; |
2493 | 0 | buf[53] = buf[55] ^ pre[1][i]; buf[92] = buf[84] ^ pre[3][i]; |
2494 | 0 | buf[52] = buf[53] ^ pre[0][i]; buf[93] = buf[92] ^ pre[0][i]; |
2495 | 0 | buf[60] = buf[52] ^ pre[3][i]; buf[95] = buf[93] ^ pre[1][i]; |
2496 | 0 | buf[61] = buf[60] ^ pre[0][i]; buf[94] = buf[95] ^ pre[0][i]; |
2497 | 0 | buf[63] = buf[61] ^ pre[1][i]; buf[90] = buf[94] ^ pre[2][i]; |
2498 | 0 | buf[62] = buf[63] ^ pre[0][i]; buf[91] = buf[90] ^ pre[0][i]; |
2499 | 0 | buf[58] = buf[62] ^ pre[2][i]; buf[89] = buf[91] ^ pre[1][i]; |
2500 | 0 | buf[59] = buf[58] ^ pre[0][i]; buf[88] = buf[89] ^ pre[0][i]; |
2501 | 0 | buf[57] = buf[59] ^ pre[1][i]; buf[72] = buf[88] ^ pre[4][i]; |
2502 | 0 | buf[56] = buf[57] ^ pre[0][i]; buf[73] = buf[72] ^ pre[0][i]; |
2503 | 0 | buf[40] = buf[56] ^ pre[4][i]; buf[75] = buf[73] ^ pre[1][i]; |
2504 | 0 | buf[41] = buf[40] ^ pre[0][i]; buf[74] = buf[75] ^ pre[0][i]; |
2505 | 0 | buf[43] = buf[41] ^ pre[1][i]; buf[78] = buf[74] ^ pre[2][i]; |
2506 | 0 | buf[42] = buf[43] ^ pre[0][i]; buf[79] = buf[78] ^ pre[0][i]; |
2507 | 0 | buf[46] = buf[42] ^ pre[2][i]; buf[77] = buf[79] ^ pre[1][i]; |
2508 | 0 | buf[47] = buf[46] ^ pre[0][i]; buf[76] = buf[77] ^ pre[0][i]; |
2509 | 0 | buf[45] = buf[47] ^ pre[1][i]; buf[68] = buf[76] ^ pre[3][i]; |
2510 | 0 | buf[44] = buf[45] ^ pre[0][i]; buf[69] = buf[68] ^ pre[0][i]; |
2511 | 0 | buf[36] = buf[44] ^ pre[3][i]; buf[71] = buf[69] ^ pre[1][i]; |
2512 | 0 | buf[37] = buf[36] ^ pre[0][i]; buf[70] = buf[71] ^ pre[0][i]; |
2513 | 0 | buf[39] = buf[37] ^ pre[1][i]; buf[66] = buf[70] ^ pre[2][i]; |
2514 | 0 | buf[38] = buf[39] ^ pre[0][i]; buf[67] = buf[66] ^ pre[0][i]; |
2515 | 0 | buf[34] = buf[38] ^ pre[2][i]; buf[65] = buf[67] ^ pre[1][i]; |
2516 | 0 | buf[35] = buf[34] ^ pre[0][i]; |
2517 | 0 | buf[33] = buf[35] ^ pre[1][i]; buf[64] = in[0][i] ^ pre[6][i]; |
2518 | |
|
2519 | 0 | transpose_64x64(buf + 0, buf + 0); |
2520 | 0 | transpose_64x64(buf + 64, buf + 64); |
2521 | |
|
2522 | 0 | for (j = 0; j < 128; j++) |
2523 | 0 | out[ reversal[j] ][i] = buf[j]; |
2524 | 0 | } |
2525 | |
|
2526 | 0 | for (i = 1; i <= 6; i++) |
2527 | 0 | { |
2528 | 0 | s = 1 << i; |
2529 | |
|
2530 | 0 | for (j = 0; j < 128; j += 2*s) |
2531 | 0 | for (k = j; k < j+s; k++) |
2532 | 0 | { |
2533 | 0 | vec_mul(tmp, out[k+s], fft_consts[ consts_ptr + (k-j) ]); |
2534 | |
|
2535 | 0 | for (b = 0; b < GFBITS; b++) out[k ][b] ^= tmp[b]; |
2536 | 0 | for (b = 0; b < GFBITS; b++) out[k+s][b] ^= out[k][b]; |
2537 | 0 | } |
2538 | |
|
2539 | 0 | consts_ptr += (1 << i); |
2540 | 0 | } |
2541 | | |
2542 | | /* adding the part contributed by x^128 */ |
2543 | |
|
2544 | 0 | for (i = 0; i < 128; i++) |
2545 | 0 | for (b = 0; b < GFBITS; b++) |
2546 | 0 | out[i][b] ^= fft_powers[i][b]; |
2547 | 0 | } |
2548 | | |
2549 | | /* input: in, polynomial in bitsliced form */ |
2550 | | /* output: out, bitsliced results of evaluating in all the field elements */ |
2551 | | static void fft(vec out[][GFBITS], vec in[][GFBITS]) |
2552 | 0 | { |
2553 | 0 | radix_conversions(in); |
2554 | 0 | butterflies(out, in); |
2555 | 0 | } |
2556 | | |
2557 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c */ |
2558 | | /* |
2559 | | This file is for transpose of the Gao-Mateer FFT |
2560 | | Functions with names ending with _tr are (roughly) the transpose of the corresponding functions in fft.c |
2561 | | |
2562 | | For the implementation strategy, see |
2563 | | https://eprint.iacr.org/2017/793.pdf |
2564 | | */ |
2565 | | /* 20221230 djb: split these arrays into separate .c files */ |
2566 | | /* 20221230 djb: rename consts array as fft_consts */ |
2567 | | /* 20221230 djb: rename s array as fft_scalars_4x */ |
2568 | | /* 20221230 djb: add linker lines */ |
2569 | | |
2570 | | /* linker define fft_tr */ |
2571 | | /* linker use vec_mul */ |
2572 | | /* linker use fft_scalars_4x fft_consts */ |
2573 | | |
2574 | | |
2575 | | |
2576 | | |
2577 | | static void radix_conversions_tr(vec in[][ GFBITS ]) |
2578 | 0 | { |
2579 | 0 | int i, j, k; |
2580 | |
|
2581 | 0 | const vec mask[6][2] = |
2582 | 0 | { |
2583 | 0 | {0x2222222222222222, 0x4444444444444444}, |
2584 | 0 | {0x0C0C0C0C0C0C0C0C, 0x3030303030303030}, |
2585 | 0 | {0x00F000F000F000F0, 0x0F000F000F000F00}, |
2586 | 0 | {0x0000FF000000FF00, 0x00FF000000FF0000}, |
2587 | 0 | {0x00000000FFFF0000, 0x0000FFFF00000000}, |
2588 | 0 | {0xFFFFFFFF00000000, 0x00000000FFFFFFFF} |
2589 | 0 | }; |
2590 | | |
2591 | | /**/ |
2592 | |
|
2593 | 0 | for (j = 6; j >= 0; j--) |
2594 | 0 | { |
2595 | 0 | if (j < 6) |
2596 | 0 | { |
2597 | 0 | vec_mul(in[0], in[0], fft_scalars_4x[j][0]); /* scaling */ |
2598 | 0 | vec_mul(in[1], in[1], fft_scalars_4x[j][1]); /* scaling */ |
2599 | 0 | vec_mul(in[2], in[2], fft_scalars_4x[j][2]); /* scaling */ |
2600 | 0 | vec_mul(in[3], in[3], fft_scalars_4x[j][3]); /* scaling */ |
2601 | 0 | } |
2602 | |
|
2603 | 0 | for (k = j; k <= 4; k++) |
2604 | 0 | for (i = 0; i < GFBITS; i++) |
2605 | 0 | { |
2606 | 0 | in[0][i] ^= (in[0][i] & mask[k][0]) << (1 << k); |
2607 | 0 | in[0][i] ^= (in[0][i] & mask[k][1]) << (1 << k); |
2608 | 0 | in[1][i] ^= (in[1][i] & mask[k][0]) << (1 << k); |
2609 | 0 | in[1][i] ^= (in[1][i] & mask[k][1]) << (1 << k); |
2610 | 0 | in[2][i] ^= (in[2][i] & mask[k][0]) << (1 << k); |
2611 | 0 | in[2][i] ^= (in[2][i] & mask[k][1]) << (1 << k); |
2612 | 0 | in[3][i] ^= (in[3][i] & mask[k][0]) << (1 << k); |
2613 | 0 | in[3][i] ^= (in[3][i] & mask[k][1]) << (1 << k); |
2614 | 0 | } |
2615 | |
|
2616 | 0 | if (j <= 5) |
2617 | 0 | for (i = 0; i < GFBITS; i++) |
2618 | 0 | { |
2619 | 0 | in[1][i] ^= in[0][i] >> 32; |
2620 | 0 | in[1][i] ^= in[1][i] << 32; |
2621 | |
|
2622 | 0 | in[3][i] ^= in[2][i] >> 32; |
2623 | 0 | in[3][i] ^= in[3][i] << 32; |
2624 | 0 | } |
2625 | |
|
2626 | 0 | for (i = 0; i < GFBITS; i++) |
2627 | 0 | in[3][i] ^= in[2][i] ^= in[1][i]; |
2628 | 0 | } |
2629 | 0 | } |
2630 | | |
2631 | | static void butterflies_tr(vec out[][ GFBITS ], vec in[][ GFBITS ]) |
2632 | 0 | { |
2633 | 0 | int i, j, k, s, b; |
2634 | |
|
2635 | 0 | vec tmp[ GFBITS ]; |
2636 | 0 | vec pre[6][2][ GFBITS ]; |
2637 | 0 | vec buf[2][64]; |
2638 | |
|
2639 | 0 | uint64_t consts_ptr = 128; |
2640 | |
|
2641 | 0 | const unsigned char reversal[128] = |
2642 | 0 | { |
2643 | 0 | 0, 64, 32, 96, 16, 80, 48, 112, |
2644 | 0 | 8, 72, 40, 104, 24, 88, 56, 120, |
2645 | 0 | 4, 68, 36, 100, 20, 84, 52, 116, |
2646 | 0 | 12, 76, 44, 108, 28, 92, 60, 124, |
2647 | 0 | 2, 66, 34, 98, 18, 82, 50, 114, |
2648 | 0 | 10, 74, 42, 106, 26, 90, 58, 122, |
2649 | 0 | 6, 70, 38, 102, 22, 86, 54, 118, |
2650 | 0 | 14, 78, 46, 110, 30, 94, 62, 126, |
2651 | 0 | 1, 65, 33, 97, 17, 81, 49, 113, |
2652 | 0 | 9, 73, 41, 105, 25, 89, 57, 121, |
2653 | 0 | 5, 69, 37, 101, 21, 85, 53, 117, |
2654 | 0 | 13, 77, 45, 109, 29, 93, 61, 125, |
2655 | 0 | 3, 67, 35, 99, 19, 83, 51, 115, |
2656 | 0 | 11, 75, 43, 107, 27, 91, 59, 123, |
2657 | 0 | 7, 71, 39, 103, 23, 87, 55, 119, |
2658 | 0 | 15, 79, 47, 111, 31, 95, 63, 127 |
2659 | 0 | }; |
2660 | |
|
2661 | 0 | const uint16_t beta[6] = {5246, 5306, 6039, 6685, 4905, 6755}; |
2662 | | |
2663 | | /**/ |
2664 | |
|
2665 | 0 | for (i = 6; i >= 0; i--) |
2666 | 0 | { |
2667 | 0 | s = 1 << i; |
2668 | 0 | consts_ptr -= s; |
2669 | |
|
2670 | 0 | for (j = 0; j < 128; j += 2*s) |
2671 | 0 | for (k = j; k < j+s; k++) |
2672 | 0 | { |
2673 | 0 | for (b = 0; b < GFBITS; b++) in[k][b] ^= in[k+s][b]; |
2674 | |
|
2675 | 0 | vec_mul(tmp, in[k], fft_consts[ consts_ptr + (k-j) ]); |
2676 | |
|
2677 | 0 | for (b = 0; b < GFBITS; b++) in[k+s][b] ^= tmp[b]; |
2678 | 0 | } |
2679 | 0 | } |
2680 | |
|
2681 | 0 | for (i = 0; i < GFBITS; i++) |
2682 | 0 | { |
2683 | 0 | for (k = 0; k < 128; k++) |
2684 | 0 | (&buf[0][0])[ k ] = in[ reversal[k] ][i]; |
2685 | |
|
2686 | 0 | transpose_64x64(buf[0], buf[0]); |
2687 | 0 | transpose_64x64(buf[1], buf[1]); |
2688 | |
|
2689 | 0 | for (k = 0; k < 2; k++) |
2690 | 0 | { |
2691 | 0 | pre[0][k][i] = buf[k][32]; buf[k][33] ^= buf[k][32]; |
2692 | 0 | pre[1][k][i] = buf[k][33]; buf[k][35] ^= buf[k][33]; |
2693 | 0 | pre[0][k][i] ^= buf[k][35]; buf[k][34] ^= buf[k][35]; |
2694 | 0 | pre[2][k][i] = buf[k][34]; buf[k][38] ^= buf[k][34]; |
2695 | 0 | pre[0][k][i] ^= buf[k][38]; buf[k][39] ^= buf[k][38]; |
2696 | 0 | pre[1][k][i] ^= buf[k][39]; buf[k][37] ^= buf[k][39]; |
2697 | 0 | pre[0][k][i] ^= buf[k][37]; buf[k][36] ^= buf[k][37]; |
2698 | 0 | pre[3][k][i] = buf[k][36]; buf[k][44] ^= buf[k][36]; |
2699 | 0 | pre[0][k][i] ^= buf[k][44]; buf[k][45] ^= buf[k][44]; |
2700 | 0 | pre[1][k][i] ^= buf[k][45]; buf[k][47] ^= buf[k][45]; |
2701 | 0 | pre[0][k][i] ^= buf[k][47]; buf[k][46] ^= buf[k][47]; |
2702 | 0 | pre[2][k][i] ^= buf[k][46]; buf[k][42] ^= buf[k][46]; |
2703 | 0 | pre[0][k][i] ^= buf[k][42]; buf[k][43] ^= buf[k][42]; |
2704 | 0 | pre[1][k][i] ^= buf[k][43]; buf[k][41] ^= buf[k][43]; |
2705 | 0 | pre[0][k][i] ^= buf[k][41]; buf[k][40] ^= buf[k][41]; |
2706 | 0 | pre[4][k][i] = buf[k][40]; buf[k][56] ^= buf[k][40]; |
2707 | 0 | pre[0][k][i] ^= buf[k][56]; buf[k][57] ^= buf[k][56]; |
2708 | 0 | pre[1][k][i] ^= buf[k][57]; buf[k][59] ^= buf[k][57]; |
2709 | 0 | pre[0][k][i] ^= buf[k][59]; buf[k][58] ^= buf[k][59]; |
2710 | 0 | pre[2][k][i] ^= buf[k][58]; buf[k][62] ^= buf[k][58]; |
2711 | 0 | pre[0][k][i] ^= buf[k][62]; buf[k][63] ^= buf[k][62]; |
2712 | 0 | pre[1][k][i] ^= buf[k][63]; buf[k][61] ^= buf[k][63]; |
2713 | 0 | pre[0][k][i] ^= buf[k][61]; buf[k][60] ^= buf[k][61]; |
2714 | 0 | pre[3][k][i] ^= buf[k][60]; buf[k][52] ^= buf[k][60]; |
2715 | 0 | pre[0][k][i] ^= buf[k][52]; buf[k][53] ^= buf[k][52]; |
2716 | 0 | pre[1][k][i] ^= buf[k][53]; buf[k][55] ^= buf[k][53]; |
2717 | 0 | pre[0][k][i] ^= buf[k][55]; buf[k][54] ^= buf[k][55]; |
2718 | 0 | pre[2][k][i] ^= buf[k][54]; buf[k][50] ^= buf[k][54]; |
2719 | 0 | pre[0][k][i] ^= buf[k][50]; buf[k][51] ^= buf[k][50]; |
2720 | 0 | pre[1][k][i] ^= buf[k][51]; buf[k][49] ^= buf[k][51]; |
2721 | 0 | pre[0][k][i] ^= buf[k][49]; buf[k][48] ^= buf[k][49]; |
2722 | 0 | pre[5][k][i] = buf[k][48]; buf[k][16] ^= buf[k][48]; |
2723 | 0 | pre[0][k][i] ^= buf[k][16]; buf[k][17] ^= buf[k][16]; |
2724 | 0 | pre[1][k][i] ^= buf[k][17]; buf[k][19] ^= buf[k][17]; |
2725 | 0 | pre[0][k][i] ^= buf[k][19]; buf[k][18] ^= buf[k][19]; |
2726 | 0 | pre[2][k][i] ^= buf[k][18]; buf[k][22] ^= buf[k][18]; |
2727 | 0 | pre[0][k][i] ^= buf[k][22]; buf[k][23] ^= buf[k][22]; |
2728 | 0 | pre[1][k][i] ^= buf[k][23]; buf[k][21] ^= buf[k][23]; |
2729 | 0 | pre[0][k][i] ^= buf[k][21]; buf[k][20] ^= buf[k][21]; |
2730 | 0 | pre[3][k][i] ^= buf[k][20]; buf[k][28] ^= buf[k][20]; |
2731 | 0 | pre[0][k][i] ^= buf[k][28]; buf[k][29] ^= buf[k][28]; |
2732 | 0 | pre[1][k][i] ^= buf[k][29]; buf[k][31] ^= buf[k][29]; |
2733 | 0 | pre[0][k][i] ^= buf[k][31]; buf[k][30] ^= buf[k][31]; |
2734 | 0 | pre[2][k][i] ^= buf[k][30]; buf[k][26] ^= buf[k][30]; |
2735 | 0 | pre[0][k][i] ^= buf[k][26]; buf[k][27] ^= buf[k][26]; |
2736 | 0 | pre[1][k][i] ^= buf[k][27]; buf[k][25] ^= buf[k][27]; |
2737 | 0 | pre[0][k][i] ^= buf[k][25]; buf[k][24] ^= buf[k][25]; |
2738 | 0 | pre[4][k][i] ^= buf[k][24]; buf[k][8] ^= buf[k][24]; |
2739 | 0 | pre[0][k][i] ^= buf[k][8]; buf[k][9] ^= buf[k][8]; |
2740 | 0 | pre[1][k][i] ^= buf[k][9]; buf[k][11] ^= buf[k][9]; |
2741 | 0 | pre[0][k][i] ^= buf[k][11]; buf[k][10] ^= buf[k][11]; |
2742 | 0 | pre[2][k][i] ^= buf[k][10]; buf[k][14] ^= buf[k][10]; |
2743 | 0 | pre[0][k][i] ^= buf[k][14]; buf[k][15] ^= buf[k][14]; |
2744 | 0 | pre[1][k][i] ^= buf[k][15]; buf[k][13] ^= buf[k][15]; |
2745 | 0 | pre[0][k][i] ^= buf[k][13]; buf[k][12] ^= buf[k][13]; |
2746 | 0 | pre[3][k][i] ^= buf[k][12]; buf[k][4] ^= buf[k][12]; |
2747 | 0 | pre[0][k][i] ^= buf[k][4]; buf[k][5] ^= buf[k][4]; |
2748 | 0 | pre[1][k][i] ^= buf[k][5]; buf[k][7] ^= buf[k][5]; |
2749 | 0 | pre[0][k][i] ^= buf[k][7]; buf[k][6] ^= buf[k][7]; |
2750 | 0 | pre[2][k][i] ^= buf[k][6]; buf[k][2] ^= buf[k][6]; |
2751 | 0 | pre[0][k][i] ^= buf[k][2]; buf[k][3] ^= buf[k][2]; |
2752 | 0 | pre[1][k][i] ^= buf[k][3]; buf[k][1] ^= buf[k][3]; |
2753 | |
|
2754 | 0 | pre[0][k][i] ^= buf[k][1]; out[k][i] = buf[k][0] ^ buf[k][1]; |
2755 | 0 | } |
2756 | 0 | } |
2757 | |
|
2758 | 0 | for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[0] >> j) & 1); |
2759 | |
|
2760 | 0 | vec_mul(out[2], pre[0][0], tmp); |
2761 | 0 | vec_mul(out[3], pre[0][1], tmp); |
2762 | |
|
2763 | 0 | for (i = 1; i < 6; i++) |
2764 | 0 | { |
2765 | 0 | for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[i] >> j) & 1); |
2766 | |
|
2767 | 0 | vec_mul(pre[i][0], pre[i][0], tmp); |
2768 | 0 | vec_mul(pre[i][1], pre[i][1], tmp); |
2769 | |
|
2770 | 0 | for (b = 0; b < GFBITS; b++) |
2771 | 0 | { |
2772 | 0 | out[2][b] ^= pre[i][0][b]; |
2773 | 0 | out[3][b] ^= pre[i][1][b]; |
2774 | 0 | } |
2775 | 0 | } |
2776 | |
|
2777 | 0 | } |
2778 | | |
2779 | | static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ]) |
2780 | 0 | { |
2781 | 0 | butterflies_tr(out, in); |
2782 | |
|
2783 | 0 | radix_conversions_tr(out); |
2784 | 0 | } |
2785 | | |
2786 | | |
2787 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.c */ |
2788 | | /* |
2789 | | this file is for functions for field arithmetic |
2790 | | */ |
2791 | | /* 20221231 djb: const for GF_mul */ |
2792 | | /* 20221230 djb: add linker line */ |
2793 | | |
2794 | | /* linker define gf_iszero gf_mul gf_inv gf_frac GF_mul */ |
2795 | | |
2796 | | |
2797 | | |
2798 | | /* field multiplication */ |
2799 | | gf gf_mul(gf in0, gf in1) |
2800 | 0 | { |
2801 | 0 | int i; |
2802 | |
|
2803 | 0 | uint64_t tmp; |
2804 | 0 | uint64_t t0; |
2805 | 0 | uint64_t t1; |
2806 | 0 | uint64_t t; |
2807 | |
|
2808 | 0 | t0 = in0; |
2809 | 0 | t1 = in1; |
2810 | |
|
2811 | 0 | tmp = t0 * (t1 & 1); |
2812 | |
|
2813 | 0 | for (i = 1; i < GFBITS; i++) |
2814 | 0 | tmp ^= (t0 * (t1 & (1 << i))); |
2815 | | |
2816 | | /**/ |
2817 | |
|
2818 | 0 | t = tmp & 0x1FF0000; |
2819 | 0 | tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
2820 | |
|
2821 | 0 | t = tmp & 0x000E000; |
2822 | 0 | tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
2823 | |
|
2824 | 0 | return tmp & GFMASK; |
2825 | 0 | } |
2826 | | |
2827 | | /* 2 field squarings */ |
2828 | | static inline gf gf_sq2(gf in) |
2829 | 0 | { |
2830 | 0 | int i; |
2831 | |
|
2832 | 0 | const uint64_t B[] = {0x1111111111111111, |
2833 | 0 | 0x0303030303030303, |
2834 | 0 | 0x000F000F000F000F, |
2835 | 0 | 0x000000FF000000FF}; |
2836 | |
|
2837 | 0 | const uint64_t M[] = {0x0001FF0000000000, |
2838 | 0 | 0x000000FF80000000, |
2839 | 0 | 0x000000007FC00000, |
2840 | 0 | 0x00000000003FE000}; |
2841 | |
|
2842 | 0 | uint64_t x = in; |
2843 | 0 | uint64_t t; |
2844 | |
|
2845 | 0 | x = (x | (x << 24)) & B[3]; |
2846 | 0 | x = (x | (x << 12)) & B[2]; |
2847 | 0 | x = (x | (x << 6)) & B[1]; |
2848 | 0 | x = (x | (x << 3)) & B[0]; |
2849 | |
|
2850 | 0 | for (i = 0; i < 4; i++) |
2851 | 0 | { |
2852 | 0 | t = x & M[i]; |
2853 | 0 | x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
2854 | 0 | } |
2855 | |
|
2856 | 0 | return x & GFMASK; |
2857 | 0 | } |
2858 | | |
2859 | | /* square and multiply */ |
2860 | | static inline gf gf_sqmul(gf in, gf m) |
2861 | 0 | { |
2862 | 0 | int i; |
2863 | |
|
2864 | 0 | uint64_t x; |
2865 | 0 | uint64_t t0; |
2866 | 0 | uint64_t t1; |
2867 | 0 | uint64_t t; |
2868 | |
|
2869 | 0 | const uint64_t M[] = {0x0000001FF0000000, |
2870 | 0 | 0x000000000FF80000, |
2871 | 0 | 0x000000000007E000}; |
2872 | |
|
2873 | 0 | t0 = in; |
2874 | 0 | t1 = m; |
2875 | |
|
2876 | 0 | x = (t1 << 6) * (t0 & (1 << 6)); |
2877 | |
|
2878 | 0 | t0 ^= (t0 << 7); |
2879 | |
|
2880 | 0 | x ^= (t1 * (t0 & (0x04001))); |
2881 | 0 | x ^= (t1 * (t0 & (0x08002))) << 1; |
2882 | 0 | x ^= (t1 * (t0 & (0x10004))) << 2; |
2883 | 0 | x ^= (t1 * (t0 & (0x20008))) << 3; |
2884 | 0 | x ^= (t1 * (t0 & (0x40010))) << 4; |
2885 | 0 | x ^= (t1 * (t0 & (0x80020))) << 5; |
2886 | |
|
2887 | 0 | for (i = 0; i < 3; i++) |
2888 | 0 | { |
2889 | 0 | t = x & M[i]; |
2890 | 0 | x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
2891 | 0 | } |
2892 | |
|
2893 | 0 | return x & GFMASK; |
2894 | 0 | } |
2895 | | |
2896 | | /* square twice and multiply */ |
2897 | | static inline gf gf_sq2mul(gf in, gf m) |
2898 | 0 | { |
2899 | 0 | int i; |
2900 | |
|
2901 | 0 | uint64_t x; |
2902 | 0 | uint64_t t0; |
2903 | 0 | uint64_t t1; |
2904 | 0 | uint64_t t; |
2905 | |
|
2906 | 0 | const uint64_t M[] = {0x1FF0000000000000, |
2907 | 0 | 0x000FF80000000000, |
2908 | 0 | 0x000007FC00000000, |
2909 | 0 | 0x00000003FE000000, |
2910 | 0 | 0x0000000001FE0000, |
2911 | 0 | 0x000000000001E000}; |
2912 | |
|
2913 | 0 | t0 = in; |
2914 | 0 | t1 = m; |
2915 | |
|
2916 | 0 | x = (t1 << 18) * (t0 & (1 << 6)); |
2917 | |
|
2918 | 0 | t0 ^= (t0 << 21); |
2919 | |
|
2920 | 0 | x ^= (t1 * (t0 & (0x010000001))); |
2921 | 0 | x ^= (t1 * (t0 & (0x020000002))) << 3; |
2922 | 0 | x ^= (t1 * (t0 & (0x040000004))) << 6; |
2923 | 0 | x ^= (t1 * (t0 & (0x080000008))) << 9; |
2924 | 0 | x ^= (t1 * (t0 & (0x100000010))) << 12; |
2925 | 0 | x ^= (t1 * (t0 & (0x200000020))) << 15; |
2926 | |
|
2927 | 0 | for (i = 0; i < 6; i++) |
2928 | 0 | { |
2929 | 0 | t = x & M[i]; |
2930 | 0 | x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); |
2931 | 0 | } |
2932 | |
|
2933 | 0 | return x & GFMASK; |
2934 | 0 | } |
2935 | | |
2936 | | /* return num/den */ |
2937 | | gf gf_frac(gf den, gf num) |
2938 | 0 | { |
2939 | 0 | gf tmp_11; |
2940 | 0 | gf tmp_1111; |
2941 | 0 | gf out; |
2942 | |
|
2943 | 0 | tmp_11 = gf_sqmul(den, den); /* 11 */ |
2944 | 0 | tmp_1111 = gf_sq2mul(tmp_11, tmp_11); /* 1111 */ |
2945 | 0 | out = gf_sq2(tmp_1111); |
2946 | 0 | out = gf_sq2mul(out, tmp_1111); /* 11111111 */ |
2947 | 0 | out = gf_sq2(out); |
2948 | 0 | out = gf_sq2mul(out, tmp_1111); /* 111111111111 */ |
2949 | |
|
2950 | 0 | return gf_sqmul(out, num); /* 1111111111110 */ |
2951 | 0 | } |
2952 | | |
2953 | | /* return 1/den */ |
2954 | | gf gf_inv(gf den) |
2955 | 0 | { |
2956 | 0 | return gf_frac(den, ((gf) 1)); |
2957 | 0 | } |
2958 | | |
2959 | | /* check if a == 0 */ |
2960 | | gf gf_iszero(gf a) |
2961 | 0 | { |
2962 | 0 | uint32_t t = a; |
2963 | |
|
2964 | 0 | t -= 1; |
2965 | 0 | t >>= 19; |
2966 | |
|
2967 | 0 | return (gf) t; |
2968 | 0 | } |
2969 | | |
2970 | | /* multiplication in GF((2^m)^t) */ |
2971 | | static void GF_mul(gf *out, const gf *in0, const gf *in1) |
2972 | 0 | { |
2973 | 0 | int i, j; |
2974 | |
|
2975 | 0 | gf prod[255]; |
2976 | |
|
2977 | 0 | for (i = 0; i < 255; i++) |
2978 | 0 | prod[i] = 0; |
2979 | |
|
2980 | 0 | for (i = 0; i < 128; i++) |
2981 | 0 | for (j = 0; j < 128; j++) |
2982 | 0 | prod[i+j] ^= gf_mul(in0[i], in1[j]); |
2983 | | |
2984 | | /**/ |
2985 | |
|
2986 | 0 | for (i = 254; i >= 128; i--) |
2987 | 0 | { |
2988 | 0 | prod[i - 121] ^= prod[i]; |
2989 | 0 | prod[i - 126] ^= prod[i]; |
2990 | 0 | prod[i - 127] ^= prod[i]; |
2991 | 0 | prod[i - 128] ^= prod[i]; |
2992 | 0 | } |
2993 | |
|
2994 | 0 | for (i = 0; i < 128; i++) |
2995 | 0 | out[i] = prod[i]; |
2996 | 0 | } |
2997 | | |
2998 | | |
2999 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c */ |
3000 | | /* 20221230 djb: add linker lines */ |
3001 | | /* 20221230 djb: split out of operations.c */ |
3002 | | |
3003 | | /* linker define operation_dec */ |
3004 | | /* linker use decrypt */ |
3005 | | |
3006 | | |
3007 | | |
3008 | | |
3009 | | static void operation_dec( |
3010 | | unsigned char *key, |
3011 | | const unsigned char *c, |
3012 | | const unsigned char *sk |
3013 | | ) |
3014 | 0 | { |
3015 | 0 | int i; |
3016 | |
|
3017 | 0 | unsigned char ret_decrypt = 0; |
3018 | |
|
3019 | 0 | uint16_t m; |
3020 | |
|
3021 | 0 | unsigned char e[ SYS_N/8 ]; |
3022 | 0 | unsigned char preimage[ 1 + SYS_N/8 + SYND_BYTES ]; |
3023 | 0 | unsigned char *x = preimage; |
3024 | 0 | const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES; |
3025 | | |
3026 | | /**/ |
3027 | |
|
3028 | 0 | ret_decrypt = decrypt(e, sk + 40, c); |
3029 | |
|
3030 | 0 | m = ret_decrypt; |
3031 | 0 | m -= 1; |
3032 | 0 | m >>= 8; |
3033 | |
|
3034 | 0 | *x++ = m & 1; |
3035 | 0 | for (i = 0; i < SYS_N/8; i++) |
3036 | 0 | *x++ = (~m & s[i]) | (m & e[i]); |
3037 | |
|
3038 | 0 | for (i = 0; i < SYND_BYTES; i++) |
3039 | 0 | *x++ = c[i]; |
3040 | |
|
3041 | 0 | crypto_hash_32b(key, preimage, sizeof(preimage)); |
3042 | 0 | } |
3043 | | |
3044 | | |
3045 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c */ |
3046 | | /* 20230102 djb: rename encrypt() as pke_encrypt() */ |
3047 | | /* 20221230 djb: add linker lines */ |
3048 | | /* 20221230 djb: split out of operations.c */ |
3049 | | |
3050 | | /* linker define operation_enc */ |
3051 | | /* linker use pke_encrypt */ |
3052 | | |
3053 | | |
3054 | | |
3055 | | |
3056 | | static void operation_enc( |
3057 | | unsigned char *c, |
3058 | | unsigned char *key, |
3059 | | const unsigned char *pk |
3060 | | ) |
3061 | 0 | { |
3062 | 0 | unsigned char e[ SYS_N/8 ]; |
3063 | 0 | unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1}; |
3064 | | |
3065 | | /**/ |
3066 | |
|
3067 | 0 | pke_encrypt(c, pk, e); |
3068 | |
|
3069 | 0 | memcpy(one_ec + 1, e, SYS_N/8); |
3070 | 0 | memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES); |
3071 | |
|
3072 | 0 | crypto_hash_32b(key, one_ec, sizeof(one_ec)); |
3073 | 0 | } |
3074 | | |
3075 | | |
3076 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c */ |
3077 | | /* 20221230 djb: add linker lines */ |
3078 | | /* 20221230 djb: split out of operations.c */ |
3079 | | |
3080 | | /* linker define operation_keypair */ |
3081 | | /* linker use controlbitsfrompermutation genpoly_gen pk_gen */ |
3082 | | |
3083 | | |
3084 | | |
3085 | | |
3086 | | static void operation_keypair |
3087 | | ( |
3088 | | unsigned char *pk, |
3089 | | unsigned char *sk |
3090 | | ) |
3091 | 0 | { |
3092 | 0 | int i; |
3093 | 0 | unsigned char seed[ 33 ] = {64}; |
3094 | 0 | unsigned char r[ SYS_N/8 + (1 << GFBITS)*sizeof(uint32_t) + SYS_T*2 + 32 ]; |
3095 | 0 | unsigned char *rp, *skp; |
3096 | 0 | uint64_t pivots = 0; |
3097 | |
|
3098 | 0 | gf f[ SYS_T ]; /* element in GF(2^mt) */ |
3099 | 0 | gf irr[ SYS_T ]; /* Goppa polynomial */ |
3100 | 0 | uint32_t perm[ 1 << GFBITS ]; /* random permutation as 32-bit integers */ |
3101 | 0 | int16_t pi[ 1 << GFBITS ]; /* random permutation */ |
3102 | |
|
3103 | 0 | randombytes(seed+1, 32); |
3104 | |
|
3105 | 0 | while (1) |
3106 | 0 | { |
3107 | 0 | rp = &r[ sizeof(r)-32 ]; |
3108 | 0 | skp = sk; |
3109 | | |
3110 | | /* expanding and updating the seed */ |
3111 | |
|
3112 | 0 | shake(r, sizeof(r), seed, 33); |
3113 | 0 | memcpy(skp, seed+1, 32); |
3114 | 0 | skp += 32 + 8; |
3115 | 0 | memcpy(seed+1, &r[ sizeof(r)-32 ], 32); |
3116 | | |
3117 | | /* generating irreducible polynomial */ |
3118 | |
|
3119 | 0 | rp -= sizeof(f); |
3120 | |
|
3121 | 0 | for (i = 0; i < SYS_T; i++) |
3122 | 0 | f[i] = load_gf(rp + i*2); |
3123 | |
|
3124 | 0 | if (genpoly_gen(irr, f)) |
3125 | 0 | continue; |
3126 | | |
3127 | 0 | for (i = 0; i < SYS_T; i++) |
3128 | 0 | store_gf(skp + i*2, irr[i]); |
3129 | |
|
3130 | 0 | skp += IRR_BYTES; |
3131 | | |
3132 | | /* generating permutation */ |
3133 | |
|
3134 | 0 | rp -= sizeof(perm); |
3135 | |
|
3136 | 0 | for (i = 0; i < (1 << GFBITS); i++) |
3137 | 0 | perm[i] = load4(rp + i*4); |
3138 | |
|
3139 | 0 | if (pk_gen(pk, skp - IRR_BYTES, perm, pi, &pivots)) |
3140 | 0 | continue; |
3141 | | |
3142 | 0 | controlbitsfrompermutation(skp, pi, GFBITS, 1 << GFBITS); |
3143 | 0 | skp += COND_BYTES; |
3144 | | |
3145 | | /* storing the random string s */ |
3146 | |
|
3147 | 0 | rp -= SYS_N/8; |
3148 | 0 | memcpy(skp, rp, SYS_N/8); |
3149 | | |
3150 | | /* storing positions of the 32 pivots */ |
3151 | |
|
3152 | 0 | store8(sk + 32, pivots); |
3153 | |
|
3154 | 0 | break; |
3155 | 0 | } |
3156 | 0 | } |
3157 | | |
3158 | | |
3159 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c */ |
3160 | | /* |
3161 | | This file is for public-key generation |
3162 | | */ |
3163 | | /* 20221231 djb: remove unused min definition */ |
3164 | | /* 20221231 djb: more 0 initialization to clarify data flow; tnx thom wiggers */ |
3165 | | /* 20221230 djb: add linker lines */ |
3166 | | |
3167 | | /* linker define pk_gen */ |
3168 | | /* linker use fft vec_inv vec_mul */ |
3169 | | |
3170 | | |
3171 | | |
3172 | | static crypto_uint64 uint64_is_equal_declassify(uint64_t t,uint64_t u) |
3173 | 0 | { |
3174 | 0 | crypto_uint64 mask = crypto_uint64_equal_mask(t,u); |
3175 | 0 | crypto_declassify(&mask,sizeof mask); |
3176 | 0 | return mask; |
3177 | 0 | } |
3178 | | |
3179 | | static crypto_uint64 uint64_is_zero_declassify(uint64_t t) |
3180 | 0 | { |
3181 | 0 | crypto_uint64 mask = crypto_uint64_zero_mask(t); |
3182 | 0 | crypto_declassify(&mask,sizeof mask); |
3183 | 0 | return mask; |
3184 | 0 | } |
3185 | | |
3186 | | |
3187 | | static void de_bitslicing(uint64_t * out, const vec in[][GFBITS]) |
3188 | 0 | { |
3189 | 0 | int i, j, r; |
3190 | |
|
3191 | 0 | for (i = 0; i < (1 << GFBITS); i++) |
3192 | 0 | out[i] = 0 ; |
3193 | |
|
3194 | 0 | for (i = 0; i < 128; i++) |
3195 | 0 | for (j = GFBITS-1; j >= 0; j--) |
3196 | 0 | for (r = 0; r < 64; r++) |
3197 | 0 | { |
3198 | 0 | out[i*64 + r] <<= 1; |
3199 | 0 | out[i*64 + r] |= (in[i][j] >> r) & 1; |
3200 | 0 | } |
3201 | 0 | } |
3202 | | |
3203 | | static void to_bitslicing_2x(vec out0[][GFBITS], vec out1[][GFBITS], const uint64_t * in) |
3204 | 0 | { |
3205 | 0 | int i, j, r; |
3206 | |
|
3207 | 0 | for (i = 0; i < 128; i++) |
3208 | 0 | { |
3209 | 0 | for (j = 0;j < GFBITS;++j) out0[i][j] = out1[i][j] = 0; |
3210 | |
|
3211 | 0 | for (j = GFBITS-1; j >= 0; j--) |
3212 | 0 | for (r = 63; r >= 0; r--) |
3213 | 0 | { |
3214 | 0 | out1[i][j] <<= 1; |
3215 | 0 | out1[i][j] |= (in[i*64 + r] >> (j + GFBITS)) & 1; |
3216 | 0 | } |
3217 | |
|
3218 | 0 | for (j = GFBITS-1; j >= 0; j--) |
3219 | 0 | for (r = 63; r >= 0; r--) |
3220 | 0 | { |
3221 | 0 | out0[i][GFBITS-1-j] <<= 1; |
3222 | 0 | out0[i][GFBITS-1-j] |= (in[i*64 + r] >> j) & 1; |
3223 | 0 | } |
3224 | 0 | } |
3225 | 0 | } |
3226 | | |
3227 | | /* return number of trailing zeros of in */ |
3228 | | static inline int ctz(uint64_t in) |
3229 | 0 | { |
3230 | 0 | int i, b, m = 0, r = 0; |
3231 | |
|
3232 | 0 | for (i = 0; i < 64; i++) |
3233 | 0 | { |
3234 | 0 | b = (in >> i) & 1; |
3235 | 0 | m |= b; |
3236 | 0 | r += (m^1) & (b^1); |
3237 | 0 | } |
3238 | |
|
3239 | 0 | return r; |
3240 | 0 | } |
3241 | | |
3242 | | static inline uint64_t same_mask(uint16_t x, uint16_t y) |
3243 | 0 | { |
3244 | 0 | uint64_t mask; |
3245 | |
|
3246 | 0 | mask = x ^ y; |
3247 | 0 | mask -= 1; |
3248 | 0 | mask >>= 63; |
3249 | 0 | mask = -mask; |
3250 | |
|
3251 | 0 | return mask; |
3252 | 0 | } |
3253 | | |
3254 | | static int mov_columns(uint64_t mat[][ (SYS_N + 63) / 64 ], int16_t * pi, uint64_t * pivots) |
3255 | 0 | { |
3256 | 0 | int i, j, k, s, block_idx, row; |
3257 | 0 | uint64_t buf[64], ctz_list[32], t, d, mask, one = 1; |
3258 | |
|
3259 | 0 | row = PK_NROWS - 32; |
3260 | 0 | block_idx = row/64; |
3261 | | |
3262 | | /* extract the 32x64 matrix */ |
3263 | |
|
3264 | 0 | for (i = 0; i < 32; i++) |
3265 | 0 | buf[i] = (mat[ row + i ][ block_idx + 0 ] >> 32) | |
3266 | 0 | (mat[ row + i ][ block_idx + 1 ] << 32); |
3267 | | |
3268 | | /* compute the column indices of pivots by Gaussian elimination. */ |
3269 | | /* the indices are stored in ctz_list */ |
3270 | |
|
3271 | 0 | *pivots = 0; |
3272 | |
|
3273 | 0 | for (i = 0; i < 32; i++) |
3274 | 0 | { |
3275 | 0 | t = buf[i]; |
3276 | 0 | for (j = i+1; j < 32; j++) |
3277 | 0 | t |= buf[j]; |
3278 | |
|
3279 | 0 | if (uint64_is_zero_declassify(t)) return -1; /* return if buf is not full rank */ |
3280 | | |
3281 | 0 | ctz_list[i] = s = ctz(t); |
3282 | 0 | *pivots |= one << ctz_list[i]; |
3283 | |
|
3284 | 0 | for (j = i+1; j < 32; j++) { mask = (buf[i] >> s) & 1; mask -= 1; buf[i] ^= buf[j] & mask; } |
3285 | 0 | for (j = i+1; j < 32; j++) { mask = (buf[j] >> s) & 1; mask = -mask; buf[j] ^= buf[i] & mask; } |
3286 | 0 | } |
3287 | | |
3288 | | /* updating permutation */ |
3289 | | |
3290 | 0 | for (j = 0; j < 32; j++) |
3291 | 0 | for (k = j+1; k < 64; k++) |
3292 | 0 | { |
3293 | 0 | d = pi[ row + j ] ^ pi[ row + k ]; |
3294 | 0 | d &= same_mask(k, ctz_list[j]); |
3295 | 0 | pi[ row + j ] ^= d; |
3296 | 0 | pi[ row + k ] ^= d; |
3297 | 0 | } |
3298 | | |
3299 | | /* moving columns of mat according to the column indices of pivots */ |
3300 | |
|
3301 | 0 | for (i = 0; i < PK_NROWS; i++) |
3302 | 0 | { |
3303 | 0 | t = (mat[ i ][ block_idx + 0 ] >> 32) | |
3304 | 0 | (mat[ i ][ block_idx + 1 ] << 32); |
3305 | |
|
3306 | 0 | for (j = 0; j < 32; j++) |
3307 | 0 | { |
3308 | 0 | d = t >> j; |
3309 | 0 | d ^= t >> ctz_list[j]; |
3310 | 0 | d &= 1; |
3311 | |
|
3312 | 0 | t ^= d << ctz_list[j]; |
3313 | 0 | t ^= d << j; |
3314 | 0 | } |
3315 | |
|
3316 | 0 | mat[ i ][ block_idx + 0 ] = (mat[ i ][ block_idx + 0 ] << 32 >> 32) | (t << 32); |
3317 | 0 | mat[ i ][ block_idx + 1 ] = (mat[ i ][ block_idx + 1 ] >> 32 << 32) | (t >> 32); |
3318 | 0 | } |
3319 | |
|
3320 | 0 | return 0; |
3321 | 0 | } |
3322 | | |
3323 | | static int pk_gen(unsigned char * pk, const unsigned char * irr, uint32_t * perm, int16_t * pi, uint64_t * pivots) |
3324 | 0 | { |
3325 | 0 | const int nblocks_H = (SYS_N + 63) / 64; |
3326 | 0 | const int nblocks_I = (PK_NROWS + 63) / 64; |
3327 | |
|
3328 | 0 | int i, j, k; |
3329 | 0 | int row, c; |
3330 | |
|
3331 | 0 | uint64_t mat[ PK_NROWS ][ nblocks_H ]; |
3332 | |
|
3333 | 0 | uint64_t mask; |
3334 | |
|
3335 | 0 | vec irr_int[2][ GFBITS ]; |
3336 | |
|
3337 | 0 | vec consts[ 128 ][ GFBITS ]; |
3338 | 0 | vec eval[ 128 ][ GFBITS ]; |
3339 | 0 | vec prod[ 128 ][ GFBITS ]; |
3340 | 0 | vec tmp[ GFBITS ]; |
3341 | |
|
3342 | 0 | uint64_t list[1 << GFBITS]; |
3343 | | |
3344 | | /* compute the inverses */ |
3345 | |
|
3346 | 0 | irr_load(irr_int, irr); |
3347 | |
|
3348 | 0 | fft(eval, irr_int); |
3349 | |
|
3350 | 0 | vec_copy(prod[0], eval[0]); |
3351 | |
|
3352 | 0 | for (i = 1; i < 128; i++) |
3353 | 0 | vec_mul(prod[i], prod[i-1], eval[i]); |
3354 | |
|
3355 | 0 | vec_inv(tmp, prod[127]); |
3356 | |
|
3357 | 0 | for (i = 126; i >= 0; i--) |
3358 | 0 | { |
3359 | 0 | vec_mul(prod[i+1], prod[i], tmp); |
3360 | 0 | vec_mul(tmp, tmp, eval[i+1]); |
3361 | 0 | } |
3362 | |
|
3363 | 0 | vec_copy(prod[0], tmp); |
3364 | | |
3365 | | /* fill matrix */ |
3366 | |
|
3367 | 0 | de_bitslicing(list, prod); |
3368 | |
|
3369 | 0 | for (i = 0; i < (1 << GFBITS); i++) |
3370 | 0 | { |
3371 | 0 | list[i] <<= GFBITS; |
3372 | 0 | list[i] |= i; |
3373 | 0 | list[i] |= ((uint64_t) perm[i]) << 31; |
3374 | 0 | } |
3375 | |
|
3376 | 0 | uint64_sort(list, 1 << GFBITS); |
3377 | |
|
3378 | 0 | for (i = 1; i < (1 << GFBITS); i++) |
3379 | 0 | if (uint64_is_equal_declassify(list[i-1] >> 31,list[i] >> 31)) |
3380 | 0 | return -1; |
3381 | | |
3382 | 0 | to_bitslicing_2x(consts, prod, list); |
3383 | |
|
3384 | 0 | for (i = 0; i < (1 << GFBITS); i++) |
3385 | 0 | pi[i] = list[i] & GFMASK; |
3386 | |
|
3387 | 0 | for (j = 0; j < nblocks_H; j++) |
3388 | 0 | for (k = 0; k < GFBITS; k++) |
3389 | 0 | mat[ k ][ j ] = prod[ j ][ k ]; |
3390 | |
|
3391 | 0 | for (i = 1; i < SYS_T; i++) |
3392 | 0 | for (j = 0; j < nblocks_H; j++) |
3393 | 0 | { |
3394 | 0 | vec_mul(prod[j], prod[j], consts[j]); |
3395 | |
|
3396 | 0 | for (k = 0; k < GFBITS; k++) |
3397 | 0 | mat[ i*GFBITS + k ][ j ] = prod[ j ][ k ]; |
3398 | 0 | } |
3399 | | |
3400 | | /* gaussian elimination */ |
3401 | |
|
3402 | 0 | for (row = 0; row < PK_NROWS; row++) |
3403 | 0 | { |
3404 | 0 | i = row >> 6; |
3405 | 0 | j = row & 63; |
3406 | |
|
3407 | 0 | if (row == PK_NROWS - 32) |
3408 | 0 | { |
3409 | 0 | if (mov_columns(mat, pi, pivots)) |
3410 | 0 | return -1; |
3411 | 0 | } |
3412 | | |
3413 | 0 | for (k = row + 1; k < PK_NROWS; k++) |
3414 | 0 | { |
3415 | 0 | mask = mat[ row ][ i ] >> j; |
3416 | 0 | mask &= 1; |
3417 | 0 | mask -= 1; |
3418 | |
|
3419 | 0 | for (c = 0; c < nblocks_H; c++) |
3420 | 0 | mat[ row ][ c ] ^= mat[ k ][ c ] & mask; |
3421 | 0 | } |
3422 | |
|
3423 | 0 | if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) /* return if not systematic */ |
3424 | 0 | { |
3425 | 0 | return -1; |
3426 | 0 | } |
3427 | | |
3428 | 0 | for (k = 0; k < row; k++) |
3429 | 0 | { |
3430 | 0 | mask = mat[ k ][ i ] >> j; |
3431 | 0 | mask &= 1; |
3432 | 0 | mask = -mask; |
3433 | |
|
3434 | 0 | for (c = 0; c < nblocks_H; c++) |
3435 | 0 | mat[ k ][ c ] ^= mat[ row ][ c ] & mask; |
3436 | 0 | } |
3437 | |
|
3438 | 0 | for (k = row+1; k < PK_NROWS; k++) |
3439 | 0 | { |
3440 | 0 | mask = mat[ k ][ i ] >> j; |
3441 | 0 | mask &= 1; |
3442 | 0 | mask = -mask; |
3443 | |
|
3444 | 0 | for (c = 0; c < nblocks_H; c++) |
3445 | 0 | mat[ k ][ c ] ^= mat[ row ][ c ] & mask; |
3446 | 0 | } |
3447 | 0 | } |
3448 | | |
3449 | 0 | for (i = 0; i < PK_NROWS; i++) |
3450 | 0 | { |
3451 | 0 | for (j = nblocks_I; j < nblocks_H-1; j++) |
3452 | 0 | { |
3453 | 0 | store8(pk, mat[i][j]); |
3454 | 0 | pk += 8; |
3455 | 0 | } |
3456 | |
|
3457 | 0 | store_i(pk, mat[i][j], PK_ROW_BYTES % 8); |
3458 | |
|
3459 | 0 | pk += PK_ROW_BYTES % 8; |
3460 | 0 | } |
3461 | | |
3462 | | /**/ |
3463 | |
|
3464 | 0 | return 0; |
3465 | 0 | } |
3466 | | |
3467 | | |
3468 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c */ |
3469 | | /* |
3470 | | This file is for secret-key generation |
3471 | | */ |
3472 | | /* 20221230 djb: add linker lines */ |
3473 | | |
3474 | | /* linker define genpoly_gen */ |
3475 | | /* linker use gf_iszero gf_mul gf_inv GF_mul */ |
3476 | | |
3477 | | |
3478 | | |
3479 | | static inline crypto_uint16 gf_is_zero_declassify(gf t) |
3480 | 0 | { |
3481 | 0 | crypto_uint16 mask = crypto_uint16_zero_mask(t); |
3482 | 0 | crypto_declassify(&mask,sizeof mask); |
3483 | 0 | return mask; |
3484 | 0 | } |
3485 | | |
3486 | | /* input: f, element in GF((2^m)^t) */ |
3487 | | /* output: out, minimal polynomial of f */ |
3488 | | /* return: 0 for success and -1 for failure */ |
3489 | | static int genpoly_gen(gf *out, gf *f) |
3490 | 0 | { |
3491 | 0 | int i, j, k, c; |
3492 | |
|
3493 | 0 | gf mat[ SYS_T+1 ][ SYS_T ]; |
3494 | 0 | gf mask, inv, t; |
3495 | | |
3496 | | /* fill matrix */ |
3497 | |
|
3498 | 0 | mat[0][0] = 1; |
3499 | |
|
3500 | 0 | for (i = 1; i < SYS_T; i++) |
3501 | 0 | mat[0][i] = 0; |
3502 | |
|
3503 | 0 | for (i = 0; i < SYS_T; i++) |
3504 | 0 | mat[1][i] = f[i]; |
3505 | |
|
3506 | 0 | for (j = 2; j <= SYS_T; j++) |
3507 | 0 | GF_mul(mat[j], mat[j-1], f); |
3508 | | |
3509 | | /* gaussian */ |
3510 | |
|
3511 | 0 | for (j = 0; j < SYS_T; j++) |
3512 | 0 | { |
3513 | 0 | for (k = j + 1; k < SYS_T; k++) |
3514 | 0 | { |
3515 | 0 | mask = gf_iszero(mat[ j ][ j ]); |
3516 | |
|
3517 | 0 | for (c = j; c < SYS_T + 1; c++) |
3518 | 0 | mat[ c ][ j ] ^= mat[ c ][ k ] & mask; |
3519 | |
|
3520 | 0 | } |
3521 | |
|
3522 | 0 | if ( gf_is_zero_declassify(mat[ j ][ j ]) ) /* return if not systematic */ |
3523 | 0 | { |
3524 | 0 | return -1; |
3525 | 0 | } |
3526 | | |
3527 | 0 | inv = gf_inv(mat[j][j]); |
3528 | |
|
3529 | 0 | for (c = j; c < SYS_T + 1; c++) |
3530 | 0 | mat[ c ][ j ] = gf_mul(mat[ c ][ j ], inv) ; |
3531 | |
|
3532 | 0 | for (k = 0; k < SYS_T; k++) |
3533 | 0 | { |
3534 | 0 | if (k != j) |
3535 | 0 | { |
3536 | 0 | t = mat[ j ][ k ]; |
3537 | |
|
3538 | 0 | for (c = j; c < SYS_T + 1; c++) |
3539 | 0 | mat[ c ][ k ] ^= gf_mul(mat[ c ][ j ], t); |
3540 | 0 | } |
3541 | 0 | } |
3542 | 0 | } |
3543 | | |
3544 | 0 | for (i = 0; i < SYS_T; i++) |
3545 | 0 | out[i] = mat[ SYS_T ][ i ]; |
3546 | |
|
3547 | 0 | return 0; |
3548 | 0 | } |
3549 | | |
3550 | | |
3551 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.c */ |
3552 | | /* 20221230 djb: add linker line */ |
3553 | | |
3554 | | /* linker define vec_mul vec_sq vec_inv */ |
3555 | | |
3556 | | |
3557 | | |
3558 | | static void vec_mul(vec * h, const vec * f, const vec * g) |
3559 | 0 | { |
3560 | 0 | int i, j; |
3561 | 0 | vec buf[ 2*GFBITS-1 ]; |
3562 | |
|
3563 | 0 | for (i = 0; i < 2*GFBITS-1; i++) |
3564 | 0 | buf[i] = 0; |
3565 | |
|
3566 | 0 | for (i = 0; i < GFBITS; i++) |
3567 | 0 | for (j = 0; j < GFBITS; j++) |
3568 | 0 | buf[i+j] ^= f[i] & g[j]; |
3569 | |
|
3570 | 0 | for (i = 2*GFBITS-2; i >= GFBITS; i--) |
3571 | 0 | { |
3572 | 0 | buf[i-GFBITS+4] ^= buf[i]; |
3573 | 0 | buf[i-GFBITS+3] ^= buf[i]; |
3574 | 0 | buf[i-GFBITS+1] ^= buf[i]; |
3575 | 0 | buf[i-GFBITS+0] ^= buf[i]; |
3576 | 0 | } |
3577 | |
|
3578 | 0 | for (i = 0; i < GFBITS; i++) |
3579 | 0 | h[i] = buf[i]; |
3580 | 0 | } |
3581 | | |
3582 | | /* bitsliced field squarings */ |
3583 | | static void vec_sq(vec * out, vec * in) |
3584 | 0 | { |
3585 | 0 | int i; |
3586 | 0 | vec result[GFBITS], t; |
3587 | |
|
3588 | 0 | t = in[11] ^ in[12]; |
3589 | |
|
3590 | 0 | result[0] = in[0] ^ in[11]; |
3591 | 0 | result[1] = in[7] ^ t; |
3592 | 0 | result[2] = in[1] ^ in[7]; |
3593 | 0 | result[3] = in[8] ^ t; |
3594 | 0 | result[4] = in[2] ^ in[7]; |
3595 | 0 | result[4] = result[4] ^ in[8]; |
3596 | 0 | result[4] = result[4] ^ t; |
3597 | 0 | result[5] = in[7] ^ in[9]; |
3598 | 0 | result[6] = in[3] ^ in[8]; |
3599 | 0 | result[6] = result[6] ^ in[9]; |
3600 | 0 | result[6] = result[6] ^ in[12]; |
3601 | 0 | result[7] = in[8] ^ in[10]; |
3602 | 0 | result[8] = in[4] ^ in[9]; |
3603 | 0 | result[8] = result[8] ^ in[10]; |
3604 | 0 | result[9] = in[9] ^ in[11]; |
3605 | 0 | result[10] = in[5] ^ in[10]; |
3606 | 0 | result[10] = result[10] ^ in[11]; |
3607 | 0 | result[11] = in[10] ^ in[12]; |
3608 | 0 | result[12] = in[6] ^ t; |
3609 | |
|
3610 | 0 | for (i = 0; i < GFBITS; i++) |
3611 | 0 | out[i] = result[i]; |
3612 | 0 | } |
3613 | | |
3614 | | /* bitsliced field inverses */ |
3615 | | static void vec_inv(vec * out, vec * in) |
3616 | 0 | { |
3617 | 0 | vec tmp_11[ GFBITS ]; |
3618 | 0 | vec tmp_1111[ GFBITS ]; |
3619 | |
|
3620 | 0 | vec_copy(out, in); |
3621 | |
|
3622 | 0 | vec_sq(out, out); |
3623 | 0 | vec_mul(tmp_11, out, in); /* ^11 */ |
3624 | |
|
3625 | 0 | vec_sq(out, tmp_11); |
3626 | 0 | vec_sq(out, out); |
3627 | 0 | vec_mul(tmp_1111, out, tmp_11); /* ^1111 */ |
3628 | |
|
3629 | 0 | vec_sq(out, tmp_1111); |
3630 | 0 | vec_sq(out, out); |
3631 | 0 | vec_sq(out, out); |
3632 | 0 | vec_sq(out, out); |
3633 | 0 | vec_mul(out, out, tmp_1111); /* ^11111111 */ |
3634 | |
|
3635 | 0 | vec_sq(out, out); |
3636 | 0 | vec_sq(out, out); |
3637 | 0 | vec_sq(out, out); |
3638 | 0 | vec_sq(out, out); |
3639 | 0 | vec_mul(out, out, tmp_1111); /* ^111111111111 */ |
3640 | |
|
3641 | 0 | vec_sq(out, out); /* ^1111111111110 */ |
3642 | 0 | } |
3643 | | |
3644 | | |
3645 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c */ |
3646 | | |
3647 | | void mceliece6688128f_dec(uint8_t *key, |
3648 | | const uint8_t *c, |
3649 | | const uint8_t *sk) |
3650 | 0 | { |
3651 | 0 | operation_dec((unsigned char*) key, |
3652 | 0 | (unsigned char*) c, |
3653 | 0 | (unsigned char*) sk); |
3654 | 0 | } |
3655 | | |
3656 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c */ |
3657 | | |
3658 | | void mceliece6688128f_enc(uint8_t *c, |
3659 | | uint8_t *key, |
3660 | | const uint8_t *pk) |
3661 | 0 | { |
3662 | 0 | operation_enc((unsigned char*) c, |
3663 | 0 | (unsigned char*) key, |
3664 | 0 | (unsigned char*) pk); |
3665 | 0 | } |
3666 | | |
3667 | | /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c */ |
3668 | | |
3669 | | void mceliece6688128f_keypair(uint8_t *pk, |
3670 | | uint8_t *sk) |
3671 | 0 | { |
3672 | 0 | operation_keypair((unsigned char*) pk, (unsigned char*) sk); |
3673 | 0 | } |