Falcon: consolidate the native C into a single falcon.c

Merge the nine wc_falcon_*.c cores into wolfcrypt/src/falcon.c, matching the
one-file-per-algorithm convention (ed25519.c, wc_mldsa.c). Sign and keygen are
gated internally on WOLFSSL_FALCON_VERIFY_ONLY and the internal helpers become
static. The fpr/fft/poly primitives stay external (shared with the separate
AVX2/NEON FFT backends) so their three headers are retained; the other five
internal headers are removed.
This commit is contained in:
Daniele Lacamera
2026-07-15 08:02:12 +02:00
parent 9fc9b181eb
commit b3274a58b1
20 changed files with 8062 additions and 8680 deletions
-9
View File
@@ -16,16 +16,7 @@ ASM_SRCS := start.S
# Full native Falcon (keygen + sign + verify) + SHAKE256 + runtime. # Full native Falcon (keygen + sign + verify) + SHAKE256 + runtime.
WOLFSSL_SRCS := \ WOLFSSL_SRCS := \
../../wolfcrypt/src/falcon.c \ ../../wolfcrypt/src/falcon.c \
../../wolfcrypt/src/wc_falcon.c \
../../wolfcrypt/src/wc_falcon_fpr.c \
../../wolfcrypt/src/wc_falcon_fft.c \
../../wolfcrypt/src/wc_falcon_fft_neon.c \ ../../wolfcrypt/src/wc_falcon_fft_neon.c \
../../wolfcrypt/src/wc_falcon_poly.c \
../../wolfcrypt/src/wc_falcon_sampler.c \
../../wolfcrypt/src/wc_falcon_codec.c \
../../wolfcrypt/src/wc_falcon_keygen.c \
../../wolfcrypt/src/wc_falcon_sign.c \
../../wolfcrypt/src/wc_falcon_bigint.c \
../../wolfcrypt/src/sha3.c \ ../../wolfcrypt/src/sha3.c \
../../wolfcrypt/src/sha256.c \ ../../wolfcrypt/src/sha256.c \
../../wolfcrypt/src/hash.c \ ../../wolfcrypt/src/hash.c \
-11
View File
@@ -1143,17 +1143,6 @@ function(generate_lib_src_list LIB_SOURCES)
endif() endif()
endif() endif()
if(BUILD_FALCON)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_fpr.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_fft.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_poly.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_sampler.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_codec.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_bigint.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_keygen.c)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_falcon_sign.c)
endif()
if(BUILD_WC_MLKEM) if(BUILD_WC_MLKEM)
list(APPEND LIB_SOURCES wolfcrypt/src/wc_mlkem.c) list(APPEND LIB_SOURCES wolfcrypt/src/wc_mlkem.c)
-24
View File
@@ -1342,18 +1342,6 @@ endif BUILD_INTELASM
endif !BUILD_X86_ASM endif !BUILD_X86_ASM
endif endif
if BUILD_FALCON
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_fpr.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_fft.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_poly.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_sampler.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_codec.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_bigint.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_keygen.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_sign.c
endif
if BUILD_WC_LMS if BUILD_WC_LMS
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms_impl.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms_impl.c
@@ -2145,18 +2133,6 @@ endif BUILD_INTELASM
endif !BUILD_X86_ASM endif !BUILD_X86_ASM
endif endif
if BUILD_FALCON
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_fpr.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_fft.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_poly.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_sampler.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_codec.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_bigint.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_keygen.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_falcon_sign.c
endif
if BUILD_WC_LMS if BUILD_WC_LMS
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms.c
src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms_impl.c src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms_impl.c
+8056 -6
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-370
View File
@@ -1,370 +0,0 @@
/* wc_falcon_codec.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Falcon encode/decode routines for the signing and
* key-generation paths. These are faithful ports of the Falcon reference
* implementation (codec.c): modq_encode, comp_encode, trim_i8_encode and
* trim_i8_decode, plus the secret-key decoder that drives them.
*
* The verification-side decoders (modq_decode, comp_decode) are static
* functions in wc_falcon.c and are deliberately not duplicated here. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
#include <wolfssl/wolfcrypt/falcon.h>
#include <wolfssl/wolfcrypt/wc_falcon_codec.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
/* Maximum bit width used to encode f and g, indexed by logn (0..10).
* From the Falcon reference (codec.c). */
static const byte falcon_max_fg_bits[] = {
0, /* unused */
8,
8,
8,
8,
8,
7,
7,
6,
6,
5
};
/* Maximum bit width used to encode F (and G), indexed by logn (0..10).
* From the Falcon reference (codec.c). */
static const byte falcon_max_FG_bits[] = {
0, /* unused */
8,
8,
8,
8,
8,
8,
8,
8,
8,
8
};
/* ------------------------------------------------------------------------ */
/* Pack the public key polynomial h: n coefficients, 14 bits each, packed
* most-significant bit first. Inverse of falcon_modq_decode. Returns the number
* of bytes written, or 0 on a coefficient >= q or output overflow. */
size_t falcon_modq_encode(byte* out, size_t max_out, const word16* x,
unsigned logn)
{
size_t n = (size_t)1 << logn;
size_t out_len = ((n * 14) + 7) >> 3;
size_t u, v;
word32 acc = 0;
int acc_len = 0;
for (u = 0; u < n; u++) {
if (x[u] >= FALCON_Q) {
return 0;
}
}
if (out_len > max_out) {
return 0;
}
v = 0;
for (u = 0; u < n; u++) {
acc = (acc << 14) | (word32)x[u];
acc_len += 14;
while (acc_len >= 8) {
acc_len -= 8;
out[v++] = (byte)(acc >> acc_len);
}
}
if (acc_len > 0) {
out[v++] = (byte)(acc << (8 - acc_len));
}
return out_len;
}
/* ------------------------------------------------------------------------ */
/* Compress the signature polynomial s2 with Golomb-Rice coding (k=7). Exact
* inverse of the reference comp_decode. Returns the number of bytes written, or
* 0 if any |x[i]| > 2047 or the output buffer overflows. */
size_t falcon_comp_encode(byte* out, size_t max_out, const sword16* x,
unsigned logn)
{
size_t n = (size_t)1 << logn;
size_t u, v;
word32 acc = 0;
unsigned acc_len = 0;
/* All coefficients must fit in the -2047..+2047 range. */
for (u = 0; u < n; u++) {
if (x[u] < -2047 || x[u] > 2047) {
return 0;
}
}
v = 0;
for (u = 0; u < n; u++) {
int t;
unsigned w;
/* Sign bit (1 for negative), then the low 7 bits of |x|. */
acc <<= 1;
t = (int)x[u];
if (t < 0) {
t = -t;
acc |= 1;
}
w = (unsigned)t;
acc <<= 7;
acc |= w & 127u;
w >>= 7;
acc_len += 8;
/* Unary high part: w zero bits then a terminating one. The absolute
* value is at most 2047, so w <= 15 here and at most 16 bits are added;
* combined with the 8 bits above and up to 7 carried bits, the 32-bit
* accumulator never overflows. */
acc <<= (w + 1);
acc |= 1;
acc_len += w + 1;
while (acc_len >= 8) {
acc_len -= 8;
if (v >= max_out) {
return 0;
}
out[v++] = (byte)(acc >> acc_len);
}
}
/* Flush any remaining bits, left-aligned in the final byte. */
if (acc_len > 0) {
if (v >= max_out) {
return 0;
}
out[v++] = (byte)(acc << (8 - acc_len));
}
return v;
}
/* ------------------------------------------------------------------------ */
/* Pack n signed 8-bit coefficients, each in 'bits' bits, MSB first. The valid
* range is -(2^(bits-1)-1) .. +(2^(bits-1)-1); the most-negative value is not
* representable. Returns bytes written, or 0 on range violation / overflow. */
size_t falcon_trim_i8_encode(byte* out, size_t max_out, const sword8* x,
unsigned logn, unsigned bits)
{
size_t n = (size_t)1 << logn;
size_t out_len = ((n * bits) + 7) >> 3;
size_t u, v;
int minv, maxv;
word32 acc = 0, mask;
unsigned acc_len = 0;
/* Callers only pass falcon_max_fg_bits/falcon_max_FG_bits values (5..8);
* guard the shifts below against out-of-range widths anyway. */
if (bits < 2 || bits > 8) {
return 0;
}
maxv = (1 << (bits - 1)) - 1;
minv = -maxv;
for (u = 0; u < n; u++) {
if (x[u] < minv || x[u] > maxv) {
return 0;
}
}
if (out_len > max_out) {
return 0;
}
mask = ((word32)1 << bits) - 1;
v = 0;
for (u = 0; u < n; u++) {
acc = (acc << bits) | ((word32)(byte)x[u] & mask);
acc_len += bits;
while (acc_len >= 8) {
acc_len -= 8;
out[v++] = (byte)(acc >> acc_len);
}
}
if (acc_len > 0) {
out[v++] = (byte)(acc << (8 - acc_len));
}
return out_len;
}
/* Unpack n signed 8-bit coefficients packed at 'bits' bits each (MSB first).
* The most-negative value -2^(bits-1) is rejected. Trailing pad bits in the
* final byte must be zero. Returns bytes consumed, or 0 on any violation. */
size_t falcon_trim_i8_decode(sword8* x, unsigned logn, unsigned bits,
const byte* in, size_t max_in)
{
size_t n = (size_t)1 << logn;
size_t in_len = ((n * bits) + 7) >> 3;
size_t u, v;
word32 acc = 0, mask1, mask2;
unsigned acc_len = 0;
/* Same defensive width guard as falcon_trim_i8_encode. */
if (bits < 2 || bits > 8) {
return 0;
}
if (in_len > max_in) {
return 0;
}
mask1 = ((word32)1 << bits) - 1;
mask2 = (word32)1 << (bits - 1);
u = 0;
v = 0;
while (u < n) {
acc = (acc << 8) | (word32)in[v++];
acc_len += 8;
while (acc_len >= bits && u < n) {
word32 w;
acc_len -= bits;
w = (acc >> acc_len) & mask1;
/* Sign-extend from the high bit. */
w |= (word32)(-(sword32)(w & mask2));
if (w == (word32)(-(sword32)mask2)) {
/* The -2^(bits-1) value is forbidden. */
return 0;
}
x[u++] = (sword8)(sword32)w;
}
}
/* Extra bits in the last consumed byte must be zero. */
if ((acc & (((word32)1 << acc_len) - 1)) != 0) {
return 0;
}
return in_len;
}
/* ------------------------------------------------------------------------ */
/* Decode a Falcon secret key into its (f, g, F) basis polynomials. The encoding
* is: header byte (0x50 | logn), then trim_i8(f, max_fg_bits[logn]),
* trim_i8(g, max_fg_bits[logn]), trim_i8(F, max_FG_bits[logn]). G is not stored
* (it is recomputed from f, g, F at use time). The header and an exact length
* match are both validated. */
int falcon_privkey_decode(const byte* sk, size_t sklen, sword8* f, sword8* g,
sword8* F, unsigned logn)
{
size_t u, v;
if (sk == NULL || f == NULL || g == NULL || F == NULL) {
return BAD_FUNC_ARG;
}
if (logn < 1 || logn > 10) {
return BAD_FUNC_ARG;
}
if (sklen < 1) {
return BUFFER_E;
}
if (sk[0] != (byte)(0x50 | logn)) {
return ASN_PARSE_E;
}
u = 1;
v = falcon_trim_i8_decode(f, logn, falcon_max_fg_bits[logn],
sk + u, sklen - u);
if (v == 0) {
return ASN_PARSE_E;
}
u += v;
v = falcon_trim_i8_decode(g, logn, falcon_max_fg_bits[logn],
sk + u, sklen - u);
if (v == 0) {
return ASN_PARSE_E;
}
u += v;
v = falcon_trim_i8_decode(F, logn, falcon_max_FG_bits[logn],
sk + u, sklen - u);
if (v == 0) {
return ASN_PARSE_E;
}
u += v;
/* The whole secret key must be consumed exactly. */
if (u != sklen) {
return ASN_PARSE_E;
}
return 0;
}
/* Encode a Falcon secret key from its (f, g, F) basis: header byte
* (0x50 | logn), then trim_i8(f), trim_i8(g) at max_fg_bits[logn] and
* trim_i8(F) at max_FG_bits[logn]. Returns the number of bytes written, or 0 on
* range violation / output overflow. */
size_t falcon_privkey_encode(byte* sk, size_t max_sk, const sword8* f,
const sword8* g, const sword8* F, unsigned logn)
{
size_t u, v;
if (sk == NULL || f == NULL || g == NULL || F == NULL) {
return 0;
}
if (logn < 1 || logn > 10) {
return 0;
}
if (max_sk < 1) {
return 0;
}
sk[0] = (byte)(0x50 | logn);
u = 1;
v = falcon_trim_i8_encode(sk + u, max_sk - u, f, logn,
falcon_max_fg_bits[logn]);
if (v == 0) {
return 0;
}
u += v;
v = falcon_trim_i8_encode(sk + u, max_sk - u, g, logn,
falcon_max_fg_bits[logn]);
if (v == 0) {
return 0;
}
u += v;
v = falcon_trim_i8_encode(sk + u, max_sk - u, F, logn,
falcon_max_FG_bits[logn]);
if (v == 0) {
return 0;
}
u += v;
return u;
}
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
-635
View File
@@ -1,635 +0,0 @@
/* wc_falcon_fft.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Falcon FFT over the fpr seam. See wolfssl/wolfcrypt/wc_falcon_fft.h.
* Algorithm and twiddle-table layout validated against a schoolbook negacyclic
* reference (round-trip and FFT-based multiplication) for n in {8,512,1024}. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
#include <wolfssl/wolfcrypt/wc_falcon_fft.h>
/* Complex helpers over the fpr seam. d may alias a/b inputs only via temps. */
#define FPC_ADD(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
(d_re) = fpr_add(_ar, _br); \
(d_im) = fpr_add(_ai, _bi); \
} while (0)
#define FPC_SUB(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
(d_re) = fpr_sub(_ar, _br); \
(d_im) = fpr_sub(_ai, _bi); \
} while (0)
/* (a_re + i a_im) * (b_re + i b_im) */
#define FPC_MUL(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
(d_re) = fpr_sub(fpr_mul(_ar, _br), fpr_mul(_ai, _bi)); \
(d_im) = fpr_add(fpr_mul(_ar, _bi), fpr_mul(_ai, _br)); \
} while (0)
/* falcon_gm_tab[2*p+0]=cos, [2*p+1]=sin; angle=pi*(2*brev_u(i)+1)/(2m).
* Generated table of correctly-rounded IEEE-754 twiddle factors, n<=1024.
* Exported (declared in wc_falcon_fft.h) for use by the poly_split/merge ops. */
const fpr falcon_gm_tab[2048] = {
0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
0x3FE6A09E667F3BCDULL, 0x3FE6A09E667F3BCCULL, 0xBFE6A09E667F3BCCULL, 0x3FE6A09E667F3BCDULL,
0x3FED906BCF328D46ULL, 0x3FD87DE2A6AEA963ULL, 0xBFD87DE2A6AEA962ULL, 0x3FED906BCF328D46ULL,
0x3FD87DE2A6AEA964ULL, 0x3FED906BCF328D46ULL, 0xBFED906BCF328D46ULL, 0x3FD87DE2A6AEA965ULL,
0x3FEF6297CFF75CB0ULL, 0x3FC8F8B83C69A60AULL, 0xBFC8F8B83C69A608ULL, 0x3FEF6297CFF75CB0ULL,
0x3FE1C73B39AE68C9ULL, 0x3FEA9B66290EA1A3ULL, 0xBFEA9B66290EA1A4ULL, 0x3FE1C73B39AE68C8ULL,
0x3FEA9B66290EA1A3ULL, 0x3FE1C73B39AE68C8ULL, 0xBFE1C73B39AE68C6ULL, 0x3FEA9B66290EA1A5ULL,
0x3FC8F8B83C69A60DULL, 0x3FEF6297CFF75CB0ULL, 0xBFEF6297CFF75CB0ULL, 0x3FC8F8B83C69A617ULL,
0x3FEFD88DA3D12526ULL, 0x3FB917A6BC29B42CULL, 0xBFB917A6BC29B42FULL, 0x3FEFD88DA3D12526ULL,
0x3FE44CF325091DD6ULL, 0x3FE8BC806B151741ULL, 0xBFE8BC806B151741ULL, 0x3FE44CF325091DD6ULL,
0x3FEC38B2F180BDB1ULL, 0x3FDE2B5D3806F63BULL, 0xBFDE2B5D3806F63CULL, 0x3FEC38B2F180BDB1ULL,
0x3FD294062ED59F05ULL, 0x3FEE9F4156C62DDBULL, 0xBFEE9F4156C62DDAULL, 0x3FD294062ED59F06ULL,
0x3FEE9F4156C62DDAULL, 0x3FD294062ED59F05ULL, 0xBFD294062ED59F02ULL, 0x3FEE9F4156C62DDBULL,
0x3FDE2B5D3806F63EULL, 0x3FEC38B2F180BDB0ULL, 0xBFEC38B2F180BDB0ULL, 0x3FDE2B5D3806F63FULL,
0x3FE8BC806B151741ULL, 0x3FE44CF325091DD6ULL, 0xBFE44CF325091DD5ULL, 0x3FE8BC806B151742ULL,
0x3FB917A6BC29B438ULL, 0x3FEFD88DA3D12525ULL, 0xBFEFD88DA3D12525ULL, 0x3FB917A6BC29B43CULL,
0x3FEFF621E3796D7EULL, 0x3FA91F65F10DD814ULL, 0xBFA91F65F10DD813ULL, 0x3FEFF621E3796D7EULL,
0x3FE57D69348CEC9FULL, 0x3FE7B5DF226AAFAFULL, 0xBFE7B5DF226AAFADULL, 0x3FE57D69348CECA1ULL,
0x3FECED7AF43CC773ULL, 0x3FDB5D1009E15CC0ULL, 0xBFDB5D1009E15CBCULL, 0x3FECED7AF43CC774ULL,
0x3FD58F9A75AB1FDDULL, 0x3FEE212104F686E5ULL, 0xBFEE212104F686E4ULL, 0x3FD58F9A75AB1FE2ULL,
0x3FEF0A7EFB9230D7ULL, 0x3FCF19F97B215F1AULL, 0xBFCF19F97B215F1AULL, 0x3FEF0A7EFB9230D7ULL,
0x3FE073879922FFEDULL, 0x3FEB728345196E3EULL, 0xBFEB728345196E3DULL, 0x3FE073879922FFEEULL,
0x3FE9B3E047F38741ULL, 0x3FE30FF7FCE17035ULL, 0xBFE30FF7FCE17035ULL, 0x3FE9B3E047F38741ULL,
0x3FC2C8106E8E613AULL, 0x3FEFA7557F08A517ULL, 0xBFEFA7557F08A517ULL, 0x3FC2C8106E8E613CULL,
0x3FEFA7557F08A517ULL, 0x3FC2C8106E8E613AULL, 0xBFC2C8106E8E6136ULL, 0x3FEFA7557F08A517ULL,
0x3FE30FF7FCE17036ULL, 0x3FE9B3E047F38740ULL, 0xBFE9B3E047F38740ULL, 0x3FE30FF7FCE17036ULL,
0x3FEB728345196E3EULL, 0x3FE073879922FFEDULL, 0xBFE073879922FFEDULL, 0x3FEB728345196E3EULL,
0x3FCF19F97B215F1EULL, 0x3FEF0A7EFB9230D7ULL, 0xBFEF0A7EFB9230D7ULL, 0x3FCF19F97B215F21ULL,
0x3FEE212104F686E5ULL, 0x3FD58F9A75AB1FDDULL, 0xBFD58F9A75AB1FDBULL, 0x3FEE212104F686E5ULL,
0x3FDB5D1009E15CC2ULL, 0x3FECED7AF43CC773ULL, 0xBFECED7AF43CC773ULL, 0x3FDB5D1009E15CBFULL,
0x3FE7B5DF226AAFAFULL, 0x3FE57D69348CEC9FULL, 0xBFE57D69348CECA0ULL, 0x3FE7B5DF226AAFAEULL,
0x3FA91F65F10DD824ULL, 0x3FEFF621E3796D7EULL, 0xBFEFF621E3796D7EULL, 0x3FA91F65F10DD80DULL,
0x3FEFFD886084CD0DULL, 0x3F992155F7A3667EULL, 0xBF992155F7A36654ULL, 0x3FEFFD886084CD0DULL,
0x3FE610B7551D2CDFULL, 0x3FE72D0837EFFF96ULL, 0xBFE72D0837EFFF95ULL, 0x3FE610B7551D2CE0ULL,
0x3FED4134D14DC93AULL, 0x3FD9EF7943A8ED8AULL, 0xBFD9EF7943A8ED88ULL, 0x3FED4134D14DC93AULL,
0x3FD7088530FA45A1ULL, 0x3FEDDB13B6CCC23CULL, 0xBFEDDB13B6CCC23CULL, 0x3FD7088530FA45A2ULL,
0x3FEF38F3AC64E589ULL, 0x3FCC0B826A7E4F63ULL, 0xBFCC0B826A7E4F5EULL, 0x3FEF38F3AC64E589ULL,
0x3FE11EB3541B4B23ULL, 0x3FEB090A581501FFULL, 0xBFEB090A58150200ULL, 0x3FE11EB3541B4B22ULL,
0x3FEA29A7A0462782ULL, 0x3FE26D054CDD12DFULL, 0xBFE26D054CDD12DFULL, 0x3FEA29A7A0462782ULL,
0x3FC5E214448B3FCBULL, 0x3FEF8764FA714BA9ULL, 0xBFEF8764FA714BA9ULL, 0x3FC5E214448B3FC6ULL,
0x3FEFC26470E19FD3ULL, 0x3FBF564E56A9730EULL, 0xBFBF564E56A9730BULL, 0x3FEFC26470E19FD3ULL,
0x3FE3AFFA292050B9ULL, 0x3FE93A22499263FBULL, 0xBFE93A22499263FBULL, 0x3FE3AFFA292050BAULL,
0x3FEBD7C0AC6F952AULL, 0x3FDF8BA4DBF89ABAULL, 0xBFDF8BA4DBF89AB9ULL, 0x3FEBD7C0AC6F952AULL,
0x3FD111D262B1F678ULL, 0x3FEED740E7684963ULL, 0xBFEED740E7684963ULL, 0x3FD111D262B1F679ULL,
0x3FEE6288EC48E112ULL, 0x3FD4135C94176602ULL, 0xBFD4135C94176600ULL, 0x3FEE6288EC48E112ULL,
0x3FDCC66E9931C45EULL, 0x3FEC954B213411F5ULL, 0xBFEC954B213411F4ULL, 0x3FDCC66E9931C463ULL,
0x3FE83B0E0BFF976EULL, 0x3FE4E6CABBE3E5E9ULL, 0xBFE4E6CABBE3E5E7ULL, 0x3FE83B0E0BFF976FULL,
0x3FB2D52092CE19F8ULL, 0x3FEFE9CDAD01883AULL, 0xBFEFE9CDAD01883AULL, 0x3FB2D52092CE1A0CULL,
0x3FEFE9CDAD01883AULL, 0x3FB2D52092CE19F6ULL, 0xBFB2D52092CE19EFULL, 0x3FEFE9CDAD01883AULL,
0x3FE4E6CABBE3E5E9ULL, 0x3FE83B0E0BFF976DULL, 0xBFE83B0E0BFF976EULL, 0x3FE4E6CABBE3E5E8ULL,
0x3FEC954B213411F5ULL, 0x3FDCC66E9931C45DULL, 0xBFDCC66E9931C460ULL, 0x3FEC954B213411F4ULL,
0x3FD4135C94176603ULL, 0x3FEE6288EC48E112ULL, 0xBFEE6288EC48E112ULL, 0x3FD4135C94176600ULL,
0x3FEED740E7684963ULL, 0x3FD111D262B1F677ULL, 0xBFD111D262B1F676ULL, 0x3FEED740E7684963ULL,
0x3FDF8BA4DBF89ABBULL, 0x3FEBD7C0AC6F9529ULL, 0xBFEBD7C0AC6F9529ULL, 0x3FDF8BA4DBF89ABCULL,
0x3FE93A22499263FCULL, 0x3FE3AFFA292050B9ULL, 0xBFE3AFFA292050B8ULL, 0x3FE93A22499263FCULL,
0x3FBF564E56A97314ULL, 0x3FEFC26470E19FD3ULL, 0xBFEFC26470E19FD3ULL, 0x3FBF564E56A97319ULL,
0x3FEF8764FA714BA9ULL, 0x3FC5E214448B3FC6ULL, 0xBFC5E214448B3FC7ULL, 0x3FEF8764FA714BA9ULL,
0x3FE26D054CDD12DFULL, 0x3FEA29A7A0462782ULL, 0xBFEA29A7A0462781ULL, 0x3FE26D054CDD12E0ULL,
0x3FEB090A58150200ULL, 0x3FE11EB3541B4B22ULL, 0xBFE11EB3541B4B21ULL, 0x3FEB090A58150201ULL,
0x3FCC0B826A7E4F62ULL, 0x3FEF38F3AC64E589ULL, 0xBFEF38F3AC64E588ULL, 0x3FCC0B826A7E4F6CULL,
0x3FEDDB13B6CCC23DULL, 0x3FD7088530FA459EULL, 0xBFD7088530FA459FULL, 0x3FEDDB13B6CCC23CULL,
0x3FD9EF7943A8ED8AULL, 0x3FED4134D14DC93AULL, 0xBFED4134D14DC93AULL, 0x3FD9EF7943A8ED8BULL,
0x3FE72D0837EFFF97ULL, 0x3FE610B7551D2CDEULL, 0xBFE610B7551D2CDFULL, 0x3FE72D0837EFFF96ULL,
0x3F992155F7A36677ULL, 0x3FEFFD886084CD0DULL, 0xBFEFFD886084CD0DULL, 0x3F992155F7A36689ULL,
0x3FEFFF62169B92DBULL, 0x3F8921D1FCDEC784ULL, 0xBF8921D1FCDEC749ULL, 0x3FEFFF62169B92DBULL,
0x3FE6591925F0783EULL, 0x3FE6E74454EAA8AEULL, 0xBFE6E74454EAA8AEULL, 0x3FE6591925F0783EULL,
0x3FED696173C9E68BULL, 0x3FD9372A63BC93D7ULL, 0xBFD9372A63BC93D5ULL, 0x3FED696173C9E68BULL,
0x3FD7C3A9311DCCE8ULL, 0x3FEDB6526238A09AULL, 0xBFEDB6526238A09AULL, 0x3FD7C3A9311DCCEAULL,
0x3FEF4E603B0B2F2DULL, 0x3FCA82A025B00451ULL, 0xBFCA82A025B0044DULL, 0x3FEF4E603B0B2F2DULL,
0x3FE1734D63DEDB49ULL, 0x3FEAD2BC9E21D510ULL, 0xBFEAD2BC9E21D511ULL, 0x3FE1734D63DEDB48ULL,
0x3FEA63091B02FAE2ULL, 0x3FE21A799933EB58ULL, 0xBFE21A799933EB59ULL, 0x3FEA63091B02FAE1ULL,
0x3FC76DD9DE50BF35ULL, 0x3FEF7599A3A12077ULL, 0xBFEF7599A3A12077ULL, 0x3FC76DD9DE50BF2FULL,
0x3FEFCE15FD6DA67BULL, 0x3FBC3785C79EC2D5ULL, 0xBFBC3785C79EC2D5ULL, 0x3FEFCE15FD6DA67BULL,
0x3FE3FED9534556D5ULL, 0x3FE8FBCCA3EF940CULL, 0xBFE8FBCCA3EF940DULL, 0x3FE3FED9534556D4ULL,
0x3FEC08C426725549ULL, 0x3FDEDC1952EF78D5ULL, 0xBFDEDC1952EF78D5ULL, 0x3FEC08C426725549ULL,
0x3FD1D3443F4CDB3DULL, 0x3FEEBBD8C8DF0B74ULL, 0xBFEEBBD8C8DF0B74ULL, 0x3FD1D3443F4CDB3FULL,
0x3FEE817BAB4CD10DULL, 0x3FD35410C2E18152ULL, 0xBFD35410C2E18152ULL, 0x3FEE817BAB4CD10DULL,
0x3FDD79775B86E389ULL, 0x3FEC678B3488739BULL, 0xBFEC678B3488739AULL, 0x3FDD79775B86E38DULL,
0x3FE87C400FBA2EBFULL, 0x3FE49A449B9B0938ULL, 0xBFE49A449B9B0937ULL, 0x3FE87C400FBA2EC0ULL,
0x3FB5F6D00A9AA418ULL, 0x3FEFE1CAFCBD5B09ULL, 0xBFEFE1CAFCBD5B09ULL, 0x3FB5F6D00A9AA42CULL,
0x3FEFF095658E71ADULL, 0x3FAF656E79F820E0ULL, 0xBFAF656E79F820D9ULL, 0x3FEFF095658E71ADULL,
0x3FE5328292A35596ULL, 0x3FE7F8ECE3571770ULL, 0xBFE7F8ECE357176FULL, 0x3FE5328292A35598ULL,
0x3FECC1F0F3FCFC5CULL, 0x3FDC1249D8011EE7ULL, 0xBFDC1249D8011EE2ULL, 0x3FECC1F0F3FCFC5DULL,
0x3FD4D1E24278E76BULL, 0x3FEE426A4B2BC17EULL, 0xBFEE426A4B2BC17DULL, 0x3FD4D1E24278E770ULL,
0x3FEEF178A3E473C2ULL, 0x3FD04FB80E37FDAEULL, 0xBFD04FB80E37FDADULL, 0x3FEEF178A3E473C2ULL,
0x3FE01CFC874C3EB7ULL, 0x3FEBA5AA673590D2ULL, 0xBFEBA5AA673590D2ULL, 0x3FE01CFC874C3EB8ULL,
0x3FE9777EF4C7D742ULL, 0x3FE36058B10659F3ULL, 0xBFE36058B10659F2ULL, 0x3FE9777EF4C7D742ULL,
0x3FC139F0CEDAF578ULL, 0x3FEFB5797195D741ULL, 0xBFEFB5797195D741ULL, 0x3FC139F0CEDAF57AULL,
0x3FEF97F924C9099BULL, 0x3FC45576B1293E5AULL, 0xBFC45576B1293E54ULL, 0x3FEF97F924C9099BULL,
0x3FE2BEDB25FAF3EAULL, 0x3FE9EF43EF29AF94ULL, 0xBFE9EF43EF29AF93ULL, 0x3FE2BEDB25FAF3EBULL,
0x3FEB3E4D3EF55712ULL, 0x3FE0C9704D5D898FULL, 0xBFE0C9704D5D898DULL, 0x3FEB3E4D3EF55712ULL,
0x3FCD934FE5454317ULL, 0x3FEF2252F7763AD9ULL, 0xBFEF2252F7763AD9ULL, 0x3FCD934FE5454319ULL,
0x3FEDFEAE622DBE2BULL, 0x3FD64C7DDD3F27C6ULL, 0xBFD64C7DDD3F27C3ULL, 0x3FEDFEAE622DBE2BULL,
0x3FDAA6C82B6D3FCCULL, 0x3FED17E7743E35DBULL, 0xBFED17E7743E35DCULL, 0x3FDAA6C82B6D3FC9ULL,
0x3FE771E75F037261ULL, 0x3FE5C77BBE65018CULL, 0xBFE5C77BBE65018CULL, 0x3FE771E75F037261ULL,
0x3FA2D865759455E4ULL, 0x3FEFFA72EFFEF75DULL, 0xBFEFFA72EFFEF75DULL, 0x3FA2D865759455CDULL,
0x3FEFFA72EFFEF75DULL, 0x3FA2D865759455CDULL, 0xBFA2D865759455D2ULL, 0x3FEFFA72EFFEF75DULL,
0x3FE5C77BBE65018DULL, 0x3FE771E75F037261ULL, 0xBFE771E75F037260ULL, 0x3FE5C77BBE65018EULL,
0x3FED17E7743E35DCULL, 0x3FDAA6C82B6D3FC9ULL, 0xBFDAA6C82B6D3FC6ULL, 0x3FED17E7743E35DDULL,
0x3FD64C7DDD3F27C5ULL, 0x3FEDFEAE622DBE2BULL, 0xBFEDFEAE622DBE2AULL, 0x3FD64C7DDD3F27CAULL,
0x3FEF2252F7763ADAULL, 0x3FCD934FE5454311ULL, 0xBFCD934FE5454312ULL, 0x3FEF2252F7763ADAULL,
0x3FE0C9704D5D898EULL, 0x3FEB3E4D3EF55712ULL, 0xBFEB3E4D3EF55712ULL, 0x3FE0C9704D5D898FULL,
0x3FE9EF43EF29AF94ULL, 0x3FE2BEDB25FAF3EAULL, 0xBFE2BEDB25FAF3EAULL, 0x3FE9EF43EF29AF94ULL,
0x3FC45576B1293E58ULL, 0x3FEF97F924C9099BULL, 0xBFEF97F924C9099BULL, 0x3FC45576B1293E5BULL,
0x3FEFB5797195D741ULL, 0x3FC139F0CEDAF576ULL, 0xBFC139F0CEDAF574ULL, 0x3FEFB5797195D741ULL,
0x3FE36058B10659F3ULL, 0x3FE9777EF4C7D741ULL, 0xBFE9777EF4C7D741ULL, 0x3FE36058B10659F4ULL,
0x3FEBA5AA673590D3ULL, 0x3FE01CFC874C3EB7ULL, 0xBFE01CFC874C3EB6ULL, 0x3FEBA5AA673590D3ULL,
0x3FD04FB80E37FDAFULL, 0x3FEEF178A3E473C2ULL, 0xBFEEF178A3E473C2ULL, 0x3FD04FB80E37FDB0ULL,
0x3FEE426A4B2BC17EULL, 0x3FD4D1E24278E76AULL, 0xBFD4D1E24278E769ULL, 0x3FEE426A4B2BC17FULL,
0x3FDC1249D8011EE8ULL, 0x3FECC1F0F3FCFC5CULL, 0xBFECC1F0F3FCFC5DULL, 0x3FDC1249D8011EE5ULL,
0x3FE7F8ECE3571771ULL, 0x3FE5328292A35596ULL, 0xBFE5328292A35597ULL, 0x3FE7F8ECE3571770ULL,
0x3FAF656E79F820EAULL, 0x3FEFF095658E71ADULL, 0xBFEFF095658E71ADULL, 0x3FAF656E79F820D3ULL,
0x3FEFE1CAFCBD5B09ULL, 0x3FB5F6D00A9AA419ULL, 0xBFB5F6D00A9AA40FULL, 0x3FEFE1CAFCBD5B09ULL,
0x3FE49A449B9B0939ULL, 0x3FE87C400FBA2EBFULL, 0xBFE87C400FBA2EBFULL, 0x3FE49A449B9B0938ULL,
0x3FEC678B3488739BULL, 0x3FDD79775B86E389ULL, 0xBFDD79775B86E38AULL, 0x3FEC678B3488739BULL,
0x3FD35410C2E18154ULL, 0x3FEE817BAB4CD10CULL, 0xBFEE817BAB4CD10DULL, 0x3FD35410C2E18151ULL,
0x3FEEBBD8C8DF0B74ULL, 0x3FD1D3443F4CDB3DULL, 0xBFD1D3443F4CDB3BULL, 0x3FEEBBD8C8DF0B75ULL,
0x3FDEDC1952EF78D7ULL, 0x3FEC08C426725549ULL, 0xBFEC08C426725548ULL, 0x3FDEDC1952EF78D8ULL,
0x3FE8FBCCA3EF940DULL, 0x3FE3FED9534556D4ULL, 0xBFE3FED9534556D3ULL, 0x3FE8FBCCA3EF940EULL,
0x3FBC3785C79EC2DEULL, 0x3FEFCE15FD6DA67BULL, 0xBFEFCE15FD6DA67BULL, 0x3FBC3785C79EC2E2ULL,
0x3FEF7599A3A12077ULL, 0x3FC76DD9DE50BF31ULL, 0xBFC76DD9DE50BF30ULL, 0x3FEF7599A3A12077ULL,
0x3FE21A799933EB59ULL, 0x3FEA63091B02FAE2ULL, 0xBFEA63091B02FAE0ULL, 0x3FE21A799933EB5BULL,
0x3FEAD2BC9E21D511ULL, 0x3FE1734D63DEDB49ULL, 0xBFE1734D63DEDB47ULL, 0x3FEAD2BC9E21D512ULL,
0x3FCA82A025B00451ULL, 0x3FEF4E603B0B2F2DULL, 0xBFEF4E603B0B2F2CULL, 0x3FCA82A025B0045BULL,
0x3FEDB6526238A09BULL, 0x3FD7C3A9311DCCE7ULL, 0xBFD7C3A9311DCCE6ULL, 0x3FEDB6526238A09BULL,
0x3FD9372A63BC93D7ULL, 0x3FED696173C9E68BULL, 0xBFED696173C9E68BULL, 0x3FD9372A63BC93D8ULL,
0x3FE6E74454EAA8AEULL, 0x3FE6591925F0783EULL, 0xBFE6591925F0783DULL, 0x3FE6E74454EAA8AFULL,
0x3F8921D1FCDEC78FULL, 0x3FEFFF62169B92DBULL, 0xBFEFFF62169B92DBULL, 0x3F8921D1FCDEC7B3ULL,
0x3FEFFFD8858E8A92ULL, 0x3F7921F0FE670071ULL, 0xBF7921F0FE670012ULL, 0x3FEFFFD8858E8A92ULL,
0x3FE67CF78491AF10ULL, 0x3FE6C40D73C18275ULL, 0xBFE6C40D73C18276ULL, 0x3FE67CF78491AF0FULL,
0x3FED7D0B02B8ECFAULL, 0x3FD8DAA52EC8A4AFULL, 0xBFD8DAA52EC8A4AEULL, 0x3FED7D0B02B8ECFAULL,
0x3FD820E3B04EAAC5ULL, 0x3FEDA383A9668987ULL, 0xBFEDA383A9668988ULL, 0x3FD820E3B04EAAC2ULL,
0x3FEF58A2B1789E84ULL, 0x3FC9BDCBF2DC4366ULL, 0xBFC9BDCBF2DC4363ULL, 0x3FEF58A2B1789E84ULL,
0x3FE19D5A09F2B9B8ULL, 0x3FEAB7325916C0D4ULL, 0xBFEAB7325916C0D4ULL, 0x3FE19D5A09F2B9B9ULL,
0x3FEA7F58529FE69DULL, 0x3FE1F0F08BBC861BULL, 0xBFE1F0F08BBC861AULL, 0x3FEA7F58529FE69DULL,
0x3FC83366E89C64C8ULL, 0x3FEF6C3F7DF5BBB7ULL, 0xBFEF6C3F7DF5BBB7ULL, 0x3FC83366E89C64CBULL,
0x3FEFD37914220B84ULL, 0x3FBAA7B724495C04ULL, 0xBFBAA7B724495C05ULL, 0x3FEFD37914220B84ULL,
0x3FE425FF178E6BB2ULL, 0x3FE8DC45331698CCULL, 0xBFE8DC45331698CBULL, 0x3FE425FF178E6BB3ULL,
0x3FEC20DE3FA971B0ULL, 0x3FDE83E0EAF85113ULL, 0xBFDE83E0EAF85110ULL, 0x3FEC20DE3FA971B0ULL,
0x3FD233BBABC3BB71ULL, 0x3FEEADB2E8E7A88EULL, 0xBFEEADB2E8E7A88DULL, 0x3FD233BBABC3BB76ULL,
0x3FEE9084361DF7F3ULL, 0x3FD2F422DAEC0386ULL, 0xBFD2F422DAEC0387ULL, 0x3FEE9084361DF7F2ULL,
0x3FDDD28F1481CC57ULL, 0x3FEC5042012B6907ULL, 0xBFEC5042012B6907ULL, 0x3FDDD28F1481CC58ULL,
0x3FE89C7E9A4DD4ABULL, 0x3FE473B51B987347ULL, 0xBFE473B51B987347ULL, 0x3FE89C7E9A4DD4AAULL,
0x3FB787586A5D5B1FULL, 0x3FEFDD539FF1F456ULL, 0xBFEFDD539FF1F456ULL, 0x3FB787586A5D5B23ULL,
0x3FEFF3830F8D575CULL, 0x3FAC428D12C0D7E2ULL, 0xBFAC428D12C0D7DFULL, 0x3FEFF3830F8D575CULL,
0x3FE5581038975137ULL, 0x3FE7D7836CC33DB2ULL, 0xBFE7D7836CC33DB2ULL, 0x3FE5581038975138ULL,
0x3FECD7D9898B32F6ULL, 0x3FDBB7CF2304BD01ULL, 0xBFDBB7CF2304BD00ULL, 0x3FECD7D9898B32F6ULL,
0x3FD530D880AF3C24ULL, 0x3FEE31EAE870CE25ULL, 0xBFEE31EAE870CE25ULL, 0x3FD530D880AF3C25ULL,
0x3FEEFE220C0B95EDULL, 0x3FCFDCDC1ADFEDF8ULL, 0xBFCFDCDC1ADFEDF7ULL, 0x3FEEFE220C0B95EDULL,
0x3FE0485626AE221AULL, 0x3FEB8C38D27504E9ULL, 0xBFEB8C38D27504E7ULL, 0x3FE0485626AE221DULL,
0x3FE995CF2ED80D22ULL, 0x3FE338400D0C8E57ULL, 0xBFE338400D0C8E55ULL, 0x3FE995CF2ED80D24ULL,
0x3FC20116D4EC7BCFULL, 0x3FEFAE8E8E46CFBBULL, 0xBFEFAE8E8E46CFBAULL, 0x3FC20116D4EC7BDAULL,
0x3FEF9FCE55ADB2C8ULL, 0x3FC38EDBB0CD8D14ULL, 0xBFC38EDBB0CD8D0FULL, 0x3FEF9FCE55ADB2C8ULL,
0x3FE2E780E3E8EA17ULL, 0x3FE9D1B1F5EA80D5ULL, 0xBFE9D1B1F5EA80D6ULL, 0x3FE2E780E3E8EA16ULL,
0x3FEB5889FE921405ULL, 0x3FE09E907417C5E1ULL, 0xBFE09E907417C5E1ULL, 0x3FEB5889FE921405ULL,
0x3FCE56CA1E101A20ULL, 0x3FEF168F53F7205DULL, 0xBFEF168F53F7205DULL, 0x3FCE56CA1E101A1AULL,
0x3FEE100CCA2980ACULL, 0x3FD5EE27379EA693ULL, 0xBFD5EE27379EA691ULL, 0x3FEE100CCA2980ACULL,
0x3FDB020D6C7F400BULL, 0x3FED02D4FEB2BD92ULL, 0xBFED02D4FEB2BD92ULL, 0x3FDB020D6C7F400CULL,
0x3FE79400574F55E5ULL, 0x3FE5A28D2A5D7250ULL, 0xBFE5A28D2A5D724FULL, 0x3FE79400574F55E6ULL,
0x3FA5FC00D290CD57ULL, 0x3FEFF871DADB81DFULL, 0xBFEFF871DADB81DFULL, 0x3FA5FC00D290CD60ULL,
0x3FEFFC251DF1D3F8ULL, 0x3F9F693731D1CF01ULL, 0xBF9F693731D1CED1ULL, 0x3FEFFC251DF1D3F8ULL,
0x3FE5EC3495837074ULL, 0x3FE74F948DA8D28DULL, 0xBFE74F948DA8D28DULL, 0x3FE5EC3495837074ULL,
0x3FED2CB220E0EF9FULL, 0x3FDA4B4127DEA1E4ULL, 0xBFDA4B4127DEA1E2ULL, 0x3FED2CB220E0EF9FULL,
0x3FD6AA9D7DC77E19ULL, 0x3FEDED05F7DE47D9ULL, 0xBFEDED05F7DE47DAULL, 0x3FD6AA9D7DC77E17ULL,
0x3FEF2DC9C9089A9DULL, 0x3FCCCF8CB312B286ULL, 0xBFCCCF8CB312B280ULL, 0x3FEF2DC9C9089A9DULL,
0x3FE0F426BB2A8E7FULL, 0x3FEB23CD470013B3ULL, 0xBFEB23CD470013B3ULL, 0x3FE0F426BB2A8E7FULL,
0x3FEA0C95EABAF937ULL, 0x3FE2960727629CA8ULL, 0xBFE2960727629CA7ULL, 0x3FEA0C95EABAF938ULL,
0x3FC51BDF8597C5F8ULL, 0x3FEF8FD5FFAE41DBULL, 0xBFEF8FD5FFAE41DAULL, 0x3FC51BDF8597C5FAULL,
0x3FEFBC1617E44186ULL, 0x3FC072A047BA831DULL, 0xBFC072A047BA831BULL, 0x3FEFBC1617E44186ULL,
0x3FE3884185DFEB22ULL, 0x3FE958EFE48E6DD7ULL, 0xBFE958EFE48E6DD5ULL, 0x3FE3884185DFEB24ULL,
0x3FEBBED7C49380EAULL, 0x3FDFE2F64BE71210ULL, 0xBFDFE2F64BE7120BULL, 0x3FEBBED7C49380EBULL,
0x3FD0B0D9CFDBDB91ULL, 0x3FEEE482E25A9DBCULL, 0xBFEEE482E25A9DBBULL, 0x3FD0B0D9CFDBDB96ULL,
0x3FEE529F04729FFCULL, 0x3FD472B8A5571054ULL, 0xBFD472B8A5571053ULL, 0x3FEE529F04729FFDULL,
0x3FDC6C7F4997000BULL, 0x3FECABC169A0B900ULL, 0xBFECABC169A0B900ULL, 0x3FDC6C7F4997000CULL,
0x3FE81A1B33B57ACCULL, 0x3FE50CC09F59A09BULL, 0xBFE50CC09F59A09BULL, 0x3FE81A1B33B57ACCULL,
0x3FB1440134D709B6ULL, 0x3FEFED58ECB673C4ULL, 0xBFEFED58ECB673C4ULL, 0x3FB1440134D709BBULL,
0x3FEFE5F3AF2E3940ULL, 0x3FB4661179272096ULL, 0xBFB466117927208EULL, 0x3FEFE5F3AF2E3941ULL,
0x3FE4C0A145EC0005ULL, 0x3FE85BC51AE958CCULL, 0xBFE85BC51AE958CBULL, 0x3FE4C0A145EC0005ULL,
0x3FEC7E8E52233CF3ULL, 0x3FDD2016E8E9DB5BULL, 0xBFDD2016E8E9DB59ULL, 0x3FEC7E8E52233CF4ULL,
0x3FD3B3CEFA0414B9ULL, 0x3FEE7227DB6A9744ULL, 0xBFEE7227DB6A9744ULL, 0x3FD3B3CEFA0414BAULL,
0x3FEEC9B2D3C3BF84ULL, 0x3FD172A0D7765177ULL, 0xBFD172A0D7765175ULL, 0x3FEEC9B2D3C3BF84ULL,
0x3FDF3405963FD069ULL, 0x3FEBF064E15377DDULL, 0xBFEBF064E15377DDULL, 0x3FDF3405963FD066ULL,
0x3FE91B166FD49DA2ULL, 0x3FE3D78238C58343ULL, 0xBFE3D78238C58344ULL, 0x3FE91B166FD49DA1ULL,
0x3FBDC70ECBAE9FD1ULL, 0x3FEFC8646CFEB721ULL, 0xBFEFC8646CFEB721ULL, 0x3FBDC70ECBAE9FC5ULL,
0x3FEF7EA629E63D6EULL, 0x3FC6A81304F64AB2ULL, 0xBFC6A81304F64AB2ULL, 0x3FEF7EA629E63D6EULL,
0x3FE243D5FB98AC20ULL, 0x3FEA4678C8119AC8ULL, 0xBFEA4678C8119AC8ULL, 0x3FE243D5FB98AC1FULL,
0x3FEAEE04B43C1474ULL, 0x3FE14915AF336CEBULL, 0xBFE14915AF336CEBULL, 0x3FEAEE04B43C1474ULL,
0x3FCB4732EF3D6722ULL, 0x3FEF43D085FF92DDULL, 0xBFEF43D085FF92DDULL, 0x3FCB4732EF3D6724ULL,
0x3FEDC8D7CB410260ULL, 0x3FD766340F2418F6ULL, 0xBFD766340F2418F6ULL, 0x3FEDC8D7CB410260ULL,
0x3FD993716141BDFEULL, 0x3FED556F52E93EB1ULL, 0xBFED556F52E93EB0ULL, 0x3FD993716141BE03ULL,
0x3FE70A42B3176D7AULL, 0x3FE63503A31C1BE9ULL, 0xBFE63503A31C1BE7ULL, 0x3FE70A42B3176D7BULL,
0x3F92D936BBE30EFDULL, 0x3FEFFE9CB44B51A1ULL, 0xBFEFFE9CB44B51A1ULL, 0x3F92D936BBE30F4EULL,
0x3FEFFE9CB44B51A1ULL, 0x3F92D936BBE30EFDULL, 0xBF92D936BBE30ED9ULL, 0x3FEFFE9CB44B51A1ULL,
0x3FE63503A31C1BE9ULL, 0x3FE70A42B3176D7AULL, 0xBFE70A42B3176D7AULL, 0x3FE63503A31C1BE9ULL,
0x3FED556F52E93EB1ULL, 0x3FD993716141BDFEULL, 0xBFD993716141BDFCULL, 0x3FED556F52E93EB1ULL,
0x3FD766340F2418F8ULL, 0x3FEDC8D7CB410260ULL, 0xBFEDC8D7CB410260ULL, 0x3FD766340F2418F5ULL,
0x3FEF43D085FF92DDULL, 0x3FCB4732EF3D6722ULL, 0xBFCB4732EF3D671EULL, 0x3FEF43D085FF92DDULL,
0x3FE14915AF336CECULL, 0x3FEAEE04B43C1473ULL, 0xBFEAEE04B43C1473ULL, 0x3FE14915AF336CECULL,
0x3FEA4678C8119AC8ULL, 0x3FE243D5FB98AC1FULL, 0xBFE243D5FB98AC1EULL, 0x3FEA4678C8119AC9ULL,
0x3FC6A81304F64AB6ULL, 0x3FEF7EA629E63D6EULL, 0xBFEF7EA629E63D6EULL, 0x3FC6A81304F64AB9ULL,
0x3FEFC8646CFEB721ULL, 0x3FBDC70ECBAE9FC8ULL, 0xBFBDC70ECBAE9FC8ULL, 0x3FEFC8646CFEB721ULL,
0x3FE3D78238C58344ULL, 0x3FE91B166FD49DA2ULL, 0xBFE91B166FD49DA0ULL, 0x3FE3D78238C58346ULL,
0x3FEBF064E15377DDULL, 0x3FDF3405963FD068ULL, 0xBFDF3405963FD063ULL, 0x3FEBF064E15377DEULL,
0x3FD172A0D7765177ULL, 0x3FEEC9B2D3C3BF84ULL, 0xBFEEC9B2D3C3BF83ULL, 0x3FD172A0D776517CULL,
0x3FEE7227DB6A9744ULL, 0x3FD3B3CEFA0414B7ULL, 0xBFD3B3CEFA0414B7ULL, 0x3FEE7227DB6A9744ULL,
0x3FDD2016E8E9DB5BULL, 0x3FEC7E8E52233CF3ULL, 0xBFEC7E8E52233CF3ULL, 0x3FDD2016E8E9DB5CULL,
0x3FE85BC51AE958CCULL, 0x3FE4C0A145EC0004ULL, 0xBFE4C0A145EC0004ULL, 0x3FE85BC51AE958CDULL,
0x3FB4661179272096ULL, 0x3FEFE5F3AF2E3940ULL, 0xBFEFE5F3AF2E3940ULL, 0x3FB466117927209BULL,
0x3FEFED58ECB673C4ULL, 0x3FB1440134D709B2ULL, 0xBFB1440134D709ADULL, 0x3FEFED58ECB673C4ULL,
0x3FE50CC09F59A09BULL, 0x3FE81A1B33B57ACBULL, 0xBFE81A1B33B57ACBULL, 0x3FE50CC09F59A09CULL,
0x3FECABC169A0B901ULL, 0x3FDC6C7F4997000AULL, 0xBFDC6C7F49970009ULL, 0x3FECABC169A0B901ULL,
0x3FD472B8A5571055ULL, 0x3FEE529F04729FFCULL, 0xBFEE529F04729FFCULL, 0x3FD472B8A5571056ULL,
0x3FEEE482E25A9DBCULL, 0x3FD0B0D9CFDBDB90ULL, 0xBFD0B0D9CFDBDB8FULL, 0x3FEEE482E25A9DBCULL,
0x3FDFE2F64BE71210ULL, 0x3FEBBED7C49380EAULL, 0xBFEBBED7C49380EBULL, 0x3FDFE2F64BE7120EULL,
0x3FE958EFE48E6DD7ULL, 0x3FE3884185DFEB22ULL, 0xBFE3884185DFEB23ULL, 0x3FE958EFE48E6DD6ULL,
0x3FC072A047BA831FULL, 0x3FEFBC1617E44186ULL, 0xBFEFBC1617E44186ULL, 0x3FC072A047BA831AULL,
0x3FEF8FD5FFAE41DBULL, 0x3FC51BDF8597C5F2ULL, 0xBFC51BDF8597C5F3ULL, 0x3FEF8FD5FFAE41DBULL,
0x3FE2960727629CA8ULL, 0x3FEA0C95EABAF936ULL, 0xBFEA0C95EABAF937ULL, 0x3FE2960727629CA8ULL,
0x3FEB23CD470013B4ULL, 0x3FE0F426BB2A8E7DULL, 0xBFE0F426BB2A8E7EULL, 0x3FEB23CD470013B4ULL,
0x3FCCCF8CB312B284ULL, 0x3FEF2DC9C9089A9DULL, 0xBFEF2DC9C9089A9DULL, 0x3FCCCF8CB312B286ULL,
0x3FEDED05F7DE47DAULL, 0x3FD6AA9D7DC77E16ULL, 0xBFD6AA9D7DC77E17ULL, 0x3FEDED05F7DE47DAULL,
0x3FDA4B4127DEA1E4ULL, 0x3FED2CB220E0EF9FULL, 0xBFED2CB220E0EF9EULL, 0x3FDA4B4127DEA1E8ULL,
0x3FE74F948DA8D28DULL, 0x3FE5EC3495837074ULL, 0xBFE5EC3495837073ULL, 0x3FE74F948DA8D28EULL,
0x3F9F693731D1CEF4ULL, 0x3FEFFC251DF1D3F8ULL, 0xBFEFFC251DF1D3F8ULL, 0x3F9F693731D1CF46ULL,
0x3FEFF871DADB81DFULL, 0x3FA5FC00D290CD43ULL, 0xBFA5FC00D290CD45ULL, 0x3FEFF871DADB81DFULL,
0x3FE5A28D2A5D7251ULL, 0x3FE79400574F55E4ULL, 0xBFE79400574F55E5ULL, 0x3FE5A28D2A5D7250ULL,
0x3FED02D4FEB2BD92ULL, 0x3FDB020D6C7F4009ULL, 0xBFDB020D6C7F4009ULL, 0x3FED02D4FEB2BD92ULL,
0x3FD5EE27379EA693ULL, 0x3FEE100CCA2980ACULL, 0xBFEE100CCA2980ACULL, 0x3FD5EE27379EA694ULL,
0x3FEF168F53F7205DULL, 0x3FCE56CA1E101A1BULL, 0xBFCE56CA1E101A1CULL, 0x3FEF168F53F7205DULL,
0x3FE09E907417C5E0ULL, 0x3FEB5889FE921405ULL, 0xBFEB5889FE921404ULL, 0x3FE09E907417C5E2ULL,
0x3FE9D1B1F5EA80D6ULL, 0x3FE2E780E3E8EA16ULL, 0xBFE2E780E3E8EA15ULL, 0x3FE9D1B1F5EA80D7ULL,
0x3FC38EDBB0CD8D13ULL, 0x3FEF9FCE55ADB2C8ULL, 0xBFEF9FCE55ADB2C8ULL, 0x3FC38EDBB0CD8D1DULL,
0x3FEFAE8E8E46CFBBULL, 0x3FC20116D4EC7BCEULL, 0xBFC20116D4EC7BCBULL, 0x3FEFAE8E8E46CFBBULL,
0x3FE338400D0C8E57ULL, 0x3FE995CF2ED80D22ULL, 0xBFE995CF2ED80D23ULL, 0x3FE338400D0C8E56ULL,
0x3FEB8C38D27504E9ULL, 0x3FE0485626AE221AULL, 0xBFE0485626AE221BULL, 0x3FEB8C38D27504E8ULL,
0x3FCFDCDC1ADFEDFCULL, 0x3FEEFE220C0B95ECULL, 0xBFEEFE220C0B95EDULL, 0x3FCFDCDC1ADFEDF6ULL,
0x3FEE31EAE870CE25ULL, 0x3FD530D880AF3C24ULL, 0xBFD530D880AF3C22ULL, 0x3FEE31EAE870CE25ULL,
0x3FDBB7CF2304BD02ULL, 0x3FECD7D9898B32F6ULL, 0xBFECD7D9898B32F5ULL, 0x3FDBB7CF2304BD03ULL,
0x3FE7D7836CC33DB3ULL, 0x3FE5581038975137ULL, 0xBFE5581038975136ULL, 0x3FE7D7836CC33DB3ULL,
0x3FAC428D12C0D7F0ULL, 0x3FEFF3830F8D575CULL, 0xBFEFF3830F8D575CULL, 0x3FAC428D12C0D7F9ULL,
0x3FEFDD539FF1F456ULL, 0x3FB787586A5D5B21ULL, 0xBFB787586A5D5B16ULL, 0x3FEFDD539FF1F456ULL,
0x3FE473B51B987347ULL, 0x3FE89C7E9A4DD4AAULL, 0xBFE89C7E9A4DD4A9ULL, 0x3FE473B51B987348ULL,
0x3FEC5042012B6907ULL, 0x3FDDD28F1481CC58ULL, 0xBFDDD28F1481CC55ULL, 0x3FEC5042012B6908ULL,
0x3FD2F422DAEC0389ULL, 0x3FEE9084361DF7F2ULL, 0xBFEE9084361DF7F2ULL, 0x3FD2F422DAEC038AULL,
0x3FEEADB2E8E7A88EULL, 0x3FD233BBABC3BB72ULL, 0xBFD233BBABC3BB6FULL, 0x3FEEADB2E8E7A88EULL,
0x3FDE83E0EAF85116ULL, 0x3FEC20DE3FA971AFULL, 0xBFEC20DE3FA971B0ULL, 0x3FDE83E0EAF85113ULL,
0x3FE8DC45331698CCULL, 0x3FE425FF178E6BB1ULL, 0xBFE425FF178E6BB2ULL, 0x3FE8DC45331698CCULL,
0x3FBAA7B724495C0EULL, 0x3FEFD37914220B84ULL, 0xBFEFD37914220B84ULL, 0x3FBAA7B724495C03ULL,
0x3FEF6C3F7DF5BBB7ULL, 0x3FC83366E89C64C5ULL, 0xBFC83366E89C64C4ULL, 0x3FEF6C3F7DF5BBB7ULL,
0x3FE1F0F08BBC861BULL, 0x3FEA7F58529FE69DULL, 0xBFEA7F58529FE69CULL, 0x3FE1F0F08BBC861CULL,
0x3FEAB7325916C0D4ULL, 0x3FE19D5A09F2B9B8ULL, 0xBFE19D5A09F2B9B7ULL, 0x3FEAB7325916C0D5ULL,
0x3FC9BDCBF2DC4368ULL, 0x3FEF58A2B1789E84ULL, 0xBFEF58A2B1789E84ULL, 0x3FC9BDCBF2DC436AULL,
0x3FEDA383A9668988ULL, 0x3FD820E3B04EAAC4ULL, 0xBFD820E3B04EAAC3ULL, 0x3FEDA383A9668988ULL,
0x3FD8DAA52EC8A4B0ULL, 0x3FED7D0B02B8ECF9ULL, 0xBFED7D0B02B8ECF8ULL, 0x3FD8DAA52EC8A4B5ULL,
0x3FE6C40D73C18275ULL, 0x3FE67CF78491AF10ULL, 0xBFE67CF78491AF0EULL, 0x3FE6C40D73C18277ULL,
0x3F7921F0FE67009FULL, 0x3FEFFFD8858E8A92ULL, 0xBFEFFFD8858E8A92ULL, 0x3F7921F0FE6701E6ULL,
0x3FEFFFF621621D02ULL, 0x3F6921F8BECCA4BAULL, 0xBF6921F8BECCA515ULL, 0x3FEFFFF621621D02ULL,
0x3FE68ED1EAA19C72ULL, 0x3FE6B25CED2FE29BULL, 0xBFE6B25CED2FE29AULL, 0x3FE68ED1EAA19C73ULL,
0x3FED86C48445A450ULL, 0x3FD8AC4B86D5ED44ULL, 0xBFD8AC4B86D5ED45ULL, 0x3FED86C48445A44FULL,
0x3FD84F6AAAF3903EULL, 0x3FED9A00DD8B3D46ULL, 0xBFED9A00DD8B3D45ULL, 0x3FD84F6AAAF39043ULL,
0x3FEF5DA6ED43685DULL, 0x3FC95B49E9B62AF9ULL, 0xBFC95B49E9B62AFBULL, 0x3FEF5DA6ED43685DULL,
0x3FE1B250171373BFULL, 0x3FEAA9547A2CB98EULL, 0xBFEAA9547A2CB98EULL, 0x3FE1B250171373BFULL,
0x3FEA8D676E545AD2ULL, 0x3FE1DC1B64DC4872ULL, 0xBFE1DC1B64DC4872ULL, 0x3FEA8D676E545AD2ULL,
0x3FC8961727C41802ULL, 0x3FEF677556883CEEULL, 0xBFEF677556883CEEULL, 0x3FC8961727C41805ULL,
0x3FEFD60D2DA75C9EULL, 0x3FB9DFB6EB24A85CULL, 0xBFB9DFB6EB24A857ULL, 0x3FEFD60D2DA75C9EULL,
0x3FE4397F5B2A4380ULL, 0x3FE8CC6A75184654ULL, 0xBFE8CC6A75184654ULL, 0x3FE4397F5B2A4380ULL,
0x3FEC2CD14931E3F1ULL, 0x3FDE57A86D3CD824ULL, 0xBFDE57A86D3CD823ULL, 0x3FEC2CD14931E3F2ULL,
0x3FD263E6995554BBULL, 0x3FEEA68393E65800ULL, 0xBFEEA68393E65800ULL, 0x3FD263E6995554BCULL,
0x3FEE97EC36016B30ULL, 0x3FD2C41A4E954520ULL, 0xBFD2C41A4E95451FULL, 0x3FEE97EC36016B31ULL,
0x3FDDFEFF66A941DEULL, 0x3FEC44833141C004ULL, 0xBFEC44833141C005ULL, 0x3FDDFEFF66A941DCULL,
0x3FE8AC871EDE1D88ULL, 0x3FE4605A692B32A2ULL, 0xBFE4605A692B32A3ULL, 0x3FE8AC871EDE1D87ULL,
0x3FB84F8712C130A5ULL, 0x3FEFDAFA7514538CULL, 0xBFEFDAFA7514538CULL, 0x3FB84F8712C1309AULL,
0x3FEFF4DC54B1BED3ULL, 0x3FAAB101BD5F8317ULL, 0xBFAAB101BD5F8304ULL, 0x3FEFF4DC54B1BED3ULL,
0x3FE56AC35197649EULL, 0x3FE7C6B89CE2D333ULL, 0xBFE7C6B89CE2D333ULL, 0x3FE56AC35197649EULL,
0x3FECE2B32799A060ULL, 0x3FDB8A7814FD5693ULL, 0xBFDB8A7814FD5695ULL, 0x3FECE2B32799A060ULL,
0x3FD5604012F467B6ULL, 0x3FEE298F4439197AULL, 0xBFEE298F4439197AULL, 0x3FD5604012F467B4ULL,
0x3FEF045A14CF738CULL, 0x3FCF7B7480BD3801ULL, 0xBFCF7B7480BD37FDULL, 0x3FEF045A14CF738CULL,
0x3FE05DF3EC31B8B8ULL, 0x3FEB7F6686E792E9ULL, 0xBFEB7F6686E792E9ULL, 0x3FE05DF3EC31B8B8ULL,
0x3FE9A4DFA42B06B2ULL, 0x3FE32421EC49A61FULL, 0xBFE32421EC49A61EULL, 0x3FE9A4DFA42B06B3ULL,
0x3FC264994DFD340EULL, 0x3FEFAAFBCB0CFDDBULL, 0xBFEFAAFBCB0CFDDBULL, 0x3FC264994DFD3410ULL,
0x3FEFA39BAC7A1791ULL, 0x3FC32B7BF94516A7ULL, 0xBFC32B7BF94516A7ULL, 0x3FEFA39BAC7A1791ULL,
0x3FE2FBC24B441015ULL, 0x3FE9C2D110F075C3ULL, 0xBFE9C2D110F075C1ULL, 0x3FE2FBC24B441017ULL,
0x3FEB658F14FDBC47ULL, 0x3FE089112032B08CULL, 0xBFE089112032B08AULL, 0x3FEB658F14FDBC48ULL,
0x3FCEB86B462DE348ULL, 0x3FEF1090BC898F5FULL, 0xBFEF1090BC898F5EULL, 0x3FCEB86B462DE352ULL,
0x3FEE18A02FDC66D9ULL, 0x3FD5BEE78B9DB3B6ULL, 0xBFD5BEE78B9DB3B6ULL, 0x3FEE18A02FDC66D9ULL,
0x3FDB2F971DB31972ULL, 0x3FECF830E8CE467BULL, 0xBFECF830E8CE467AULL, 0x3FDB2F971DB31973ULL,
0x3FE7A4F707BF97D2ULL, 0x3FE59001D5F723DFULL, 0xBFE59001D5F723DFULL, 0x3FE7A4F707BF97D3ULL,
0x3FA78DBAA5874688ULL, 0x3FEFF753BB1B9164ULL, 0xBFEFF753BB1B9164ULL, 0x3FA78DBAA5874691ULL,
0x3FEFFCE09CE2A679ULL, 0x3F9C454F4CE53B1CULL, 0xBF9C454F4CE53B10ULL, 0x3FEFFCE09CE2A679ULL,
0x3FE5FE7CBDE56A10ULL, 0x3FE73E558E079942ULL, 0xBFE73E558E079940ULL, 0x3FE5FE7CBDE56A11ULL,
0x3FED36FC7BCBFBDCULL, 0x3FDA1D6543B50AC0ULL, 0xBFDA1D6543B50ABFULL, 0x3FED36FC7BCBFBDCULL,
0x3FD6D998638A0CB6ULL, 0x3FEDE4160F6D8D81ULL, 0xBFEDE4160F6D8D80ULL, 0x3FD6D998638A0CBBULL,
0x3FEF33685A3AAEF0ULL, 0x3FCC6D90535D74DCULL, 0xBFCC6D90535D74DBULL, 0x3FEF33685A3AAEF0ULL,
0x3FE1097248D0A957ULL, 0x3FEB16742A4CA2F4ULL, 0xBFEB16742A4CA2F4ULL, 0x3FE1097248D0A957ULL,
0x3FEA1B26D2C0A75EULL, 0x3FE2818BEF4D3CBAULL, 0xBFE2818BEF4D3CB9ULL, 0x3FEA1B26D2C0A75EULL,
0x3FC57F008654CBE0ULL, 0x3FEF8BA737CB4B77ULL, 0xBFEF8BA737CB4B77ULL, 0x3FC57F008654CBE2ULL,
0x3FEFBF470F0A8D88ULL, 0x3FC00EE8AD6FB85BULL, 0xBFC00EE8AD6FB855ULL, 0x3FEFBF470F0A8D88ULL,
0x3FE39C23E3D63029ULL, 0x3FE94990E3AC4A6CULL, 0xBFE94990E3AC4A6BULL, 0x3FE39C23E3D6302AULL,
0x3FEBCB54CB0D2327ULL, 0x3FDFB7575C24D2DEULL, 0xBFDFB7575C24D2DBULL, 0x3FEBCB54CB0D2328ULL,
0x3FD0E15B4E1749D0ULL, 0x3FEEDDEB6A078650ULL, 0xBFEEDDEB6A078650ULL, 0x3FD0E15B4E1749D1ULL,
0x3FEE5A9D550467D3ULL, 0x3FD44310DC8936F0ULL, 0xBFD44310DC8936EEULL, 0x3FEE5A9D550467D4ULL,
0x3FDC997FC386538BULL, 0x3FECA08F19B9C448ULL, 0xBFECA08F19B9C449ULL, 0x3FDC997FC3865388ULL,
0x3FE82A9C13F545FFULL, 0x3FE4F9CC25CCA486ULL, 0xBFE4F9CC25CCA487ULL, 0x3FE82A9C13F545FFULL,
0x3FB20C9674ED4457ULL, 0x3FEFEB9D2530410FULL, 0xBFEFEB9D2530410FULL, 0x3FB20C9674ED444CULL,
0x3FEFE7EA85482D60ULL, 0x3FB39D9F12C5A299ULL, 0xBFB39D9F12C5A29AULL, 0x3FEFE7EA85482D60ULL,
0x3FE4D3BC6D589F80ULL, 0x3FE84B7111AF83F9ULL, 0xBFE84B7111AF83FAULL, 0x3FE4D3BC6D589F80ULL,
0x3FEC89F587029C13ULL, 0x3FDCF34BAEE1CD21ULL, 0xBFDCF34BAEE1CD21ULL, 0x3FEC89F587029C13ULL,
0x3FD3E39BE96EC271ULL, 0x3FEE6A61C55D53A7ULL, 0xBFEE6A61C55D53A7ULL, 0x3FD3E39BE96EC272ULL,
0x3FEED0835E999009ULL, 0x3FD1423EEFC69378ULL, 0xBFD1423EEFC69378ULL, 0x3FEED0835E999009ULL,
0x3FDF5FDEE656CDA2ULL, 0x3FEBE41B611154C1ULL, 0xBFEBE41B611154BFULL, 0x3FDF5FDEE656CDA7ULL,
0x3FE92AA41FC5A815ULL, 0x3FE3C3C44981C517ULL, 0xBFE3C3C44981C516ULL, 0x3FE92AA41FC5A816ULL,
0x3FBE8EB7FDE4AA3EULL, 0x3FEFC56E3B7D9AF6ULL, 0xBFEFC56E3B7D9AF6ULL, 0x3FBE8EB7FDE4AA52ULL,
0x3FEF830F4A40C60CULL, 0x3FC6451A831D830DULL, 0xBFC6451A831D8309ULL, 0x3FEF830F4A40C60CULL,
0x3FE258734CBB7111ULL, 0x3FEA38184A593BC5ULL, 0xBFEA38184A593BC6ULL, 0x3FE258734CBB710FULL,
0x3FEAFB8FD89F57B6ULL, 0x3FE133E9CFEE254EULL, 0xBFE133E9CFEE2550ULL, 0x3FEAFB8FD89F57B6ULL,
0x3FCBA96334F15DB0ULL, 0x3FEF3E6BBC1BBC65ULL, 0xBFEF3E6BBC1BBC65ULL, 0x3FCBA96334F15DAAULL,
0x3FEDD1FEF38A915AULL, 0x3FD73763C9261092ULL, 0xBFD73763C9261090ULL, 0x3FEDD1FEF38A915AULL,
0x3FD9C17D440DF9F4ULL, 0x3FED4B5B1B187524ULL, 0xBFED4B5B1B187523ULL, 0x3FD9C17D440DF9F5ULL,
0x3FE71BAC960E41BFULL, 0x3FE622E44FEC22FFULL, 0xBFE622E44FEC22FEULL, 0x3FE71BAC960E41C0ULL,
0x3F95FD4D21FAB242ULL, 0x3FEFFE1C6870CB77ULL, 0xBFEFFE1C6870CB77ULL, 0x3F95FD4D21FAB254ULL,
0x3FEFFF0943C53BD1ULL, 0x3F8F6A296AB997CAULL, 0xBF8F6A296AB997C9ULL, 0x3FEFFF0943C53BD1ULL,
0x3FE64715437F535BULL, 0x3FE6F8CA99C95B75ULL, 0xBFE6F8CA99C95B74ULL, 0x3FE64715437F535CULL,
0x3FED5F7172888A7FULL, 0x3FD96555B7AB948FULL, 0xBFD96555B7AB948FULL, 0x3FED5F7172888A7FULL,
0x3FD794F5E613DFAEULL, 0x3FEDBF9E4395759BULL, 0xBFEDBF9E4395759AULL, 0x3FD794F5E613DFB3ULL,
0x3FEF492206BCABB4ULL, 0x3FCAE4F1D5F3B9ABULL, 0xBFCAE4F1D5F3B9ABULL, 0x3FEF492206BCABB4ULL,
0x3FE15E36E4DBE2BDULL, 0x3FEAE068F345ECEEULL, 0xBFEAE068F345ECEFULL, 0x3FE15E36E4DBE2BCULL,
0x3FEA54C91090F524ULL, 0x3FE22F2D662C13E1ULL, 0xBFE22F2D662C13E1ULL, 0x3FEA54C91090F523ULL,
0x3FC70AFD8D08C4FFULL, 0x3FEF7A299C1A322AULL, 0xBFEF7A299C1A322AULL, 0x3FC70AFD8D08C501ULL,
0x3FEFCB4703914354ULL, 0x3FBCFF533B307DC1ULL, 0xBFBCFF533B307DB9ULL, 0x3FEFCB4703914354ULL,
0x3FE3EB33EABE0681ULL, 0x3FE90B7943575EFEULL, 0xBFE90B7943575EFDULL, 0x3FE3EB33EABE0681ULL,
0x3FEBFC9D25A1B147ULL, 0x3FDF081906BFF7FDULL, 0xBFDF081906BFF7FCULL, 0x3FEBFC9D25A1B148ULL,
0x3FD1A2F7FBE8F245ULL, 0x3FEEC2CF4B1AF6B2ULL, 0xBFEEC2CF4B1AF6B2ULL, 0x3FD1A2F7FBE8F246ULL,
0x3FEE79DB29A5165AULL, 0x3FD383F5E353B6AAULL, 0xBFD383F5E353B6A8ULL, 0x3FEE79DB29A5165AULL,
0x3FDD4CD02BA8609EULL, 0x3FEC7315899EAAD7ULL, 0xBFEC7315899EAAD7ULL, 0x3FDD4CD02BA8609CULL,
0x3FE86C0A1D9AA195ULL, 0x3FE4AD79516722F0ULL, 0xBFE4AD79516722F1ULL, 0x3FE86C0A1D9AA195ULL,
0x3FB52E774A4D4D12ULL, 0x3FEFE3E92BE9D886ULL, 0xBFEFE3E92BE9D886ULL, 0x3FB52E774A4D4D06ULL,
0x3FEFEF0102826191ULL, 0x3FB07B614E463064ULL, 0xBFB07B614E463057ULL, 0x3FEFEF0102826191ULL,
0x3FE51FA81CD99AA6ULL, 0x3FE8098B756E52FAULL, 0xBFE8098B756E52FBULL, 0x3FE51FA81CD99AA6ULL,
0x3FECB6E20A00DA99ULL, 0x3FDC3F6D47263129ULL, 0xBFDC3F6D4726312AULL, 0x3FECB6E20A00DA99ULL,
0x3FD4A253D11B82F6ULL, 0x3FEE4A8DFF81CE5EULL, 0xBFEE4A8DFF81CE5EULL, 0x3FD4A253D11B82F3ULL,
0x3FEEEB074C50A544ULL, 0x3FD0804E05EB661EULL, 0xBFD0804E05EB661BULL, 0x3FEEEB074C50A545ULL,
0x3FE00740C82B82E2ULL, 0x3FEBB249A0B6C40CULL, 0xBFEBB249A0B6C40CULL, 0x3FE00740C82B82E2ULL,
0x3FE9683F42BD7FE1ULL, 0x3FE374531B817F8DULL, 0xBFE374531B817F8CULL, 0x3FE9683F42BD7FE2ULL,
0x3FC0D64DBCB2678CULL, 0x3FEFB8D18D66ADB7ULL, 0xBFEFB8D18D66ADB7ULL, 0x3FC0D64DBCB2678EULL,
0x3FEF93F14F85AC08ULL, 0x3FC4B8B17F79FA88ULL, 0xBFC4B8B17F79FA86ULL, 0x3FEF93F14F85AC08ULL,
0x3FE2AA76E87AEB58ULL, 0x3FE9FDF4F13149DEULL, 0xBFE9FDF4F13149DDULL, 0x3FE2AA76E87AEB5AULL,
0x3FEB3115A5F37BF4ULL, 0x3FE0DED0B84BC4B5ULL, 0xBFE0DED0B84BC4B3ULL, 0x3FEB3115A5F37BF5ULL,
0x3FCD31774D2CBDF0ULL, 0x3FEF2817FC4609CDULL, 0xBFEF2817FC4609CDULL, 0x3FCD31774D2CBDFAULL,
0x3FEDF5E36A9BA59CULL, 0x3FD67B949CAD63CAULL, 0xBFD67B949CAD63C9ULL, 0x3FEDF5E36A9BA59CULL,
0x3FDA790CD3DBF31BULL, 0x3FED2255C6E5A4E0ULL, 0xBFED2255C6E5A4E0ULL, 0x3FDA790CD3DBF31CULL,
0x3FE760C52C304764ULL, 0x3FE5D9DEE73E345CULL, 0xBFE5D9DEE73E345BULL, 0x3FE760C52C304764ULL,
0x3FA14685DB42C187ULL, 0x3FEFFB55E425FDAEULL, 0xBFEFFB55E425FDAEULL, 0x3FA14685DB42C190ULL,
0x3FEFF97C4208C014ULL, 0x3FA46A396FF86179ULL, 0xBFA46A396FF8616DULL, 0x3FEFF97C4208C014ULL,
0x3FE5B50B264F7449ULL, 0x3FE782FB1B90B35AULL, 0xBFE782FB1B90B35BULL, 0x3FE5B50B264F7447ULL,
0x3FED0D672F59D2B9ULL, 0x3FDAD473125CDC08ULL, 0xBFDAD473125CDC0BULL, 0x3FED0D672F59D2B8ULL,
0x3FD61D595C88C204ULL, 0x3FEE0766D9280F54ULL, 0xBFEE0766D9280F55ULL, 0x3FD61D595C88C201ULL,
0x3FEF1C7ABE284708ULL, 0x3FCDF5163F01099AULL, 0xBFCDF5163F010996ULL, 0x3FEF1C7ABE284709ULL,
0x3FE0B405878F85ECULL, 0x3FEB4B7409DE7925ULL, 0xBFEB4B7409DE7925ULL, 0x3FE0B405878F85EDULL,
0x3FE9E082EDB42472ULL, 0x3FE2D333D34E9BB7ULL, 0xBFE2D333D34E9BB7ULL, 0x3FE9E082EDB42473ULL,
0x3FC3F22F57DB4896ULL, 0x3FEF9BED7CFBDE29ULL, 0xBFEF9BED7CFBDE29ULL, 0x3FC3F22F57DB4898ULL,
0x3FEFB20DC681D54DULL, 0x3FC19D8940BE24E7ULL, 0xBFC19D8940BE24E8ULL, 0x3FEFB20DC681D54CULL,
0x3FE34C5252C14DE2ULL, 0x3FE986AEF1457593ULL, 0xBFE986AEF1457592ULL, 0x3FE34C5252C14DE3ULL,
0x3FEB98FA1FD9155FULL, 0x3FE032AE55EDBD95ULL, 0xBFE032AE55EDBD94ULL, 0x3FEB98FA1FD9155FULL,
0x3FD01F1806B9FDD1ULL, 0x3FEEF7D6E51CA3C0ULL, 0xBFEEF7D6E51CA3BFULL, 0x3FD01F1806B9FDD6ULL,
0x3FEE3A33EC75CE85ULL, 0x3FD50163DC197047ULL, 0xBFD50163DC197048ULL, 0x3FEE3A33EC75CE85ULL,
0x3FDBE51517FFC0D9ULL, 0x3FECCCEE20C2DEA0ULL, 0xBFECCCEE20C2DE9FULL, 0x3FDBE51517FFC0DAULL,
0x3FE7E83F87B03686ULL, 0x3FE5454FF5159DFBULL, 0xBFE5454FF5159DFCULL, 0x3FE7E83F87B03686ULL,
0x3FADD406F9808EC5ULL, 0x3FEFF21614E131EDULL, 0xBFEFF21614E131EDULL, 0x3FADD406F9808ECEULL,
0x3FEFDF9922F73307ULL, 0x3FB6BF1B3E79B129ULL, 0xBFB6BF1B3E79B126ULL, 0x3FEFDF9922F73307ULL,
0x3FE48703306091FFULL, 0x3FE88C66E7481BA1ULL, 0xBFE88C66E7481BA0ULL, 0x3FE48703306091FFULL,
0x3FEC5BEF59FEF85AULL, 0x3FDDA60C5CFA10D8ULL, 0xBFDDA60C5CFA10D8ULL, 0x3FEC5BEF59FEF85AULL,
0x3FD3241FB638BAAFULL, 0x3FEE89095BAD6025ULL, 0xBFEE89095BAD6024ULL, 0x3FD3241FB638BAB0ULL,
0x3FEEB4CF515B8811ULL, 0x3FD2038583D727BDULL, 0xBFD2038583D727BDULL, 0x3FEEB4CF515B8811ULL,
0x3FDEB00695F25620ULL, 0x3FEC14D9DC465E57ULL, 0xBFEC14D9DC465E56ULL, 0x3FDEB00695F25625ULL,
0x3FE8EC109B486C49ULL, 0x3FE41272663D108CULL, 0xBFE41272663D108AULL, 0x3FE8EC109B486C4AULL,
0x3FBB6FA6EC38F64EULL, 0x3FEFD0D158D86087ULL, 0xBFEFD0D158D86087ULL, 0x3FBB6FA6EC38F663ULL,
0x3FEF70F6434B7EB7ULL, 0x3FC7D0A7BBD2CB1BULL, 0xBFC7D0A7BBD2CB16ULL, 0x3FEF70F6434B7EB7ULL,
0x3FE205BAA17560D6ULL, 0x3FEA7138DE9D60F4ULL, 0xBFEA7138DE9D60F5ULL, 0x3FE205BAA17560D6ULL,
0x3FEAC4FFBD3EFAC8ULL, 0x3FE188591F3A46E5ULL, 0xBFE188591F3A46E5ULL, 0x3FEAC4FFBD3EFAC8ULL,
0x3FCA203E1B1831DFULL, 0x3FEF538B1FAF2D07ULL, 0xBFEF538B1FAF2D07ULL, 0x3FCA203E1B1831D9ULL,
0x3FEDACF42CE68AB9ULL, 0x3FD7F24DD37341E3ULL, 0xBFD7F24DD37341E2ULL, 0x3FEDACF42CE68AB9ULL,
0x3FD908EF81EF7BD3ULL, 0x3FED733F508C0DFEULL, 0xBFED733F508C0DFEULL, 0x3FD908EF81EF7BD4ULL,
0x3FE6D5AFEF4AAFCDULL, 0x3FE66B0F3F52B386ULL, 0xBFE66B0F3F52B385ULL, 0x3FE6D5AFEF4AAFCEULL,
0x3F82D96B0E509754ULL, 0x3FEFFFA72C978C4FULL, 0xBFEFFFA72C978C4FULL, 0x3F82D96B0E509777ULL,
0x3FEFFFA72C978C4FULL, 0x3F82D96B0E509703ULL, 0xBF82D96B0E50970DULL, 0x3FEFFFA72C978C4FULL,
0x3FE66B0F3F52B387ULL, 0x3FE6D5AFEF4AAFCCULL, 0xBFE6D5AFEF4AAFCDULL, 0x3FE66B0F3F52B386ULL,
0x3FED733F508C0DFFULL, 0x3FD908EF81EF7BD1ULL, 0xBFD908EF81EF7BD1ULL, 0x3FED733F508C0DFFULL,
0x3FD7F24DD37341E4ULL, 0x3FEDACF42CE68AB9ULL, 0xBFEDACF42CE68AB9ULL, 0x3FD7F24DD37341E5ULL,
0x3FEF538B1FAF2D07ULL, 0x3FCA203E1B1831DAULL, 0xBFCA203E1B1831DBULL, 0x3FEF538B1FAF2D07ULL,
0x3FE188591F3A46E5ULL, 0x3FEAC4FFBD3EFAC7ULL, 0xBFEAC4FFBD3EFAC7ULL, 0x3FE188591F3A46E7ULL,
0x3FEA7138DE9D60F5ULL, 0x3FE205BAA17560D6ULL, 0xBFE205BAA17560D5ULL, 0x3FEA7138DE9D60F6ULL,
0x3FC7D0A7BBD2CB1BULL, 0x3FEF70F6434B7EB7ULL, 0xBFEF70F6434B7EB7ULL, 0x3FC7D0A7BBD2CB25ULL,
0x3FEFD0D158D86087ULL, 0x3FBB6FA6EC38F64CULL, 0xBFBB6FA6EC38F646ULL, 0x3FEFD0D158D86087ULL,
0x3FE41272663D108DULL, 0x3FE8EC109B486C48ULL, 0xBFE8EC109B486C49ULL, 0x3FE41272663D108CULL,
0x3FEC14D9DC465E58ULL, 0x3FDEB00695F25620ULL, 0xBFDEB00695F25622ULL, 0x3FEC14D9DC465E57ULL,
0x3FD2038583D727BFULL, 0x3FEEB4CF515B8811ULL, 0xBFEEB4CF515B8811ULL, 0x3FD2038583D727BCULL,
0x3FEE89095BAD6025ULL, 0x3FD3241FB638BAAFULL, 0xBFD3241FB638BAADULL, 0x3FEE89095BAD6025ULL,
0x3FDDA60C5CFA10DAULL, 0x3FEC5BEF59FEF85AULL, 0xBFEC5BEF59FEF859ULL, 0x3FDDA60C5CFA10DBULL,
0x3FE88C66E7481BA1ULL, 0x3FE48703306091FFULL, 0xBFE48703306091FEULL, 0x3FE88C66E7481BA2ULL,
0x3FB6BF1B3E79B12FULL, 0x3FEFDF9922F73307ULL, 0xBFEFDF9922F73307ULL, 0x3FB6BF1B3E79B134ULL,
0x3FEFF21614E131EDULL, 0x3FADD406F9808EC8ULL, 0xBFADD406F9808EB3ULL, 0x3FEFF21614E131EDULL,
0x3FE5454FF5159DFCULL, 0x3FE7E83F87B03686ULL, 0xBFE7E83F87B03685ULL, 0x3FE5454FF5159DFDULL,
0x3FECCCEE20C2DEA0ULL, 0x3FDBE51517FFC0D9ULL, 0xBFDBE51517FFC0D7ULL, 0x3FECCCEE20C2DEA0ULL,
0x3FD50163DC19704AULL, 0x3FEE3A33EC75CE85ULL, 0xBFEE3A33EC75CE84ULL, 0x3FD50163DC19704BULL,
0x3FEEF7D6E51CA3C0ULL, 0x3FD01F1806B9FDD2ULL, 0xBFD01F1806B9FDCFULL, 0x3FEEF7D6E51CA3C0ULL,
0x3FE032AE55EDBD97ULL, 0x3FEB98FA1FD9155EULL, 0xBFEB98FA1FD9155EULL, 0x3FE032AE55EDBD95ULL,
0x3FE986AEF1457594ULL, 0x3FE34C5252C14DE1ULL, 0xBFE34C5252C14DE2ULL, 0x3FE986AEF1457593ULL,
0x3FC19D8940BE24ECULL, 0x3FEFB20DC681D54CULL, 0xBFEFB20DC681D54DULL, 0x3FC19D8940BE24E7ULL,
0x3FEF9BED7CFBDE29ULL, 0x3FC3F22F57DB4893ULL, 0xBFC3F22F57DB4892ULL, 0x3FEF9BED7CFBDE29ULL,
0x3FE2D333D34E9BB8ULL, 0x3FE9E082EDB42472ULL, 0xBFE9E082EDB42472ULL, 0x3FE2D333D34E9BB8ULL,
0x3FEB4B7409DE7925ULL, 0x3FE0B405878F85ECULL, 0xBFE0B405878F85EBULL, 0x3FEB4B7409DE7926ULL,
0x3FCDF5163F01099BULL, 0x3FEF1C7ABE284708ULL, 0xBFEF1C7ABE284708ULL, 0x3FCDF5163F01099DULL,
0x3FEE0766D9280F54ULL, 0x3FD61D595C88C203ULL, 0xBFD61D595C88C202ULL, 0x3FEE0766D9280F55ULL,
0x3FDAD473125CDC09ULL, 0x3FED0D672F59D2B8ULL, 0xBFED0D672F59D2B7ULL, 0x3FDAD473125CDC0EULL,
0x3FE782FB1B90B35BULL, 0x3FE5B50B264F7448ULL, 0xBFE5B50B264F7446ULL, 0x3FE782FB1B90B35CULL,
0x3FA46A396FF8617EULL, 0x3FEFF97C4208C014ULL, 0xBFEFF97C4208C014ULL, 0x3FA46A396FF861A7ULL,
0x3FEFFB55E425FDAEULL, 0x3FA14685DB42C17EULL, 0xBFA14685DB42C175ULL, 0x3FEFFB55E425FDAEULL,
0x3FE5D9DEE73E345CULL, 0x3FE760C52C304764ULL, 0xBFE760C52C304763ULL, 0x3FE5D9DEE73E345DULL,
0x3FED2255C6E5A4E1ULL, 0x3FDA790CD3DBF31AULL, 0xBFDA790CD3DBF319ULL, 0x3FED2255C6E5A4E1ULL,
0x3FD67B949CAD63CBULL, 0x3FEDF5E36A9BA59CULL, 0xBFEDF5E36A9BA59CULL, 0x3FD67B949CAD63CCULL,
0x3FEF2817FC4609CEULL, 0x3FCD31774D2CBDEEULL, 0xBFCD31774D2CBDECULL, 0x3FEF2817FC4609CEULL,
0x3FE0DED0B84BC4B6ULL, 0x3FEB3115A5F37BF3ULL, 0xBFEB3115A5F37BF4ULL, 0x3FE0DED0B84BC4B5ULL,
0x3FE9FDF4F13149DEULL, 0x3FE2AA76E87AEB58ULL, 0xBFE2AA76E87AEB59ULL, 0x3FE9FDF4F13149DEULL,
0x3FC4B8B17F79FA8AULL, 0x3FEF93F14F85AC07ULL, 0xBFEF93F14F85AC08ULL, 0x3FC4B8B17F79FA85ULL,
0x3FEFB8D18D66ADB7ULL, 0x3FC0D64DBCB26786ULL, 0xBFC0D64DBCB26787ULL, 0x3FEFB8D18D66ADB7ULL,
0x3FE374531B817F8EULL, 0x3FE9683F42BD7FE1ULL, 0xBFE9683F42BD7FE1ULL, 0x3FE374531B817F8DULL,
0x3FEBB249A0B6C40DULL, 0x3FE00740C82B82E0ULL, 0xBFE00740C82B82E1ULL, 0x3FEBB249A0B6C40DULL,
0x3FD0804E05EB661DULL, 0x3FEEEB074C50A545ULL, 0xBFEEEB074C50A544ULL, 0x3FD0804E05EB661EULL,
0x3FEE4A8DFF81CE5EULL, 0x3FD4A253D11B82F3ULL, 0xBFD4A253D11B82F3ULL, 0x3FEE4A8DFF81CE5EULL,
0x3FDC3F6D47263128ULL, 0x3FECB6E20A00DA99ULL, 0xBFECB6E20A00DA98ULL, 0x3FDC3F6D4726312DULL,
0x3FE8098B756E52FBULL, 0x3FE51FA81CD99AA6ULL, 0xBFE51FA81CD99AA5ULL, 0x3FE8098B756E52FCULL,
0x3FB07B614E463060ULL, 0x3FEFEF0102826191ULL, 0xBFEFEF0102826191ULL, 0x3FB07B614E463075ULL,
0x3FEFE3E92BE9D886ULL, 0x3FB52E774A4D4D0AULL, 0xBFB52E774A4D4D09ULL, 0x3FEFE3E92BE9D886ULL,
0x3FE4AD79516722F1ULL, 0x3FE86C0A1D9AA195ULL, 0xBFE86C0A1D9AA193ULL, 0x3FE4AD79516722F3ULL,
0x3FEC7315899EAAD7ULL, 0x3FDD4CD02BA8609CULL, 0xBFDD4CD02BA86099ULL, 0x3FEC7315899EAAD8ULL,
0x3FD383F5E353B6ABULL, 0x3FEE79DB29A5165AULL, 0xBFEE79DB29A51659ULL, 0x3FD383F5E353B6AFULL,
0x3FEEC2CF4B1AF6B2ULL, 0x3FD1A2F7FBE8F243ULL, 0xBFD1A2F7FBE8F243ULL, 0x3FEEC2CF4B1AF6B2ULL,
0x3FDF081906BFF7FEULL, 0x3FEBFC9D25A1B147ULL, 0xBFEBFC9D25A1B147ULL, 0x3FDF081906BFF7FEULL,
0x3FE90B7943575EFEULL, 0x3FE3EB33EABE0680ULL, 0xBFE3EB33EABE0680ULL, 0x3FE90B7943575EFEULL,
0x3FBCFF533B307DC2ULL, 0x3FEFCB4703914354ULL, 0xBFEFCB4703914354ULL, 0x3FBCFF533B307DC6ULL,
0x3FEF7A299C1A322AULL, 0x3FC70AFD8D08C4FFULL, 0xBFC70AFD8D08C4FBULL, 0x3FEF7A299C1A322AULL,
0x3FE22F2D662C13E1ULL, 0x3FEA54C91090F523ULL, 0xBFEA54C91090F522ULL, 0x3FE22F2D662C13E3ULL,
0x3FEAE068F345ECEFULL, 0x3FE15E36E4DBE2BCULL, 0xBFE15E36E4DBE2BBULL, 0x3FEAE068F345ECF0ULL,
0x3FCAE4F1D5F3B9AFULL, 0x3FEF492206BCABB4ULL, 0xBFEF492206BCABB4ULL, 0x3FCAE4F1D5F3B9B2ULL,
0x3FEDBF9E4395759BULL, 0x3FD794F5E613DFAEULL, 0xBFD794F5E613DFACULL, 0x3FEDBF9E4395759BULL,
0x3FD96555B7AB9491ULL, 0x3FED5F7172888A7EULL, 0xBFED5F7172888A7FULL, 0x3FD96555B7AB948EULL,
0x3FE6F8CA99C95B75ULL, 0x3FE64715437F535BULL, 0xBFE64715437F535BULL, 0x3FE6F8CA99C95B75ULL,
0x3F8F6A296AB9980FULL, 0x3FEFFF0943C53BD1ULL, 0xBFEFFF0943C53BD1ULL, 0x3F8F6A296AB997B3ULL,
0x3FEFFE1C6870CB77ULL, 0x3F95FD4D21FAB226ULL, 0xBF95FD4D21FAB21FULL, 0x3FEFFE1C6870CB77ULL,
0x3FE622E44FEC22FFULL, 0x3FE71BAC960E41BFULL, 0xBFE71BAC960E41BEULL, 0x3FE622E44FEC2300ULL,
0x3FED4B5B1B187524ULL, 0x3FD9C17D440DF9F2ULL, 0xBFD9C17D440DF9F2ULL, 0x3FED4B5B1B187524ULL,
0x3FD73763C9261092ULL, 0x3FEDD1FEF38A915AULL, 0xBFEDD1FEF38A9159ULL, 0x3FD73763C9261093ULL,
0x3FEF3E6BBC1BBC65ULL, 0x3FCBA96334F15DADULL, 0xBFCBA96334F15DACULL, 0x3FEF3E6BBC1BBC65ULL,
0x3FE133E9CFEE254FULL, 0x3FEAFB8FD89F57B6ULL, 0xBFEAFB8FD89F57B5ULL, 0x3FE133E9CFEE2551ULL,
0x3FEA38184A593BC5ULL, 0x3FE258734CBB7110ULL, 0xBFE258734CBB710EULL, 0x3FEA38184A593BC7ULL,
0x3FC6451A831D830EULL, 0x3FEF830F4A40C60CULL, 0xBFEF830F4A40C60CULL, 0x3FC6451A831D8318ULL,
0x3FEFC56E3B7D9AF6ULL, 0x3FBE8EB7FDE4AA3EULL, 0xBFBE8EB7FDE4AA35ULL, 0x3FEFC56E3B7D9AF6ULL,
0x3FE3C3C44981C518ULL, 0x3FE92AA41FC5A815ULL, 0xBFE92AA41FC5A815ULL, 0x3FE3C3C44981C517ULL,
0x3FEBE41B611154C0ULL, 0x3FDF5FDEE656CDA3ULL, 0xBFDF5FDEE656CDA4ULL, 0x3FEBE41B611154C0ULL,
0x3FD1423EEFC6937AULL, 0x3FEED0835E999009ULL, 0xBFEED0835E999009ULL, 0x3FD1423EEFC69378ULL,
0x3FEE6A61C55D53A7ULL, 0x3FD3E39BE96EC271ULL, 0xBFD3E39BE96EC26FULL, 0x3FEE6A61C55D53A8ULL,
0x3FDCF34BAEE1CD23ULL, 0x3FEC89F587029C13ULL, 0xBFEC89F587029C12ULL, 0x3FDCF34BAEE1CD24ULL,
0x3FE84B7111AF83FAULL, 0x3FE4D3BC6D589F7FULL, 0xBFE4D3BC6D589F7EULL, 0x3FE84B7111AF83FBULL,
0x3FB39D9F12C5A2A2ULL, 0x3FEFE7EA85482D60ULL, 0xBFEFE7EA85482D60ULL, 0x3FB39D9F12C5A2A7ULL,
0x3FEFEB9D2530410FULL, 0x3FB20C9674ED444CULL, 0xBFB20C9674ED444FULL, 0x3FEFEB9D2530410FULL,
0x3FE4F9CC25CCA487ULL, 0x3FE82A9C13F545FFULL, 0xBFE82A9C13F545FEULL, 0x3FE4F9CC25CCA488ULL,
0x3FECA08F19B9C449ULL, 0x3FDC997FC3865388ULL, 0xBFDC997FC3865385ULL, 0x3FECA08F19B9C44AULL,
0x3FD44310DC8936F0ULL, 0x3FEE5A9D550467D3ULL, 0xBFEE5A9D550467D3ULL, 0x3FD44310DC8936F4ULL,
0x3FEEDDEB6A078651ULL, 0x3FD0E15B4E1749CDULL, 0xBFD0E15B4E1749CEULL, 0x3FEEDDEB6A078651ULL,
0x3FDFB7575C24D2DDULL, 0x3FEBCB54CB0D2327ULL, 0xBFEBCB54CB0D2327ULL, 0x3FDFB7575C24D2DEULL,
0x3FE94990E3AC4A6CULL, 0x3FE39C23E3D63029ULL, 0xBFE39C23E3D63029ULL, 0x3FE94990E3AC4A6CULL,
0x3FC00EE8AD6FB85AULL, 0x3FEFBF470F0A8D88ULL, 0xBFEFBF470F0A8D88ULL, 0x3FC00EE8AD6FB85CULL,
0x3FEF8BA737CB4B78ULL, 0x3FC57F008654CBDEULL, 0xBFC57F008654CBDBULL, 0x3FEF8BA737CB4B78ULL,
0x3FE2818BEF4D3CBAULL, 0x3FEA1B26D2C0A75EULL, 0xBFEA1B26D2C0A75DULL, 0x3FE2818BEF4D3CBBULL,
0x3FEB16742A4CA2F5ULL, 0x3FE1097248D0A956ULL, 0xBFE1097248D0A956ULL, 0x3FEB16742A4CA2F5ULL,
0x3FCC6D90535D74DFULL, 0x3FEF33685A3AAEF0ULL, 0xBFEF33685A3AAEF0ULL, 0x3FCC6D90535D74E1ULL,
0x3FEDE4160F6D8D82ULL, 0x3FD6D998638A0CB5ULL, 0xBFD6D998638A0CB4ULL, 0x3FEDE4160F6D8D82ULL,
0x3FDA1D6543B50AC1ULL, 0x3FED36FC7BCBFBDBULL, 0xBFED36FC7BCBFBDCULL, 0x3FDA1D6543B50ABEULL,
0x3FE73E558E079942ULL, 0x3FE5FE7CBDE56A0FULL, 0xBFE5FE7CBDE56A10ULL, 0x3FE73E558E079941ULL,
0x3F9C454F4CE53B33ULL, 0x3FEFFCE09CE2A679ULL, 0xBFEFFCE09CE2A679ULL, 0x3F9C454F4CE53B05ULL,
0x3FEFF753BB1B9164ULL, 0x3FA78DBAA5874685ULL, 0xBFA78DBAA5874676ULL, 0x3FEFF753BB1B9164ULL,
0x3FE59001D5F723E0ULL, 0x3FE7A4F707BF97D2ULL, 0xBFE7A4F707BF97D1ULL, 0x3FE59001D5F723E0ULL,
0x3FECF830E8CE467BULL, 0x3FDB2F971DB31972ULL, 0xBFDB2F971DB31970ULL, 0x3FECF830E8CE467BULL,
0x3FD5BEE78B9DB3B8ULL, 0x3FEE18A02FDC66D9ULL, 0xBFEE18A02FDC66D9ULL, 0x3FD5BEE78B9DB3B9ULL,
0x3FEF1090BC898F5FULL, 0x3FCEB86B462DE348ULL, 0xBFCEB86B462DE344ULL, 0x3FEF1090BC898F5FULL,
0x3FE089112032B08DULL, 0x3FEB658F14FDBC47ULL, 0xBFEB658F14FDBC47ULL, 0x3FE089112032B08BULL,
0x3FE9C2D110F075C3ULL, 0x3FE2FBC24B441015ULL, 0xBFE2FBC24B441016ULL, 0x3FE9C2D110F075C2ULL,
0x3FC32B7BF94516ABULL, 0x3FEFA39BAC7A1791ULL, 0xBFEFA39BAC7A1791ULL, 0x3FC32B7BF94516A5ULL,
0x3FEFAAFBCB0CFDDCULL, 0x3FC264994DFD340AULL, 0xBFC264994DFD3409ULL, 0x3FEFAAFBCB0CFDDCULL,
0x3FE32421EC49A620ULL, 0x3FE9A4DFA42B06B1ULL, 0xBFE9A4DFA42B06B2ULL, 0x3FE32421EC49A620ULL,
0x3FEB7F6686E792EAULL, 0x3FE05DF3EC31B8B6ULL, 0xBFE05DF3EC31B8B7ULL, 0x3FEB7F6686E792E9ULL,
0x3FCF7B7480BD3801ULL, 0x3FEF045A14CF738CULL, 0xBFEF045A14CF738BULL, 0x3FCF7B7480BD3803ULL,
0x3FEE298F4439197AULL, 0x3FD5604012F467B4ULL, 0xBFD5604012F467B4ULL, 0x3FEE298F4439197AULL,
0x3FDB8A7814FD5693ULL, 0x3FECE2B32799A060ULL, 0xBFECE2B32799A05FULL, 0x3FDB8A7814FD5698ULL,
0x3FE7C6B89CE2D333ULL, 0x3FE56AC35197649EULL, 0xBFE56AC35197649DULL, 0x3FE7C6B89CE2D334ULL,
0x3FAAB101BD5F8316ULL, 0x3FEFF4DC54B1BED3ULL, 0xBFEFF4DC54B1BED2ULL, 0x3FAAB101BD5F833EULL,
0x3FEFDAFA7514538CULL, 0x3FB84F8712C130A0ULL, 0xBFB84F8712C1309DULL, 0x3FEFDAFA7514538CULL,
0x3FE4605A692B32A2ULL, 0x3FE8AC871EDE1D87ULL, 0xBFE8AC871EDE1D86ULL, 0x3FE4605A692B32A4ULL,
0x3FEC44833141C004ULL, 0x3FDDFEFF66A941DDULL, 0xBFDDFEFF66A941D9ULL, 0x3FEC44833141C005ULL,
0x3FD2C41A4E954521ULL, 0x3FEE97EC36016B30ULL, 0xBFEE97EC36016B2FULL, 0x3FD2C41A4E954526ULL,
0x3FEEA68393E65800ULL, 0x3FD263E6995554BAULL, 0xBFD263E6995554B9ULL, 0x3FEEA68393E65800ULL,
0x3FDE57A86D3CD825ULL, 0x3FEC2CD14931E3F1ULL, 0xBFEC2CD14931E3F1ULL, 0x3FDE57A86D3CD826ULL,
0x3FE8CC6A75184655ULL, 0x3FE4397F5B2A4380ULL, 0xBFE4397F5B2A437FULL, 0x3FE8CC6A75184655ULL,
0x3FB9DFB6EB24A860ULL, 0x3FEFD60D2DA75C9EULL, 0xBFEFD60D2DA75C9EULL, 0x3FB9DFB6EB24A864ULL,
0x3FEF677556883CEEULL, 0x3FC8961727C41804ULL, 0xBFC8961727C417FEULL, 0x3FEF677556883CEEULL,
0x3FE1DC1B64DC4872ULL, 0x3FEA8D676E545AD2ULL, 0xBFEA8D676E545AD1ULL, 0x3FE1DC1B64DC4874ULL,
0x3FEAA9547A2CB98EULL, 0x3FE1B250171373BEULL, 0xBFE1B250171373BDULL, 0x3FEAA9547A2CB98FULL,
0x3FC95B49E9B62AFFULL, 0x3FEF5DA6ED43685CULL, 0xBFEF5DA6ED43685CULL, 0x3FC95B49E9B62B02ULL,
0x3FED9A00DD8B3D46ULL, 0x3FD84F6AAAF3903FULL, 0xBFD84F6AAAF3903CULL, 0x3FED9A00DD8B3D47ULL,
0x3FD8AC4B86D5ED47ULL, 0x3FED86C48445A44FULL, 0xBFED86C48445A450ULL, 0x3FD8AC4B86D5ED44ULL,
0x3FE6B25CED2FE29CULL, 0x3FE68ED1EAA19C71ULL, 0xBFE68ED1EAA19C71ULL, 0x3FE6B25CED2FE29BULL,
0x3F6921F8BECCA62FULL, 0x3FEFFFF621621D02ULL, 0xBFEFFFF621621D02ULL, 0x3F6921F8BECCA4BCULL,
};
#if !defined(WOLFSSL_FALCON_FFT_AVX2) && !defined(WOLFSSL_FALCON_FFT_NEON)
/* When the AVX2 backend is selected, falcon_FFT/falcon_iFFT are provided by
* wc_falcon_fft_avx2.c instead; the twiddle table above is still shared. */
/* In-place forward FFT: coefficient representation -> FFT representation. */
void falcon_FFT(fpr* f, unsigned logn)
{
unsigned u;
size_t t, n, hn, m;
n = (size_t)1 << logn;
hn = n >> 1;
t = hn;
for (u = 1, m = 2; u < logn; u++, m <<= 1) {
size_t ht = t >> 1, hm = m >> 1, i1, j1;
for (i1 = 0, j1 = 0; i1 < hm; i1++, j1 += t) {
size_t j, j2 = j1 + ht;
fpr s_re = falcon_gm_tab[((m + i1) << 1) + 0];
fpr s_im = falcon_gm_tab[((m + i1) << 1) + 1];
for (j = j1; j < j2; j++) {
fpr x_re = f[j], x_im = f[j + hn];
fpr y_re = f[j + ht], y_im = f[j + ht + hn];
FPC_MUL(y_re, y_im, y_re, y_im, s_re, s_im);
FPC_ADD(f[j], f[j + hn], x_re, x_im, y_re, y_im);
FPC_SUB(f[j + ht], f[j + ht + hn], x_re, x_im, y_re, y_im);
}
}
t = ht;
}
}
/* In-place inverse FFT: exact reversal of falcon_FFT, then scale by 2^-(logn-1).
* Each inverse butterfly is (a+b) and (a-b)*conj(s). */
void falcon_iFFT(fpr* f, unsigned logn)
{
int u;
size_t n = (size_t)1 << logn, hn = n >> 1;
for (u = (int)logn - 1; u >= 1; u--) {
size_t m = (size_t)1 << u, hm = m >> 1;
size_t t = hn >> u; /* butterfly stride */
size_t i1, j1;
for (i1 = 0, j1 = 0; i1 < hm; i1++, j1 += (t << 1)) {
size_t j, j2 = j1 + t;
fpr s_re = falcon_gm_tab[((m + i1) << 1) + 0];
fpr s_im = fpr_neg(falcon_gm_tab[((m + i1) << 1) + 1]);
for (j = j1; j < j2; j++) {
fpr a_re = f[j], a_im = f[j + hn];
fpr b_re = f[j + t], b_im = f[j + t + hn];
fpr d_re, d_im;
FPC_ADD(f[j], f[j + hn], a_re, a_im, b_re, b_im);
FPC_SUB(d_re, d_im, a_re, a_im, b_re, b_im);
FPC_MUL(f[j + t], f[j + t + hn], d_re, d_im, s_re, s_im);
}
}
}
{
fpr ni = fpr_inv(fpr_of((sword64)hn)); /* 1 / 2^(logn-1) (exact) */
size_t j;
for (j = 0; j < n; j++) {
f[j] = fpr_mul(f[j], ni);
}
}
}
#endif /* !WOLFSSL_FALCON_FFT_AVX2 */
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
-652
View File
@@ -1,652 +0,0 @@
/* wc_falcon_fpr.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Integer-emulated IEEE-754 binary64 backend for the Falcon
* floating-point primitive seam (wolfssl/wolfcrypt/wc_falcon_fpr.h).
*
* This is the portable, FP-unit-free, fully deterministic and constant-time
* backend: every operation is performed with integer arithmetic only (64-bit
* mantissa multiply-accumulate, shifts and CLZ-style normalization). No
* hardware FPU is used and there is no branch or memory access that depends on
* an operand value, so results are bit-identical to round-to-nearest-even
* IEEE-754 binary64 on every platform.
*
* The algorithm is a port of the well-known Falcon reference "fpr" emulated
* implementation by Thomas Pornin (MIT licensed), adapted to wolfSSL house
* style (word64 / sword64 / word32). See https://falcon-sign.info/ and the
* NIST PQC / Falcon round-3 reference code. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(HAVE_FALCON) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
/* ------------------------------------------------------------------------ */
/* Low-level helpers. */
/* */
/* These shift helpers tolerate a (possibly secret) shift count in 0..63 in */
/* constant time: a variable shift is split into a fixed conditional 32-bit */
/* part plus a 0..31 part, avoiding both undefined behaviour and any */
/* operand-dependent timing on platforms whose shift is data dependent. */
/* ------------------------------------------------------------------------ */
/* Right-shift a 64-bit unsigned value by n (0..63), constant-time. */
static WC_INLINE fpr fpr_ursh(word64 x, int n)
{
x ^= (x ^ (x >> 32)) & ((word64)0 - (word64)(n >> 5));
return x >> (n & 31);
}
/* Right-shift a 64-bit signed value by n (0..63), constant-time. */
static WC_INLINE sword64 fpr_irsh(sword64 x, int n)
{
x ^= (x ^ (x >> 32)) & ((sword64)0 - (sword64)(n >> 5));
return x >> (n & 31);
}
/* Left-shift a 64-bit unsigned value by n (0..63), constant-time. */
static WC_INLINE word64 fpr_ulsh(word64 x, int n)
{
x ^= (x ^ (x << 32)) & ((word64)0 - (word64)(n >> 5));
return x << (n & 31);
}
/* Pack a sign s (0/1), unbiased exponent e and mantissa m (2^54 <= m < 2^55,
* with the low 3 bits carrying guard/round/sticky information) into the
* IEEE-754 binary64 bit pattern, applying round-to-nearest-even.
*
* If m == 0 a (signed) zero is produced. If e < -1076 the value underflows to
* a (signed) zero. */
static WC_INLINE fpr FPR(int s, int e, word64 m)
{
fpr x;
word32 t;
unsigned int f;
/* If e >= -1076 the value is "normal"; otherwise it would be subnormal,
* which we clamp down to zero. */
e += 1076;
t = (word32)e >> 31;
m &= (word64)t - 1;
/* If m == 0 we want a zero: force e to 0 too (the sign is conserved). */
t = (word32)(m >> 54);
e &= -(int)t;
/* The 52 stored mantissa bits come from m. Its top set bit (bit 54)
* increments the exponent field by one when added, which is what we want
* (and produces 0 for m == 0). */
x = (((word64)s << 63) | (m >> 2)) + ((word64)(word32)e << 52);
/* Round to nearest, ties to even: increment when the low 3 bits of m are
* 011, 110 or 111. A carry spilling into the exponent field is the desired
* behaviour. */
f = (unsigned int)m & 7U;
x += (0xC8U >> f) & 1U;
return x;
}
/* Normalize mantissa m so its top bit (bit 63) is set, adjusting exponent e so
* that m * 2^e is preserved. A zero m is left unchanged. Constant-time. */
#define FPR_NORM64(m, e) do { \
word32 nt_; \
\
(e) -= 63; \
\
nt_ = (word32)((m) >> 32); \
nt_ = (nt_ | (word32)(0U - nt_)) >> 31; \
(m) ^= ((m) ^ ((m) << 32)) & ((word64)nt_ - 1); \
(e) += (int)(nt_ << 5); \
\
nt_ = (word32)((m) >> 48); \
nt_ = (nt_ | (word32)(0U - nt_)) >> 31; \
(m) ^= ((m) ^ ((m) << 16)) & ((word64)nt_ - 1); \
(e) += (int)(nt_ << 4); \
\
nt_ = (word32)((m) >> 56); \
nt_ = (nt_ | (word32)(0U - nt_)) >> 31; \
(m) ^= ((m) ^ ((m) << 8)) & ((word64)nt_ - 1); \
(e) += (int)(nt_ << 3); \
\
nt_ = (word32)((m) >> 60); \
nt_ = (nt_ | (word32)(0U - nt_)) >> 31; \
(m) ^= ((m) ^ ((m) << 4)) & ((word64)nt_ - 1); \
(e) += (int)(nt_ << 2); \
\
nt_ = (word32)((m) >> 62); \
nt_ = (nt_ | (word32)(0U - nt_)) >> 31; \
(m) ^= ((m) ^ ((m) << 2)) & ((word64)nt_ - 1); \
(e) += (int)(nt_ << 1); \
\
nt_ = (word32)((m) >> 63); \
(m) ^= ((m) ^ ((m) << 1)) & ((word64)nt_ - 1); \
(e) += (int)(nt_); \
} while (0)
/* ------------------------------------------------------------------------ */
/* Constructors / conversions. */
/* ------------------------------------------------------------------------ */
#ifndef WOLFSSL_FALCON_FPR_DOUBLE /* inline backend provides fpr_scaled */
fpr fpr_scaled(sword64 i, int sc)
{
/* Convert i * 2^sc to fpr: take the sign and absolute value, normalize the
* magnitude so the top bit is set, round down to a 55-bit mantissa (with a
* sticky low bit) and pack. The source integer is assumed not to be
* -2^63. */
int s, e;
word32 t;
word64 m;
/* Sign and absolute value (-i == 1 + ~i). */
s = (int)((word64)i >> 63);
i ^= -(sword64)s;
i += s;
/* Suppose i != 0 for now: normalize it so the top bit is set. */
m = (word64)i;
e = 9 + sc;
FPR_NORM64(m, e);
/* m is now in 2^63..2^64-1; divide by 512 into the 2^54..2^55-1 range,
* folding any dropped bit into the sticky low bit. */
m |= ((word32)m & 0x1FF) + 0x1FF;
m >>= 9;
/* Corrective action for i == 0: clamp e and m to zero. */
t = (word32)((word64)((word64)i | (word64)(0 - (word64)i)) >> 63);
m &= (word64)0 - (word64)t;
e &= -(int)t;
/* FPR() handles exponents that are too low. */
return FPR(s, e, m);
}
#endif /* !WOLFSSL_FALCON_FPR_DOUBLE */
#if !defined(WOLFSSL_FALCON_FPR_ASM) && !defined(WOLFSSL_FALCON_FPR_DOUBLE)
/* The scalar fpr operations below are supplied by the per-architecture assembly
* backend (wc_falcon_fpr_x86_64_asm.S, WOLFSSL_FALCON_FPR_ASM) or by the inline
* native-double backend (WOLFSSL_FALCON_FPR_DOUBLE) when either is set;
* otherwise this constant-time integer emulation is used. fpr_expm_p63 and the
* fpr constants (below) always come from this file. */
fpr fpr_of(sword64 i)
{
return fpr_scaled(i, 0);
}
sword64 fpr_rint(fpr x)
{
word64 m, d;
int e;
word32 s, dd, f;
/* Assuming the value fits in -(2^63-1)..+(2^63-1), extract the mantissa as
* a 63-bit integer and right-shift it as needed. */
m = ((x << 10) | ((word64)1 << 62)) & (((word64)1 << 63) - 1);
e = 1085 - ((int)(x >> 52) & 0x7FF);
/* A shift of more than 63 bits sets m to zero (also covers x == 0). */
m &= (word64)0 - (word64)((word32)(e - 64) >> 31);
e &= 63;
/* Right-shift m by e, rounding to nearest with ties to even. We build a
* word holding all dropped bits plus the lowest kept bit, then shrink it
* to three bits, the lowest being sticky. */
d = fpr_ulsh(m, 63 - e);
dd = (word32)d | ((word32)(d >> 32) & 0x1FFFFFFF);
f = (word32)(d >> 61) | ((dd | (word32)(0U - dd)) >> 31);
m = fpr_ursh(m, e) + (word64)((0xC8U >> f) & 1U);
/* Apply the sign bit. */
s = (word32)(x >> 63);
return ((sword64)m ^ -(sword64)s) + (sword64)s;
}
sword64 fpr_floor(fpr x)
{
word64 t;
sword64 xi;
int e, cc;
/* Extract the value as a signed scaled integer in the 2^62..2^63-1 range
* (absolute value), so only a right-shift is needed afterwards. */
e = (int)(x >> 52) & 0x7FF;
t = x >> 63;
xi = (sword64)(((x << 10) | ((word64)1 << 62)) & (((word64)1 << 63) - 1));
xi = (xi ^ -(sword64)t) + (sword64)t;
cc = 1085 - e;
/* An arithmetic right-shift implements floor() (round toward -inf) for
* both positive and negative values. */
xi = fpr_irsh(xi, cc & 63);
/* If the true shift count was 64 or more, replace xi with 0 (nonnegative)
* or -1 (negative). This also fixes the bogus implicit-bit assumption for
* a zero input. */
xi ^= (xi ^ -(sword64)t) & -(sword64)((word32)(63 - cc) >> 31);
return xi;
}
sword64 fpr_trunc(fpr x)
{
word64 t, xu;
int e, cc;
/* Extract the absolute value as a scaled integer in the 2^62..2^63-1
* range, then right-shift. */
e = (int)(x >> 52) & 0x7FF;
xu = ((x << 10) | ((word64)1 << 62)) & (((word64)1 << 63) - 1);
cc = 1085 - e;
xu = fpr_ursh(xu, cc & 63);
/* If the exponent is too low (cc > 63), clamp to zero (also covers
* x == 0). */
xu &= (word64)0 - (word64)((word32)(cc - 64) >> 31);
/* Apply the sign. */
t = x >> 63;
xu = (xu ^ ((word64)0 - t)) + t;
return (sword64)xu;
}
/* ------------------------------------------------------------------------ */
/* Arithmetic. */
/* ------------------------------------------------------------------------ */
fpr fpr_add(fpr x, fpr y)
{
word64 m, xu, yu, za;
word32 cs;
int ex, ey, sx, sy, cc;
/* Ensure x has the larger absolute value, so the exponent of y is no
* greater than that of x. We also conditionally swap when abs(x) == abs(y)
* and the sign of x is 1, which guarantees the result keeps the sign of x
* (and is +0 in the exact-cancellation case). */
m = ((word64)1 << 63) - 1;
za = (x & m) - (y & m);
cs = (word32)(za >> 63)
| ((1U - (word32)(((word64)0 - za) >> 63)) & (word32)(x >> 63));
m = (x ^ y) & ((word64)0 - (word64)cs);
x ^= m;
y ^= m;
/* Extract sign bits, biased exponents and mantissas. The mantissas are
* scaled up to the 2^55..2^56-1 range. A zero operand gets mantissa 0 and
* exponent -1078. */
ex = (int)(x >> 52);
sx = ex >> 11;
ex &= 0x7FF;
m = (word64)(word32)((ex + 0x7FF) >> 11) << 52;
xu = ((x & (((word64)1 << 52) - 1)) | m) << 3;
ex -= 1078;
ey = (int)(y >> 52);
sy = ey >> 11;
ey &= 0x7FF;
m = (word64)(word32)((ey + 0x7FF) >> 11) << 52;
yu = ((y & (((word64)1 << 52) - 1)) | m) << 3;
ey -= 1078;
/* x has the larger exponent; right-shift y to align. A shift of 60 bits or
* more clamps y to zero. */
cc = ex - ey;
yu &= (word64)0 - (word64)((word32)(cc - 60) >> 31);
cc &= 63;
/* The lowest bit of yu becomes sticky over the shifted-out bits. */
m = fpr_ulsh(1, cc) - 1;
yu |= (yu & m) + m;
yu = fpr_ursh(yu, cc);
/* Same sign: add mantissas; differing signs: subtract. */
xu += yu - ((yu << 1) & ((word64)0 - (word64)(sx ^ sy)));
/* Renormalize the (possibly cancelled or carried) result. */
FPR_NORM64(xu, ex);
/* Scale down to the 2^54..2^55-1 range, keeping a sticky low bit. */
xu |= ((word32)xu & 0x1FF) + 0x1FF;
xu >>= 9;
ex += 9;
/* The result keeps the sign of x (the swap above made the -0 corner cases
* impossible); FPR() clamps a too-low exponent to zero without altering
* the sign. */
return FPR(sx, ex, xu);
}
fpr fpr_sub(fpr x, fpr y)
{
y ^= (word64)1 << 63;
return fpr_add(x, y);
}
fpr fpr_neg(fpr x)
{
x ^= (word64)1 << 63;
return x;
}
fpr fpr_half(fpr x)
{
/* Halving subtracts 1 from the exponent; handle zero specially. */
word32 t;
x -= (word64)1 << 52;
t = (((word32)(x >> 52) & 0x7FF) + 1) >> 11;
x &= (word64)t - 1;
return x;
}
fpr fpr_double(fpr x)
{
/* Doubling increments the exponent; handle zero specially. Infinities and
* NaNs are not a concern for this backend. */
x += (word64)((((unsigned int)(x >> 52) & 0x7FFU) + 0x7FFU) >> 11) << 52;
return x;
}
fpr fpr_mul(fpr x, fpr y)
{
word64 xu, yu, w, zu, zv;
word32 x0, x1, y0, y1, z0, z1, z2;
int ex, ey, d, e, s;
/* Extract mantissas (with implicit bit) as 53-bit integers. */
xu = (x & (((word64)1 << 52) - 1)) | ((word64)1 << 52);
yu = (y & (((word64)1 << 52) - 1)) | ((word64)1 << 52);
/* Multiply the two 53-bit integers using 25-bit low halves so the low
* limbs (z0, z1) only ever matter for the sticky bit. */
x0 = (word32)xu & 0x01FFFFFF;
x1 = (word32)(xu >> 25);
y0 = (word32)yu & 0x01FFFFFF;
y1 = (word32)(yu >> 25);
w = (word64)x0 * (word64)y0;
z0 = (word32)w & 0x01FFFFFF;
z1 = (word32)(w >> 25);
w = (word64)x0 * (word64)y1;
z1 += (word32)w & 0x01FFFFFF;
z2 = (word32)(w >> 25);
w = (word64)x1 * (word64)y0;
z1 += (word32)w & 0x01FFFFFF;
z2 += (word32)(w >> 25);
zu = (word64)x1 * (word64)y1;
z2 += (z1 >> 25);
z1 &= 0x01FFFFFF;
zu += z2;
/* The product is in 2^104..2^106-1. Keep the top part (zu); fold the low
* limbs into a sticky bit. */
zu |= ((z0 | z1) + 0x01FFFFFF) >> 25;
/* Normalize zu to 2^54..2^55-1; it may be one bit too large. The
* conditional right-shift preserves the sticky bit. */
zv = (zu >> 1) | (zu & 1);
w = zu >> 55;
zu ^= (zu ^ zv) & ((word64)0 - w);
/* Aggregate scaling factor: sum the exponents, remove 2*(1023+52), then
* add 50 + w (the right-shift amounts applied above). */
ex = (int)((x >> 52) & 0x7FF);
ey = (int)((y >> 52) & 0x7FF);
e = ex + ey - 2100 + (int)w;
/* Result sign is the XOR of the operand signs. */
s = (int)((x ^ y) >> 63);
/* Corrective action: if either operand is zero, clamp the mantissa. */
d = ((ex + 0x7FF) & (ey + 0x7FF)) >> 11;
zu &= (word64)0 - (word64)d;
return FPR(s, e, zu);
}
fpr fpr_sqr(fpr x)
{
return fpr_mul(x, x);
}
fpr fpr_div(fpr x, fpr y)
{
word64 xu, yu, q, q2, w;
int i, ex, ey, e, d, s;
/* Extract mantissas (with implicit bit). */
xu = (x & (((word64)1 << 52) - 1)) | ((word64)1 << 52);
yu = (y & (((word64)1 << 52) - 1)) | ((word64)1 << 52);
/* Bit-by-bit long division of xu by yu, for 55 bits. */
q = 0;
for (i = 0; i < 55; i++) {
word64 b;
b = ((xu - yu) >> 63) - 1;
xu -= b & yu;
q |= b & 1;
xu <<= 1;
q <<= 1;
}
/* Make the 56th (extra) bit sticky: set it iff the remainder is nonzero. */
q |= (xu | ((word64)0 - xu)) >> 63;
/* Normalize q to the 2^54..2^55-1 range (conditional shift, sticky-aware);
* the top bit may be zero but then the next bit is one. */
q2 = (q >> 1) | (q & 1);
w = q >> 55;
q ^= (q ^ q2) & ((word64)0 - w);
/* Scaling: exponent biases cancel; remove 55 (division shift) and add w. */
ex = (int)((x >> 52) & 0x7FF);
ey = (int)((y >> 52) & 0x7FF);
e = ex - ey - 55 + (int)w;
/* Result sign is the XOR of the operand signs. */
s = (int)((x ^ y) >> 63);
/* Corrective action for x == 0 (division by zero is excluded by the
* caller's contract). */
d = (ex + 0x7FF) >> 11;
s &= d;
e &= -d;
q &= (word64)0 - (word64)d;
return FPR(s, e, q);
}
fpr fpr_inv(fpr x)
{
/* 1.0 / x: fpr_one is the bit pattern of the double 1.0. */
return fpr_div(fpr_one, x);
}
fpr fpr_sqrt(fpr x)
{
word64 xu, q, s, r;
int i, ex, e;
/* Extract the mantissa and the true exponent (mantissa in 1..2). The sign
* is ignored: the operand is assumed nonnegative. */
xu = (x & (((word64)1 << 52) - 1)) | ((word64)1 << 52);
ex = (int)((x >> 52) & 0x7FF);
e = ex - 1023;
/* If the exponent is odd, double the mantissa and decrement the exponent,
* then halve the exponent for the square root. */
xu += xu & ((word64)0 - (word64)(e & 1));
e >>= 1;
/* Double the mantissa: now in 2^53..2^55-1, representing a value in
* [1, 4) with 53 fractional bits. */
xu <<= 1;
/* Compute the square root bit by bit. */
q = 0;
s = 0;
r = (word64)1 << 53;
for (i = 0; i < 54; i++) {
word64 t, b;
t = s + r;
b = ((xu - t) >> 63) - 1;
s += (r << 1) & b;
xu -= t & b;
q += r & b;
xu <<= 1;
r >>= 1;
}
/* q is a rounded-low 54-bit value (leading 1, 52 fractional digits and a
* guard bit); add a sticky bit for the remaining operand. */
q <<= 1;
q |= (xu | ((word64)0 - xu)) >> 63;
/* q is now an integer in 2^54..2^55-1; bias the exponent by 54. */
e -= 54;
/* Corrective action for an operand of value zero. */
q &= (word64)0 - (word64)((ex + 0x7FF) >> 11);
return FPR(0, e, q);
}
/* ------------------------------------------------------------------------ */
/* Predicates. */
/* ------------------------------------------------------------------------ */
int fpr_lt(fpr x, fpr y)
{
/* For equal signs a signed comparison of the bit patterns yields the
* correct order (and x - y does not overflow). For differing signs the
* sign of x decides. For two negatives the order is reversed, so we
* combine sgn(x-y) and sgn(y-x). */
int cc0, cc1;
sword64 sx;
sword64 sy;
sx = (sword64)x;
sy = (sword64)y;
sy &= ~((sx ^ sy) >> 63); /* sy = 0 if the signs differ */
cc0 = (int)((sx - sy) >> 63) & 1; /* neither subtraction overflows when */
cc1 = (int)((sy - sx) >> 63) & 1; /* the signs are the same */
return cc0 ^ ((cc0 ^ cc1) & (int)((x & y) >> 63));
}
#endif /* !WOLFSSL_FALCON_FPR_ASM */
/* ------------------------------------------------------------------------ */
/* Sampler support: ccs * exp(-x) in fixed point scaled by 2^63. */
/* ------------------------------------------------------------------------ */
/* Top 64 bits of the 128-bit product z*y. This is the inner operation of the
* Bernoulli-exp polynomial and the hottest scalar op in signing. On 64-bit
* targets it is a single multiply instruction; the portable 32x32 fallback
* (one MUL becomes four) is kept for platforms without a 128-bit integer type
* (e.g. Cortex-M). Both paths are constant-time and bit-identical. */
#if defined(__SIZEOF_INT128__)
#define FALCON_MULHI(z, y) \
((word64)(((unsigned __int128)(word64)(z) * (unsigned __int128)(word64)(y)) >> 64))
#else
static WC_INLINE word64 falcon_mulhi(word64 z, word64 y)
{
word32 z0 = (word32)z, z1 = (word32)(z >> 32);
word32 y0 = (word32)y, y1 = (word32)(y >> 32);
word64 a = ((word64)z0 * (word64)y1) + (((word64)z0 * (word64)y0) >> 32);
word64 b = ((word64)z1 * (word64)y0);
word64 c = (a >> 32) + (b >> 32);
c += (((word64)(word32)a + (word64)(word32)b) >> 32);
c += (word64)z1 * (word64)y1;
return c;
}
#define FALCON_MULHI(z, y) falcon_mulhi((z), (y))
#endif
word64 fpr_expm_p63(fpr x, fpr ccs)
{
/* Polynomial approximation of exp(-x), coefficients from FACCT
* (https://eprint.iacr.org/2018/1234, https://github.com/raykzhao/gaussian)
* scaled up by 2^63 and converted to integers. The maximum observed
* deviation from the true value over the 0..log(2) range is below
* 2^(-50). */
static const word64 C[] = {
0x00000004741183A3u,
0x00000036548CFC06u,
0x0000024FDCBF140Au,
0x0000171D939DE045u,
0x0000D00CF58F6F84u,
0x000680681CF796E3u,
0x002D82D8305B0FEAu,
0x011111110E066FD0u,
0x0555555555070F00u,
0x155555555581FF00u,
0x400000000002B400u,
0x7FFFFFFFFFFF4800u,
0x8000000000000000u
};
word64 z, y;
/* Horner evaluation of the degree-12 polynomial; each step keeps the top
* 64 bits of z*y. Fully unrolled (the loop bound is a compile-time 13). */
y = C[0];
z = (word64)fpr_trunc(fpr_mul(x, fpr_ptwo63)) << 1;
y = C[1] - FALCON_MULHI(z, y);
y = C[2] - FALCON_MULHI(z, y);
y = C[3] - FALCON_MULHI(z, y);
y = C[4] - FALCON_MULHI(z, y);
y = C[5] - FALCON_MULHI(z, y);
y = C[6] - FALCON_MULHI(z, y);
y = C[7] - FALCON_MULHI(z, y);
y = C[8] - FALCON_MULHI(z, y);
y = C[9] - FALCON_MULHI(z, y);
y = C[10] - FALCON_MULHI(z, y);
y = C[11] - FALCON_MULHI(z, y);
y = C[12] - FALCON_MULHI(z, y);
/* Apply the scaling factor ccs (converted to the same fixed-point format)
* with a final 64x64->high-64 multiplication. */
z = (word64)fpr_trunc(fpr_mul(ccs, fpr_ptwo63)) << 1;
y = FALCON_MULHI(z, y);
return y;
}
/* ------------------------------------------------------------------------ */
/* Named constants: IEEE-754 binary64 bit patterns. */
/* ------------------------------------------------------------------------ */
const fpr fpr_zero = 0;
const fpr fpr_one = 4607182418800017408U; /* 1.0 */
const fpr fpr_two = 4611686018427387904U; /* 2.0 */
const fpr fpr_onehalf = 4602678819172646912U; /* 0.5 */
const fpr fpr_invsqrt2 = 4604544271217802189U; /* 1/sqrt(2) */
const fpr fpr_invsqrt8 = 4600040671590431693U; /* 1/sqrt(8) */
const fpr fpr_ptwo31 = 4746794007248502784U; /* 2^31 */
const fpr fpr_ptwo31m1 = 4746794007244308480U; /* 2^31 - 1 */
const fpr fpr_mtwo31m1 = 13970166044099084288U; /* -(2^31 - 1) */
const fpr fpr_ptwo63m1 = 4890909195324358656U; /* 2^63 - 1 */
const fpr fpr_mtwo63m1 = 14114281232179134464U; /* -(2^63 - 1) */
const fpr fpr_ptwo63 = 4890909195324358656U; /* 2^63 */
#endif /* HAVE_FALCON */
File diff suppressed because it is too large Load Diff
-310
View File
@@ -1,310 +0,0 @@
/* wc_falcon_poly.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Falcon FFT-domain polynomial operations over the fpr seam. Faithful
* port of the poly_* functions from the MIT-licensed Falcon reference (fft.c,
* Thomas Pornin). See wolfssl/wolfcrypt/wc_falcon_poly.h. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
#include <wolfssl/wolfcrypt/wc_falcon_poly.h>
#include <wolfssl/wolfcrypt/wc_falcon_fft.h> /* falcon_gm_tab */
/* Complex helpers (temps make the macros alias-safe). */
#define FPC_ADD(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
(d_re) = fpr_add(_ar, _br); \
(d_im) = fpr_add(_ai, _bi); \
} while (0)
#define FPC_SUB(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
(d_re) = fpr_sub(_ar, _br); \
(d_im) = fpr_sub(_ai, _bi); \
} while (0)
#define FPC_MUL(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
(d_re) = fpr_sub(fpr_mul(_ar, _br), fpr_mul(_ai, _bi)); \
(d_im) = fpr_add(fpr_mul(_ar, _bi), fpr_mul(_ai, _br)); \
} while (0)
/* (a) / (b) for complex a,b. */
#define FPC_DIV(d_re, d_im, a_re, a_im, b_re, b_im) do { \
fpr _ar = (a_re), _ai = (a_im), _br = (b_re), _bi = (b_im); \
fpr _m = fpr_inv(fpr_add(fpr_mul(_br, _br), fpr_mul(_bi, _bi))); \
_br = fpr_mul(_br, _m); \
_bi = fpr_neg(fpr_mul(_bi, _m)); \
(d_re) = fpr_sub(fpr_mul(_ar, _br), fpr_mul(_ai, _bi)); \
(d_im) = fpr_add(fpr_mul(_ar, _bi), fpr_mul(_ai, _br)); \
} while (0)
void falcon_poly_add(fpr* a, const fpr* b, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_add_avx2(a, b, logn);
#else
size_t n = (size_t)1 << logn, u;
for (u = 0; u < n; u++) {
a[u] = fpr_add(a[u], b[u]);
}
#endif
}
void falcon_poly_sub(fpr* a, const fpr* b, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_sub_avx2(a, b, logn);
#else
size_t n = (size_t)1 << logn, u;
for (u = 0; u < n; u++) {
a[u] = fpr_sub(a[u], b[u]);
}
#endif
}
void falcon_poly_neg(fpr* a, unsigned logn)
{
size_t n = (size_t)1 << logn, u;
for (u = 0; u < n; u++) {
a[u] = fpr_neg(a[u]);
}
}
void falcon_poly_adj_fft(fpr* a, unsigned logn)
{
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = hn; u < n; u++) {
a[u] = fpr_neg(a[u]);
}
}
void falcon_poly_mul_fft(fpr* a, const fpr* b, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_mul_fft_avx2(a, b, logn);
#else
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr a_re = a[u], a_im = a[u + hn];
fpr b_re = b[u], b_im = b[u + hn];
FPC_MUL(a[u], a[u + hn], a_re, a_im, b_re, b_im);
}
#endif
}
void falcon_poly_muladj_fft(fpr* a, const fpr* b, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_muladj_fft_avx2(a, b, logn);
#else
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr a_re = a[u], a_im = a[u + hn];
fpr b_re = b[u], b_im = fpr_neg(b[u + hn]);
FPC_MUL(a[u], a[u + hn], a_re, a_im, b_re, b_im);
}
#endif
}
void falcon_poly_mulselfadj_fft(fpr* a, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_mulselfadj_fft_avx2(a, logn);
#else
/* a * adj(a) = |a|^2 (real). */
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr a_re = a[u], a_im = a[u + hn];
a[u] = fpr_add(fpr_mul(a_re, a_re), fpr_mul(a_im, a_im));
a[u + hn] = fpr_zero;
}
#endif
}
void falcon_poly_mulconst(fpr* a, fpr x, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_mulconst_avx2(a, x, logn);
#else
size_t n = (size_t)1 << logn, u;
for (u = 0; u < n; u++) {
a[u] = fpr_mul(a[u], x);
}
#endif
}
void falcon_poly_div_fft(fpr* a, const fpr* b, unsigned logn)
{
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr a_re = a[u], a_im = a[u + hn];
fpr b_re = b[u], b_im = b[u + hn];
FPC_DIV(a[u], a[u + hn], a_re, a_im, b_re, b_im);
}
}
void falcon_poly_invnorm2_fft(fpr* d, const fpr* a, const fpr* b, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_invnorm2_fft_avx2(d, a, b, logn);
#else
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr a_re = a[u], a_im = a[u + hn];
fpr b_re = b[u], b_im = b[u + hn];
d[u] = fpr_inv(fpr_add(
fpr_add(fpr_mul(a_re, a_re), fpr_mul(a_im, a_im)),
fpr_add(fpr_mul(b_re, b_re), fpr_mul(b_im, b_im))));
}
#endif
}
void falcon_poly_add_muladj_fft(fpr* d, const fpr* F, const fpr* G,
const fpr* f, const fpr* g, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_add_muladj_fft_avx2(d, F, G, f, g, logn);
#else
/* d = F*adj(f) + G*adj(g). */
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr F_re = F[u], F_im = F[u + hn];
fpr G_re = G[u], G_im = G[u + hn];
fpr f_re = f[u], f_im = f[u + hn];
fpr g_re = g[u], g_im = g[u + hn];
fpr a_re, a_im, b_re, b_im;
FPC_MUL(a_re, a_im, F_re, F_im, f_re, fpr_neg(f_im));
FPC_MUL(b_re, b_im, G_re, G_im, g_re, fpr_neg(g_im));
d[u] = fpr_add(a_re, b_re);
d[u + hn] = fpr_add(a_im, b_im);
}
#endif
}
void falcon_poly_mul_autoadj_fft(fpr* a, const fpr* b, unsigned logn)
{
/* b is self-adjoint (real); only its lower half is meaningful. */
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
a[u] = fpr_mul(a[u], b[u]);
a[u + hn] = fpr_mul(a[u + hn], b[u]);
}
}
void falcon_poly_div_autoadj_fft(fpr* a, const fpr* b, unsigned logn)
{
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr ib = fpr_inv(b[u]);
a[u] = fpr_mul(a[u], ib);
a[u + hn] = fpr_mul(a[u + hn], ib);
}
}
void falcon_poly_LDL_fft(const fpr* g00, fpr* g01, fpr* g11, unsigned logn)
{
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr g00_re = g00[u], g00_im = g00[u + hn];
fpr g01_re = g01[u], g01_im = g01[u + hn];
fpr g11_re = g11[u], g11_im = g11[u + hn];
fpr mu_re, mu_im, xx_re, xx_im;
FPC_DIV(mu_re, mu_im, g01_re, g01_im, g00_re, g00_im);
FPC_MUL(xx_re, xx_im, mu_re, mu_im, g01_re, fpr_neg(g01_im));
FPC_SUB(g11[u], g11[u + hn], g11_re, g11_im, xx_re, xx_im);
g01[u] = mu_re;
g01[u + hn] = fpr_neg(mu_im);
}
}
void falcon_poly_LDLmv_fft(fpr* d11, fpr* l10, const fpr* g00, const fpr* g01,
const fpr* g11, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_LDLmv_fft_avx2(d11, l10, g00, g01, g11, logn);
#else
size_t n = (size_t)1 << logn, hn = n >> 1, u;
for (u = 0; u < hn; u++) {
fpr g00_re = g00[u], g00_im = g00[u + hn];
fpr g01_re = g01[u], g01_im = g01[u + hn];
fpr g11_re = g11[u], g11_im = g11[u + hn];
fpr mu_re, mu_im, xx_re, xx_im;
FPC_DIV(mu_re, mu_im, g01_re, g01_im, g00_re, g00_im);
FPC_MUL(xx_re, xx_im, mu_re, mu_im, g01_re, fpr_neg(g01_im));
FPC_SUB(d11[u], d11[u + hn], g11_re, g11_im, xx_re, xx_im);
l10[u] = mu_re;
l10[u + hn] = fpr_neg(mu_im);
}
#endif
}
void falcon_poly_split_fft(fpr* f0, fpr* f1, const fpr* f, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_split_fft_avx2(f0, f1, f, logn);
#else
size_t n = (size_t)1 << logn, hn = n >> 1, qn = hn >> 1, u;
/* Base case (logn==1, qn==0): single coefficient halves. */
f0[0] = f[0];
f1[0] = f[hn];
for (u = 0; u < qn; u++) {
fpr a_re = f[(u << 1) + 0], a_im = f[(u << 1) + 0 + hn];
fpr b_re = f[(u << 1) + 1], b_im = f[(u << 1) + 1 + hn];
fpr t_re, t_im;
FPC_ADD(t_re, t_im, a_re, a_im, b_re, b_im);
f0[u] = fpr_half(t_re);
f0[u + qn] = fpr_half(t_im);
FPC_SUB(t_re, t_im, a_re, a_im, b_re, b_im);
FPC_MUL(t_re, t_im, t_re, t_im,
falcon_gm_tab[((u + hn) << 1) + 0],
fpr_neg(falcon_gm_tab[((u + hn) << 1) + 1]));
f1[u] = fpr_half(t_re);
f1[u + qn] = fpr_half(t_im);
}
#endif
}
void falcon_poly_merge_fft(fpr* f, const fpr* f0, const fpr* f1, unsigned logn)
{
#if defined(WOLFSSL_FALCON_FFT_AVX2)
falcon_poly_merge_fft_avx2(f, f0, f1, logn);
#else
size_t n = (size_t)1 << logn, hn = n >> 1, qn = hn >> 1, u;
/* Base case (logn==1, qn==0). */
f[0] = f0[0];
f[hn] = f1[0];
for (u = 0; u < qn; u++) {
fpr a_re = f0[u], a_im = f0[u + qn];
fpr b_re, b_im, t_re, t_im;
FPC_MUL(b_re, b_im, f1[u], f1[u + qn],
falcon_gm_tab[((u + hn) << 1) + 0],
falcon_gm_tab[((u + hn) << 1) + 1]);
FPC_ADD(t_re, t_im, a_re, a_im, b_re, b_im);
f[(u << 1) + 0] = t_re;
f[(u << 1) + 0 + hn] = t_im;
FPC_SUB(t_re, t_im, a_re, a_im, b_re, b_im);
f[(u << 1) + 1] = t_re;
f[(u << 1) + 1 + hn] = t_im;
}
#endif
}
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
-388
View File
@@ -1,388 +0,0 @@
/* wc_falcon_sampler.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Discrete Gaussian sampler (SamplerZ) for Falcon signing.
*
* This is a faithful port of the constant-time reference sampler written by
* Thomas Pornin for the Falcon submission (MIT licensed). The identical code
* is distributed in PQClean as the gaussian0_sampler / BerExp / sampler trio
* (e.g. crypto_sign/falcon-512/clean/sign.c). It has been adapted to wolfSSL
* house style (word32/word64/sword64, WOLFSSL_LOCAL linkage) and re-targeted
* onto two wolfSSL seams:
*
* 1. The floating-point seam wolfssl/wolfcrypt/wc_falcon_fpr.h. All real
* arithmetic goes through fpr_* (round-to-nearest-even IEEE-754 binary64,
* bit-exact and branch-free in the default integer-emulated backend), and
* the Bernoulli test uses fpr_expm_p63().
* 2. A SHAKE256 randomness stream (wolfssl/wolfcrypt/sha3.h) seeded from a
* WC_RNG (wolfssl/wolfcrypt/random.h), replacing the reference's ChaCha20
* PRNG. The sampler algorithm is agnostic to the byte source; only the
* uniform-byte contract matters for correctness and security.
*
* CONSTANT TIME / SIDE CHANNELS
* - gaussian0() consumes a fixed 9 random bytes and runs a fixed-length,
* branch-free table scan (comparison via borrow bits), so its running time
* and PRNG consumption are independent of the sampled value.
* - BerExp() and sampler() perform no branch or memory access that depends
* on the secret center (mu) or secret inverse-sigma (isigma): the only
* data-dependent control flow is the rejection-sampling retry loop and
* BerExp's lazy byte comparison, both of which depend solely on fresh
* uniform random bytes (the rejection probability is deliberately
* decorrelated from mu/sigma by the sigma_min scaling factor ccs). This is
* the standard Falcon argument; see the reference comments reproduced
* below.
* - The fpr backend supplies constant-time, value-independent arithmetic, so
* no floating-point operation leaks operand values through timing.
*
* This translation unit is the signing-only sampler and is therefore excluded
* from verify-only builds. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
#include <wolfssl/wolfcrypt/wc_falcon_sampler.h>
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
/* ------------------------------------------------------------------------ */
/* fpr constants needed by the sampler that are not exported by the seam. */
/* */
/* These are IEEE-754 binary64 bit patterns, identical to the values used by */
/* the Falcon reference (fpr.h). Each has been verified by decoding the bit */
/* pattern back to the documented decimal value (shown in the comment). */
/* ------------------------------------------------------------------------ */
/* log(2) = 0.6931471805599453 */
static const fpr falcon_fpr_log2 = (fpr)4604418534313441775U;
/* 1/log(2) = 1.4426950408889634 */
static const fpr falcon_fpr_inv_log2 = (fpr)4609176140021203710U;
/* 1/(2*sigma0^2) with sigma0 = 1.8205 -> 0.15086504887537272 */
static const fpr falcon_fpr_inv_2sqrsigma0 = (fpr)4594603506513722306U;
/* sigma_min, indexed by logn (degree = 2^logn). These match the Falcon
* specification's sigma_min(n) table; entries decode to a smooth monotonic
* curve from 1.1165 (n=2) to 1.2983 (n=1024). Falcon uses logn 9 and 10:
* logn = 9 (Falcon-512 ) : 1.2778336969128337
* logn = 10 (Falcon-1024) : 1.298280334344292 */
static const fpr falcon_fpr_sigma_min[11] = {
(fpr)0U, /* logn 0 : unused */
(fpr)4607707126469777035U, /* logn 1 : 1.1165085072 */
(fpr)4607777455861499430U, /* logn 2 : 1.1321247692 */
(fpr)4607846828256951418U, /* logn 3 : 1.1475285354 */
(fpr)4607949175006100261U, /* logn 4 : 1.1702540789 */
(fpr)4608049571757433526U, /* logn 5 : 1.1925466358 */
(fpr)4608148125896792003U, /* logn 6 : 1.2144300508 */
(fpr)4608244935301382692U, /* logn 7 : 1.2359260568 */
(fpr)4608340089478362016U, /* logn 8 : 1.2570545284 */
(fpr)4608433670533905013U, /* logn 9 : 1.2778336969 */
(fpr)4608525754002622308U /* logn 10: 1.2982803343 */
};
/* ------------------------------------------------------------------------ */
/* SHAKE256 pseudo-random byte stream. */
/* */
/* Construction: absorb FALCON_PRNG_SEED_LEN fresh bytes from WC_RNG into a */
/* SHAKE256 sponge, then squeeze the output in fixed FALCON_PRNG_BLOCKS-block */
/* batches. get_u64 reads 8 stream bytes little-endian; get_u8 reads one. */
/* The refill is a fixed-size squeeze, hence constant-time; consumption order */
/* (and thus how many bytes are discarded at a refill boundary) never */
/* depends on a secret. */
/* ------------------------------------------------------------------------ */
/* Squeeze a fresh batch of blocks into the buffer. Constant-time. */
static int falcon_prng_refill(falcon_prng* p)
{
int ret;
/* Once the sticky error is latched the stream is already invalid and the
* result will be rejected; don't keep re-issuing failing squeezes. */
if (p->err != 0) {
p->ptr = 0;
p->len = 0;
return p->err;
}
ret = wc_Shake256_SqueezeBlocks(&p->shake, p->buf, FALCON_PRNG_BLOCKS);
p->ptr = 0;
p->len = (ret == 0) ? (word32)FALCON_PRNG_BUFLEN : 0;
/* Latch the first failure. get_u8/get_u64 have no error return, so a squeeze
* failure is made sticky here and checked by the signer (falcon_sign_core),
* which rejects any signature produced from an invalid PRNG state instead of
* consuming stale buffer bytes. */
if (ret != 0)
p->err = ret;
return ret;
}
int falcon_prng_init(falcon_prng* p, WC_RNG* rng)
{
byte seed[FALCON_PRNG_SEED_LEN];
int ret;
if (p == NULL || rng == NULL)
return BAD_FUNC_ARG;
p->ptr = 0;
p->len = 0;
p->err = 0;
ret = wc_RNG_GenerateBlock(rng, seed, (word32)sizeof(seed));
if (ret == 0) {
ret = wc_InitShake256(&p->shake, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Shake256_Absorb(&p->shake, seed, (word32)sizeof(seed));
if (ret == 0)
ret = falcon_prng_refill(p);
/* On failure past a successful init the caller never sees a live
* context (falcon_native_sign_msg only frees the sponge when this
* function succeeded), so release it here. This matters in
* WOLFSSL_ASYNC_CRYPT builds where wc_InitShake256 allocates a
* device context. */
if (ret != 0)
wc_Shake256_Free(&p->shake);
}
}
ForceZero(seed, (word32)sizeof(seed));
return ret;
}
byte falcon_prng_get_u8(falcon_prng* p)
{
byte v;
/* On a refill failure len becomes 0 and p->err is latched; the buffer read
* below stays in bounds (ptr reset to 0) but yields a discarded value --
* falcon_sign_core checks p->err and rejects the resulting signature. */
if (p->ptr + 1U > p->len)
(void)falcon_prng_refill(p);
v = p->buf[p->ptr];
p->ptr += 1U;
return v;
}
word64 falcon_prng_get_u64(falcon_prng* p)
{
word64 v;
word32 i;
if (p->ptr + 8U > p->len)
(void)falcon_prng_refill(p);
i = p->ptr;
v = (word64)p->buf[i + 0]
| ((word64)p->buf[i + 1] << 8)
| ((word64)p->buf[i + 2] << 16)
| ((word64)p->buf[i + 3] << 24)
| ((word64)p->buf[i + 4] << 32)
| ((word64)p->buf[i + 5] << 40)
| ((word64)p->buf[i + 6] << 48)
| ((word64)p->buf[i + 7] << 56);
p->ptr += 8U;
return v;
}
/* ------------------------------------------------------------------------ */
/* gaussian0: base half-Gaussian sampler (centered on 0, sigma0 = 1.8205). */
/* */
/* Faithful port of Pornin's reference gaussian0_sampler. The RCDT (reverse */
/* cumulative distribution table) "dist[]" below is copied VERBATIM from the */
/* Falcon reference implementation (18 rows; each row is a 72-bit threshold */
/* stored as three 24-bit limbs, most significant limb first). It is the */
/* same table that appears in PQClean's */
/* crypto_sign/falcon-512/clean/sign.c */
/* and in the original Falcon round-3 reference. Do not edit these numbers. */
/* ------------------------------------------------------------------------ */
int falcon_gaussian0(falcon_prng* p)
{
/* RCDT for the half-Gaussian of standard deviation sigma0 = 1.8205,
* verbatim from the Falcon reference (Thomas Pornin). Each row holds a
* 72-bit value as (hi24, mid24, lo24). */
static const word32 dist[] = {
10745844u, 3068844u, 3741698u,
5559083u, 1580863u, 8248194u,
2260429u, 13669192u, 2736639u,
708981u, 4421575u, 10046180u,
169348u, 7122675u, 4136815u,
30538u, 13063405u, 7650655u,
4132u, 14505003u, 7826148u,
417u, 16768101u, 11363290u,
31u, 8444042u, 8086568u,
1u, 12844466u, 265321u,
0u, 1232676u, 13644283u,
0u, 38047u, 9111839u,
0u, 870u, 6138264u,
0u, 14u, 12545723u,
0u, 0u, 3104126u,
0u, 0u, 28824u,
0u, 0u, 198u,
0u, 0u, 1u
};
word32 v0, v1, v2, hi;
word64 lo;
word32 u;
int z;
/* Get a random 72-bit value, into three 24-bit limbs v0..v2. */
lo = falcon_prng_get_u64(p);
hi = (word32)falcon_prng_get_u8(p);
v0 = (word32)lo & 0xFFFFFFu;
v1 = (word32)(lo >> 24) & 0xFFFFFFu;
v2 = (word32)(lo >> 48) | (hi << 16);
/* Sampled value is z, the number of leading table thresholds that the
* uniform 72-bit value (v0..v2) is strictly less than. Done with borrow
* bits, fully branch-free. */
z = 0;
for (u = 0; u < (word32)((sizeof dist) / sizeof(dist[0])); u += 3) {
word32 w0, w1, w2, cc;
w0 = dist[u + 2];
w1 = dist[u + 1];
w2 = dist[u + 0];
cc = (v0 - w0) >> 31;
cc = (v1 - w1 - cc) >> 31;
cc = (v2 - w2 - cc) >> 31;
z += (int)cc;
}
return z;
}
/* ------------------------------------------------------------------------ */
/* BerExp: Bernoulli test, returns 1 with probability ccs * exp(-x). */
/* */
/* Faithful port of Pornin's reference BerExp. x >= 0 is guaranteed by the */
/* caller. The only data-dependent loop is the lazy 8-bit comparison, whose */
/* iteration count depends on fresh random bytes, not on secrets. */
/* ------------------------------------------------------------------------ */
static int falcon_berexp(falcon_prng* p, fpr x, fpr ccs)
{
int s, i;
fpr r;
word32 sw, w;
word64 z;
/* Reduce x modulo log(2): x = s*log(2) + r, with s an integer and
* 0 <= r < log(2). Since x >= 0 we can use fpr_trunc (toward zero). */
s = (int)fpr_trunc(fpr_mul(x, falcon_fpr_inv_log2));
r = fpr_sub(x, fpr_mul(fpr_of((sword64)s), falcon_fpr_log2));
/* It may happen (rarely) that s >= 64; if so, BerExp would be non-zero
* with probability below 2^-64, so we simply saturate s at 63. */
sw = (word32)s;
sw ^= (sw ^ 63u) & (word32)(0U - ((63u - sw) >> 31));
s = (int)sw;
/* exp(-r), scaled to 2^63, scaled up to 2^64, then >> s to obtain
* exp(-x) = 2^-s * exp(-r). The "-1" keeps the value on 64 bits. */
z = ((fpr_expm_p63(r, ccs) << 1) - 1) >> s;
/* Compare exp(-x) against fresh random bytes, 8 bits at a time; the sign
* of the difference yields the sampled bit. */
i = 64;
do {
i -= 8;
w = (word32)falcon_prng_get_u8(p) - ((word32)(z >> i) & 0xFFu);
} while ((w == 0) && (i > 0));
return (int)(w >> 31);
}
/* ------------------------------------------------------------------------ */
/* sampler (SamplerZ): discrete Gaussian of center mu, std dev 1/isigma. */
/* */
/* Faithful port of Pornin's reference sampler. ctx is an falcon_sampler_ctx. */
/* ------------------------------------------------------------------------ */
int falcon_sampler_z(void* ctx, fpr mu, fpr isigma)
{
falcon_sampler_ctx* spc = (falcon_sampler_ctx*)ctx;
int s;
fpr r, dss, ccs;
/* Center is mu = s + r, with s an integer and 0 <= r < 1. */
s = (int)fpr_floor(mu);
r = fpr_sub(mu, fpr_of((sword64)s));
/* dss = 1/(2*sigma^2) = 0.5 * isigma^2. */
dss = fpr_half(fpr_sqr(isigma));
/* ccs = sigma_min / sigma = sigma_min * isigma. */
ccs = fpr_mul(isigma, spc->sigma_min);
/* Sample on center r. */
for (;;) {
int z0, z, b;
fpr x;
/* A wedged PRNG (latched sticky error) turns every squeezed byte into
* a constant, which can make the rejection test below deterministic --
* and, if it rejects, this loop endless. Bail out instead: the value
* returned is discarded, as falcon_sign_core rejects the entire
* signature whenever p.err is set. */
if (spc->p.err != 0) {
return s;
}
/* Half-Gaussian sample, plus a random bit b turning it bimodal:
* b = 1 -> use z0+1 (centered on 1), b = 0 -> use -z0 (centered 0). */
z0 = falcon_gaussian0(&spc->p);
b = (int)falcon_prng_get_u8(&spc->p) & 1;
z = b + ((b << 1) - 1) * z0;
/* Rejection sampling. Keep z with probability exp(-x), where
* x = ((z-r)^2)/(2*sigma^2) - (z0^2)/(2*sigma0^2).
* The sigma_min scaling in ccs decorrelates the rejection rate from
* mu/sigma, keeping the whole sampler constant-time. */
x = fpr_mul(fpr_sqr(fpr_sub(fpr_of((sword64)z), r)), dss);
x = fpr_sub(x, fpr_mul(fpr_of((sword64)(z0 * z0)),
falcon_fpr_inv_2sqrsigma0));
if (falcon_berexp(&spc->p, x, ccs)) {
/* Rejection was centered on r; the actual center is mu = s + r. */
return s + z;
}
}
}
/* ------------------------------------------------------------------------ */
/* Context initialisation. */
/* ------------------------------------------------------------------------ */
int falcon_sampler_init(falcon_sampler_ctx* spc, int logn, WC_RNG* rng)
{
int ret;
if (spc == NULL || rng == NULL)
return BAD_FUNC_ARG;
if (logn < 1 || logn > 10)
return BAD_FUNC_ARG;
spc->sigma_min = falcon_fpr_sigma_min[logn];
ret = falcon_prng_init(&spc->p, rng);
return ret;
}
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
-886
View File
@@ -1,886 +0,0 @@
/* wc_falcon_sign.c
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Falcon signing orchestration. See wolfssl/wolfcrypt/wc_falcon_sign.h.
*
* Faithful port of the signature-generation core of the MIT-licensed Falcon
* reference implementation sign.c (Thomas Pornin, Falcon Project, 2017-2019):
* expand_privkey (B0 basis in FFT + ffLDL tree), ffSampling_fft and
* do_sign_tree. The big-integer NTRU completion of G (complete_private) is done
* here over the FFT seam. All floating-point work flows through the abstract
* fpr_* seam (wc_falcon_fpr / fft / poly); the discrete Gaussian sampler and its
* SHAKE256-backed randomness come from wc_falcon_sampler. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY) && !defined(WOLF_CRYPTO_CB_ONLY_FALCON)
#include <wolfssl/wolfcrypt/wc_falcon_sign.h>
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
#include <wolfssl/wolfcrypt/wc_falcon_fft.h>
#include <wolfssl/wolfcrypt/wc_falcon_poly.h>
#include <wolfssl/wolfcrypt/wc_falcon_sampler.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define MKN(logn) ((size_t)1 << (logn))
#define FALCON_Q 12289
/* Safety bound on the sign-tree restart loop. The per-iteration restart
* probability is well below 1 (expected iteration count ~1), so the chance of
* legitimately reaching even a few dozen restarts is astronomically small; this
* bound is never approached in normal operation. It only guarantees termination
* if the sampler can no longer produce accepting candidates (e.g. a failed PRNG
* squeeze), in which case falcon_sign_core additionally rejects the result via
* the PRNG's sticky error. */
#define FALCON_SIGN_MAX_RESTARTS 4096UL
/* IEEE-754 binary64 bit patterns (the fpr seam carries doubles as word64).
* These mirror named constants from the reference fpr.h that are not part of
* the public wc_falcon_fpr.h API. fpr_invsqrt2 / fpr_invsqrt8 ARE exported by
* the seam and are used directly. */
static const fpr fpr_q = 4667981563525332992ULL; /* (double)12289 */
static const fpr fpr_inverse_of_q = 4545632735260551042ULL; /* 1/12289 */
/* 1/sigma, indexed by logn (1..10). Ported from the reference fpr.h. */
static const fpr fpr_inv_sigma[] = {
0, /* unused */
4574611497772390042ULL,
4574501679055810265ULL,
4574396282908341804ULL,
4574245855758572086ULL,
4574103865040221165ULL,
4573969550563515544ULL,
4573842244705920822ULL,
4573721358406441454ULL,
4573606369665796042ULL,
4573496814039276259ULL
};
/* Acceptance bound for the (squared) l2-norm of the signature, indexed by logn
* (1..10). Inclusive bounds (= floor(beta^2)). Ported from the reference
* common.c l2bound[]. */
static const word32 l2bound[] = {
0, /* unused */
101498u,
208714u,
428865u,
892039u,
1852696u,
3842630u,
7959734u,
16468416u,
34034726u,
70265242u
};
/* ==================================================================== */
/* complete_private: recompute G from (f, g, F). */
/* The keygen NTRU solver produces (F, G) such that f*G - g*F = q, hence
* G = (g*F + q) / f. We recompute it over the FFT seam, add the constant q to
* the real (lower) half of the FFT representation, divide by f, inverse-FFT and
* round to integers. */
int falcon_complete_private(sword8* G, const sword8* f, const sword8* g,
const sword8* F, unsigned logn, void* heap)
{
size_t n, hn, u;
fpr* t1;
fpr* t2;
fpr* t3;
int ret = 0;
if (G == NULL || f == NULL || g == NULL || F == NULL
|| logn < 1 || logn > 10) {
return BAD_FUNC_ARG;
}
n = MKN(logn);
hn = n >> 1;
/* Three working polynomials. */
t1 = (fpr*)XMALLOC((size_t)3 * n * sizeof(fpr), heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (t1 == NULL) {
return MEMORY_E;
}
t2 = t1 + n;
t3 = t2 + n;
for (u = 0; u < n; u++) {
t1[u] = fpr_of(g[u]); /* g */
t2[u] = fpr_of(F[u]); /* F */
t3[u] = fpr_of(f[u]); /* f */
}
falcon_FFT(t1, logn);
falcon_FFT(t2, logn);
falcon_FFT(t3, logn);
/* t1 <- g*F. */
falcon_poly_mul_fft(t1, t2, logn);
/* t1 <- g*F + q. The constant polynomial q evaluates to q (a real value) at
* every FFT point, so only the real (lower) half is incremented. */
for (u = 0; u < hn; u++) {
t1[u] = fpr_add(t1[u], fpr_q);
}
/* t1 <- (g*F + q) / f. */
falcon_poly_div_fft(t1, t3, logn);
falcon_iFFT(t1, logn);
for (u = 0; u < n; u++) {
sword64 z;
z = fpr_rint(t1[u]);
if (z < -127 || z > 127) {
ret = BAD_FUNC_ARG;
break;
}
G[u] = (sword8)z;
}
/* t1 held the FFT images of the secret basis (g, F, f) and the derived G. */
wc_ForceZero(t1, (word32)((size_t)3 * n * sizeof(fpr)));
XFREE(t1, heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
/* ==================================================================== */
/* ffLDL tree construction (expand_privkey). */
/* Size of the ffLDL tree (number of fpr elements) for polynomials of degree
* 2^logn: s(0) = 1, s(logn) = 2^logn + 2*s(logn-1) => (logn+1)*2^logn. */
static WC_INLINE unsigned ffLDL_treesize(unsigned logn)
{
return (logn + 1) << logn;
}
/* The reference implementation expresses ffLDL construction, tree
* normalization and Fast Fourier sampling as self-recursions on logn. wolfSSL
* forbids recursion, so each is flattened here into an iteration over an
* explicit stack of frames; depth is bounded by logn <= 10, so the stacks are
* small fixed arrays. Sub-invocations run in exactly the reference order --
* for ffSampling this is a hard requirement, since the discrete Gaussian
* sampler consumes a PRNG stream and only the reference order reproduces the
* reference signatures. */
/* One pending ffLDL_fft_inner sub-invocation. */
typedef struct ffLDL_job {
fpr* tree;
fpr* g0;
fpr* g1;
unsigned logn;
} ffLDL_job;
/* Iterative equivalent of the reference ffLDL_fft_inner recursion. All work of
* an invocation happens before its two half-degree sub-invocations, so a LIFO
* list of pending jobs suffices. Expects the (auto-adjoint, quasicyclic)
* matrix in (g0, g1), which are used as modifiable temporaries. tmp[] needs
* room for at least one polynomial; it is only used within a single job, never
* across jobs. */
static void ffLDL_fft_inner(fpr* tree, fpr* g0, fpr* g1, unsigned logn,
fpr* tmp)
{
/* A job at logn > 0 replaces itself with two jobs at logn - 1, leaving at
* most one pending sibling per level plus the current job: logn + 1
* frames, <= 11 for logn <= 10. */
ffLDL_job stk[11];
int sp;
stk[0].tree = tree;
stk[0].g0 = g0;
stk[0].g1 = g1;
stk[0].logn = logn;
sp = 0;
while (sp >= 0) {
ffLDL_job job;
size_t n, hn;
job = stk[sp];
sp--;
n = MKN(job.logn);
if (n == 1) {
job.tree[0] = job.g0[0];
continue;
}
hn = n >> 1;
/* d00 = g0; d11 -> tmp; L[1][0] -> tree. */
falcon_poly_LDLmv_fft(tmp, job.tree, job.g0, job.g1, job.g0, job.logn);
/* Split d00 (in g0) and d11 (in tmp), reusing g0/g1 as scratch:
* d00 -> g1, g1+hn ; d11 -> g0, g0+hn. */
falcon_poly_split_fft(job.g1, job.g1 + hn, job.g0, job.logn);
falcon_poly_split_fft(job.g0, job.g0 + hn, tmp, job.logn);
/* Queue both half-degree sub-invocations; their buffers are disjoint.
* The d11 half (in g0) is pushed first so that the d00 half (in g1)
* runs first, matching the reference order. */
sp++;
stk[sp].tree = job.tree + n + ffLDL_treesize(job.logn - 1);
stk[sp].g0 = job.g0;
stk[sp].g1 = job.g0 + hn;
stk[sp].logn = job.logn - 1;
sp++;
stk[sp].tree = job.tree + n;
stk[sp].g0 = job.g1;
stk[sp].g1 = job.g1 + hn;
stk[sp].logn = job.logn - 1;
}
}
/* Compute the ffLDL tree of the auto-adjoint matrix [[g00, adj(g01)],
* [g01, g11]] (FFT representation). tmp[] needs room for at least three
* polynomials. */
static void ffLDL_fft(fpr* tree, const fpr* g00, const fpr* g01,
const fpr* g11, unsigned logn, fpr* tmp)
{
size_t n, hn;
fpr* d00;
fpr* d11;
n = MKN(logn);
if (n == 1) {
tree[0] = g00[0];
return;
}
hn = n >> 1;
d00 = tmp;
d11 = tmp + n;
tmp += n << 1;
XMEMCPY(d00, g00, n * sizeof(*g00));
falcon_poly_LDLmv_fft(d11, tree, g00, g01, g11, logn);
falcon_poly_split_fft(tmp, tmp + hn, d00, logn);
falcon_poly_split_fft(d00, d00 + hn, d11, logn);
XMEMCPY(d11, tmp, n * sizeof(*tmp));
ffLDL_fft_inner(tree + n, d11, d11 + hn, logn - 1, tmp);
ffLDL_fft_inner(tree + n + ffLDL_treesize(logn - 1),
d00, d00 + hn, logn - 1, tmp);
}
/* Normalize an ffLDL tree: each leaf x is replaced with sigma/sqrt(x). The leaf
* stores the inverse of the spec value, saving a division here and in the
* sampler. Iterative equivalent of the reference recursion: internal nodes do
* no work of their own, so a LIFO list of pending subtrees replaces the two
* tail calls (see ffLDL_fft_inner for the occupancy bound). */
static void ffLDL_binary_normalize(fpr* tree, unsigned orig_logn, unsigned logn)
{
struct {
fpr* tree;
unsigned logn;
} stk[11];
int sp;
stk[0].tree = tree;
stk[0].logn = logn;
sp = 0;
while (sp >= 0) {
fpr* t;
unsigned l;
size_t n;
t = stk[sp].tree;
l = stk[sp].logn;
sp--;
n = MKN(l);
if (n == 1) {
t[0] = fpr_mul(fpr_sqrt(t[0]), fpr_inv_sigma[orig_logn]);
continue;
}
sp++;
stk[sp].tree = t + n + ffLDL_treesize(l - 1);
stk[sp].logn = l - 1;
sp++;
stk[sp].tree = t + n;
stk[sp].logn = l - 1;
}
}
/* Convert a small-integer polynomial into the fpr representation. */
static void smallints_to_fpr(fpr* r, const sword8* t, unsigned logn)
{
size_t n, u;
n = MKN(logn);
for (u = 0; u < n; u++) {
r[u] = fpr_of(t[u]);
}
}
/* Expanded-key layout offsets (in fpr elements). */
static WC_INLINE size_t skoff_b00(unsigned logn) { (void)logn; return 0; }
static WC_INLINE size_t skoff_b01(unsigned logn) { return MKN(logn); }
static WC_INLINE size_t skoff_b10(unsigned logn) { return 2 * MKN(logn); }
static WC_INLINE size_t skoff_b11(unsigned logn) { return 3 * MKN(logn); }
static WC_INLINE size_t skoff_tree(unsigned logn) { return 4 * MKN(logn); }
int falcon_expand_privkey(fpr* expanded, const sword8* f, const sword8* g,
const sword8* F, const sword8* G, unsigned logn, void* heap)
{
size_t n;
fpr* rf;
fpr* rg;
fpr* rF;
fpr* rG;
fpr* b00;
fpr* b01;
fpr* b10;
fpr* b11;
fpr* g00;
fpr* g01;
fpr* g11;
fpr* gxx;
fpr* tree;
fpr* tmp;
if (expanded == NULL || f == NULL || g == NULL || F == NULL || G == NULL
|| logn < 1 || logn > 10) {
return BAD_FUNC_ARG;
}
n = MKN(logn);
/* Internal scratch: six polynomials (matches the reference 48*2^logn). */
tmp = (fpr*)XMALLOC((size_t)6 * n * sizeof(fpr), heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) {
return MEMORY_E;
}
b00 = expanded + skoff_b00(logn);
b01 = expanded + skoff_b01(logn);
b10 = expanded + skoff_b10(logn);
b11 = expanded + skoff_b11(logn);
tree = expanded + skoff_tree(logn);
/* B0 = [[g, -f], [G, -F]]. */
rf = b01;
rg = b00;
rF = b11;
rG = b10;
smallints_to_fpr(rf, f, logn);
smallints_to_fpr(rg, g, logn);
smallints_to_fpr(rF, F, logn);
smallints_to_fpr(rG, G, logn);
falcon_FFT(rf, logn);
falcon_FFT(rg, logn);
falcon_FFT(rF, logn);
falcon_FFT(rG, logn);
falcon_poly_neg(rf, logn);
falcon_poly_neg(rF, logn);
/* Gram matrix G = B*B^* (upper triangle: g00, g01, g11). */
g00 = tmp;
g01 = g00 + n;
g11 = g01 + n;
gxx = g11 + n;
XMEMCPY(g00, b00, n * sizeof(*b00));
falcon_poly_mulselfadj_fft(g00, logn);
XMEMCPY(gxx, b01, n * sizeof(*b01));
falcon_poly_mulselfadj_fft(gxx, logn);
falcon_poly_add(g00, gxx, logn);
XMEMCPY(g01, b00, n * sizeof(*b00));
falcon_poly_muladj_fft(g01, b10, logn);
XMEMCPY(gxx, b01, n * sizeof(*b01));
falcon_poly_muladj_fft(gxx, b11, logn);
falcon_poly_add(g01, gxx, logn);
XMEMCPY(g11, b10, n * sizeof(*b10));
falcon_poly_mulselfadj_fft(g11, logn);
XMEMCPY(gxx, b11, n * sizeof(*b11));
falcon_poly_mulselfadj_fft(gxx, logn);
falcon_poly_add(g11, gxx, logn);
/* Falcon tree, then normalization. */
ffLDL_fft(tree, g00, g01, g11, logn, gxx);
ffLDL_binary_normalize(tree, logn, logn);
/* tmp held the secret-derived Gram matrix and ffLDL intermediates. */
wc_ForceZero(tmp, (word32)((size_t)6 * n * sizeof(fpr)));
XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
}
/* ==================================================================== */
/* Fast Fourier sampling. */
/* Base case at logn == 2 (n = 4): the two bottom levels of the sampling
* walk, fully unrolled over the four coefficients (as in the reference). */
static WC_INLINE void ffSampling_fft_deg4(falcon_samplerZ samp, void* samp_ctx,
fpr* z0, fpr* z1, const fpr* tree, const fpr* t0, const fpr* t1)
{
const fpr* tree0;
const fpr* tree1;
fpr x0, x1, y0, y1, w0, w1, w2, w3, sigma;
fpr a_re, a_im, b_re, b_im, c_re, c_im;
tree0 = tree + 4;
tree1 = tree + 8;
a_re = t1[0];
a_im = t1[2];
b_re = t1[1];
b_im = t1[3];
c_re = fpr_add(a_re, b_re);
c_im = fpr_add(a_im, b_im);
w0 = fpr_half(c_re);
w1 = fpr_half(c_im);
c_re = fpr_sub(a_re, b_re);
c_im = fpr_sub(a_im, b_im);
w2 = fpr_mul(fpr_add(c_re, c_im), fpr_invsqrt8);
w3 = fpr_mul(fpr_sub(c_im, c_re), fpr_invsqrt8);
x0 = w2;
x1 = w3;
sigma = tree1[3];
w2 = fpr_of(samp(samp_ctx, x0, sigma));
w3 = fpr_of(samp(samp_ctx, x1, sigma));
a_re = fpr_sub(x0, w2);
a_im = fpr_sub(x1, w3);
b_re = tree1[0];
b_im = tree1[1];
c_re = fpr_sub(fpr_mul(a_re, b_re), fpr_mul(a_im, b_im));
c_im = fpr_add(fpr_mul(a_re, b_im), fpr_mul(a_im, b_re));
x0 = fpr_add(c_re, w0);
x1 = fpr_add(c_im, w1);
sigma = tree1[2];
w0 = fpr_of(samp(samp_ctx, x0, sigma));
w1 = fpr_of(samp(samp_ctx, x1, sigma));
a_re = w0;
a_im = w1;
b_re = w2;
b_im = w3;
c_re = fpr_mul(fpr_sub(b_re, b_im), fpr_invsqrt2);
c_im = fpr_mul(fpr_add(b_re, b_im), fpr_invsqrt2);
z1[0] = w0 = fpr_add(a_re, c_re);
z1[2] = w2 = fpr_add(a_im, c_im);
z1[1] = w1 = fpr_sub(a_re, c_re);
z1[3] = w3 = fpr_sub(a_im, c_im);
w0 = fpr_sub(t1[0], w0);
w1 = fpr_sub(t1[1], w1);
w2 = fpr_sub(t1[2], w2);
w3 = fpr_sub(t1[3], w3);
a_re = w0;
a_im = w2;
b_re = tree[0];
b_im = tree[2];
w0 = fpr_sub(fpr_mul(a_re, b_re), fpr_mul(a_im, b_im));
w2 = fpr_add(fpr_mul(a_re, b_im), fpr_mul(a_im, b_re));
a_re = w1;
a_im = w3;
b_re = tree[1];
b_im = tree[3];
w1 = fpr_sub(fpr_mul(a_re, b_re), fpr_mul(a_im, b_im));
w3 = fpr_add(fpr_mul(a_re, b_im), fpr_mul(a_im, b_re));
w0 = fpr_add(w0, t0[0]);
w1 = fpr_add(w1, t0[1]);
w2 = fpr_add(w2, t0[2]);
w3 = fpr_add(w3, t0[3]);
a_re = w0;
a_im = w2;
b_re = w1;
b_im = w3;
c_re = fpr_add(a_re, b_re);
c_im = fpr_add(a_im, b_im);
w0 = fpr_half(c_re);
w1 = fpr_half(c_im);
c_re = fpr_sub(a_re, b_re);
c_im = fpr_sub(a_im, b_im);
w2 = fpr_mul(fpr_add(c_re, c_im), fpr_invsqrt8);
w3 = fpr_mul(fpr_sub(c_im, c_re), fpr_invsqrt8);
x0 = w2;
x1 = w3;
sigma = tree0[3];
w2 = y0 = fpr_of(samp(samp_ctx, x0, sigma));
w3 = y1 = fpr_of(samp(samp_ctx, x1, sigma));
a_re = fpr_sub(x0, y0);
a_im = fpr_sub(x1, y1);
b_re = tree0[0];
b_im = tree0[1];
c_re = fpr_sub(fpr_mul(a_re, b_re), fpr_mul(a_im, b_im));
c_im = fpr_add(fpr_mul(a_re, b_im), fpr_mul(a_im, b_re));
x0 = fpr_add(c_re, w0);
x1 = fpr_add(c_im, w1);
sigma = tree0[2];
w0 = fpr_of(samp(samp_ctx, x0, sigma));
w1 = fpr_of(samp(samp_ctx, x1, sigma));
a_re = w0;
a_im = w1;
b_re = w2;
b_im = w3;
c_re = fpr_mul(fpr_sub(b_re, b_im), fpr_invsqrt2);
c_im = fpr_mul(fpr_add(b_re, b_im), fpr_invsqrt2);
z0[0] = fpr_add(a_re, c_re);
z0[2] = fpr_add(a_im, c_im);
z0[1] = fpr_sub(a_re, c_re);
z0[3] = fpr_sub(a_im, c_im);
}
/* Base case at logn == 1 (n = 2): reachable only for the (insecure) smallest
* degree. */
static WC_INLINE void ffSampling_fft_deg2(falcon_samplerZ samp, void* samp_ctx,
fpr* z0, fpr* z1, const fpr* tree, const fpr* t0, const fpr* t1)
{
fpr x0, x1, y0, y1, sigma;
fpr a_re, a_im, b_re, b_im, c_re, c_im;
x0 = t1[0];
x1 = t1[1];
sigma = tree[3];
z1[0] = y0 = fpr_of(samp(samp_ctx, x0, sigma));
z1[1] = y1 = fpr_of(samp(samp_ctx, x1, sigma));
a_re = fpr_sub(x0, y0);
a_im = fpr_sub(x1, y1);
b_re = tree[0];
b_im = tree[1];
c_re = fpr_sub(fpr_mul(a_re, b_re), fpr_mul(a_im, b_im));
c_im = fpr_add(fpr_mul(a_re, b_im), fpr_mul(a_im, b_re));
x0 = fpr_add(c_re, t0[0]);
x1 = fpr_add(c_im, t0[1]);
sigma = tree[2];
z0[0] = fpr_of(samp(samp_ctx, x0, sigma));
z0[1] = fpr_of(samp(samp_ctx, x1, sigma));
}
/* One flattened falcon_ffSampling_fft invocation at logn >= 3. Each frame is
* visited three times, tracked by 'stage':
* FF_SAMP_STAGE_T1: split t1 and descend into the tree1 subtree;
* FF_SAMP_STAGE_T0: merge z1, build tb0 = t0 + (t1 - z1)*L in tmp, split
* it and descend into the tree0 subtree;
* FF_SAMP_STAGE_DONE: merge z0 and pop back to the parent frame. */
typedef struct ffSampling_frame {
fpr* z0;
fpr* z1;
const fpr* tree;
const fpr* t0;
const fpr* t1;
fpr* tmp;
unsigned logn;
unsigned stage;
} ffSampling_frame;
#define FF_SAMP_STAGE_T1 0U
#define FF_SAMP_STAGE_T0 1U
#define FF_SAMP_STAGE_DONE 2U
/* Maximum frame-stack depth: one frame per level from the top logn down to 3
* (levels 2 and 1 run as the inlined base cases above), so at most logn - 2
* <= 8 frames for logn <= 10. */
#define FF_SAMP_MAX_FRAMES 8
/* Descend into a sub-invocation at 'logn': run the base case directly when
* the walk bottoms out (logn == 2), otherwise push a frame for the state
* machine in falcon_ffSampling_fft. Returns the new top-of-stack index. */
static WC_INLINE int ffSampling_descend(ffSampling_frame* stk, int sp,
falcon_samplerZ samp, void* samp_ctx, fpr* z0, fpr* z1,
const fpr* tree, const fpr* t0, const fpr* t1, unsigned logn, fpr* tmp)
{
if (logn == 2) {
ffSampling_fft_deg4(samp, samp_ctx, z0, z1, tree, t0, t1);
}
else {
sp++;
stk[sp].z0 = z0;
stk[sp].z1 = z1;
stk[sp].tree = tree;
stk[sp].t0 = t0;
stk[sp].t1 = t1;
stk[sp].tmp = tmp;
stk[sp].logn = logn;
stk[sp].stage = FF_SAMP_STAGE_T1;
}
return sp;
}
/* Iterative equivalent of the reference ffSampling_fft recursion. The frames
* are visited -- and hence the sampler is invoked -- in exactly the reference
* recursion order; the sampler consumes a PRNG stream, so preserving that
* order is what keeps the produced signatures identical to the reference. */
void falcon_ffSampling_fft(falcon_samplerZ samp, void* samp_ctx,
fpr* z0, fpr* z1, const fpr* tree, const fpr* t0, const fpr* t1,
unsigned logn, fpr* tmp)
{
ffSampling_frame stk[FF_SAMP_MAX_FRAMES];
int sp;
/* Degrees handled entirely by the inlined base cases. */
if (logn == 2) {
ffSampling_fft_deg4(samp, samp_ctx, z0, z1, tree, t0, t1);
return;
}
if (logn == 1) {
ffSampling_fft_deg2(samp, samp_ctx, z0, z1, tree, t0, t1);
return;
}
/* Callers validate 1 <= logn <= 10 (falcon_do_sign_tree); this keeps the
* frame stack in bounds regardless. */
if (logn < 1 || logn > 10) {
return;
}
sp = ffSampling_descend(stk, -1, samp, samp_ctx, z0, z1, tree, t0, t1,
logn, tmp);
while (sp >= 0) {
ffSampling_frame* f;
size_t n, hn;
f = &stk[sp];
n = (size_t)1 << f->logn;
hn = n >> 1;
switch (f->stage) {
case FF_SAMP_STAGE_T1:
f->stage = FF_SAMP_STAGE_T0;
/* Split t1 into z1, then sample the halves against the tree1
* subtree; the sampled halves land in tmp, tmp + hn. */
falcon_poly_split_fft(f->z1, f->z1 + hn, f->t1, f->logn);
sp = ffSampling_descend(stk, sp, samp, samp_ctx,
f->tmp, f->tmp + hn,
f->tree + n + ffLDL_treesize(f->logn - 1),
f->z1, f->z1 + hn, f->logn - 1, f->tmp + n);
break;
case FF_SAMP_STAGE_T0:
f->stage = FF_SAMP_STAGE_DONE;
/* Merge the sampled halves back into z1. */
falcon_poly_merge_fft(f->z1, f->tmp, f->tmp + hn, f->logn);
/* tb0 = t0 + (t1 - z1) * L, built in tmp[]. */
XMEMCPY(f->tmp, f->t1, n * sizeof(*f->t1));
falcon_poly_sub(f->tmp, f->z1, f->logn);
falcon_poly_mul_fft(f->tmp, f->tree, f->logn);
falcon_poly_add(f->tmp, f->t0, f->logn);
/* Split tb0 into z0, then sample the halves against the tree0
* subtree. */
falcon_poly_split_fft(f->z0, f->z0 + hn, f->tmp, f->logn);
sp = ffSampling_descend(stk, sp, samp, samp_ctx,
f->tmp, f->tmp + hn, f->tree + n,
f->z0, f->z0 + hn, f->logn - 1, f->tmp + n);
break;
default:
/* FF_SAMP_STAGE_DONE: merge the sampled halves back into z0;
* this invocation is complete. */
falcon_poly_merge_fft(f->z0, f->tmp, f->tmp + hn, f->logn);
sp--;
break;
}
}
}
/* ==================================================================== */
/* do_sign_tree / sign_core. */
/* is_short_half: squared l2-norm of (s1, s2) where the s1 partial sum (sqn) is
* already accumulated and saturates to 2^32-1. Returns 1 if within bound. */
static int is_short_half(word32 sqn, const sword16* s2, unsigned logn)
{
size_t n, u;
word32 ng;
n = (size_t)1 << logn;
ng = (word32)(0 - (sqn >> 31));
for (u = 0; u < n; u++) {
sword32 z;
z = s2[u];
sqn += (word32)(z * z);
ng |= sqn;
}
sqn |= (word32)(0 - (ng >> 31));
return sqn <= l2bound[logn];
}
/* Single signing attempt over the expanded key. Returns 1 if the produced
* (s1, s2) is short enough (s2 written), 0 if the caller should retry. tmp[]
* needs room for six polynomials. */
static int do_sign_tree_once(falcon_samplerZ samp, void* samp_ctx, sword16* s2,
const fpr* expanded, const word16* hm, unsigned logn, fpr* tmp)
{
size_t n, u;
fpr* t0;
fpr* t1;
fpr* tx;
fpr* ty;
const fpr* b00;
const fpr* b01;
const fpr* b10;
const fpr* b11;
const fpr* tree;
fpr ni;
word32 sqn, ng;
sword16* s1tmp;
sword16* s2tmp;
n = MKN(logn);
t0 = tmp;
t1 = t0 + n;
b00 = expanded + skoff_b00(logn);
b01 = expanded + skoff_b01(logn);
b10 = expanded + skoff_b10(logn);
b11 = expanded + skoff_b11(logn);
tree = expanded + skoff_tree(logn);
/* Target vector [hm, 0]. */
for (u = 0; u < n; u++) {
t0[u] = fpr_of(hm[u]);
}
/* Apply the basis to obtain the real target (after q-normalization). */
falcon_FFT(t0, logn);
ni = fpr_inverse_of_q;
XMEMCPY(t1, t0, n * sizeof(*t0));
falcon_poly_mul_fft(t1, b01, logn);
falcon_poly_mulconst(t1, fpr_neg(ni), logn);
falcon_poly_mul_fft(t0, b11, logn);
falcon_poly_mulconst(t0, ni, logn);
tx = t1 + n;
ty = tx + n;
/* Sampling; output written to [tx, ty]. */
falcon_ffSampling_fft(samp, samp_ctx, tx, ty, tree, t0, t1, logn, ty + n);
/* Lattice point corresponding to that short vector. */
XMEMCPY(t0, tx, n * sizeof(*tx));
XMEMCPY(t1, ty, n * sizeof(*ty));
falcon_poly_mul_fft(tx, b00, logn);
falcon_poly_mul_fft(ty, b10, logn);
falcon_poly_add(tx, ty, logn);
XMEMCPY(ty, t0, n * sizeof(*t0));
falcon_poly_mul_fft(ty, b01, logn);
XMEMCPY(t0, tx, n * sizeof(*tx));
falcon_poly_mul_fft(t1, b11, logn);
falcon_poly_add(t1, ty, logn);
falcon_iFFT(t0, logn);
falcon_iFFT(t1, logn);
/* s1 = hm - round(t0); accumulate squared norm with saturation. */
s1tmp = (sword16*)tx;
sqn = 0;
ng = 0;
for (u = 0; u < n; u++) {
sword32 z;
z = (sword32)hm[u] - (sword32)fpr_rint(t0[u]);
sqn += (word32)(z * z);
ng |= sqn;
s1tmp[u] = (sword16)z;
}
sqn |= (word32)(0 - (ng >> 31));
/* s2 = -round(t1) (written into tmp; never into s2[] until accepted, so a
* retry preserves hm[]). */
s2tmp = (sword16*)tmp;
for (u = 0; u < n; u++) {
s2tmp[u] = (sword16)(0 - fpr_rint(t1[u]));
}
if (is_short_half(sqn, s2tmp, logn)) {
XMEMCPY(s2, s2tmp, n * sizeof(*s2));
XMEMCPY(tmp, s1tmp, n * sizeof(*s1tmp));
return 1;
}
return 0;
}
int falcon_do_sign_tree(falcon_samplerZ samp, void* samp_ctx, sword16* s2,
const fpr* expanded, const word16* hm, unsigned logn, fpr* tmp,
const int* samplerErr)
{
if (samp == NULL || s2 == NULL || expanded == NULL || hm == NULL
|| tmp == NULL || logn < 1 || logn > 10) {
return BAD_FUNC_ARG;
}
/* Loop until the candidate (s1, s2) is short enough. With degrees 512 and
* 1024 a restart is very rare (expected iteration count is ~1), so the
* bound below is astronomically beyond any legitimate run; it exists only
* so a wedged sampler -- e.g. a PRNG whose SHAKE256 squeeze started failing,
* yielding candidates that never pass the norm bound -- terminates instead
* of spinning forever. */
{
unsigned long iter;
for (iter = 0; iter < FALCON_SIGN_MAX_RESTARTS; iter++) {
if (do_sign_tree_once(samp, samp_ctx, s2, expanded, hm, logn, tmp)) {
return 0;
}
/* Fail fast on a sampler PRNG error (non-secret, already latched):
* no point burning restarts on candidates built from invalid
* randomness. */
if (samplerErr != NULL && *samplerErr != 0) {
return *samplerErr;
}
#ifdef WOLFSSL_FALCON_SIGN_STATS
/* Optional instrumentation for test harnesses: counts the rare
* ffSampling restarts. Not compiled into production builds. */
extern unsigned long falcon_sign_restart_count;
falcon_sign_restart_count++;
#endif
}
}
/* Exhausted the restart bound: treat as an operational failure. */
return WC_FAILURE;
}
int falcon_sign_core(falcon_sampler_ctx* spc, const fpr* expanded,
const word16* c, sword16* s2, fpr* tmp, unsigned logn)
{
int ret;
if (spc == NULL) {
return BAD_FUNC_ARG;
}
ret = falcon_do_sign_tree(falcon_sampler_z, spc, s2, expanded, c, logn, tmp,
&spc->p.err);
/* Reject the signature if the sampler's PRNG failed at any point: the
* squeezed bytes it consumed would be invalid, so the result is unsafe. */
if (ret == 0 && spc->p.err != 0) {
ret = spc->p.err;
}
return ret;
}
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
+6 -8
View File
@@ -254,16 +254,14 @@ nobase_include_HEADERS+= wolfssl/wolfcrypt/port/riscv/riscv-64-asm.h
endif endif
if BUILD_FALCON if BUILD_FALCON
# Internal Falcon headers (the public API is wolfssl/wolfcrypt/falcon.h, listed # Internal Falcon headers kept for the separate AVX2/NEON FFT backends, which
# unconditionally above). Automake distributes both branches of a conditional, # share the fpr primitives, the falcon_gm_tab twiddle table, and the poly seam
# so these are still included in "make dist" when Falcon is disabled. # with the merged falcon.c. The rest of the Falcon internals now live as static
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_bigint.h # code inside falcon.c. The public API is wolfssl/wolfcrypt/falcon.h (above).
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_codec.h # Automake distributes both branches of a conditional, so these are still
# included in "make dist" when Falcon is disabled.
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_fft.h nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_fft.h
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_fpr.h nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_fpr.h
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_keygen.h
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_poly.h nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_poly.h
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_sampler.h
nobase_include_HEADERS+= wolfssl/wolfcrypt/wc_falcon_sign.h
endif endif
-138
View File
@@ -1,138 +0,0 @@
/* wc_falcon_bigint.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/wc_falcon_bigint.h
*/
/* Self-contained big-integer / RNS arithmetic for native Falcon
* key generation.
*
* Falcon key generation solves the NTRU equation g*F - f*G = q, which is
* performed by the Falcon "ntru_solve" routine. That routine relies on a
* specialized integer-only big-number layer using a residue number system
* (RNS) of 31-bit prime moduli, with a small-modulus NTT for fast
* polynomial arithmetic and an extended-binary-GCD (Bezout) solver.
*
* The algorithms and limb conventions here are ported faithfully from the
* Falcon reference implementation keygen.c by Thomas Pornin (MIT licensed):
* - big integers are little-endian arrays of word32 "limbs", each limb
* holding 31 bits of value (the top bit is unused for carry handling);
* - products use word64; signed reductions use sword32 / sword64;
* - the RNS primes p satisfy 2^30 < p < 2^31 and p = 1 mod 2048.
*
* This module is INTEGER-ONLY and independent of the floating-point seam.
* It is excluded from verify-only builds (keygen is not needed there). */
#ifndef WOLF_CRYPT_WC_FALCON_BIGINT_H
#define WOLF_CRYPT_WC_FALCON_BIGINT_H
#include <wolfssl/wolfcrypt/types.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
#ifdef __cplusplus
extern "C" {
#endif
/* One entry of the RNS small-prime table. Fields mirror the Falcon
* reference small_prime structure:
* p A prime modulus, with 2^30 < p < 2^31 and p = 1 mod 2048.
* g A primitive root of phi = X^N+1 in the field Z_p.
* s The inverse of the product of all previous primes in the table,
* computed modulo p and in Montgomery representation.
* The table is sorted in decreasing order of p and terminated with a
* { 0, 0, 0 } sentinel. */
typedef struct falcon_small_prime {
word32 p;
word32 g;
word32 s;
} falcon_small_prime;
/* RNS prime table (terminated with a { 0, 0, 0 } sentinel). */
WOLFSSL_LOCAL extern const falcon_small_prime FALCON_PRIMES[];
/* ---- modular small-integer helpers (single 31-bit prime modulus) ---- */
WOLFSSL_LOCAL word32 modp_set(sword32 x, word32 p);
WOLFSSL_LOCAL sword32 modp_norm(word32 x, word32 p);
WOLFSSL_LOCAL word32 modp_ninv31(word32 p);
WOLFSSL_LOCAL word32 modp_R(word32 p);
WOLFSSL_LOCAL word32 modp_add(word32 a, word32 b, word32 p);
WOLFSSL_LOCAL word32 modp_sub(word32 a, word32 b, word32 p);
WOLFSSL_LOCAL word32 modp_montymul(word32 a, word32 b, word32 p, word32 p0i);
WOLFSSL_LOCAL word32 modp_R2(word32 p, word32 p0i);
WOLFSSL_LOCAL word32 modp_Rx(unsigned int x, word32 p, word32 p0i, word32 R2);
/* Modular division a/b mod p (returns 0 when b == 0). This is the
* reference's modular-inverse helper (the canonical Falcon keygen.c has no
* separately named "modp_get_inv"; modp_div(R,b,...) yields 1/b). */
WOLFSSL_LOCAL word32 modp_div(word32 a, word32 b, word32 p, word32 p0i,
word32 R);
/* ---- small-modulus NTT used in the RNS ---- */
WOLFSSL_LOCAL void modp_mkgm2(word32* gm, word32* igm, unsigned int logn,
word32 g, word32 p, word32 p0i);
WOLFSSL_LOCAL void modp_NTT2_ext(word32* a, size_t stride, const word32* gm,
unsigned int logn, word32 p, word32 p0i);
WOLFSSL_LOCAL void modp_iNTT2_ext(word32* a, size_t stride, const word32* igm,
unsigned int logn, word32 p, word32 p0i);
/* Convenience wrappers for unit-stride polynomials. */
#define modp_NTT2(a, gm, logn, p, p0i) \
modp_NTT2_ext(a, 1, gm, logn, p, p0i)
#define modp_iNTT2(a, igm, logn, p, p0i) \
modp_iNTT2_ext(a, 1, igm, logn, p, p0i)
/* ---- big-integer (zint) helpers ---- */
WOLFSSL_LOCAL word32 zint_sub(word32* a, const word32* b, size_t len,
word32 ctl);
WOLFSSL_LOCAL word32 zint_mul_small(word32* m, size_t mlen, word32 x);
WOLFSSL_LOCAL word32 zint_mod_small_unsigned(const word32* d, size_t dlen,
word32 p, word32 p0i, word32 R2);
WOLFSSL_LOCAL word32 zint_mod_small_signed(const word32* d, size_t dlen,
word32 p, word32 p0i, word32 R2, word32 Rx);
WOLFSSL_LOCAL void zint_add_mul_small(word32* x, const word32* y, size_t len,
word32 s);
WOLFSSL_LOCAL void zint_norm_zero(word32* x, const word32* p, size_t len);
WOLFSSL_LOCAL void zint_rebuild_CRT(word32* xx, size_t xlen, size_t xstride,
size_t num, const falcon_small_prime* primes, int normalize_signed,
word32* tmp);
WOLFSSL_LOCAL void zint_negate(word32* a, size_t len, word32 ctl);
WOLFSSL_LOCAL word32 zint_co_reduce(word32* a, word32* b, size_t len,
sword64 xa, sword64 xb, sword64 ya, sword64 yb);
WOLFSSL_LOCAL void zint_finish_mod(word32* a, size_t len, const word32* m,
word32 neg);
WOLFSSL_LOCAL void zint_co_reduce_mod(word32* a, word32* b, const word32* m,
size_t len, word32 m0i, sword64 xa, sword64 xb, sword64 ya,
sword64 yb);
WOLFSSL_LOCAL int zint_bezout(word32* u, word32* v, const word32* x,
const word32* y, size_t len, word32* tmp);
WOLFSSL_LOCAL void zint_add_scaled_mul_small(word32* x, size_t xlen,
const word32* y, size_t ylen, sword32 k, word32 sch, word32 scl);
WOLFSSL_LOCAL void zint_sub_scaled(word32* x, size_t xlen, const word32* y,
size_t ylen, word32 sch, word32 scl);
WOLFSSL_LOCAL sword32 zint_one_to_plain(const word32* x);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
#endif /* WOLF_CRYPT_WC_FALCON_BIGINT_H */
-75
View File
@@ -1,75 +0,0 @@
/* wc_falcon_codec.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Falcon encode/decode routines for the
* signing and key-generation paths. The verification-side decoders
* (modq_decode, comp_decode) live as static functions in wc_falcon.c and are
* not referenced here. */
#ifndef WOLF_CRYPT_WC_FALCON_CODEC_H
#define WOLF_CRYPT_WC_FALCON_CODEC_H
#include <wolfssl/wolfcrypt/types.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
#ifdef __cplusplus
extern "C" {
#endif
/* Golomb-Rice (k=7) compress of the signature polynomial s2. Exact inverse of
* the reference comp_decode. Rejects any |x[i]| > 2047. Returns the number of
* bytes written, or 0 on range violation / output overflow. */
WOLFSSL_LOCAL size_t falcon_comp_encode(byte* out, size_t max_out,
const sword16* x, unsigned logn);
/* 14-bit big-endian pack of the public-key polynomial h. Each coefficient must
* be < q (12289). Returns the number of bytes written, or 0 on range violation
* / output overflow. */
WOLFSSL_LOCAL size_t falcon_modq_encode(byte* out, size_t max_out,
const word16* x, unsigned logn);
/* Signed 8-bit polynomial pack/unpack using a fixed per-coefficient bit width.
* The most-negative value -2^(bits-1) is forbidden (matching the reference). */
WOLFSSL_LOCAL size_t falcon_trim_i8_encode(byte* out, size_t max_out,
const sword8* x, unsigned logn, unsigned bits);
WOLFSSL_LOCAL size_t falcon_trim_i8_decode(sword8* x, unsigned logn,
unsigned bits, const byte* in, size_t max_in);
/* Decode a Falcon secret key: header byte (0x50 | logn), then trim_i8 encoded
* f, g (max_fg_bits[logn]) and F (max_FG_bits[logn]). Validates the header and
* that the input length is exactly consumed. Returns 0 on success or a negative
* wolfCrypt error. */
WOLFSSL_LOCAL int falcon_privkey_decode(const byte* sk, size_t sklen,
sword8* f, sword8* g, sword8* F, unsigned logn);
/* Encode a Falcon secret key from (f, g, F). Inverse of falcon_privkey_decode.
* Returns bytes written, or 0 on failure. */
WOLFSSL_LOCAL size_t falcon_privkey_encode(byte* sk, size_t max_sk,
const sword8* f, const sword8* g, const sword8* F, unsigned logn);
#ifdef __cplusplus
}
#endif
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
#endif /* WOLF_CRYPT_WC_FALCON_CODEC_H */
-80
View File
@@ -1,80 +0,0 @@
/* wc_falcon_keygen.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/wc_falcon_keygen.h
*/
/* Falcon key-pair generation.
*
* Generates an (f, g, F, G) NTRU lattice basis together with the public key
* h = g/f mod q. The procedure is a faithful port of the key-generation half
* of the MIT-licensed Falcon reference implementation keygen.c (Thomas
* Pornin):
*
* - sample f, g from a discrete Gaussian of standard deviation
* 1.17*sqrt(q/(2n)), driven by a SHAKE256 stream seeded from a WC_RNG;
* - reject (f, g) until the resultant with X^n+1 is odd, the (g,-f) norm
* and the orthogonalized vector norm are below the 1.17*sqrt(q) bound,
* and f is invertible modulo q;
* - solve the NTRU equation f*G - g*F = q with the recursive "ntru_solve"
* built on the validated big-integer / RNS layer (wc_falcon_bigint);
* - return the basis and the public polynomial h.
*
* This module is excluded from verify-only builds (keygen is not needed
* there) and depends on the floating-point seam (wc_falcon_fpr / fft / poly). */
#ifndef WOLF_CRYPT_WC_FALCON_KEYGEN_H
#define WOLF_CRYPT_WC_FALCON_KEYGEN_H
#include <wolfssl/wolfcrypt/types.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
#include <wolfssl/wolfcrypt/random.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Generate a complete Falcon key pair of degree n = 2^logn.
*
* rng initialized WC_RNG used to seed the SHAKE256 sampler stream.
* f,g output secret polynomials (n signed coefficients each).
* F,G output NTRU completion polynomials (n signed coefficients each);
* G may be reconstructed internally but is always written out here.
* h output public key polynomial (n coefficients in [0, q)); may be
* NULL if only the (f,g,F,G) basis is required.
* logn base-2 logarithm of the ring degree (1..10; 9 and 10 are the
* Falcon-512 and Falcon-1024 levels).
*
* The routine loops, drawing fresh (f,g) until every acceptance test passes
* and the NTRU equation is solved, exactly as the reference does. Returns 0
* on success or a negative wolfCrypt error code. */
WOLFSSL_LOCAL int falcon_keygen(WC_RNG* rng, sword8* f, sword8* g,
sword8* F, sword8* G, word16* h, unsigned logn);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
#endif /* WOLF_CRYPT_WC_FALCON_KEYGEN_H */
-108
View File
@@ -1,108 +0,0 @@
/* wc_falcon_sampler.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/wc_falcon_sampler.h
*/
/* Discrete Gaussian sampler for Falcon signing (SamplerZ).
*
* This is a faithful port of the constant-time reference sampler by Thomas
* Pornin (MIT-licensed Falcon reference implementation; the same code ships in
* PQClean as PQCLEAN_FALCONxxx_CLEAN_gaussian0_sampler / BerExp / sampler).
* The floating-point work is done exclusively through the abstract fpr_* seam
* (wolfssl/wolfcrypt/wc_falcon_fpr.h), so the sampler inherits the deterministic
* bit-exact, branch-free IEEE-754 behaviour of whatever fpr backend is active.
*
* SECURITY: the sampler is constant-time with respect to the secret center
* (mu) and the secret inverse standard deviation (isigma). There are no
* secret-dependent branches or memory accesses; see the notes in
* wc_falcon_sampler.c. Randomness is drawn from a SHAKE256 stream seeded from a
* WC_RNG instance. This file is compiled only on the signing side. */
#ifndef WOLF_CRYPT_WC_FALCON_SAMPLER_H
#define WOLF_CRYPT_WC_FALCON_SAMPLER_H
#include <wolfssl/wolfcrypt/types.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
#include <wolfssl/wolfcrypt/sha3.h>
#include <wolfssl/wolfcrypt/random.h>
#ifdef __cplusplus
extern "C" {
#endif
/* PRNG buffer: an integral number of SHAKE256 squeeze blocks (rate = 136
* bytes). 136 is divisible by 8, so 8-byte reads never straddle the boundary
* that triggers a refill. */
#define FALCON_PRNG_BLOCKS 8
#define FALCON_PRNG_BUFLEN (FALCON_PRNG_BLOCKS * WC_SHA3_256_BLOCK_SIZE)
/* SHAKE256-backed pseudo-random byte stream.
*
* Construction: the SHAKE256 sponge absorbs a seed obtained from WC_RNG
* (FALCON_PRNG_SEED_LEN fresh random bytes), then is squeezed in fixed-size
* blocks. get_u8 returns the next stream byte; get_u64 returns the next 8
* stream bytes interpreted little-endian. */
typedef struct falcon_prng {
wc_Shake shake; /* SHAKE256 sponge state */
byte buf[FALCON_PRNG_BUFLEN];/* squeezed stream buffer */
word32 ptr; /* index of next byte to consume */
word32 len; /* number of valid bytes in buf */
int err; /* sticky: first refill error, or 0 */
} falcon_prng;
/* Sampler context: the PRNG plus the parameter-set-dependent sigma_min. */
typedef struct falcon_sampler_ctx {
falcon_prng p;
fpr sigma_min; /* sigma_min for the active logn */
} falcon_sampler_ctx;
/* Seed length (bytes) drawn from WC_RNG to key the SHAKE256 stream. */
#define FALCON_PRNG_SEED_LEN 56
/* PRNG primitives. */
WOLFSSL_LOCAL int falcon_prng_init(falcon_prng* p, WC_RNG* rng);
WOLFSSL_LOCAL byte falcon_prng_get_u8(falcon_prng* p);
WOLFSSL_LOCAL word64 falcon_prng_get_u64(falcon_prng* p);
/* Initialise a sampler context for the given degree (logn = 9 or 10), seeding
* the PRNG from rng. Returns 0 on success or a negative wolfCrypt error. */
WOLFSSL_LOCAL int falcon_sampler_init(falcon_sampler_ctx* spc, int logn,
WC_RNG* rng);
/* The base half-Gaussian sampler (z >= 0, sigma0 = 1.8205). Exposed for test
* harnesses; consumes 9 PRNG bytes. */
WOLFSSL_LOCAL int falcon_gaussian0(falcon_prng* p);
/* SamplerZ: return an integer sampled from the discrete Gaussian of center mu
* and standard deviation 1/isigma. ctx is a (falcon_sampler_ctx*). */
WOLFSSL_LOCAL int falcon_sampler_z(void* ctx, fpr mu, fpr isigma);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
#endif /* WOLF_CRYPT_WC_FALCON_SAMPLER_H */
-132
View File
@@ -1,132 +0,0 @@
/* wc_falcon_sign.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*!
\file wolfssl/wolfcrypt/wc_falcon_sign.h
*/
/* Falcon signing orchestration (the "tree" signer).
*
* Faithful port of the signature-generation core of the MIT-licensed Falcon
* reference implementation sign.c (Thomas Pornin, Falcon Project, 2017-2019):
*
* - falcon_complete_private: recompute G from (f, g, F) using the NTRU
* relation f*G - g*F = q (so G = (g*F + q)/f), via the FFT seam.
* - falcon_expand_privkey: build the B0 = [[g, -f], [G, -F]] basis in FFT
* representation, the Gram matrix G = B*B^*, and the normalized ffLDL
* tree (the "expanded private key").
* - falcon_ffSampling_fft: the Fast Fourier sampling walk driving the
* discrete Gaussian sampler over the ffLDL tree. The reference expresses
* this (and the ffLDL construction) as recursions; per wolfSSL's
* no-recursion rule they are implemented as explicit-stack iterations
* that visit sub-problems in the exact reference order.
* - falcon_do_sign_tree / falcon_sign_core: produce the signature short
* vector s2, looping over the sampler until the (s1, s2) squared l2-norm
* is within the Falcon acceptance bound.
*
* The floating-point work flows exclusively through the abstract fpr_* seam
* (wc_falcon_fpr.h), the FFT (wc_falcon_fft.h) and the FFT-domain polynomial
* primitives (wc_falcon_poly.h); randomness for the sampler comes from the
* SHAKE256-backed sampler context (wc_falcon_sampler.h). This module is
* compiled only on the signing side. */
#ifndef WOLF_CRYPT_WC_FALCON_SIGN_H
#define WOLF_CRYPT_WC_FALCON_SIGN_H
#include <wolfssl/wolfcrypt/types.h>
#if defined(HAVE_FALCON) && !defined(WOLFSSL_FALCON_VERIFY_ONLY)
#include <wolfssl/wolfcrypt/wc_falcon_fpr.h>
#include <wolfssl/wolfcrypt/wc_falcon_sampler.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Number of fpr elements in an expanded private key for degree n = 2^logn.
* Layout: the four B0 matrix polynomials (b00, b01, b10, b11), each of n
* elements, followed by the ffLDL tree of (logn+1)*2^logn elements. The total
* is therefore (logn+5)*2^logn fpr (matching the reference's (8*logn+40)*2^logn
* bytes). */
#define FALCON_EXPANDED_KEY_FPR(logn) (((size_t)((logn) + 5)) << (logn))
/* Number of fpr elements of scratch required by falcon_do_sign_tree /
* falcon_sign_core (six polynomials of degree n), matching the reference's
* 48*2^logn bytes. */
#define FALCON_SIGN_TMP_FPR(logn) ((size_t)6 << (logn))
/* The discrete-Gaussian sampler callback type used by ffSampling. The second
* argument is the center mu, the third the inverse standard deviation isigma.
* falcon_sampler_z (wc_falcon_sampler.h) implements this contract. */
typedef int (*falcon_samplerZ)(void* ctx, fpr mu, fpr isigma);
/* Recompute the NTRU completion polynomial G from (f, g, F) such that
* f*G - g*F = q (G = (g*F + q)/f), computed over the FFT seam and rounded to
* integers. G receives n signed coefficients. For a well-formed key the
* quotient is exact; a rounded coefficient outside the [-127, 127] range is
* rejected (this also catches a grossly inconsistent/corrupt key). Returns 0 on
* success, or a negative wolfCrypt error on out-of-range coefficient or memory
* allocation failure. */
WOLFSSL_LOCAL int falcon_complete_private(sword8* G, const sword8* f,
const sword8* g, const sword8* F, unsigned logn, void* heap);
/* Expand the private basis (f, g, F, G) into 'expanded' (which must hold
* FALCON_EXPANDED_KEY_FPR(logn) fpr elements): the B0 matrix in FFT
* representation and the normalized ffLDL tree. Allocates an internal scratch
* of FALCON_SIGN_TMP_FPR(logn) fpr. Returns 0 on success or a negative
* wolfCrypt error. */
WOLFSSL_LOCAL int falcon_expand_privkey(fpr* expanded, const sword8* f,
const sword8* g, const sword8* F, const sword8* G, unsigned logn,
void* heap);
/* Fast Fourier sampling: sample the target (t0, t1) against the ffLDL 'tree',
* writing the sampled lattice coordinates into (z0, z1). 'tmp' needs room for
* at least two polynomials of degree 2^logn. Iterative (explicit-stack)
* equivalent of the reference ffSampling_fft recursion; sampler invocation
* order is identical to the reference. */
WOLFSSL_LOCAL void falcon_ffSampling_fft(falcon_samplerZ samp, void* samp_ctx,
fpr* z0, fpr* z1, const fpr* tree, const fpr* t0, const fpr* t1,
unsigned logn, fpr* tmp);
/* Produce the signature short vector s2 (n sword16 values) from the expanded
* key and hashed point hm (n word16 values in [0, q)). Loops over the sampler
* until the (s1, s2) squared l2-norm is within the Falcon bound. 'tmp' must
* hold FALCON_SIGN_TMP_FPR(logn) fpr. 'samplerErr', if non-NULL, points at the
* sampler's sticky error flag; the loop bails out as soon as it becomes
* non-zero (a wedged PRNG) instead of running to the restart bound. Returns 0
* on success. */
WOLFSSL_LOCAL int falcon_do_sign_tree(falcon_samplerZ samp, void* samp_ctx,
sword16* s2, const fpr* expanded, const word16* hm, unsigned logn,
fpr* tmp, const int* samplerErr);
/* Convenience top-level: sign hashed point c with the expanded key, using the
* provided (already initialized) sampler context, writing s2. 'tmp' must hold
* FALCON_SIGN_TMP_FPR(logn) fpr. Returns 0 on success. */
WOLFSSL_LOCAL int falcon_sign_core(falcon_sampler_ctx* spc, const fpr* expanded,
const word16* c, sword16* s2, fpr* tmp, unsigned logn);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* HAVE_FALCON && !WOLFSSL_FALCON_VERIFY_ONLY */
#endif /* WOLF_CRYPT_WC_FALCON_SIGN_H */
-9
View File
@@ -79,15 +79,6 @@ if(CONFIG_WOLFSSL)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ed448.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ed448.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/error.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/error.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/falcon.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/falcon.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_bigint.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_codec.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_fft.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_fpr.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_keygen.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_poly.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_sampler.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_falcon_sign.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_448.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_448.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_low_mem.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_low_mem.c)
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_operations.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_operations.c)