diff --git a/cipher/mceliece6688128f.c b/cipher/mceliece6688128f.c index fefed8ba..63d20a68 100644 --- a/cipher/mceliece6688128f.c +++ b/cipher/mceliece6688128f.c @@ -1,3673 +1,3673 @@ /* mceliece6688128f.c - Classic McEliece for libgcrypt * Copyright (C) 2023-2024 Simon Josefsson * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1-or-later * */ /* This file is extracted from libmceliece. */ /* * libmceliece is hereby placed into the public domain. * * [SPDX-License-Identifier](https://spdx.dev/ids/): * [LicenseRef-PD-hp](https://cr.yp.to/spdx.html) * OR * [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html) * OR * [0BSD](https://spdx.org/licenses/0BSD.html) * OR * [MIT-0](https://spdx.org/licenses/MIT-0.html) * OR * [MIT](https://spdx.org/licenses/MIT.html) * * libmceliece is based on the official Classic McEliece software, which * was written by Tung Chou. See the following papers for the major * algorithms used for speed inside that software: * * * Daniel J. Bernstein, Tung Chou, Peter Schwabe. "McBits: fast * constant-time code-based cryptography." CHES 2013. * [https://tungchou.github.io/papers/mcbits.pdf](https://tungchou.github.io/papers/mcbits.pdf) * * * Tung Chou. "McBits revisited." CHES 2017. * [https://tungchou.github.io/papers/mcbits_revisited.pdf](https://tungchou.github.io/papers/mcbits_revisited.pdf) * * The official Classic McEliece software includes `ref`, `vec`, `sse`, and * `avx` implementations; libmceliece includes only `vec` and `avx`. * * The following components of libmceliece are from Daniel J. Bernstein: * * * Small [changes](download.html#changelog) * for namespacing, portability, etc. * * * Software to compute control bits (also used in the official software). * See the following paper: Daniel J. Bernstein. "Verified fast formulas * for control bits for permutation networks." 2020. * [https://cr.yp.to/papers.html#controlbits](https://cr.yp.to/papers.html#controlbits) * * * `crypto_sort/int32`. See [https://sorting.cr.yp.to](https://sorting.cr.yp.to). * * * Infrastructure to build a library with automatic run-time selection of * implementations based on the run-time CPU and a database of * benchmarks. This infrastructure was introduced in * [`lib25519`](https://lib25519.cr.yp.to), with some extensions and * adaptations in libmceliece. * * * Various software for tests and benchmarks. This is based on * public-domain code in the SUPERCOP benchmarking framework. * * This file is generated by mceliece6688128f.sh from these files: * * libmceliece-20230612/include-build/crypto_declassify.h * libmceliece-20230612/crypto_kem/6688128f/vec/params.h * libmceliece-20230612/inttypes/crypto_intN.h * libmceliece-20230612/inttypes/crypto_intN.h * libmceliece-20230612/inttypes/crypto_intN.h * libmceliece-20230612/inttypes/crypto_uintN.h * libmceliece-20230612/inttypes/crypto_uintN.h * libmceliece-20230612/inttypes/crypto_uintN.h * libmceliece-20230612/crypto_kem/6688128f/vec/vec.h * libmceliece-20230612/crypto_kem/6688128f/vec/benes.h * libmceliece-20230612/crypto_kem/6688128f/vec/bm.h * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h * libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h * libmceliece-20230612/crypto_kem/6688128f/vec/fft.h * libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h * libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h * libmceliece-20230612/crypto_kem/6688128f/vec/gf.h * libmceliece-20230612/crypto_kem/6688128f/vec/hash.h * libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h * libmceliece-20230612/crypto_kem/6688128f/vec/operations.h * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h * libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h * libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h * libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h * libmceliece-20230612/crypto_kem/6688128f/vec/util.h * libmceliece-20230612/crypto_kem/6688128f/vec/benes.c * libmceliece-20230612/crypto_kem/6688128f/vec/bm.c * libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c * libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c * libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c * libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c * libmceliece-20230612/crypto_kem/6688128f/vec/fft.c * libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c * libmceliece-20230612/crypto_kem/6688128f/vec/gf.c * libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c * libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c * libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c * libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c * libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c * libmceliece-20230612/crypto_kem/6688128f/vec/vec.c * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c * libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c * */ #ifdef HAVE_CONFIG_H #include #endif #include "g10lib.h" #include "mceliece6688128f.h" #define int8 crypto_int8 #define uint8 crypto_uint8 #define int16 crypto_int16 #define uint16 crypto_uint16 #define int32 crypto_int32 #define uint32 crypto_uint32 #define int64 crypto_int64 #define uint64 crypto_uint64 static void randombytes (uint8_t *out, size_t outlen) { _gcry_randomize (out, outlen, GCRY_STRONG_RANDOM); } /* from libmceliece-20230612/include-build/crypto_declassify.h */ #ifndef crypto_declassify_h #define crypto_declassify_h static void crypto_declassify(void *crypto_declassify_v,long long crypto_declassify_vlen) { (void) crypto_declassify_v; (void) crypto_declassify_vlen; } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/params.h */ #ifndef PARAMS_H #define PARAMS_H #define GFBITS 13 #define SYS_N 6688 #define SYS_T 128 #define COND_BYTES ((1 << (GFBITS-4))*(2*GFBITS - 1)) #define IRR_BYTES (SYS_T * 2) #define PK_NROWS (SYS_T*GFBITS) #define PK_NCOLS (SYS_N - PK_NROWS) #define PK_ROW_BYTES ((PK_NCOLS + 7)/8) #define SYND_BYTES ((PK_NROWS + 7)/8) #define GFMASK ((1 << GFBITS) - 1) #endif /* from libmceliece-20230612/inttypes/crypto_intN.h */ #ifndef crypto_int64_h #define crypto_int64_h #define crypto_int64 int64_t -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_negative_mask(crypto_int64 crypto_int64_x) { return crypto_int64_x >> (64-1); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_nonzero_mask(crypto_int64 crypto_int64_x) { return crypto_int64_negative_mask(crypto_int64_x) | crypto_int64_negative_mask(-crypto_int64_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_zero_mask(crypto_int64 crypto_int64_x) { return ~crypto_int64_nonzero_mask(crypto_int64_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_positive_mask(crypto_int64 crypto_int64_x) { crypto_int64 crypto_int64_z = -crypto_int64_x; crypto_int64_z ^= crypto_int64_x & crypto_int64_z; return crypto_int64_negative_mask(crypto_int64_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_unequal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y; return crypto_int64_nonzero_mask(crypto_int64_xy); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_equal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { return ~crypto_int64_unequal_mask(crypto_int64_x,crypto_int64_y); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_smaller_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { crypto_int64 crypto_int64_xy = crypto_int64_x ^ crypto_int64_y; crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y; crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_x); return crypto_int64_negative_mask(crypto_int64_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_min(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x; crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y); crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); crypto_int64_z &= crypto_int64_xy; return crypto_int64_x ^ crypto_int64_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int64 crypto_int64_max(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x; crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y); crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); crypto_int64_z &= crypto_int64_xy; return crypto_int64_y ^ crypto_int64_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static void crypto_int64_minmax(crypto_int64 *crypto_int64_a,crypto_int64 *crypto_int64_b) { crypto_int64 crypto_int64_x = *crypto_int64_a; crypto_int64 crypto_int64_y = *crypto_int64_b; crypto_int64 crypto_int64_xy = crypto_int64_y ^ crypto_int64_x; crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; crypto_int64_z ^= crypto_int64_xy & (crypto_int64_z ^ crypto_int64_y); crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); crypto_int64_z &= crypto_int64_xy; *crypto_int64_a = crypto_int64_x ^ crypto_int64_z; *crypto_int64_b = crypto_int64_y ^ crypto_int64_z; } #endif /* from libmceliece-20230612/inttypes/crypto_intN.h */ #ifndef crypto_int16_h #define crypto_int16_h #define crypto_int16 int16_t -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x) { return crypto_int16_x >> (16-1); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x) { return crypto_int16_negative_mask(crypto_int16_x) | crypto_int16_negative_mask(-crypto_int16_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x) { return ~crypto_int16_nonzero_mask(crypto_int16_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x) { crypto_int16 crypto_int16_z = -crypto_int16_x; crypto_int16_z ^= crypto_int16_x & crypto_int16_z; return crypto_int16_negative_mask(crypto_int16_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y; return crypto_int16_nonzero_mask(crypto_int16_xy); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { return ~crypto_int16_unequal_mask(crypto_int16_x,crypto_int16_y); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { crypto_int16 crypto_int16_xy = crypto_int16_x ^ crypto_int16_y; crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_x); return crypto_int16_negative_mask(crypto_int16_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); crypto_int16_z &= crypto_int16_xy; return crypto_int16_x ^ crypto_int16_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); crypto_int16_z &= crypto_int16_xy; return crypto_int16_y ^ crypto_int16_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static void crypto_int16_minmax(crypto_int16 *crypto_int16_a,crypto_int16 *crypto_int16_b) { crypto_int16 crypto_int16_x = *crypto_int16_a; crypto_int16 crypto_int16_y = *crypto_int16_b; crypto_int16 crypto_int16_xy = crypto_int16_y ^ crypto_int16_x; crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; crypto_int16_z ^= crypto_int16_xy & (crypto_int16_z ^ crypto_int16_y); crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); crypto_int16_z &= crypto_int16_xy; *crypto_int16_a = crypto_int16_x ^ crypto_int16_z; *crypto_int16_b = crypto_int16_y ^ crypto_int16_z; } #endif /* from libmceliece-20230612/inttypes/crypto_intN.h */ #ifndef crypto_int32_h #define crypto_int32_h #define crypto_int32 int32_t -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x) { return crypto_int32_x >> (32-1); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x) { return crypto_int32_negative_mask(crypto_int32_x) | crypto_int32_negative_mask(-crypto_int32_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x) { return ~crypto_int32_nonzero_mask(crypto_int32_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x) { crypto_int32 crypto_int32_z = -crypto_int32_x; crypto_int32_z ^= crypto_int32_x & crypto_int32_z; return crypto_int32_negative_mask(crypto_int32_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y; return crypto_int32_nonzero_mask(crypto_int32_xy); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { return ~crypto_int32_unequal_mask(crypto_int32_x,crypto_int32_y); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { crypto_int32 crypto_int32_xy = crypto_int32_x ^ crypto_int32_y; crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_x); return crypto_int32_negative_mask(crypto_int32_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); crypto_int32_z &= crypto_int32_xy; return crypto_int32_x ^ crypto_int32_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); crypto_int32_z &= crypto_int32_xy; return crypto_int32_y ^ crypto_int32_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static void crypto_int32_minmax(crypto_int32 *crypto_int32_a,crypto_int32 *crypto_int32_b) { crypto_int32 crypto_int32_x = *crypto_int32_a; crypto_int32 crypto_int32_y = *crypto_int32_b; crypto_int32 crypto_int32_xy = crypto_int32_y ^ crypto_int32_x; crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x; crypto_int32_z ^= crypto_int32_xy & (crypto_int32_z ^ crypto_int32_y); crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); crypto_int32_z &= crypto_int32_xy; *crypto_int32_a = crypto_int32_x ^ crypto_int32_z; *crypto_int32_b = crypto_int32_y ^ crypto_int32_z; } #endif /* from libmceliece-20230612/inttypes/crypto_uintN.h */ #ifndef crypto_uint64_h #define crypto_uint64_h #define crypto_uint64 uint64_t #define crypto_uint64_signed int64_t -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64_signed crypto_uint64_signed_negative_mask(crypto_uint64_signed crypto_uint64_signed_x) { return crypto_uint64_signed_x >> (64-1); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_nonzero_mask(crypto_uint64 crypto_uint64_x) { return crypto_uint64_signed_negative_mask(crypto_uint64_x) | crypto_uint64_signed_negative_mask(-crypto_uint64_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_zero_mask(crypto_uint64 crypto_uint64_x) { return ~crypto_uint64_nonzero_mask(crypto_uint64_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_unequal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) { crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y; return crypto_uint64_nonzero_mask(crypto_uint64_xy); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_equal_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) { return ~crypto_uint64_unequal_mask(crypto_uint64_x,crypto_uint64_y); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_smaller_mask(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) { crypto_uint64 crypto_uint64_xy = crypto_uint64_x ^ crypto_uint64_y; crypto_uint64 crypto_uint64_z = crypto_uint64_x - crypto_uint64_y; crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_x ^ (((crypto_uint64) 1) << (64-1))); return crypto_uint64_signed_negative_mask(crypto_uint64_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_min(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) { crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1))); crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); crypto_uint64_z &= crypto_uint64_xy; return crypto_uint64_x ^ crypto_uint64_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint64 crypto_uint64_max(crypto_uint64 crypto_uint64_x,crypto_uint64 crypto_uint64_y) { crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1))); crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); crypto_uint64_z &= crypto_uint64_xy; return crypto_uint64_y ^ crypto_uint64_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static void crypto_uint64_minmax(crypto_uint64 *crypto_uint64_a,crypto_uint64 *crypto_uint64_b) { crypto_uint64 crypto_uint64_x = *crypto_uint64_a; crypto_uint64 crypto_uint64_y = *crypto_uint64_b; crypto_uint64 crypto_uint64_xy = crypto_uint64_y ^ crypto_uint64_x; crypto_uint64 crypto_uint64_z = crypto_uint64_y - crypto_uint64_x; crypto_uint64_z ^= crypto_uint64_xy & (crypto_uint64_z ^ crypto_uint64_y ^ (((crypto_uint64) 1) << (64-1))); crypto_uint64_z = crypto_uint64_signed_negative_mask(crypto_uint64_z); crypto_uint64_z &= crypto_uint64_xy; *crypto_uint64_a = crypto_uint64_x ^ crypto_uint64_z; *crypto_uint64_b = crypto_uint64_y ^ crypto_uint64_z; } #endif /* from libmceliece-20230612/inttypes/crypto_uintN.h */ #ifndef crypto_uint16_h #define crypto_uint16_h #define crypto_uint16 uint16_t #define crypto_uint16_signed int16_t -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16_signed crypto_uint16_signed_negative_mask(crypto_uint16_signed crypto_uint16_signed_x) { return crypto_uint16_signed_x >> (16-1); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_nonzero_mask(crypto_uint16 crypto_uint16_x) { return crypto_uint16_signed_negative_mask(crypto_uint16_x) | crypto_uint16_signed_negative_mask(-crypto_uint16_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_zero_mask(crypto_uint16 crypto_uint16_x) { return ~crypto_uint16_nonzero_mask(crypto_uint16_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_unequal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) { crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y; return crypto_uint16_nonzero_mask(crypto_uint16_xy); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_equal_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) { return ~crypto_uint16_unequal_mask(crypto_uint16_x,crypto_uint16_y); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_smaller_mask(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) { crypto_uint16 crypto_uint16_xy = crypto_uint16_x ^ crypto_uint16_y; crypto_uint16 crypto_uint16_z = crypto_uint16_x - crypto_uint16_y; crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_x ^ (((crypto_uint16) 1) << (16-1))); return crypto_uint16_signed_negative_mask(crypto_uint16_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_min(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) { crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1))); crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); crypto_uint16_z &= crypto_uint16_xy; return crypto_uint16_x ^ crypto_uint16_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint16 crypto_uint16_max(crypto_uint16 crypto_uint16_x,crypto_uint16 crypto_uint16_y) { crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1))); crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); crypto_uint16_z &= crypto_uint16_xy; return crypto_uint16_y ^ crypto_uint16_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static void crypto_uint16_minmax(crypto_uint16 *crypto_uint16_a,crypto_uint16 *crypto_uint16_b) { crypto_uint16 crypto_uint16_x = *crypto_uint16_a; crypto_uint16 crypto_uint16_y = *crypto_uint16_b; crypto_uint16 crypto_uint16_xy = crypto_uint16_y ^ crypto_uint16_x; crypto_uint16 crypto_uint16_z = crypto_uint16_y - crypto_uint16_x; crypto_uint16_z ^= crypto_uint16_xy & (crypto_uint16_z ^ crypto_uint16_y ^ (((crypto_uint16) 1) << (16-1))); crypto_uint16_z = crypto_uint16_signed_negative_mask(crypto_uint16_z); crypto_uint16_z &= crypto_uint16_xy; *crypto_uint16_a = crypto_uint16_x ^ crypto_uint16_z; *crypto_uint16_b = crypto_uint16_y ^ crypto_uint16_z; } #endif /* from libmceliece-20230612/inttypes/crypto_uintN.h */ #ifndef crypto_uint32_h #define crypto_uint32_h #define crypto_uint32 uint32_t #define crypto_uint32_signed int32_t -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32_signed crypto_uint32_signed_negative_mask(crypto_uint32_signed crypto_uint32_signed_x) { return crypto_uint32_signed_x >> (32-1); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_nonzero_mask(crypto_uint32 crypto_uint32_x) { return crypto_uint32_signed_negative_mask(crypto_uint32_x) | crypto_uint32_signed_negative_mask(-crypto_uint32_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_zero_mask(crypto_uint32 crypto_uint32_x) { return ~crypto_uint32_nonzero_mask(crypto_uint32_x); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_unequal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) { crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y; return crypto_uint32_nonzero_mask(crypto_uint32_xy); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_equal_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) { return ~crypto_uint32_unequal_mask(crypto_uint32_x,crypto_uint32_y); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_smaller_mask(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) { crypto_uint32 crypto_uint32_xy = crypto_uint32_x ^ crypto_uint32_y; crypto_uint32 crypto_uint32_z = crypto_uint32_x - crypto_uint32_y; crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_x ^ (((crypto_uint32) 1) << (32-1))); return crypto_uint32_signed_negative_mask(crypto_uint32_z); } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_min(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) { crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1))); crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); crypto_uint32_z &= crypto_uint32_xy; return crypto_uint32_x ^ crypto_uint32_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static crypto_uint32 crypto_uint32_max(crypto_uint32 crypto_uint32_x,crypto_uint32 crypto_uint32_y) { crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1))); crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); crypto_uint32_z &= crypto_uint32_xy; return crypto_uint32_y ^ crypto_uint32_z; } -__attribute__((unused)) +GCC_ATTR_UNUSED static void crypto_uint32_minmax(crypto_uint32 *crypto_uint32_a,crypto_uint32 *crypto_uint32_b) { crypto_uint32 crypto_uint32_x = *crypto_uint32_a; crypto_uint32 crypto_uint32_y = *crypto_uint32_b; crypto_uint32 crypto_uint32_xy = crypto_uint32_y ^ crypto_uint32_x; crypto_uint32 crypto_uint32_z = crypto_uint32_y - crypto_uint32_x; crypto_uint32_z ^= crypto_uint32_xy & (crypto_uint32_z ^ crypto_uint32_y ^ (((crypto_uint32) 1) << (32-1))); crypto_uint32_z = crypto_uint32_signed_negative_mask(crypto_uint32_z); crypto_uint32_z &= crypto_uint32_xy; *crypto_uint32_a = crypto_uint32_x ^ crypto_uint32_z; *crypto_uint32_b = crypto_uint32_y ^ crypto_uint32_z; } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.h */ #ifndef VEC_H #define VEC_H typedef uint64_t vec; static inline vec vec_setbits(vec b) { vec ret = -b; return ret; } static inline vec vec_set1_16b(uint16_t v) { vec ret; ret = v; ret |= ret << 16; ret |= ret << 32; return ret; } static inline void vec_copy(vec * out, vec * in) { int i; for (i = 0; i < GFBITS; i++) out[i] = in[i]; } static inline vec vec_or_reduce(vec * a) { int i; vec ret; ret = a[0]; for (i = 1; i < GFBITS; i++) ret |= a[i]; return ret; } static inline int vec_testz(vec a) { a |= a >> 32; a |= a >> 16; a |= a >> 8; a |= a >> 4; a |= a >> 2; a |= a >> 1; return (a&1)^1; } static void vec_mul(vec *, const vec *, const vec *); static void vec_sq(vec *, vec *); static void vec_inv(vec *, vec *); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.h */ /* This file is for Benes network related functions */ #ifndef BENES_H #define BENES_H static void benes(vec *, const unsigned char *, int); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.h */ /* This file is for the inversion-free Berlekamp-Massey algorithm see https://ieeexplore.ieee.org/document/87857 */ #ifndef BM_H #define BM_H static void bm(vec [][GFBITS], vec [][ GFBITS ]); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.h */ /* This file is for implementing the Nassimi-Sahni algorithm */ /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */ /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */ #ifndef CONTROLBITS_H #define CONTROLBITS_H #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.h */ /* This file is for Nieddereiter decryption */ #ifndef DECRYPT_H #define DECRYPT_H static int decrypt(unsigned char *, const unsigned char *, const unsigned char *); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.h */ /* This file is for Niederreiter encryption */ /* 20230102 djb: rename encrypt() as pke_encrypt() */ #ifndef ENCRYPT_H #define ENCRYPT_H static void pke_encrypt(unsigned char *, const unsigned char *, unsigned char *); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_consts.h */ #ifndef fft_consts_h #define fft_consts_h #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.h */ /* This file is for the Gao-Mateer FFT sse http://www.math.clemson.edu/~sgao/papers/GM10.pdf */ #ifndef FFT_H #define FFT_H static void fft(vec [][GFBITS], vec [][GFBITS]); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_powers.h */ #ifndef fft_powers_h #define fft_powers_h #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_2x.h */ #ifndef fft_scalars_2x_h #define fft_scalars_2x_h #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_scalars_4x.h */ #ifndef fft_scalars_4x_h #define fft_scalars_4x_h #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.h */ /* This file is for transpose of the Gao-Mateer FFT */ #ifndef FFT_TR_H #define FFT_TR_H static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ]); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.h */ /* This file is for functions for field arithmetic */ /* 20221231 djb: const for GF_mul */ #ifndef GF_H #define GF_H typedef uint16_t gf; gf gf_iszero(gf); gf gf_mul(gf, gf); gf gf_frac(gf, gf); gf gf_inv(gf); static void GF_mul(gf *, const gf *, const gf *); /* 2 field multiplications */ static inline uint64_t gf_mul2(gf a, gf b0, gf b1) { int i; uint64_t tmp=0; uint64_t t0; uint64_t t1; uint64_t t; uint64_t mask = 0x0000000100000001; t0 = a; t1 = b1; t1 = (t1 << 32) | b0; for (i = 0; i < GFBITS; i++) { tmp ^= t0 * (t1 & mask); mask += mask; } /**/ t = tmp & 0x01FF000001FF0000; tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); t = tmp & 0x0000E0000000E000; tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); return tmp & 0x00001FFF00001FFF; } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/hash.h */ #define shake crypto_xof_shake256 #define crypto_hash_32b(out,in,inlen) \ shake(out,32,in,inlen) /* from libmceliece-20230612/crypto_kem/6688128f/vec/int32_sort.h */ #ifndef int32_sort_h #define int32_sort_h #define int32_MINMAX(a,b) \ do { \ int64_t ab = (int64_t)b ^ (int64_t)a; \ int64_t c = (int64_t)b - (int64_t)a; \ c ^= ab & (c ^ b); \ c >>= 31; \ c &= ab; \ a ^= c; \ b ^= c; \ } while(0) static void int32_sort(int32_t *x,long long n) { long long top,p,q,r,i; if (n < 2) return; top = 1; while (top < n - top) top += top; for (p = top;p > 0;p >>= 1) { for (i = 0;i < n - p;++i) if (!(i & p)) int32_MINMAX(x[i],x[i+p]); i = 0; for (q = top;q > p;q >>= 1) { for (;i < n - q;++i) { if (!(i & p)) { int32_t a = x[i + p]; for (r = q;r > p;r >>= 1) int32_MINMAX(a,x[i+r]); x[i + p] = a; } } } } } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/operations.h */ #ifndef OPERATIONS_H #define OPERATIONS_H static void operation_enc( unsigned char *c, unsigned char *key, const unsigned char *pk ); static void operation_dec( unsigned char *key, const unsigned char *c, const unsigned char *sk ); static void operation_keypair ( unsigned char *pk, unsigned char *sk ); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.h */ /* This file is for public-key generation */ #ifndef PK_GEN_H #define PK_GEN_H static int pk_gen(unsigned char *, const unsigned char *, uint32_t *, int16_t *, uint64_t *); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.h */ /* This file is for secret-key generation */ #ifndef SK_GEN_H #define SK_GEN_H static int genpoly_gen(gf *, gf *); #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/transpose.h */ /* This file is for matrix transposition */ #ifndef TRANSPOSE_H #define TRANSPOSE_H /* input: in, a 64x64 matrix over GF(2) */ /* output: out, transpose of in */ static inline void transpose_64x64(uint64_t * out, uint64_t * in) { int i, j, s, d; uint64_t x, y; uint64_t masks[6][2] = { {0x5555555555555555, 0xAAAAAAAAAAAAAAAA}, {0x3333333333333333, 0xCCCCCCCCCCCCCCCC}, {0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0}, {0x00FF00FF00FF00FF, 0xFF00FF00FF00FF00}, {0x0000FFFF0000FFFF, 0xFFFF0000FFFF0000}, {0x00000000FFFFFFFF, 0xFFFFFFFF00000000} }; for (i = 0; i < 64; i++) out[i] = in[i]; for (d = 5; d >= 0; d--) { s = 1 << d; for (i = 0; i < 64; i += s*2) for (j = i; j < i+s; j++) { x = (out[j] & masks[d][0]) | ((out[j+s] & masks[d][0]) << s); y = ((out[j] & masks[d][1]) >> s) | (out[j+s] & masks[d][1]); out[j+0] = x; out[j+s] = y; } } } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/uint16_sort.h */ #ifndef uint16_sort_h #define uint16_sort_h #define uint16_MINMAX(a,b) \ do { \ uint16_t c = b - a; \ c >>= 15; \ c = -c; \ c &= a ^ b; \ a ^= c; \ b ^= c; \ } while(0) static void uint16_sort(uint16_t *x,long long n) { long long top,p,q,r,i; if (n < 2) return; top = 1; while (top < n - top) top += top; for (p = top;p > 0;p >>= 1) { for (i = 0;i < n - p;++i) if (!(i & p)) uint16_MINMAX(x[i],x[i+p]); i = 0; for (q = top;q > p;q >>= 1) { for (;i < n - q;++i) { if (!(i & p)) { int16_t a = x[i + p]; for (r = q;r > p;r >>= 1) uint16_MINMAX(a,x[i+r]); x[i + p] = a; } } } } } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/uint64_sort.h */ #ifndef uint64_sort_h #define uint64_sort_h #define uint64_MINMAX(a,b) \ do { \ uint64_t c = b - a; \ c >>= 63; \ c = -c; \ c &= a ^ b; \ a ^= c; \ b ^= c; \ } while(0) static void uint64_sort(uint64_t *x,long long n) { long long top,p,q,r,i; if (n < 2) return; top = 1; while (top < n - top) top += top; for (p = top;p > 0;p >>= 1) { for (i = 0;i < n - p;++i) if (!(i & p)) uint64_MINMAX(x[i],x[i+p]); i = 0; for (q = top;q > p;q >>= 1) { for (;i < n - q;++i) { if (!(i & p)) { uint64_t a = x[i + p]; for (r = q;r > p;r >>= 1) uint64_MINMAX(a,x[i+r]); x[i + p] = a; } } } } } #endif /* from libmceliece-20230612/crypto_kem/6688128f/vec/util.h */ /* This file is for loading/storing data in a little-endian fashion */ #ifndef UTIL_H #define UTIL_H static inline void store_i(unsigned char *out, uint64_t in, int i) { int j; for (j = 0; j < i; j++) out[j] = (in >> (j * 8)) & 0xFF; } static inline void store_gf(unsigned char *dest, uint16_t a) { dest[0] = a & 0xFF; dest[1] = a >> 8; } static inline uint16_t load_gf(const unsigned char *src) { uint16_t a; a = src[1]; a <<= 8; a |= src[0]; return a & GFMASK; } static inline uint32_t load4(const unsigned char *src) { uint32_t a; a = src[3]; a <<= 8; a |= src[2]; a <<= 8; a |= src[1]; a <<= 8; a |= src[0]; return a; } static inline void irr_load(vec out[][GFBITS], const unsigned char * in) { int i, j; uint64_t v0 = 0, v1 = 0; uint16_t irr[ SYS_T ]; for (i = 0; i < SYS_T; i++) irr[i] = load_gf(in + i*2); for (i = 0; i < GFBITS; i++) { for (j = 63; j >= 0; j--) { v0 <<= 1; v1 <<= 1; v0 |= (irr[j] >> i) & 1; v1 |= (irr[j+64] >> i) & 1; } out[0][i] = v0; out[1][i] = v1; } } static inline void store8(unsigned char *out, uint64_t in) { out[0] = (in >> 0x00) & 0xFF; out[1] = (in >> 0x08) & 0xFF; out[2] = (in >> 0x10) & 0xFF; out[3] = (in >> 0x18) & 0xFF; out[4] = (in >> 0x20) & 0xFF; out[5] = (in >> 0x28) & 0xFF; out[6] = (in >> 0x30) & 0xFF; out[7] = (in >> 0x38) & 0xFF; } static inline uint64_t load8(const unsigned char * in) { int i; uint64_t ret = in[7]; for (i = 6; i >= 0; i--) { ret <<= 8; ret |= in[i]; } return ret; } #endif static void crypto_xof_shake256(unsigned char *h,long long hlen, const unsigned char *m,long long mlen) { gcry_md_hd_t mdh; gcry_err_code_t ec; ec = _gcry_md_open (&mdh, GCRY_MD_SHAKE256, 0); if (ec) log_fatal ("internal md_open failed: %d\n", ec); _gcry_md_write (mdh, m, mlen); _gcry_md_extract (mdh, GCRY_MD_SHAKE256, h, hlen); _gcry_md_close (mdh); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/benes.c */ /* This file is for Benes network related functions For the implementation strategy, see https://eprint.iacr.org/2017/793.pdf */ /* 20221230 djb: add linker lines */ /* linker define benes */ /* middle layers of the benes network */ static void layer_in(uint64_t data[2][64], uint64_t * bits, int lgs) { int i, j, s; uint64_t d; s = 1 << lgs; for (i = 0; i < 64; i += s*2) for (j = i; j < i+s; j++) { d = (data[0][j+0] ^ data[0][j+s]); d &= (*bits++); data[0][j+0] ^= d; data[0][j+s] ^= d; d = (data[1][j+0] ^ data[1][j+s]); d &= (*bits++); data[1][j+0] ^= d; data[1][j+s] ^= d; } } /* first and last layers of the benes network */ static void layer_ex(uint64_t * data, uint64_t * bits, int lgs) { int i, j, s; uint64_t d; s = 1 << lgs; for (i = 0; i < 128; i += s*2) for (j = i; j < i+s; j++) { d = (data[j+0] ^ data[j+s]); d &= (*bits++); data[j+0] ^= d; data[j+s] ^= d; } } /* input: r, sequence of bits to be permuted */ /* bits, condition bits of the Benes network */ /* rev, 0 for normal application; !0 for inverse */ /* output: r, permuted bits */ static void benes(vec * r, const unsigned char * bits, int rev) { int i, iter, inc; const unsigned char *bits_ptr; uint64_t r_int_v[2][64]; uint64_t r_int_h[2][64]; uint64_t b_int_v[64]; uint64_t b_int_h[64]; /**/ if (rev) { bits_ptr = bits + 12288; inc = -1024; } else { bits_ptr = bits; inc = 0; } for (i = 0; i < 64; i++) { r_int_v[0][i] = r[i*2 + 0]; r_int_v[1][i] = r[i*2 + 1]; } transpose_64x64(r_int_h[0], r_int_v[0]); transpose_64x64(r_int_h[1], r_int_v[1]); for (iter = 0; iter <= 6; iter++) { for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; } bits_ptr += inc; transpose_64x64(b_int_h, b_int_v); layer_ex(r_int_h[0], b_int_h, iter); } transpose_64x64(r_int_v[0], r_int_h[0]); transpose_64x64(r_int_v[1], r_int_h[1]); for (iter = 0; iter <= 5; iter++) { for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; } bits_ptr += inc; layer_in(r_int_v, b_int_v, iter); } for (iter = 4; iter >= 0; iter--) { for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; } bits_ptr += inc; layer_in(r_int_v, b_int_v, iter); } transpose_64x64(r_int_h[0], r_int_v[0]); transpose_64x64(r_int_h[1], r_int_v[1]); for (iter = 6; iter >= 0; iter--) { for (i = 0; i < 64; i++) { b_int_v[i] = load8(bits_ptr); bits_ptr += 8; } bits_ptr += inc; transpose_64x64(b_int_h, b_int_v); layer_ex(r_int_h[0], b_int_h, iter); } transpose_64x64(r_int_v[0], r_int_h[0]); transpose_64x64(r_int_v[1], r_int_h[1]); for (i = 0; i < 64; i++) { r[i*2+0] = r_int_v[0][i]; r[i*2+1] = r_int_v[1][i]; } } /* from libmceliece-20230612/crypto_kem/6688128f/vec/bm.c */ /* This file is for implementating the inversion-free Berlekamp-Massey algorithm see https://ieeexplore.ieee.org/document/87857 For the implementation strategy, see https://eprint.iacr.org/2017/793.pdf */ /* 20221230 djb: add linker lines */ /* linker define bm */ /* linker use vec_mul */ /* linker use gf_inv */ static inline uint16_t mask_nonzero(gf a) { uint32_t ret = a; ret -= 1; ret >>= 31; ret -= 1; return ret; } static inline uint16_t mask_leq(uint16_t a, uint16_t b) { uint32_t a_tmp = a; uint32_t b_tmp = b; uint32_t ret = b_tmp - a_tmp; ret >>= 31; ret -= 1; return ret; } static inline void vec_cmov(vec * out, vec * in, uint16_t mask) { int i; vec m0, m1; m0 = vec_set1_16b(mask); m1 = ~m0; for (i = 0; i < GFBITS; i++) { out[i] = (in[i] & m0) | (out[i] & m1); out[i] = (in[i] & m0) | (out[i] & m1); } } static inline void interleave(vec *in, int idx0, int idx1, vec *mask, int b) { int s = 1 << b; vec x, y; x = (in[idx0] & mask[0]) | ((in[idx1] & mask[0]) << s); y = ((in[idx0] & mask[1]) >> s) | (in[idx1] & mask[1]); in[idx0] = x; in[idx1] = y; } /* input: in, field elements in bitsliced form */ /* output: out, field elements in non-bitsliced form */ static inline void get_coefs(gf *out, vec *in) { int i, k; vec mask[4][2]; vec buf[16]; for (i = 0; i < 13; i++) buf[i] = in[i]; for (i = 13; i < 16; i++) buf[i] = 0; mask[0][0] = vec_set1_16b(0x5555); mask[0][1] = vec_set1_16b(0xAAAA); mask[1][0] = vec_set1_16b(0x3333); mask[1][1] = vec_set1_16b(0xCCCC); mask[2][0] = vec_set1_16b(0x0F0F); mask[2][1] = vec_set1_16b(0xF0F0); mask[3][0] = vec_set1_16b(0x00FF); mask[3][1] = vec_set1_16b(0xFF00); interleave(buf, 0, 8, mask[3], 3); interleave(buf, 1, 9, mask[3], 3); interleave(buf, 2, 10, mask[3], 3); interleave(buf, 3, 11, mask[3], 3); interleave(buf, 4, 12, mask[3], 3); interleave(buf, 5, 13, mask[3], 3); interleave(buf, 6, 14, mask[3], 3); interleave(buf, 7, 15, mask[3], 3); interleave(buf, 0, 4, mask[2], 2); interleave(buf, 1, 5, mask[2], 2); interleave(buf, 2, 6, mask[2], 2); interleave(buf, 3, 7, mask[2], 2); interleave(buf, 8, 12, mask[2], 2); interleave(buf, 9, 13, mask[2], 2); interleave(buf, 10, 14, mask[2], 2); interleave(buf, 11, 15, mask[2], 2); interleave(buf, 0, 2, mask[1], 1); interleave(buf, 1, 3, mask[1], 1); interleave(buf, 4, 6, mask[1], 1); interleave(buf, 5, 7, mask[1], 1); interleave(buf, 8, 10, mask[1], 1); interleave(buf, 9, 11, mask[1], 1); interleave(buf, 12, 14, mask[1], 1); interleave(buf, 13, 15, mask[1], 1); interleave(buf, 0, 1, mask[0], 0); interleave(buf, 2, 3, mask[0], 0); interleave(buf, 4, 5, mask[0], 0); interleave(buf, 6, 7, mask[0], 0); interleave(buf, 8, 9, mask[0], 0); interleave(buf, 10, 11, mask[0], 0); interleave(buf, 12, 13, mask[0], 0); interleave(buf, 14, 15, mask[0], 0); for (i = 0; i < 16; i++) for (k = 0; k < 4; k++) out[ k*16 + i ] = (buf[i] >> (k*16)) & GFMASK; } static void update(vec in[][GFBITS], const gf e) { int i; vec tmp; for (i = 0; i < GFBITS; i++) { tmp = (e >> i) & 1; in[0][i] = (in[0][i] >> 1) | (in[1][i] << 63); in[1][i] = (in[1][i] >> 1) | (tmp << 63); } } static inline gf vec_reduce(vec in[][GFBITS]) { int i; vec tmp; gf ret = 0; for (i = GFBITS-1; i >= 0; i--) { tmp = in[0][i] ^ in[1][i]; tmp ^= tmp >> 32; tmp ^= tmp >> 16; tmp ^= tmp >> 8; tmp ^= tmp >> 4; tmp ^= tmp >> 2; tmp ^= tmp >> 1; ret <<= 1; ret |= tmp & 1; } return ret; } /* input: in, sequence of field elements */ /* output: out, minimal polynomial of in */ static void bm(vec out[][ GFBITS ], vec in[][ GFBITS ]) { int i; uint16_t N, L; uint16_t mask; uint64_t one = 1, t; vec prod[2][GFBITS]; vec interval[2][GFBITS]; vec dd[2][GFBITS], bb[2][GFBITS]; vec B[2][GFBITS], C[2][GFBITS]; vec B_tmp[2][GFBITS], C_tmp[2][GFBITS]; vec v[GFBITS]; gf d, b, c0 = 1; gf coefs[256]; /* initialization */ get_coefs(&coefs[ 0], in[0]); get_coefs(&coefs[ 64], in[1]); get_coefs(&coefs[128], in[2]); get_coefs(&coefs[192], in[3]); C[0][0] = 0; C[1][0] = 0; B[0][0] = 0; B[1][0] = one << 63; for (i = 1; i < GFBITS; i++) C[0][i] = C[1][i] = B[0][i] = B[1][i] = 0; b = 1; L = 0; /**/ for (i = 0; i < GFBITS; i++) interval[0][i] = interval[1][i] = 0; for (N = 0; N < 256; N++) { vec_mul(prod[0], C[0], interval[0]); vec_mul(prod[1], C[1], interval[1]); update(interval, coefs[N]); d = vec_reduce(prod); t = gf_mul2(c0, coefs[N], b); d ^= t & 0xFFFFFFFF; mask = mask_nonzero(d) & mask_leq(L*2, N); for (i = 0; i < GFBITS; i++) { dd[0][i] = dd[1][i] = vec_setbits((d >> i) & 1); bb[0][i] = bb[1][i] = vec_setbits((b >> i) & 1); } vec_mul(B_tmp[0], dd[0], B[0]); vec_mul(B_tmp[1], dd[1], B[1]); vec_mul(C_tmp[0], bb[0], C[0]); vec_mul(C_tmp[1], bb[1], C[1]); vec_cmov(B[0], C[0], mask); vec_cmov(B[1], C[1], mask); update(B, c0 & mask); for (i = 0; i < GFBITS; i++) { C[0][i] = B_tmp[0][i] ^ C_tmp[0][i]; C[1][i] = B_tmp[1][i] ^ C_tmp[1][i]; } c0 = t >> 32; b = (d & mask) | (b & ~mask); L = ((N+1-L) & mask) | (L & ~mask); } c0 = gf_inv(c0); for (i = 0; i < GFBITS; i++) v[i] = vec_setbits((c0 >> i) & 1); vec_mul(out[0], C[0], v); vec_mul(out[1], C[1], v); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/controlbits.c */ /* This file is for implementing the Nassimi-Sahni algorithm */ /* See David Nassimi, Sartaj Sahni "Parallel algorithms to set up the Benes permutationnetwork" */ /* See also https://cr.yp.to/papers/controlbits-20200923.pdf */ /* 20221230 djb: add linker line */ /* linker define controlbitsfrompermutation */ typedef int16_t int16; typedef int32_t int32; #define int32_min crypto_int32_min /* parameters: 1 <= w <= 14; n = 2^w */ /* input: permutation pi of {0,1,...,n-1} */ /* output: (2m-1)n/2 control bits at positions pos,pos+step,... */ /* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */ /* caller must 0-initialize positions first */ /* temp must have space for int32[2*n] */ static void cbrecursion(unsigned char *out,long long pos,long long step,const int16 *pi,long long w,long long n,int32 *temp) { #define A temp #define B (temp+n) #define q ((int16 *) (temp+n+n/4)) /* q can start anywhere between temp+n and temp+n/2 */ long long x,i,j,k; if (w == 1) { out[pos>>3] ^= pi[0]<<(pos&7); return; } for (x = 0;x < n;++x) A[x] = ((pi[x]^1)<<16)|pi[x^1]; int32_sort(A,n); /* A = (id<<16)+pibar */ for (x = 0;x < n;++x) { int32 Ax = A[x]; int32 px = Ax&0xffff; int32 cx = int32_min(px,x); B[x] = (px<<16)|cx; } /* B = (p<<16)+c */ for (x = 0;x < n;++x) A[x] = (A[x]<<16)|x; /* A = (pibar<<16)+id */ int32_sort(A,n); /* A = (id<<16)+pibar^-1 */ for (x = 0;x < n;++x) A[x] = (A[x]<<16)+(B[x]>>16); /* A = (pibar^(-1)<<16)+pibar */ int32_sort(A,n); /* A = (id<<16)+pibar^2 */ if (w <= 10) { for (x = 0;x < n;++x) B[x] = ((A[x]&0xffff)<<10)|(B[x]&0x3ff); for (i = 1;i < w-1;++i) { /* B = (p<<10)+c */ for (x = 0;x < n;++x) A[x] = ((B[x]&~0x3ff)<<6)|x; /* A = (p<<16)+id */ int32_sort(A,n); /* A = (id<<16)+p^{-1} */ for (x = 0;x < n;++x) A[x] = (A[x]<<20)|B[x]; /* A = (p^{-1}<<20)+(p<<10)+c */ int32_sort(A,n); /* A = (id<<20)+(pp<<10)+cp */ for (x = 0;x < n;++x) { int32 ppcpx = A[x]&0xfffff; int32 ppcx = (A[x]&0xffc00)|(B[x]&0x3ff); B[x] = int32_min(ppcx,ppcpx); } } for (x = 0;x < n;++x) B[x] &= 0x3ff; } else { for (x = 0;x < n;++x) B[x] = (A[x]<<16)|(B[x]&0xffff); for (i = 1;i < w-1;++i) { /* B = (p<<16)+c */ for (x = 0;x < n;++x) A[x] = (B[x]&~0xffff)|x; int32_sort(A,n); /* A = (id<<16)+p^(-1) */ for (x = 0;x < n;++x) A[x] = (A[x]<<16)|(B[x]&0xffff); /* A = p^(-1)<<16+c */ if (i < w-2) { for (x = 0;x < n;++x) B[x] = (A[x]&~0xffff)|(B[x]>>16); /* B = (p^(-1)<<16)+p */ int32_sort(B,n); /* B = (id<<16)+p^(-2) */ for (x = 0;x < n;++x) B[x] = (B[x]<<16)|(A[x]&0xffff); /* B = (p^(-2)<<16)+c */ } int32_sort(A,n); /* A = id<<16+cp */ for (x = 0;x < n;++x) { int32 cpx = (B[x]&~0xffff)|(A[x]&0xffff); B[x] = int32_min(B[x],cpx); } } for (x = 0;x < n;++x) B[x] &= 0xffff; } for (x = 0;x < n;++x) A[x] = (((int32)pi[x])<<16)+x; int32_sort(A,n); /* A = (id<<16)+pi^(-1) */ for (j = 0;j < n/2;++j) { long long lx = 2*j; int32 fj = B[lx]&1; /* f[j] */ int32 Fx = lx+fj; /* F[x] */ int32 Fx1 = Fx^1; /* F[x+1] */ out[pos>>3] ^= fj<<(pos&7); pos += step; B[lx] = (A[lx]<<16)|Fx; B[lx+1] = (A[lx+1]<<16)|Fx1; } /* B = (pi^(-1)<<16)+F */ int32_sort(B,n); /* B = (id<<16)+F(pi) */ pos += (2*w-3)*step*(n/2); for (k = 0;k < n/2;++k) { long long y = 2*k; int32 lk = B[y]&1; /* l[k] */ int32 Ly = y+lk; /* L[y] */ int32 Ly1 = Ly^1; /* L[y+1] */ out[pos>>3] ^= lk<<(pos&7); pos += step; A[y] = (Ly<<16)|(B[y]&0xffff); A[y+1] = (Ly1<<16)|(B[y+1]&0xffff); } /* A = (L<<16)+F(pi) */ int32_sort(A,n); /* A = (id<<16)+F(pi(L)) = (id<<16)+M */ pos -= (2*w-2)*step*(n/2); for (j = 0;j < n/2;++j) { q[j] = (A[2*j]&0xffff)>>1; q[j+n/2] = (A[2*j+1]&0xffff)>>1; } cbrecursion(out,pos,step*2,q,w-1,n/2,temp); cbrecursion(out,pos+step,step*2,q+n/2,w-1,n/2,temp); } /* input: p, an array of int16 */ /* input: n, length of p */ /* input: s, meaning that stride-2^s cswaps are performed */ /* input: cb, the control bits */ /* output: the result of apply the control bits to p */ static void layer(int16_t *p, const unsigned char *cb, int s, int n) { int i, j; int stride = 1 << s; int index = 0; int16_t d, m; for (i = 0; i < n; i += stride*2) { for (j = 0; j < stride; j++) { d = p[ i+j ] ^ p[ i+j+stride ]; m = (cb[ index >> 3 ] >> (index & 7)) & 1; m = -m; d &= m; p[ i+j ] ^= d; p[ i+j+stride ] ^= d; index++; } } } /* parameters: 1 <= w <= 14; n = 2^w */ /* input: permutation pi of {0,1,...,n-1} */ /* output: (2m-1)n/2 control bits at positions 0,1,... */ /* output position pos is by definition 1&(out[pos/8]>>(pos&7)) */ static void controlbitsfrompermutation(unsigned char *out,const int16 *pi,long long w,long long n) { int32 temp[2*n]; int16 pi_test[n], diff; int i; unsigned char *ptr; while (1) { memset(out,0,(((2*w-1)*n/2)+7)/8); cbrecursion(out,0,1,pi,w,n,temp); /* check for correctness */ for (i = 0; i < n; i++) pi_test[i] = i; ptr = out; for (i = 0; i < w; i++) { layer(pi_test, ptr, i, n); ptr += n >> 4; } for (i = w-2; i >= 0; i--) { layer(pi_test, ptr, i, n); ptr += n >> 4; } diff = 0; for (i = 0; i < n; i++) diff |= pi[i] ^ pi_test[i]; diff = crypto_int16_nonzero_mask(diff); crypto_declassify(&diff,sizeof diff); if (diff == 0) break; } } #undef A #undef B #undef q /* from libmceliece-20230612/crypto_kem/6688128f/vec/decrypt.c */ /* This file is for Niederreiter decryption */ /* 20221230 djb: add linker lines */ /* linker define decrypt */ /* linker use benes bm fft fft_tr */ /* linker use vec_mul vec_sq vec_inv */ static void scaling(vec out[][GFBITS], vec inv[][GFBITS], const unsigned char *sk, vec *recv) { int i, j; vec irr_int[2][ GFBITS ]; vec eval[128][ GFBITS ]; vec tmp[ GFBITS ]; /**/ irr_load(irr_int, sk); fft(eval, irr_int); for (i = 0; i < 128; i++) vec_sq(eval[i], eval[i]); vec_copy(inv[0], eval[0]); for (i = 1; i < 128; i++) vec_mul(inv[i], inv[i-1], eval[i]); vec_inv(tmp, inv[127]); for (i = 126; i >= 0; i--) { vec_mul(inv[i+1], tmp, inv[i]); vec_mul(tmp, tmp, eval[i+1]); } vec_copy(inv[0], tmp); /**/ for (i = 0; i < 128; i++) for (j = 0; j < GFBITS; j++) out[i][j] = inv[i][j] & recv[i]; } static void preprocess(vec *recv, const unsigned char *s) { int i; unsigned char r[ 1024 ]; for (i = 0; i < SYND_BYTES; i++) r[i] = s[i]; for (i = SYND_BYTES; i < 1024; i++) r[i] = 0; for (i = 0; i < 128; i++) recv[i] = load8(r + i*8); } static void postprocess(unsigned char * e, vec * err) { int i; unsigned char error8[ (1 << GFBITS)/8 ]; for (i = 0; i < 128; i++) store8(error8 + i*8, err[i]); for (i = 0; i < SYS_N/8; i++) e[i] = error8[i]; } static void scaling_inv(vec out[][GFBITS], vec inv[][GFBITS], vec *recv) { int i, j; for (i = 0; i < 128; i++) for (j = 0; j < GFBITS; j++) out[i][j] = inv[i][j] & recv[i]; } static int weight_check(unsigned char * e, vec * error) { int i; uint16_t w0 = 0; uint16_t w1 = 0; uint16_t check; for (i = 0; i < (1 << GFBITS); i++) w0 += (error[i/64] >> (i%64)) & 1; for (i = 0; i < SYS_N; i++) w1 += (e[i/8] >> (i%8)) & 1; check = (w0 ^ SYS_T) | (w1 ^ SYS_T); check -= 1; check >>= 15; return check; } static uint16_t synd_cmp(vec s0[][ GFBITS ] , vec s1[][ GFBITS ]) { int i, j; vec diff = 0; for (i = 0; i < 4; i++) for (j = 0; j < GFBITS; j++) diff |= (s0[i][j] ^ s1[i][j]); return vec_testz(diff); } /* Niederreiter decryption with the Berlekamp decoder */ /* intput: sk, secret key */ /* s, ciphertext (syndrome) */ /* output: e, error vector */ /* return: 0 for success; 1 for failure */ static int decrypt(unsigned char *e, const unsigned char *sk, const unsigned char *s) { int i; uint16_t check_synd; uint16_t check_weight; vec inv[ 128 ][ GFBITS ]; vec scaled[ 128 ][ GFBITS ]; vec eval[ 128 ][ GFBITS ]; vec error[ 128 ]; vec s_priv[ 4 ][ GFBITS ]; vec s_priv_cmp[ 4 ][ GFBITS ]; vec locator[2][ GFBITS ]; vec recv[ 128 ]; vec allone; /* Berlekamp decoder */ preprocess(recv, s); benes(recv, sk + IRR_BYTES, 1); scaling(scaled, inv, sk, recv); fft_tr(s_priv, scaled); bm(locator, s_priv); fft(eval, locator); /* reencryption and weight check */ allone = vec_setbits(1); for (i = 0; i < 128; i++) { error[i] = vec_or_reduce(eval[i]); error[i] ^= allone; } scaling_inv(scaled, inv, error); fft_tr(s_priv_cmp, scaled); check_synd = synd_cmp(s_priv, s_priv_cmp); /**/ benes(error, sk + IRR_BYTES, 0); postprocess(e, error); check_weight = weight_check(e, error); #ifdef KAT { int k; printf("decrypt e: positions"); for (k = 0;k < SYS_N;++k) if (e[k/8] & (1 << (k&7))) printf(" %d",k); printf("\n"); } #endif return 1 - (check_synd & check_weight); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/encrypt.c */ /* 20230102 djb: rename encrypt() as pke_encrypt() */ /* 20221231 djb: move encrypt.h last for macos portability; tnx thom wiggers */ /* 20221230 djb: add linker line */ /* linker define pke_encrypt */ /* This file is for Niederreiter encryption */ static inline crypto_uint16 uint16_is_smaller_declassify(uint16_t t,uint16_t u) { crypto_uint16 mask = crypto_uint16_smaller_mask(t,u); crypto_declassify(&mask,sizeof mask); return mask; } static inline crypto_uint32 uint32_is_equal_declassify(uint32_t t,uint32_t u) { crypto_uint32 mask = crypto_uint32_equal_mask(t,u); crypto_declassify(&mask,sizeof mask); return mask; } /* output: e, an error vector of weight t */ static void gen_e(unsigned char *e) { int i, j, eq, count; union { uint16_t nums[ SYS_T*2 ]; unsigned char bytes[ SYS_T*2 * sizeof(uint16_t) ]; } buf; uint16_t ind[ SYS_T ]; uint64_t e_int[ (SYS_N+63)/64 ]; uint64_t one = 1; uint64_t mask; uint64_t val[ SYS_T ]; while (1) { randombytes(buf.bytes, sizeof(buf)); for (i = 0; i < SYS_T*2; i++) buf.nums[i] = load_gf(buf.bytes + i*2); /* moving and counting indices in the correct range */ count = 0; for (i = 0; i < SYS_T*2 && count < SYS_T; i++) if (uint16_is_smaller_declassify(buf.nums[i],SYS_N)) ind[ count++ ] = buf.nums[i]; if (count < SYS_T) continue; /* check for repetition */ uint16_sort(ind, SYS_T); eq = 0; for (i = 1; i < SYS_T; i++) if (uint32_is_equal_declassify(ind[i-1],ind[i])) eq = 1; if (eq == 0) break; } for (j = 0; j < SYS_T; j++) val[j] = one << (ind[j] & 63); for (i = 0; i < (SYS_N+63)/64; i++) { e_int[i] = 0; for (j = 0; j < SYS_T; j++) { mask = i ^ (ind[j] >> 6); mask -= 1; mask >>= 63; mask = -mask; e_int[i] |= val[j] & mask; } } for (i = 0; i < (SYS_N+63)/64 - 1; i++) { store8(e, e_int[i]); e += 8; } for (j = 0; j < (SYS_N % 64); j+=8) e[ j/8 ] = (e_int[i] >> j) & 0xFF; } /* input: public key pk, error vector e */ /* output: syndrome s */ static void syndrome(unsigned char *s, const unsigned char *pk, unsigned char *e) { uint64_t b; const uint64_t *pk_ptr; const uint64_t *e_ptr = ((uint64_t *) (e + SYND_BYTES)); int i, j; /**/ for (i = 0; i < SYND_BYTES; i++) s[i] = e[i]; for (i = 0; i < PK_NROWS; i++) { pk_ptr = ((uint64_t *) (pk + PK_ROW_BYTES * i)); b = 0; for (j = 0; j < PK_NCOLS/64; j++) b ^= pk_ptr[j] & e_ptr[j]; b ^= ((uint32_t *) &pk_ptr[j])[0] & ((uint32_t *) &e_ptr[j])[0]; b ^= b >> 32; b ^= b >> 16; b ^= b >> 8; b ^= b >> 4; b ^= b >> 2; b ^= b >> 1; b &= 1; s[ i/8 ] ^= (b << (i%8)); } } /* input: public key pk */ /* output: error vector e, syndrome s */ static void pke_encrypt(unsigned char *s, const unsigned char *pk, unsigned char *e) { gen_e(e); #ifdef KAT { int k; printf("encrypt e: positions"); for (k = 0;k < SYS_N;++k) if (e[k/8] & (1 << (k&7))) printf(" %d",k); printf("\n"); } #endif syndrome(s, pk, e); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_consts.c */ /* linker define fft_consts */ const vec fft_consts[128][GFBITS] = { { 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 }, }; /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_powers.c */ /* linker define fft_powers */ const vec fft_powers[128][GFBITS] = { { 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 } }; /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_2x.c */ /* linker define fft_scalars_2x */ const vec fft_scalars_2x[5][2][GFBITS] = { {{ 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 }} }; /* from libmceliece-20230612/crypto_kem/6688128f/vec/shared-fft_scalars_4x.c */ /* linker define fft_scalars_4x */ const vec fft_scalars_4x[6][4][GFBITS] = { {{ 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 }}, }; /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft.c */ /* This file is for implementing the Gao-Mateer FFT, see http://www.math.clemson.edu/~sgao/papers/GM10.pdf For the implementation strategy, see https://eprint.iacr.org/2017/793.pdf */ /* 20221230 djb: split these arrays into separate .c files */ /* 20221230 djb: rename powers array as fft_powers */ /* 20221230 djb: rename consts array as fft_consts */ /* 20221230 djb: rename s array as fft_scalars_2x */ /* 20221230 djb: add linker lines */ /* linker define fft */ /* linker use vec_mul */ /* linker use fft_scalars_2x fft_consts fft_powers */ /* input: in, polynomial in bitsliced form */ /* output: in, result of applying the radix conversions on in */ static void radix_conversions(vec in[][GFBITS]) { int i, j, k; const vec mask[5][2] = { {0x8888888888888888, 0x4444444444444444}, {0xC0C0C0C0C0C0C0C0, 0x3030303030303030}, {0xF000F000F000F000, 0x0F000F000F000F00}, {0xFF000000FF000000, 0x00FF000000FF0000}, {0xFFFF000000000000, 0x0000FFFF00000000} }; for (j = 0; j <= 5; j++) { for (i = 0; i < GFBITS; i++) { in[1][i] ^= in[1][i] >> 32; in[0][i] ^= in[1][i] << 32; } for (i = 0; i < GFBITS; i++) for (k = 4; k >= j; k--) { in[0][i] ^= (in[0][i] & mask[k][0]) >> (1 << k); in[0][i] ^= (in[0][i] & mask[k][1]) >> (1 << k); in[1][i] ^= (in[1][i] & mask[k][0]) >> (1 << k); in[1][i] ^= (in[1][i] & mask[k][1]) >> (1 << k); } if (j < 5) { vec_mul(in[0], in[0], fft_scalars_2x[j][0]); vec_mul(in[1], in[1], fft_scalars_2x[j][1]); } } } /* input: in, result of applying the radix conversions to the input polynomial */ /* output: out, evaluation results (by applying the FFT butterflies) */ static void butterflies(vec out[][ GFBITS ], vec in[][ GFBITS ]) { int i, j, k, s, b; vec tmp[ GFBITS ]; vec pre[8][ GFBITS ]; vec buf[128]; uint64_t consts_ptr = 2; const unsigned char reversal[128] = { 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120, 4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124, 2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122, 6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126, 1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121, 5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125, 3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123, 7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127 }; const uint16_t beta[7] = {2522, 7827, 7801, 8035, 6897, 8167, 3476}; /**/ for (i = 0; i < 7; i++) { for (j = 0; j < GFBITS; j++) { pre[i][j] = (beta[i] >> j) & 1; pre[i][j] = -pre[i][j]; } vec_mul(pre[i], in[1], pre[i]); } for (i = 0; i < GFBITS; i++) { buf[0] = in[0][i]; buf[1] = buf[0] ^ pre[0][i]; buf[32] = in[0][i] ^ pre[5][i]; buf[3] = buf[1] ^ pre[1][i]; buf[96] = buf[32] ^ pre[6][i]; buf[97] = buf[96] ^ pre[0][i]; buf[2] = in[0][i] ^ pre[1][i]; buf[99] = buf[97] ^ pre[1][i]; buf[6] = buf[2] ^ pre[2][i]; buf[98] = buf[99] ^ pre[0][i]; buf[7] = buf[6] ^ pre[0][i]; buf[102] = buf[98] ^ pre[2][i]; buf[5] = buf[7] ^ pre[1][i]; buf[103] = buf[102] ^ pre[0][i]; buf[101] = buf[103] ^ pre[1][i]; buf[4] = in[0][i] ^ pre[2][i]; buf[100] = buf[101] ^ pre[0][i]; buf[12] = buf[4] ^ pre[3][i]; buf[108] = buf[100] ^ pre[3][i]; buf[13] = buf[12] ^ pre[0][i]; buf[109] = buf[108] ^ pre[0][i]; buf[15] = buf[13] ^ pre[1][i]; buf[111] = buf[109] ^ pre[1][i]; buf[14] = buf[15] ^ pre[0][i]; buf[110] = buf[111] ^ pre[0][i]; buf[10] = buf[14] ^ pre[2][i]; buf[106] = buf[110] ^ pre[2][i]; buf[11] = buf[10] ^ pre[0][i]; buf[107] = buf[106] ^ pre[0][i]; buf[9] = buf[11] ^ pre[1][i]; buf[105] = buf[107] ^ pre[1][i]; buf[104] = buf[105] ^ pre[0][i]; buf[8] = in[0][i] ^ pre[3][i]; buf[120] = buf[104] ^ pre[4][i]; buf[24] = buf[8] ^ pre[4][i]; buf[121] = buf[120] ^ pre[0][i]; buf[25] = buf[24] ^ pre[0][i]; buf[123] = buf[121] ^ pre[1][i]; buf[27] = buf[25] ^ pre[1][i]; buf[122] = buf[123] ^ pre[0][i]; buf[26] = buf[27] ^ pre[0][i]; buf[126] = buf[122] ^ pre[2][i]; buf[30] = buf[26] ^ pre[2][i]; buf[127] = buf[126] ^ pre[0][i]; buf[31] = buf[30] ^ pre[0][i]; buf[125] = buf[127] ^ pre[1][i]; buf[29] = buf[31] ^ pre[1][i]; buf[124] = buf[125] ^ pre[0][i]; buf[28] = buf[29] ^ pre[0][i]; buf[116] = buf[124] ^ pre[3][i]; buf[20] = buf[28] ^ pre[3][i]; buf[117] = buf[116] ^ pre[0][i]; buf[21] = buf[20] ^ pre[0][i]; buf[119] = buf[117] ^ pre[1][i]; buf[23] = buf[21] ^ pre[1][i]; buf[118] = buf[119] ^ pre[0][i]; buf[22] = buf[23] ^ pre[0][i]; buf[114] = buf[118] ^ pre[2][i]; buf[18] = buf[22] ^ pre[2][i]; buf[115] = buf[114] ^ pre[0][i]; buf[19] = buf[18] ^ pre[0][i]; buf[113] = buf[115] ^ pre[1][i]; buf[17] = buf[19] ^ pre[1][i]; buf[112] = buf[113] ^ pre[0][i]; buf[80] = buf[112] ^ pre[5][i]; buf[16] = in[0][i] ^ pre[4][i]; buf[81] = buf[80] ^ pre[0][i]; buf[48] = buf[16] ^ pre[5][i]; buf[83] = buf[81] ^ pre[1][i]; buf[49] = buf[48] ^ pre[0][i]; buf[82] = buf[83] ^ pre[0][i]; buf[51] = buf[49] ^ pre[1][i]; buf[86] = buf[82] ^ pre[2][i]; buf[50] = buf[51] ^ pre[0][i]; buf[87] = buf[86] ^ pre[0][i]; buf[54] = buf[50] ^ pre[2][i]; buf[85] = buf[87] ^ pre[1][i]; buf[55] = buf[54] ^ pre[0][i]; buf[84] = buf[85] ^ pre[0][i]; buf[53] = buf[55] ^ pre[1][i]; buf[92] = buf[84] ^ pre[3][i]; buf[52] = buf[53] ^ pre[0][i]; buf[93] = buf[92] ^ pre[0][i]; buf[60] = buf[52] ^ pre[3][i]; buf[95] = buf[93] ^ pre[1][i]; buf[61] = buf[60] ^ pre[0][i]; buf[94] = buf[95] ^ pre[0][i]; buf[63] = buf[61] ^ pre[1][i]; buf[90] = buf[94] ^ pre[2][i]; buf[62] = buf[63] ^ pre[0][i]; buf[91] = buf[90] ^ pre[0][i]; buf[58] = buf[62] ^ pre[2][i]; buf[89] = buf[91] ^ pre[1][i]; buf[59] = buf[58] ^ pre[0][i]; buf[88] = buf[89] ^ pre[0][i]; buf[57] = buf[59] ^ pre[1][i]; buf[72] = buf[88] ^ pre[4][i]; buf[56] = buf[57] ^ pre[0][i]; buf[73] = buf[72] ^ pre[0][i]; buf[40] = buf[56] ^ pre[4][i]; buf[75] = buf[73] ^ pre[1][i]; buf[41] = buf[40] ^ pre[0][i]; buf[74] = buf[75] ^ pre[0][i]; buf[43] = buf[41] ^ pre[1][i]; buf[78] = buf[74] ^ pre[2][i]; buf[42] = buf[43] ^ pre[0][i]; buf[79] = buf[78] ^ pre[0][i]; buf[46] = buf[42] ^ pre[2][i]; buf[77] = buf[79] ^ pre[1][i]; buf[47] = buf[46] ^ pre[0][i]; buf[76] = buf[77] ^ pre[0][i]; buf[45] = buf[47] ^ pre[1][i]; buf[68] = buf[76] ^ pre[3][i]; buf[44] = buf[45] ^ pre[0][i]; buf[69] = buf[68] ^ pre[0][i]; buf[36] = buf[44] ^ pre[3][i]; buf[71] = buf[69] ^ pre[1][i]; buf[37] = buf[36] ^ pre[0][i]; buf[70] = buf[71] ^ pre[0][i]; buf[39] = buf[37] ^ pre[1][i]; buf[66] = buf[70] ^ pre[2][i]; buf[38] = buf[39] ^ pre[0][i]; buf[67] = buf[66] ^ pre[0][i]; buf[34] = buf[38] ^ pre[2][i]; buf[65] = buf[67] ^ pre[1][i]; buf[35] = buf[34] ^ pre[0][i]; buf[33] = buf[35] ^ pre[1][i]; buf[64] = in[0][i] ^ pre[6][i]; transpose_64x64(buf + 0, buf + 0); transpose_64x64(buf + 64, buf + 64); for (j = 0; j < 128; j++) out[ reversal[j] ][i] = buf[j]; } for (i = 1; i <= 6; i++) { s = 1 << i; for (j = 0; j < 128; j += 2*s) for (k = j; k < j+s; k++) { vec_mul(tmp, out[k+s], fft_consts[ consts_ptr + (k-j) ]); for (b = 0; b < GFBITS; b++) out[k ][b] ^= tmp[b]; for (b = 0; b < GFBITS; b++) out[k+s][b] ^= out[k][b]; } consts_ptr += (1 << i); } /* adding the part contributed by x^128 */ for (i = 0; i < 128; i++) for (b = 0; b < GFBITS; b++) out[i][b] ^= fft_powers[i][b]; } /* input: in, polynomial in bitsliced form */ /* output: out, bitsliced results of evaluating in all the field elements */ static void fft(vec out[][GFBITS], vec in[][GFBITS]) { radix_conversions(in); butterflies(out, in); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/fft_tr.c */ /* This file is for transpose of the Gao-Mateer FFT Functions with names ending with _tr are (roughly) the transpose of the corresponding functions in fft.c For the implementation strategy, see https://eprint.iacr.org/2017/793.pdf */ /* 20221230 djb: split these arrays into separate .c files */ /* 20221230 djb: rename consts array as fft_consts */ /* 20221230 djb: rename s array as fft_scalars_4x */ /* 20221230 djb: add linker lines */ /* linker define fft_tr */ /* linker use vec_mul */ /* linker use fft_scalars_4x fft_consts */ static void radix_conversions_tr(vec in[][ GFBITS ]) { int i, j, k; const vec mask[6][2] = { {0x2222222222222222, 0x4444444444444444}, {0x0C0C0C0C0C0C0C0C, 0x3030303030303030}, {0x00F000F000F000F0, 0x0F000F000F000F00}, {0x0000FF000000FF00, 0x00FF000000FF0000}, {0x00000000FFFF0000, 0x0000FFFF00000000}, {0xFFFFFFFF00000000, 0x00000000FFFFFFFF} }; /**/ for (j = 6; j >= 0; j--) { if (j < 6) { vec_mul(in[0], in[0], fft_scalars_4x[j][0]); /* scaling */ vec_mul(in[1], in[1], fft_scalars_4x[j][1]); /* scaling */ vec_mul(in[2], in[2], fft_scalars_4x[j][2]); /* scaling */ vec_mul(in[3], in[3], fft_scalars_4x[j][3]); /* scaling */ } for (k = j; k <= 4; k++) for (i = 0; i < GFBITS; i++) { in[0][i] ^= (in[0][i] & mask[k][0]) << (1 << k); in[0][i] ^= (in[0][i] & mask[k][1]) << (1 << k); in[1][i] ^= (in[1][i] & mask[k][0]) << (1 << k); in[1][i] ^= (in[1][i] & mask[k][1]) << (1 << k); in[2][i] ^= (in[2][i] & mask[k][0]) << (1 << k); in[2][i] ^= (in[2][i] & mask[k][1]) << (1 << k); in[3][i] ^= (in[3][i] & mask[k][0]) << (1 << k); in[3][i] ^= (in[3][i] & mask[k][1]) << (1 << k); } if (j <= 5) for (i = 0; i < GFBITS; i++) { in[1][i] ^= in[0][i] >> 32; in[1][i] ^= in[1][i] << 32; in[3][i] ^= in[2][i] >> 32; in[3][i] ^= in[3][i] << 32; } for (i = 0; i < GFBITS; i++) in[3][i] ^= in[2][i] ^= in[1][i]; } } static void butterflies_tr(vec out[][ GFBITS ], vec in[][ GFBITS ]) { int i, j, k, s, b; vec tmp[ GFBITS ]; vec pre[6][2][ GFBITS ]; vec buf[2][64]; uint64_t consts_ptr = 128; const unsigned char reversal[128] = { 0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120, 4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124, 2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122, 6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126, 1, 65, 33, 97, 17, 81, 49, 113, 9, 73, 41, 105, 25, 89, 57, 121, 5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125, 3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123, 7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127 }; const uint16_t beta[6] = {5246, 5306, 6039, 6685, 4905, 6755}; /**/ for (i = 6; i >= 0; i--) { s = 1 << i; consts_ptr -= s; for (j = 0; j < 128; j += 2*s) for (k = j; k < j+s; k++) { for (b = 0; b < GFBITS; b++) in[k][b] ^= in[k+s][b]; vec_mul(tmp, in[k], fft_consts[ consts_ptr + (k-j) ]); for (b = 0; b < GFBITS; b++) in[k+s][b] ^= tmp[b]; } } for (i = 0; i < GFBITS; i++) { for (k = 0; k < 128; k++) (&buf[0][0])[ k ] = in[ reversal[k] ][i]; transpose_64x64(buf[0], buf[0]); transpose_64x64(buf[1], buf[1]); for (k = 0; k < 2; k++) { pre[0][k][i] = buf[k][32]; buf[k][33] ^= buf[k][32]; pre[1][k][i] = buf[k][33]; buf[k][35] ^= buf[k][33]; pre[0][k][i] ^= buf[k][35]; buf[k][34] ^= buf[k][35]; pre[2][k][i] = buf[k][34]; buf[k][38] ^= buf[k][34]; pre[0][k][i] ^= buf[k][38]; buf[k][39] ^= buf[k][38]; pre[1][k][i] ^= buf[k][39]; buf[k][37] ^= buf[k][39]; pre[0][k][i] ^= buf[k][37]; buf[k][36] ^= buf[k][37]; pre[3][k][i] = buf[k][36]; buf[k][44] ^= buf[k][36]; pre[0][k][i] ^= buf[k][44]; buf[k][45] ^= buf[k][44]; pre[1][k][i] ^= buf[k][45]; buf[k][47] ^= buf[k][45]; pre[0][k][i] ^= buf[k][47]; buf[k][46] ^= buf[k][47]; pre[2][k][i] ^= buf[k][46]; buf[k][42] ^= buf[k][46]; pre[0][k][i] ^= buf[k][42]; buf[k][43] ^= buf[k][42]; pre[1][k][i] ^= buf[k][43]; buf[k][41] ^= buf[k][43]; pre[0][k][i] ^= buf[k][41]; buf[k][40] ^= buf[k][41]; pre[4][k][i] = buf[k][40]; buf[k][56] ^= buf[k][40]; pre[0][k][i] ^= buf[k][56]; buf[k][57] ^= buf[k][56]; pre[1][k][i] ^= buf[k][57]; buf[k][59] ^= buf[k][57]; pre[0][k][i] ^= buf[k][59]; buf[k][58] ^= buf[k][59]; pre[2][k][i] ^= buf[k][58]; buf[k][62] ^= buf[k][58]; pre[0][k][i] ^= buf[k][62]; buf[k][63] ^= buf[k][62]; pre[1][k][i] ^= buf[k][63]; buf[k][61] ^= buf[k][63]; pre[0][k][i] ^= buf[k][61]; buf[k][60] ^= buf[k][61]; pre[3][k][i] ^= buf[k][60]; buf[k][52] ^= buf[k][60]; pre[0][k][i] ^= buf[k][52]; buf[k][53] ^= buf[k][52]; pre[1][k][i] ^= buf[k][53]; buf[k][55] ^= buf[k][53]; pre[0][k][i] ^= buf[k][55]; buf[k][54] ^= buf[k][55]; pre[2][k][i] ^= buf[k][54]; buf[k][50] ^= buf[k][54]; pre[0][k][i] ^= buf[k][50]; buf[k][51] ^= buf[k][50]; pre[1][k][i] ^= buf[k][51]; buf[k][49] ^= buf[k][51]; pre[0][k][i] ^= buf[k][49]; buf[k][48] ^= buf[k][49]; pre[5][k][i] = buf[k][48]; buf[k][16] ^= buf[k][48]; pre[0][k][i] ^= buf[k][16]; buf[k][17] ^= buf[k][16]; pre[1][k][i] ^= buf[k][17]; buf[k][19] ^= buf[k][17]; pre[0][k][i] ^= buf[k][19]; buf[k][18] ^= buf[k][19]; pre[2][k][i] ^= buf[k][18]; buf[k][22] ^= buf[k][18]; pre[0][k][i] ^= buf[k][22]; buf[k][23] ^= buf[k][22]; pre[1][k][i] ^= buf[k][23]; buf[k][21] ^= buf[k][23]; pre[0][k][i] ^= buf[k][21]; buf[k][20] ^= buf[k][21]; pre[3][k][i] ^= buf[k][20]; buf[k][28] ^= buf[k][20]; pre[0][k][i] ^= buf[k][28]; buf[k][29] ^= buf[k][28]; pre[1][k][i] ^= buf[k][29]; buf[k][31] ^= buf[k][29]; pre[0][k][i] ^= buf[k][31]; buf[k][30] ^= buf[k][31]; pre[2][k][i] ^= buf[k][30]; buf[k][26] ^= buf[k][30]; pre[0][k][i] ^= buf[k][26]; buf[k][27] ^= buf[k][26]; pre[1][k][i] ^= buf[k][27]; buf[k][25] ^= buf[k][27]; pre[0][k][i] ^= buf[k][25]; buf[k][24] ^= buf[k][25]; pre[4][k][i] ^= buf[k][24]; buf[k][8] ^= buf[k][24]; pre[0][k][i] ^= buf[k][8]; buf[k][9] ^= buf[k][8]; pre[1][k][i] ^= buf[k][9]; buf[k][11] ^= buf[k][9]; pre[0][k][i] ^= buf[k][11]; buf[k][10] ^= buf[k][11]; pre[2][k][i] ^= buf[k][10]; buf[k][14] ^= buf[k][10]; pre[0][k][i] ^= buf[k][14]; buf[k][15] ^= buf[k][14]; pre[1][k][i] ^= buf[k][15]; buf[k][13] ^= buf[k][15]; pre[0][k][i] ^= buf[k][13]; buf[k][12] ^= buf[k][13]; pre[3][k][i] ^= buf[k][12]; buf[k][4] ^= buf[k][12]; pre[0][k][i] ^= buf[k][4]; buf[k][5] ^= buf[k][4]; pre[1][k][i] ^= buf[k][5]; buf[k][7] ^= buf[k][5]; pre[0][k][i] ^= buf[k][7]; buf[k][6] ^= buf[k][7]; pre[2][k][i] ^= buf[k][6]; buf[k][2] ^= buf[k][6]; pre[0][k][i] ^= buf[k][2]; buf[k][3] ^= buf[k][2]; pre[1][k][i] ^= buf[k][3]; buf[k][1] ^= buf[k][3]; pre[0][k][i] ^= buf[k][1]; out[k][i] = buf[k][0] ^ buf[k][1]; } } for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[0] >> j) & 1); vec_mul(out[2], pre[0][0], tmp); vec_mul(out[3], pre[0][1], tmp); for (i = 1; i < 6; i++) { for (j = 0; j < GFBITS; j++) tmp[j] = vec_setbits((beta[i] >> j) & 1); vec_mul(pre[i][0], pre[i][0], tmp); vec_mul(pre[i][1], pre[i][1], tmp); for (b = 0; b < GFBITS; b++) { out[2][b] ^= pre[i][0][b]; out[3][b] ^= pre[i][1][b]; } } } static void fft_tr(vec out[][GFBITS], vec in[][ GFBITS ]) { butterflies_tr(out, in); radix_conversions_tr(out); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/gf.c */ /* this file is for functions for field arithmetic */ /* 20221231 djb: const for GF_mul */ /* 20221230 djb: add linker line */ /* linker define gf_iszero gf_mul gf_inv gf_frac GF_mul */ /* field multiplication */ gf gf_mul(gf in0, gf in1) { int i; uint64_t tmp; uint64_t t0; uint64_t t1; uint64_t t; t0 = in0; t1 = in1; tmp = t0 * (t1 & 1); for (i = 1; i < GFBITS; i++) tmp ^= (t0 * (t1 & (1 << i))); /**/ t = tmp & 0x1FF0000; tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); t = tmp & 0x000E000; tmp ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); return tmp & GFMASK; } /* 2 field squarings */ static inline gf gf_sq2(gf in) { int i; const uint64_t B[] = {0x1111111111111111, 0x0303030303030303, 0x000F000F000F000F, 0x000000FF000000FF}; const uint64_t M[] = {0x0001FF0000000000, 0x000000FF80000000, 0x000000007FC00000, 0x00000000003FE000}; uint64_t x = in; uint64_t t; x = (x | (x << 24)) & B[3]; x = (x | (x << 12)) & B[2]; x = (x | (x << 6)) & B[1]; x = (x | (x << 3)) & B[0]; for (i = 0; i < 4; i++) { t = x & M[i]; x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); } return x & GFMASK; } /* square and multiply */ static inline gf gf_sqmul(gf in, gf m) { int i; uint64_t x; uint64_t t0; uint64_t t1; uint64_t t; const uint64_t M[] = {0x0000001FF0000000, 0x000000000FF80000, 0x000000000007E000}; t0 = in; t1 = m; x = (t1 << 6) * (t0 & (1 << 6)); t0 ^= (t0 << 7); x ^= (t1 * (t0 & (0x04001))); x ^= (t1 * (t0 & (0x08002))) << 1; x ^= (t1 * (t0 & (0x10004))) << 2; x ^= (t1 * (t0 & (0x20008))) << 3; x ^= (t1 * (t0 & (0x40010))) << 4; x ^= (t1 * (t0 & (0x80020))) << 5; for (i = 0; i < 3; i++) { t = x & M[i]; x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); } return x & GFMASK; } /* square twice and multiply */ static inline gf gf_sq2mul(gf in, gf m) { int i; uint64_t x; uint64_t t0; uint64_t t1; uint64_t t; const uint64_t M[] = {0x1FF0000000000000, 0x000FF80000000000, 0x000007FC00000000, 0x00000003FE000000, 0x0000000001FE0000, 0x000000000001E000}; t0 = in; t1 = m; x = (t1 << 18) * (t0 & (1 << 6)); t0 ^= (t0 << 21); x ^= (t1 * (t0 & (0x010000001))); x ^= (t1 * (t0 & (0x020000002))) << 3; x ^= (t1 * (t0 & (0x040000004))) << 6; x ^= (t1 * (t0 & (0x080000008))) << 9; x ^= (t1 * (t0 & (0x100000010))) << 12; x ^= (t1 * (t0 & (0x200000020))) << 15; for (i = 0; i < 6; i++) { t = x & M[i]; x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13); } return x & GFMASK; } /* return num/den */ gf gf_frac(gf den, gf num) { gf tmp_11; gf tmp_1111; gf out; tmp_11 = gf_sqmul(den, den); /* 11 */ tmp_1111 = gf_sq2mul(tmp_11, tmp_11); /* 1111 */ out = gf_sq2(tmp_1111); out = gf_sq2mul(out, tmp_1111); /* 11111111 */ out = gf_sq2(out); out = gf_sq2mul(out, tmp_1111); /* 111111111111 */ return gf_sqmul(out, num); /* 1111111111110 */ } /* return 1/den */ gf gf_inv(gf den) { return gf_frac(den, ((gf) 1)); } /* check if a == 0 */ gf gf_iszero(gf a) { uint32_t t = a; t -= 1; t >>= 19; return (gf) t; } /* multiplication in GF((2^m)^t) */ static void GF_mul(gf *out, const gf *in0, const gf *in1) { int i, j; gf prod[255]; for (i = 0; i < 255; i++) prod[i] = 0; for (i = 0; i < 128; i++) for (j = 0; j < 128; j++) prod[i+j] ^= gf_mul(in0[i], in1[j]); /**/ for (i = 254; i >= 128; i--) { prod[i - 121] ^= prod[i]; prod[i - 126] ^= prod[i]; prod[i - 127] ^= prod[i]; prod[i - 128] ^= prod[i]; } for (i = 0; i < 128; i++) out[i] = prod[i]; } /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_dec.c */ /* 20221230 djb: add linker lines */ /* 20221230 djb: split out of operations.c */ /* linker define operation_dec */ /* linker use decrypt */ static void operation_dec( unsigned char *key, const unsigned char *c, const unsigned char *sk ) { int i; unsigned char ret_decrypt = 0; uint16_t m; unsigned char e[ SYS_N/8 ]; unsigned char preimage[ 1 + SYS_N/8 + SYND_BYTES ]; unsigned char *x = preimage; const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES; /**/ ret_decrypt = decrypt(e, sk + 40, c); m = ret_decrypt; m -= 1; m >>= 8; *x++ = m & 1; for (i = 0; i < SYS_N/8; i++) *x++ = (~m & s[i]) | (m & e[i]); for (i = 0; i < SYND_BYTES; i++) *x++ = c[i]; crypto_hash_32b(key, preimage, sizeof(preimage)); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_enc.c */ /* 20230102 djb: rename encrypt() as pke_encrypt() */ /* 20221230 djb: add linker lines */ /* 20221230 djb: split out of operations.c */ /* linker define operation_enc */ /* linker use pke_encrypt */ static void operation_enc( unsigned char *c, unsigned char *key, const unsigned char *pk ) { unsigned char e[ SYS_N/8 ]; unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1}; /**/ pke_encrypt(c, pk, e); memcpy(one_ec + 1, e, SYS_N/8); memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES); crypto_hash_32b(key, one_ec, sizeof(one_ec)); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/kem_keypair.c */ /* 20221230 djb: add linker lines */ /* 20221230 djb: split out of operations.c */ /* linker define operation_keypair */ /* linker use controlbitsfrompermutation genpoly_gen pk_gen */ static void operation_keypair ( unsigned char *pk, unsigned char *sk ) { int i; unsigned char seed[ 33 ] = {64}; unsigned char r[ SYS_N/8 + (1 << GFBITS)*sizeof(uint32_t) + SYS_T*2 + 32 ]; unsigned char *rp, *skp; uint64_t pivots = 0; gf f[ SYS_T ]; /* element in GF(2^mt) */ gf irr[ SYS_T ]; /* Goppa polynomial */ uint32_t perm[ 1 << GFBITS ]; /* random permutation as 32-bit integers */ int16_t pi[ 1 << GFBITS ]; /* random permutation */ randombytes(seed+1, 32); while (1) { rp = &r[ sizeof(r)-32 ]; skp = sk; /* expanding and updating the seed */ shake(r, sizeof(r), seed, 33); memcpy(skp, seed+1, 32); skp += 32 + 8; memcpy(seed+1, &r[ sizeof(r)-32 ], 32); /* generating irreducible polynomial */ rp -= sizeof(f); for (i = 0; i < SYS_T; i++) f[i] = load_gf(rp + i*2); if (genpoly_gen(irr, f)) continue; for (i = 0; i < SYS_T; i++) store_gf(skp + i*2, irr[i]); skp += IRR_BYTES; /* generating permutation */ rp -= sizeof(perm); for (i = 0; i < (1 << GFBITS); i++) perm[i] = load4(rp + i*4); if (pk_gen(pk, skp - IRR_BYTES, perm, pi, &pivots)) continue; controlbitsfrompermutation(skp, pi, GFBITS, 1 << GFBITS); skp += COND_BYTES; /* storing the random string s */ rp -= SYS_N/8; memcpy(skp, rp, SYS_N/8); /* storing positions of the 32 pivots */ store8(sk + 32, pivots); break; } } /* from libmceliece-20230612/crypto_kem/6688128f/vec/pk_gen.c */ /* This file is for public-key generation */ /* 20221231 djb: remove unused min definition */ /* 20221231 djb: more 0 initialization to clarify data flow; tnx thom wiggers */ /* 20221230 djb: add linker lines */ /* linker define pk_gen */ /* linker use fft vec_inv vec_mul */ static crypto_uint64 uint64_is_equal_declassify(uint64_t t,uint64_t u) { crypto_uint64 mask = crypto_uint64_equal_mask(t,u); crypto_declassify(&mask,sizeof mask); return mask; } static crypto_uint64 uint64_is_zero_declassify(uint64_t t) { crypto_uint64 mask = crypto_uint64_zero_mask(t); crypto_declassify(&mask,sizeof mask); return mask; } static void de_bitslicing(uint64_t * out, const vec in[][GFBITS]) { int i, j, r; for (i = 0; i < (1 << GFBITS); i++) out[i] = 0 ; for (i = 0; i < 128; i++) for (j = GFBITS-1; j >= 0; j--) for (r = 0; r < 64; r++) { out[i*64 + r] <<= 1; out[i*64 + r] |= (in[i][j] >> r) & 1; } } static void to_bitslicing_2x(vec out0[][GFBITS], vec out1[][GFBITS], const uint64_t * in) { int i, j, r; for (i = 0; i < 128; i++) { for (j = 0;j < GFBITS;++j) out0[i][j] = out1[i][j] = 0; for (j = GFBITS-1; j >= 0; j--) for (r = 63; r >= 0; r--) { out1[i][j] <<= 1; out1[i][j] |= (in[i*64 + r] >> (j + GFBITS)) & 1; } for (j = GFBITS-1; j >= 0; j--) for (r = 63; r >= 0; r--) { out0[i][GFBITS-1-j] <<= 1; out0[i][GFBITS-1-j] |= (in[i*64 + r] >> j) & 1; } } } /* return number of trailing zeros of in */ static inline int ctz(uint64_t in) { int i, b, m = 0, r = 0; for (i = 0; i < 64; i++) { b = (in >> i) & 1; m |= b; r += (m^1) & (b^1); } return r; } static inline uint64_t same_mask(uint16_t x, uint16_t y) { uint64_t mask; mask = x ^ y; mask -= 1; mask >>= 63; mask = -mask; return mask; } static int mov_columns(uint64_t mat[][ (SYS_N + 63) / 64 ], int16_t * pi, uint64_t * pivots) { int i, j, k, s, block_idx, row; uint64_t buf[64], ctz_list[32], t, d, mask, one = 1; row = PK_NROWS - 32; block_idx = row/64; /* extract the 32x64 matrix */ for (i = 0; i < 32; i++) buf[i] = (mat[ row + i ][ block_idx + 0 ] >> 32) | (mat[ row + i ][ block_idx + 1 ] << 32); /* compute the column indices of pivots by Gaussian elimination. */ /* the indices are stored in ctz_list */ *pivots = 0; for (i = 0; i < 32; i++) { t = buf[i]; for (j = i+1; j < 32; j++) t |= buf[j]; if (uint64_is_zero_declassify(t)) return -1; /* return if buf is not full rank */ ctz_list[i] = s = ctz(t); *pivots |= one << ctz_list[i]; for (j = i+1; j < 32; j++) { mask = (buf[i] >> s) & 1; mask -= 1; buf[i] ^= buf[j] & mask; } for (j = i+1; j < 32; j++) { mask = (buf[j] >> s) & 1; mask = -mask; buf[j] ^= buf[i] & mask; } } /* updating permutation */ for (j = 0; j < 32; j++) for (k = j+1; k < 64; k++) { d = pi[ row + j ] ^ pi[ row + k ]; d &= same_mask(k, ctz_list[j]); pi[ row + j ] ^= d; pi[ row + k ] ^= d; } /* moving columns of mat according to the column indices of pivots */ for (i = 0; i < PK_NROWS; i++) { t = (mat[ i ][ block_idx + 0 ] >> 32) | (mat[ i ][ block_idx + 1 ] << 32); for (j = 0; j < 32; j++) { d = t >> j; d ^= t >> ctz_list[j]; d &= 1; t ^= d << ctz_list[j]; t ^= d << j; } mat[ i ][ block_idx + 0 ] = (mat[ i ][ block_idx + 0 ] << 32 >> 32) | (t << 32); mat[ i ][ block_idx + 1 ] = (mat[ i ][ block_idx + 1 ] >> 32 << 32) | (t >> 32); } return 0; } static int pk_gen(unsigned char * pk, const unsigned char * irr, uint32_t * perm, int16_t * pi, uint64_t * pivots) { const int nblocks_H = (SYS_N + 63) / 64; const int nblocks_I = (PK_NROWS + 63) / 64; int i, j, k; int row, c; uint64_t mat[ PK_NROWS ][ nblocks_H ]; uint64_t mask; vec irr_int[2][ GFBITS ]; vec consts[ 128 ][ GFBITS ]; vec eval[ 128 ][ GFBITS ]; vec prod[ 128 ][ GFBITS ]; vec tmp[ GFBITS ]; uint64_t list[1 << GFBITS]; /* compute the inverses */ irr_load(irr_int, irr); fft(eval, irr_int); vec_copy(prod[0], eval[0]); for (i = 1; i < 128; i++) vec_mul(prod[i], prod[i-1], eval[i]); vec_inv(tmp, prod[127]); for (i = 126; i >= 0; i--) { vec_mul(prod[i+1], prod[i], tmp); vec_mul(tmp, tmp, eval[i+1]); } vec_copy(prod[0], tmp); /* fill matrix */ de_bitslicing(list, prod); for (i = 0; i < (1 << GFBITS); i++) { list[i] <<= GFBITS; list[i] |= i; list[i] |= ((uint64_t) perm[i]) << 31; } uint64_sort(list, 1 << GFBITS); for (i = 1; i < (1 << GFBITS); i++) if (uint64_is_equal_declassify(list[i-1] >> 31,list[i] >> 31)) return -1; to_bitslicing_2x(consts, prod, list); for (i = 0; i < (1 << GFBITS); i++) pi[i] = list[i] & GFMASK; for (j = 0; j < nblocks_H; j++) for (k = 0; k < GFBITS; k++) mat[ k ][ j ] = prod[ j ][ k ]; for (i = 1; i < SYS_T; i++) for (j = 0; j < nblocks_H; j++) { vec_mul(prod[j], prod[j], consts[j]); for (k = 0; k < GFBITS; k++) mat[ i*GFBITS + k ][ j ] = prod[ j ][ k ]; } /* gaussian elimination */ for (row = 0; row < PK_NROWS; row++) { i = row >> 6; j = row & 63; if (row == PK_NROWS - 32) { if (mov_columns(mat, pi, pivots)) return -1; } for (k = row + 1; k < PK_NROWS; k++) { mask = mat[ row ][ i ] >> j; mask &= 1; mask -= 1; for (c = 0; c < nblocks_H; c++) mat[ row ][ c ] ^= mat[ k ][ c ] & mask; } if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) /* return if not systematic */ { return -1; } for (k = 0; k < row; k++) { mask = mat[ k ][ i ] >> j; mask &= 1; mask = -mask; for (c = 0; c < nblocks_H; c++) mat[ k ][ c ] ^= mat[ row ][ c ] & mask; } for (k = row+1; k < PK_NROWS; k++) { mask = mat[ k ][ i ] >> j; mask &= 1; mask = -mask; for (c = 0; c < nblocks_H; c++) mat[ k ][ c ] ^= mat[ row ][ c ] & mask; } } for (i = 0; i < PK_NROWS; i++) { for (j = nblocks_I; j < nblocks_H-1; j++) { store8(pk, mat[i][j]); pk += 8; } store_i(pk, mat[i][j], PK_ROW_BYTES % 8); pk += PK_ROW_BYTES % 8; } /**/ return 0; } /* from libmceliece-20230612/crypto_kem/6688128f/vec/sk_gen.c */ /* This file is for secret-key generation */ /* 20221230 djb: add linker lines */ /* linker define genpoly_gen */ /* linker use gf_iszero gf_mul gf_inv GF_mul */ static inline crypto_uint16 gf_is_zero_declassify(gf t) { crypto_uint16 mask = crypto_uint16_zero_mask(t); crypto_declassify(&mask,sizeof mask); return mask; } /* input: f, element in GF((2^m)^t) */ /* output: out, minimal polynomial of f */ /* return: 0 for success and -1 for failure */ static int genpoly_gen(gf *out, gf *f) { int i, j, k, c; gf mat[ SYS_T+1 ][ SYS_T ]; gf mask, inv, t; /* fill matrix */ mat[0][0] = 1; for (i = 1; i < SYS_T; i++) mat[0][i] = 0; for (i = 0; i < SYS_T; i++) mat[1][i] = f[i]; for (j = 2; j <= SYS_T; j++) GF_mul(mat[j], mat[j-1], f); /* gaussian */ for (j = 0; j < SYS_T; j++) { for (k = j + 1; k < SYS_T; k++) { mask = gf_iszero(mat[ j ][ j ]); for (c = j; c < SYS_T + 1; c++) mat[ c ][ j ] ^= mat[ c ][ k ] & mask; } if ( gf_is_zero_declassify(mat[ j ][ j ]) ) /* return if not systematic */ { return -1; } inv = gf_inv(mat[j][j]); for (c = j; c < SYS_T + 1; c++) mat[ c ][ j ] = gf_mul(mat[ c ][ j ], inv) ; for (k = 0; k < SYS_T; k++) { if (k != j) { t = mat[ j ][ k ]; for (c = j; c < SYS_T + 1; c++) mat[ c ][ k ] ^= gf_mul(mat[ c ][ j ], t); } } } for (i = 0; i < SYS_T; i++) out[i] = mat[ SYS_T ][ i ]; return 0; } /* from libmceliece-20230612/crypto_kem/6688128f/vec/vec.c */ /* 20221230 djb: add linker line */ /* linker define vec_mul vec_sq vec_inv */ static void vec_mul(vec * h, const vec * f, const vec * g) { int i, j; vec buf[ 2*GFBITS-1 ]; for (i = 0; i < 2*GFBITS-1; i++) buf[i] = 0; for (i = 0; i < GFBITS; i++) for (j = 0; j < GFBITS; j++) buf[i+j] ^= f[i] & g[j]; for (i = 2*GFBITS-2; i >= GFBITS; i--) { buf[i-GFBITS+4] ^= buf[i]; buf[i-GFBITS+3] ^= buf[i]; buf[i-GFBITS+1] ^= buf[i]; buf[i-GFBITS+0] ^= buf[i]; } for (i = 0; i < GFBITS; i++) h[i] = buf[i]; } /* bitsliced field squarings */ static void vec_sq(vec * out, vec * in) { int i; vec result[GFBITS], t; t = in[11] ^ in[12]; result[0] = in[0] ^ in[11]; result[1] = in[7] ^ t; result[2] = in[1] ^ in[7]; result[3] = in[8] ^ t; result[4] = in[2] ^ in[7]; result[4] = result[4] ^ in[8]; result[4] = result[4] ^ t; result[5] = in[7] ^ in[9]; result[6] = in[3] ^ in[8]; result[6] = result[6] ^ in[9]; result[6] = result[6] ^ in[12]; result[7] = in[8] ^ in[10]; result[8] = in[4] ^ in[9]; result[8] = result[8] ^ in[10]; result[9] = in[9] ^ in[11]; result[10] = in[5] ^ in[10]; result[10] = result[10] ^ in[11]; result[11] = in[10] ^ in[12]; result[12] = in[6] ^ t; for (i = 0; i < GFBITS; i++) out[i] = result[i]; } /* bitsliced field inverses */ static void vec_inv(vec * out, vec * in) { vec tmp_11[ GFBITS ]; vec tmp_1111[ GFBITS ]; vec_copy(out, in); vec_sq(out, out); vec_mul(tmp_11, out, in); /* ^11 */ vec_sq(out, tmp_11); vec_sq(out, out); vec_mul(tmp_1111, out, tmp_11); /* ^1111 */ vec_sq(out, tmp_1111); vec_sq(out, out); vec_sq(out, out); vec_sq(out, out); vec_mul(out, out, tmp_1111); /* ^11111111 */ vec_sq(out, out); vec_sq(out, out); vec_sq(out, out); vec_sq(out, out); vec_mul(out, out, tmp_1111); /* ^111111111111 */ vec_sq(out, out); /* ^1111111111110 */ } /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_dec.c */ void mceliece6688128f_dec(uint8_t *key, const uint8_t *c, const uint8_t *sk) { operation_dec((unsigned char*) key, (unsigned char*) c, (unsigned char*) sk); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_enc.c */ void mceliece6688128f_enc(uint8_t *c, uint8_t *key, const uint8_t *pk) { operation_enc((unsigned char*) c, (unsigned char*) key, (unsigned char*) pk); } /* from libmceliece-20230612/crypto_kem/6688128f/vec/wrap_keypair.c */ void mceliece6688128f_keypair(uint8_t *pk, uint8_t *sk) { operation_keypair((unsigned char*) pk, (unsigned char*) sk); } diff --git a/cipher/mceliece6688128f.h b/cipher/mceliece6688128f.h index 60944cb6..eb9f23a0 100644 --- a/cipher/mceliece6688128f.h +++ b/cipher/mceliece6688128f.h @@ -1,56 +1,63 @@ /* mceliece6688128f.h - Classic McEliece for libgcrypt * Copyright (C) 2023-2024 Simon Josefsson * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . * SPDX-License-Identifier: LGPL-2.1-or-later * */ #ifndef MCELIECE6688128F_H #define MCELIECE6688128F_H #include #include #ifdef _GCRYPT_IN_LIBGCRYPT /**** Start of the glue code to libgcrypt ****/ +#include "g10lib.h" /* for GCC_ATTR_UNUSED */ #include "gcrypt-int.h" #define mceliece6688128f_keypair _gcry_mceliece6688128f_keypair #define mceliece6688128f_enc _gcry_mceliece6688128f_enc #define mceliece6688128f_dec _gcry_mceliece6688128f_dec /**** End of the glue code ****/ #else +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 ) +#define GCC_ATTR_UNUSED __attribute__ ((unused)) +#else +#define GCC_ATTR_UNUSED +#endif + #define MCELIECE6688128F_SECRETKEY_SIZE 13932 #define MCELIECE6688128F_PUBLICKEY_SIZE 1044992 #define MCELIECE6688128F_CIPHERTEXT_SIZE 208 #define MCELIECE6688128F_SIZE 32 #endif typedef void mceliece6688128f_random_func (void *ctx, size_t length, uint8_t *dst); void mceliece6688128f_keypair (uint8_t *pk, uint8_t *sk); void mceliece6688128f_enc (uint8_t *c, uint8_t *k, const uint8_t *pk); void mceliece6688128f_dec (uint8_t *k, const uint8_t *c, const uint8_t *sk); #endif /* MCELIECE6688128F_H */