Sync with PQClean (#1061)

* Sync with PQClean 6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2

* Update documentation YML from PQClean

* Update documentation from PQClean
This commit is contained in:
Douglas Stebila 2021-08-01 17:02:22 -04:00 committed by GitHub
parent d0ad484a46
commit 30fbfd826f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 756 additions and 620 deletions

View File

@ -5,7 +5,7 @@
- **Principal submitters**: Daniel J. Bernstein, Tung Chou, Tanja Lange, Ingo von Maurich, Rafael Misoczki, Ruben Niederhagen, Edoardo Persichetti, Christiane Peters, Peter Schwabe, Nicolas Sendrier, Jakub Szefer, Wen Wang.
- **Authors' website**: https://classic.mceliece.org
- **Specification version**: SUPERCOP-20191221.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- SUPERCOP-20191221 "vec" and "avx" implementations
- **Implementation license (SPDX-Identifier)**: Public domain.

View File

@ -19,7 +19,7 @@ website: https://classic.mceliece.org
nist-round: 3
spec-version: SUPERCOP-20191221
spdx-license-identifier: Public domain
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- SUPERCOP-20191221 "vec" and "avx" implementations
parameter-sets:
@ -348,3 +348,4 @@ parameter-sets:
no-secret-dependent-branching-claimed: false
no-secret-dependent-branching-checked-by-valgrind: true
large-stack-usage: true
auxiliary-submitters: []

View File

@ -5,7 +5,7 @@
- **Principal submitters**: Carlos Aguilar Melchor, Nicolas Aragon, Slim Bettaieb, Olivier Blazy, Jurjen Bos, Jean-Christophe Deneuville, Philippe Gaborit, Edoardo Persichetti, Jean-Marc Robert, Pascal Véron, Gilles Zémor, Loïc Bidoux.
- **Authors' website**: https://pqc-hqc.org/
- **Specification version**: NIST Round 3 submission.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/jschanck/package-pqclean/tree/29f79e72/hqc, which takes it from:
- submission 2020-10-01 at https://pqc-hqc.org/implementation.html
- **Implementation license (SPDX-Identifier)**: Public domain.

View File

@ -18,7 +18,7 @@ website: https://pqc-hqc.org/
nist-round: 3
spec-version: NIST Round 3 submission
spdx-license-identifier: Public domain
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/jschanck/package-pqclean/tree/29f79e72/hqc
- submission 2020-10-01 at https://pqc-hqc.org/implementation.html

View File

@ -6,7 +6,7 @@
- **Auxiliary submitters**: Cong Chen, Oussama Danba, Jeffrey Hoffstein, Andreas Hülsing, Joost Rijneveld, Tsunekazu Saito, Peter Schwabe, William Whyte, Keita Xagawa, Takashi Yamakawa, Zhenfei Zhang.
- **Authors' website**: https://ntru.org/
- **Specification version**: NIST Round 3 submission.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/jschanck/ntru/tree/a43a4457
- **Implementation license (SPDX-Identifier)**: CC0-1.0.

View File

@ -19,7 +19,7 @@ website: https://ntru.org/
nist-round: 3
spec-version: NIST Round 3 submission
spdx-license-identifier: CC0-1.0
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/jschanck/ntru/tree/a43a4457
parameter-sets:

View File

@ -5,7 +5,7 @@
- **Principal submitters**: Daniel J. Bernstein, Chitchanok Chuengsatiansup, Tanja Lange, Christine van Vredendaal.
- **Authors' website**: https://ntruprime.cr.yp.to
- **Specification version**: supercop-20200826.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/jschanck/package-pqclean/tree/4d9f08c3/ntruprime, which takes it from:
- supercop-20210604
- **Implementation license (SPDX-Identifier)**: Public domain.

View File

@ -10,7 +10,7 @@ website: https://ntruprime.cr.yp.to
nist-round: 3
spec-version: supercop-20200826
spdx-license-identifier: Public domain
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/jschanck/package-pqclean/tree/4d9f08c3/ntruprime
- supercop-20210604

View File

@ -5,7 +5,7 @@
- **Principal submitters**: Jan-Pieter D'Anvers, Angshuman Karmakar, Sujoy Sinha Roy, Frederik Vercauteren.
- **Authors' website**: https://www.esat.kuleuven.be/cosic/pqcrypto/saber/
- **Specification version**: NIST Round 3 submission.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/jschanck/package-pqclean/tree/1ae84c3c/saber, which takes it from:
- https://github.com/KULeuven-COSIC/SABER/tree/509cc5ec3a7e12a751ccdd2ef5bd6e54e00bd350
- **Implementation license (SPDX-Identifier)**: Public domain.

View File

@ -10,7 +10,7 @@ website: https://www.esat.kuleuven.be/cosic/pqcrypto/saber/
nist-round: 3
spec-version: NIST Round 3 submission
spdx-license-identifier: Public domain
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/jschanck/package-pqclean/tree/1ae84c3c/saber
- https://github.com/KULeuven-COSIC/SABER/tree/509cc5ec3a7e12a751ccdd2ef5bd6e54e00bd350

View File

@ -6,7 +6,7 @@
- **Auxiliary submitters**: Pierre-Alain Fouque, Jeffrey Hoffstein, Paul Kirchner, Vadim Lyubashevsky, Thomas Pornin, Thomas Ricosset, Gregor Seiler, William Whyte, Zhenfei Zhang.
- **Authors' website**: https://falcon-sign.info
- **Specification version**: v1.2.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/jschanck/package-pqclean/tree/cea1fa5a/falcon, which takes it from:
- supercop-20201018
- **Implementation license (SPDX-Identifier)**: CC0-1.0.

View File

@ -17,7 +17,7 @@ website: https://falcon-sign.info
nist-round: 3
spec-version: v1.2
spdx-license-identifier: CC0-1.0
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/jschanck/package-pqclean/tree/cea1fa5a/falcon
- supercop-20201018

View File

@ -6,7 +6,7 @@
- **Auxiliary submitters**: Ming-Shing Chen, Matthias Kannwischer, Jacques Patarin, Albrecht Petzoldt, Dieter Schmidt, Bo-Yin Yang.
- **Authors' website**: https://www.pqcrainbow.org/
- **Specification version**: NIST Round 3 submission.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/fast-crypto-lab/rainbow-submission-round2/commit/173ada0e077e1b9dbd8e4a78994f87acc0c92263
- **Implementation license (SPDX-Identifier)**: CC0-1.0.

View File

@ -14,7 +14,7 @@ website: https://www.pqcrainbow.org/
nist-round: 3
spec-version: NIST Round 3 submission
spdx-license-identifier: CC0-1.0
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/fast-crypto-lab/rainbow-submission-round2/commit/173ada0e077e1b9dbd8e4a78994f87acc0c92263
parameter-sets:

View File

@ -6,7 +6,7 @@
- **Auxiliary submitters**: Jean-Philippe Aumasson, Daniel J. Bernstein,, Christoph Dobraunig, Maria Eichlseder, Scott Fluhrer, Stefan-Lukas Gazdag, Panos Kampanakis, Stefan Kölbl, Tanja Lange, Martin M. Lauridsen, Florian Mendel, Ruben Niederhagen, Christian Rechberger, Joost Rijneveld, Peter Schwabe.
- **Authors' website**: https://sphincs.org/
- **Specification version**: NIST Round 3 submission.
- **Implementation source**: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24, which takes it from:
- **Implementation source**: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2, which takes it from:
- https://github.com/sphincs/sphincsplus
- **Implementation license (SPDX-Identifier)**: CC0-1.0.

View File

@ -23,7 +23,7 @@ website: https://sphincs.org/
nist-round: 3
spec-version: NIST Round 3 submission
spdx-license-identifier: CC0-1.0
upstream: https://github.com/PQClean/PQClean/commit/89d34613364deca88659f6c2dd38708279c6bd24
upstream: https://github.com/PQClean/PQClean/commit/6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
upstream-ancestors:
- https://github.com/sphincs/sphincsplus
parameter-sets:

View File

@ -3,7 +3,7 @@ upstreams:
name: pqclean
git_url: https://github.com/PQClean/PQClean.git
git_branch: master
git_commit: 89d34613364deca88659f6c2dd38708279c6bd24
git_commit: 6c1ea921ee4a06a6b50c742ca540bb9b5e51aee2
kem_meta_path: 'crypto_kem/{pqclean_scheme}/META.yml'
sig_meta_path: 'crypto_sign/{pqclean_scheme}/META.yml'
kem_scheme_path: 'crypto_kem/{pqclean_scheme}'

View File

@ -6,7 +6,7 @@
set(_FALCON_OBJS "")
if(OQS_ENABLE_SIG_falcon_512)
add_library(falcon_512_clean OBJECT sig_falcon_512.c pqclean_falcon-512_clean/codec.c pqclean_falcon-512_clean/common.c pqclean_falcon-512_clean/fft.c pqclean_falcon-512_clean/fpr.c pqclean_falcon-512_clean/keygen.c pqclean_falcon-512_clean/pqclean.c pqclean_falcon-512_clean/rng.c pqclean_falcon-512_clean/sign.c pqclean_falcon-512_clean/vrfy.c)
add_library(falcon_512_clean OBJECT sig_falcon_512.c pqclean_falcon-512_clean/codec.c pqclean_falcon-512_clean/common.c pqclean_falcon-512_clean/fft.c pqclean_falcon-512_clean/fpr.c pqclean_falcon-512_clean/inner.c pqclean_falcon-512_clean/keygen.c pqclean_falcon-512_clean/pqclean.c pqclean_falcon-512_clean/rng.c pqclean_falcon-512_clean/sign.c pqclean_falcon-512_clean/vrfy.c)
target_include_directories(falcon_512_clean PRIVATE ${CMAKE_CURRENT_LIST_DIR}/pqclean_falcon-512_clean)
target_include_directories(falcon_512_clean PRIVATE ${PROJECT_SOURCE_DIR}/src/common/pqclean_shims)
set(_FALCON_OBJS ${_FALCON_OBJS} $<TARGET_OBJECTS:falcon_512_clean>)
@ -21,7 +21,7 @@ if(OQS_ENABLE_SIG_falcon_512_avx2)
endif()
if(OQS_ENABLE_SIG_falcon_1024)
add_library(falcon_1024_clean OBJECT sig_falcon_1024.c pqclean_falcon-1024_clean/codec.c pqclean_falcon-1024_clean/common.c pqclean_falcon-1024_clean/fft.c pqclean_falcon-1024_clean/fpr.c pqclean_falcon-1024_clean/keygen.c pqclean_falcon-1024_clean/pqclean.c pqclean_falcon-1024_clean/rng.c pqclean_falcon-1024_clean/sign.c pqclean_falcon-1024_clean/vrfy.c)
add_library(falcon_1024_clean OBJECT sig_falcon_1024.c pqclean_falcon-1024_clean/codec.c pqclean_falcon-1024_clean/common.c pqclean_falcon-1024_clean/fft.c pqclean_falcon-1024_clean/fpr.c pqclean_falcon-1024_clean/inner.c pqclean_falcon-1024_clean/keygen.c pqclean_falcon-1024_clean/pqclean.c pqclean_falcon-1024_clean/rng.c pqclean_falcon-1024_clean/sign.c pqclean_falcon-1024_clean/vrfy.c)
target_include_directories(falcon_1024_clean PRIVATE ${CMAKE_CURRENT_LIST_DIR}/pqclean_falcon-1024_clean)
target_include_directories(falcon_1024_clean PRIVATE ${PROJECT_SOURCE_DIR}/src/common/pqclean_shims)
set(_FALCON_OBJS ${_FALCON_OBJS} $<TARGET_OBJECTS:falcon_1024_clean>)

View File

@ -267,7 +267,7 @@ PQCLEAN_FALCON1024_AVX2_expand_privkey(fpr *expanded_key,
PQCLEAN_FALCON1024_AVX2_poly_neg(rF, logn);
/*
* The Gram matrix is G = B·B*. Formulas are:
* The Gram matrix is G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)
@ -781,7 +781,7 @@ do_sign_dyn(samplerZ samp, void *samp_ctx, int16_t *s2,
PQCLEAN_FALCON1024_AVX2_poly_neg(b11, logn);
/*
* Compute the Gram matrix G = B·B*. Formulas are:
* Compute the Gram matrix G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)

View File

@ -78,6 +78,66 @@
(e) += (int)(nt); \
} while (0)
uint64_t
fpr_ursh(uint64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(uint64_t)(n >> 5);
return x >> (n & 31);
}
int64_t
fpr_irsh(int64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(int64_t)(n >> 5);
return x >> (n & 31);
}
uint64_t
fpr_ulsh(uint64_t x, int n) {
x ^= (x ^ (x << 32)) & -(uint64_t)(n >> 5);
return x << (n & 31);
}
fpr
FPR(int s, int e, uint64_t m) {
fpr x;
uint32_t t;
unsigned f;
/*
* If e >= -1076, then the value is "normal"; otherwise, it
* should be a subnormal, which we clamp down to zero.
*/
e += 1076;
t = (uint32_t)e >> 31;
m &= (uint64_t)t - 1;
/*
* If m = 0 then we want a zero; make e = 0 too, but conserve
* the sign.
*/
t = (uint32_t)(m >> 54);
e &= -(int)t;
/*
* The 52 mantissa bits come from m. Value m has its top bit set
* (unless it is a zero); we leave it "as is": the top bit will
* increment the exponent by 1, except when m = 0, which is
* exactly what we want.
*/
x = (((uint64_t)s << 63) | (m >> 2)) + ((uint64_t)(uint32_t)e << 52);
/*
* Rounding: if the low three bits of m are 011, 110 or 111,
* then the value should be incremented to get the next
* representable value. This implements the usual
* round-to-nearest rule (with preference to even values in case
* of a tie). Note that the increment may make a carry spill
* into the exponent field, which is again exactly what we want
* in that case.
*/
f = (unsigned)m & 7U;
x += (0xC8U >> f) & 1;
return x;
}
fpr
fpr_scaled(int64_t i, int sc) {
@ -134,7 +194,131 @@ fpr_scaled(int64_t i, int sc) {
return FPR(s, e, m);
}
fpr
fpr_of(int64_t i) {
return fpr_scaled(i, 0);
}
int64_t
fpr_rint(fpr x) {
uint64_t m, d;
int e;
uint32_t s, dd, f;
/*
* We assume that the value fits in -(2^63-1)..+(2^63-1). We can
* thus extract the mantissa as a 63-bit integer, then right-shift
* it as needed.
*/
m = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
e = 1085 - ((int)(x >> 52) & 0x7FF);
/*
* If a shift of more than 63 bits is needed, then simply set m
* to zero. This also covers the case of an input operand equal
* to zero.
*/
m &= -(uint64_t)((uint32_t)(e - 64) >> 31);
e &= 63;
/*
* Right-shift m as needed. Shift count is e. Proper rounding
* mandates that:
* - If the highest dropped bit is zero, then round low.
* - If the highest dropped bit is one, and at least one of the
* other dropped bits is one, then round up.
* - If the highest dropped bit is one, and all other dropped
* bits are zero, then round up if the lowest kept bit is 1,
* or low otherwise (i.e. ties are broken by "rounding to even").
*
* We thus first extract a word consisting of all the dropped bit
* AND the lowest kept bit; then we shrink it down to three bits,
* the lowest being "sticky".
*/
d = fpr_ulsh(m, 63 - e);
dd = (uint32_t)d | ((uint32_t)(d >> 32) & 0x1FFFFFFF);
f = (uint32_t)(d >> 61) | ((dd | -dd) >> 31);
m = fpr_ursh(m, e) + (uint64_t)((0xC8U >> f) & 1U);
/*
* Apply the sign bit.
*/
s = (uint32_t)(x >> 63);
return ((int64_t)m ^ -(int64_t)s) + (int64_t)s;
}
int64_t
fpr_floor(fpr x) {
uint64_t t;
int64_t xi;
int e, cc;
/*
* We extract the integer as a _signed_ 64-bit integer with
* a scaling factor. Since we assume that the value fits
* in the -(2^63-1)..+(2^63-1) range, we can left-shift the
* absolute value to make it in the 2^62..2^63-1 range: we
* will only need a right-shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
t = x >> 63;
xi = (int64_t)(((x << 10) | ((uint64_t)1 << 62))
& (((uint64_t)1 << 63) - 1));
xi = (xi ^ -(int64_t)t) + (int64_t)t;
cc = 1085 - e;
/*
* We perform an arithmetic right-shift on the value. This
* applies floor() semantics on both positive and negative values
* (rounding toward minus infinity).
*/
xi = fpr_irsh(xi, cc & 63);
/*
* If the true shift count was 64 or more, then we should instead
* replace xi with 0 (if nonnegative) or -1 (if negative). Edge
* case: -0 will be floored to -1, not 0 (whether this is correct
* is debatable; in any case, the other functions normalize zero
* to +0).
*
* For an input of zero, the non-shifted xi was incorrect (we used
* a top implicit bit of value 1, not 0), but this does not matter
* since this operation will clamp it down.
*/
xi ^= (xi ^ -(int64_t)t) & -(int64_t)((uint32_t)(63 - cc) >> 31);
return xi;
}
int64_t
fpr_trunc(fpr x) {
uint64_t t, xu;
int e, cc;
/*
* Extract the absolute value. Since we assume that the value
* fits in the -(2^63-1)..+(2^63-1) range, we can left-shift
* the absolute value into the 2^62..2^63-1 range, and then
* do a right shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
xu = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
cc = 1085 - e;
xu = fpr_ursh(xu, cc & 63);
/*
* If the exponent is too low (cc > 63), then the shift was wrong
* and we must clamp the value to 0. This also covers the case
* of an input equal to zero.
*/
xu &= -(uint64_t)((uint32_t)(cc - 64) >> 31);
/*
* Apply back the sign, if the source value is negative.
*/
t = x >> 63;
xu = (xu ^ -t) + t;
return *(int64_t *)&xu;
}
fpr
fpr_add(fpr x, fpr y) {
@ -243,7 +427,42 @@ fpr_add(fpr x, fpr y) {
return FPR(sx, ex, xu);
}
fpr
fpr_sub(fpr x, fpr y) {
y ^= (uint64_t)1 << 63;
return fpr_add(x, y);
}
fpr
fpr_neg(fpr x) {
x ^= (uint64_t)1 << 63;
return x;
}
fpr
fpr_half(fpr x) {
/*
* To divide a value by 2, we just have to subtract 1 from its
* exponent, but we have to take care of zero.
*/
uint32_t t;
x -= (uint64_t)1 << 52;
t = (((uint32_t)(x >> 52) & 0x7FF) + 1) >> 11;
x &= (uint64_t)t - 1;
return x;
}
fpr
fpr_double(fpr x) {
/*
* To double a value, we just increment by one the exponent. We
* don't care about infinites or NaNs; however, 0 is a
* special case.
*/
x += (uint64_t)((((unsigned)(x >> 52) & 0x7FFU) + 0x7FFU) >> 11) << 52;
return x;
}
fpr
fpr_mul(fpr x, fpr y) {
@ -340,7 +559,10 @@ fpr_mul(fpr x, fpr y) {
return FPR(s, e, zu);
}
fpr
fpr_sqr(fpr x) {
return fpr_mul(x, x);
}
fpr
fpr_div(fpr x, fpr y) {
@ -428,7 +650,10 @@ fpr_div(fpr x, fpr y) {
return FPR(s, e, q);
}
fpr
fpr_inv(fpr x) {
return fpr_div(4607182418800017408u, x);
}
fpr
fpr_sqrt(fpr x) {
@ -506,6 +731,37 @@ fpr_sqrt(fpr x) {
return FPR(0, e, q);
}
int
fpr_lt(fpr x, fpr y) {
/*
* If both x and y are positive, then a signed comparison yields
* the proper result:
* - For positive values, the order is preserved.
* - The sign bit is at the same place as in integers, so
* sign is preserved.
* Moreover, we can compute [x < y] as sgn(x-y) and the computation
* of x-y will not overflow.
*
* If the signs differ, then sgn(x) gives the proper result.
*
* If both x and y are negative, then the order is reversed.
* Hence [x < y] = sgn(y-x). We must compute this separately from
* sgn(x-y); simply inverting sgn(x-y) would not handle the edge
* case x = y properly.
*/
int cc0, cc1;
int64_t sx;
int64_t sy;
sx = *(int64_t *)&x;
sy = *(int64_t *)&y;
sy &= ~((sx ^ sy) >> 63); /* set sy=0 if 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));
}
uint64_t
fpr_expm_p63(fpr x, fpr ccs) {

View File

@ -126,11 +126,8 @@ typedef uint64_t fpr;
*
* Shift count n MUST be in the 0..63 range.
*/
static inline uint64_t
fpr_ursh(uint64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(uint64_t)(n >> 5);
return x >> (n & 31);
}
#define fpr_ursh PQCLEAN_FALCON1024_CLEAN_fpr_ursh
uint64_t fpr_ursh(uint64_t x, int n);
/*
* Right-shift a 64-bit signed value by a possibly secret shift count
@ -138,11 +135,8 @@ fpr_ursh(uint64_t x, int n) {
*
* Shift count n MUST be in the 0..63 range.
*/
static inline int64_t
fpr_irsh(int64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(int64_t)(n >> 5);
return x >> (n & 31);
}
#define fpr_irsh PQCLEAN_FALCON1024_CLEAN_fpr_irsh
int64_t fpr_irsh(int64_t x, int n);
/*
* Left-shift a 64-bit unsigned value by a possibly secret shift count
@ -150,11 +144,8 @@ fpr_irsh(int64_t x, int n) {
*
* Shift count n MUST be in the 0..63 range.
*/
static inline uint64_t
fpr_ulsh(uint64_t x, int n) {
x ^= (x ^ (x << 32)) & -(uint64_t)(n >> 5);
return x << (n & 31);
}
#define fpr_ulsh PQCLEAN_FALCON1024_CLEAN_fpr_ulsh
uint64_t fpr_ulsh(uint64_t x, int n);
/*
* Expectations:
@ -171,56 +162,15 @@ fpr_ulsh(uint64_t x, int n) {
* If e >= -1076 and e != 0, m must be within the expected range
* (2^54 to 2^55-1).
*/
static inline fpr
FPR(int s, int e, uint64_t m) {
fpr x;
uint32_t t;
unsigned f;
#define FPR PQCLEAN_FALCON1024_CLEAN_FPR
fpr FPR(int s, int e, uint64_t m);
/*
* If e >= -1076, then the value is "normal"; otherwise, it
* should be a subnormal, which we clamp down to zero.
*/
e += 1076;
t = (uint32_t)e >> 31;
m &= (uint64_t)t - 1;
/*
* If m = 0 then we want a zero; make e = 0 too, but conserve
* the sign.
*/
t = (uint32_t)(m >> 54);
e &= -(int)t;
/*
* The 52 mantissa bits come from m. Value m has its top bit set
* (unless it is a zero); we leave it "as is": the top bit will
* increment the exponent by 1, except when m = 0, which is
* exactly what we want.
*/
x = (((uint64_t)s << 63) | (m >> 2)) + ((uint64_t)(uint32_t)e << 52);
/*
* Rounding: if the low three bits of m are 011, 110 or 111,
* then the value should be incremented to get the next
* representable value. This implements the usual
* round-to-nearest rule (with preference to even values in case
* of a tie). Note that the increment may make a carry spill
* into the exponent field, which is again exactly what we want
* in that case.
*/
f = (unsigned)m & 7U;
x += (0xC8U >> f) & 1;
return x;
}
#define fpr_scaled PQCLEAN_FALCON1024_CLEAN_fpr_scaled
fpr fpr_scaled(int64_t i, int sc);
static inline fpr
fpr_of(int64_t i) {
return fpr_scaled(i, 0);
}
#define fpr_of PQCLEAN_FALCON1024_CLEAN_fpr_of
fpr fpr_of(int64_t i);
static const fpr fpr_q = 4667981563525332992;
static const fpr fpr_inverse_of_q = 4545632735260551042;
@ -244,217 +194,47 @@ static const fpr fpr_ptwo63m1 = 4890909195324358656;
static const fpr fpr_mtwo63m1 = 14114281232179134464U;
static const fpr fpr_ptwo63 = 4890909195324358656;
static inline int64_t
fpr_rint(fpr x) {
uint64_t m, d;
int e;
uint32_t s, dd, f;
#define fpr_rint PQCLEAN_FALCON1024_CLEAN_fpr_rint
int64_t fpr_rint(fpr x);
/*
* We assume that the value fits in -(2^63-1)..+(2^63-1). We can
* thus extract the mantissa as a 63-bit integer, then right-shift
* it as needed.
*/
m = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
e = 1085 - ((int)(x >> 52) & 0x7FF);
#define fpr_floor PQCLEAN_FALCON1024_CLEAN_fpr_floor
int64_t fpr_floor(fpr x);
/*
* If a shift of more than 63 bits is needed, then simply set m
* to zero. This also covers the case of an input operand equal
* to zero.
*/
m &= -(uint64_t)((uint32_t)(e - 64) >> 31);
e &= 63;
/*
* Right-shift m as needed. Shift count is e. Proper rounding
* mandates that:
* - If the highest dropped bit is zero, then round low.
* - If the highest dropped bit is one, and at least one of the
* other dropped bits is one, then round up.
* - If the highest dropped bit is one, and all other dropped
* bits are zero, then round up if the lowest kept bit is 1,
* or low otherwise (i.e. ties are broken by "rounding to even").
*
* We thus first extract a word consisting of all the dropped bit
* AND the lowest kept bit; then we shrink it down to three bits,
* the lowest being "sticky".
*/
d = fpr_ulsh(m, 63 - e);
dd = (uint32_t)d | ((uint32_t)(d >> 32) & 0x1FFFFFFF);
f = (uint32_t)(d >> 61) | ((dd | -dd) >> 31);
m = fpr_ursh(m, e) + (uint64_t)((0xC8U >> f) & 1U);
/*
* Apply the sign bit.
*/
s = (uint32_t)(x >> 63);
return ((int64_t)m ^ -(int64_t)s) + (int64_t)s;
}
static inline int64_t
fpr_floor(fpr x) {
uint64_t t;
int64_t xi;
int e, cc;
/*
* We extract the integer as a _signed_ 64-bit integer with
* a scaling factor. Since we assume that the value fits
* in the -(2^63-1)..+(2^63-1) range, we can left-shift the
* absolute value to make it in the 2^62..2^63-1 range: we
* will only need a right-shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
t = x >> 63;
xi = (int64_t)(((x << 10) | ((uint64_t)1 << 62))
& (((uint64_t)1 << 63) - 1));
xi = (xi ^ -(int64_t)t) + (int64_t)t;
cc = 1085 - e;
/*
* We perform an arithmetic right-shift on the value. This
* applies floor() semantics on both positive and negative values
* (rounding toward minus infinity).
*/
xi = fpr_irsh(xi, cc & 63);
/*
* If the true shift count was 64 or more, then we should instead
* replace xi with 0 (if nonnegative) or -1 (if negative). Edge
* case: -0 will be floored to -1, not 0 (whether this is correct
* is debatable; in any case, the other functions normalize zero
* to +0).
*
* For an input of zero, the non-shifted xi was incorrect (we used
* a top implicit bit of value 1, not 0), but this does not matter
* since this operation will clamp it down.
*/
xi ^= (xi ^ -(int64_t)t) & -(int64_t)((uint32_t)(63 - cc) >> 31);
return xi;
}
static inline int64_t
fpr_trunc(fpr x) {
uint64_t t, xu;
int e, cc;
/*
* Extract the absolute value. Since we assume that the value
* fits in the -(2^63-1)..+(2^63-1) range, we can left-shift
* the absolute value into the 2^62..2^63-1 range, and then
* do a right shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
xu = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
cc = 1085 - e;
xu = fpr_ursh(xu, cc & 63);
/*
* If the exponent is too low (cc > 63), then the shift was wrong
* and we must clamp the value to 0. This also covers the case
* of an input equal to zero.
*/
xu &= -(uint64_t)((uint32_t)(cc - 64) >> 31);
/*
* Apply back the sign, if the source value is negative.
*/
t = x >> 63;
xu = (xu ^ -t) + t;
return *(int64_t *)&xu;
}
#define fpr_trunc PQCLEAN_FALCON1024_CLEAN_fpr_trunc
int64_t fpr_trunc(fpr x);
#define fpr_add PQCLEAN_FALCON1024_CLEAN_fpr_add
fpr fpr_add(fpr x, fpr y);
static inline fpr
fpr_sub(fpr x, fpr y) {
y ^= (uint64_t)1 << 63;
return fpr_add(x, y);
}
#define fpr_sub PQCLEAN_FALCON1024_CLEAN_fpr_sub
fpr fpr_sub(fpr x, fpr y);
static inline fpr
fpr_neg(fpr x) {
x ^= (uint64_t)1 << 63;
return x;
}
#define fpr_neg PQCLEAN_FALCON1024_CLEAN_fpr_neg
fpr fpr_neg(fpr x);
static inline fpr
fpr_half(fpr x) {
/*
* To divide a value by 2, we just have to subtract 1 from its
* exponent, but we have to take care of zero.
*/
uint32_t t;
#define fpr_half PQCLEAN_FALCON1024_CLEAN_fpr_half
fpr fpr_half(fpr x);
x -= (uint64_t)1 << 52;
t = (((uint32_t)(x >> 52) & 0x7FF) + 1) >> 11;
x &= (uint64_t)t - 1;
return x;
}
static inline fpr
fpr_double(fpr x) {
/*
* To double a value, we just increment by one the exponent. We
* don't care about infinites or NaNs; however, 0 is a
* special case.
*/
x += (uint64_t)((((unsigned)(x >> 52) & 0x7FFU) + 0x7FFU) >> 11) << 52;
return x;
}
#define fpr_double PQCLEAN_FALCON1024_CLEAN_fpr_double
fpr fpr_double(fpr x);
#define fpr_mul PQCLEAN_FALCON1024_CLEAN_fpr_mul
fpr fpr_mul(fpr x, fpr y);
static inline fpr
fpr_sqr(fpr x) {
return fpr_mul(x, x);
}
#define fpr_sqr PQCLEAN_FALCON1024_CLEAN_fpr_sqr
fpr fpr_sqr(fpr x);
#define fpr_div PQCLEAN_FALCON1024_CLEAN_fpr_div
fpr fpr_div(fpr x, fpr y);
static inline fpr
fpr_inv(fpr x) {
return fpr_div(4607182418800017408u, x);
}
#define fpr_inv PQCLEAN_FALCON1024_CLEAN_fpr_inv
fpr fpr_inv(fpr x);
#define fpr_sqrt PQCLEAN_FALCON1024_CLEAN_fpr_sqrt
fpr fpr_sqrt(fpr x);
static inline int
fpr_lt(fpr x, fpr y) {
/*
* If both x and y are positive, then a signed comparison yields
* the proper result:
* - For positive values, the order is preserved.
* - The sign bit is at the same place as in integers, so
* sign is preserved.
* Moreover, we can compute [x < y] as sgn(x-y) and the computation
* of x-y will not overflow.
*
* If the signs differ, then sgn(x) gives the proper result.
*
* If both x and y are negative, then the order is reversed.
* Hence [x < y] = sgn(y-x). We must compute this separately from
* sgn(x-y); simply inverting sgn(x-y) would not handle the edge
* case x = y properly.
*/
int cc0, cc1;
int64_t sx;
int64_t sy;
sx = *(int64_t *)&x;
sy = *(int64_t *)&y;
sy &= ~((sx ^ sy) >> 63); /* set sy=0 if 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));
}
#define fpr_lt PQCLEAN_FALCON1024_CLEAN_fpr_lt
int fpr_lt(fpr x, fpr y);
/*
* Compute exp(x) for x such that |x| <= ln 2. We want a precision of 50

View File

@ -0,0 +1,70 @@
#include "inner.h"
/*
* ==========================(LICENSE BEGIN)============================
*
* Copyright (c) 2017-2019 Falcon Project
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* ===========================(LICENSE END)=============================
*/
unsigned set_fpu_cw(unsigned x) {
return x;
}
uint64_t prng_get_u64(prng *p) {
size_t u;
/*
* If there are less than 9 bytes in the buffer, we refill it.
* This means that we may drop the last few bytes, but this allows
* for faster extraction code. Also, it means that we never leave
* an empty buffer.
*/
u = p->ptr;
if (u >= (sizeof p->buf.d) - 9) {
PQCLEAN_FALCON1024_CLEAN_prng_refill(p);
u = 0;
}
p->ptr = u + 8;
return (uint64_t)p->buf.d[u + 0]
| ((uint64_t)p->buf.d[u + 1] << 8)
| ((uint64_t)p->buf.d[u + 2] << 16)
| ((uint64_t)p->buf.d[u + 3] << 24)
| ((uint64_t)p->buf.d[u + 4] << 32)
| ((uint64_t)p->buf.d[u + 5] << 40)
| ((uint64_t)p->buf.d[u + 6] << 48)
| ((uint64_t)p->buf.d[u + 7] << 56);
}
unsigned prng_get_u8(prng *p) {
unsigned v;
v = p->buf.d[p->ptr ++];
if (p->ptr == sizeof p->buf.d) {
PQCLEAN_FALCON1024_CLEAN_prng_refill(p);
}
return v;
}

View File

@ -99,12 +99,8 @@
* targets other than 32-bit x86, or when the native 'double' type is
* not used, the set_fpu_cw() function does nothing at all.
*/
static inline unsigned
set_fpu_cw(unsigned x) {
return x;
}
#define set_fpu_cw PQCLEAN_FALCON1024_CLEAN_set_fpu_cw
unsigned set_fpu_cw(unsigned x);
/* ==================================================================== */
@ -496,50 +492,14 @@ void PQCLEAN_FALCON1024_CLEAN_prng_get_bytes(prng *p, void *dst, size_t len);
/*
* Get a 64-bit random value from a PRNG.
*/
static inline uint64_t
prng_get_u64(prng *p) {
size_t u;
/*
* If there are less than 9 bytes in the buffer, we refill it.
* This means that we may drop the last few bytes, but this allows
* for faster extraction code. Also, it means that we never leave
* an empty buffer.
*/
u = p->ptr;
if (u >= (sizeof p->buf.d) - 9) {
PQCLEAN_FALCON1024_CLEAN_prng_refill(p);
u = 0;
}
p->ptr = u + 8;
/*
* On systems that use little-endian encoding and allow
* unaligned accesses, we can simply read the data where it is.
*/
return (uint64_t)p->buf.d[u + 0]
| ((uint64_t)p->buf.d[u + 1] << 8)
| ((uint64_t)p->buf.d[u + 2] << 16)
| ((uint64_t)p->buf.d[u + 3] << 24)
| ((uint64_t)p->buf.d[u + 4] << 32)
| ((uint64_t)p->buf.d[u + 5] << 40)
| ((uint64_t)p->buf.d[u + 6] << 48)
| ((uint64_t)p->buf.d[u + 7] << 56);
}
#define prng_get_u64 PQCLEAN_FALCON1024_CLEAN_prng_get_u64
uint64_t prng_get_u64(prng *p);
/*
* Get an 8-bit random value from a PRNG.
*/
static inline unsigned
prng_get_u8(prng *p) {
unsigned v;
v = p->buf.d[p->ptr ++];
if (p->ptr == sizeof p->buf.d) {
PQCLEAN_FALCON1024_CLEAN_prng_refill(p);
}
return v;
}
#define prng_get_u8 PQCLEAN_FALCON1024_CLEAN_prng_get_u8
unsigned prng_get_u8(prng *p);
/* ==================================================================== */
/*

View File

@ -267,7 +267,7 @@ PQCLEAN_FALCON1024_CLEAN_expand_privkey(fpr *expanded_key,
PQCLEAN_FALCON1024_CLEAN_poly_neg(rF, logn);
/*
* The Gram matrix is G = B·B*. Formulas are:
* The Gram matrix is G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)
@ -788,7 +788,7 @@ do_sign_dyn(samplerZ samp, void *samp_ctx, int16_t *s2,
PQCLEAN_FALCON1024_CLEAN_poly_neg(b11, logn);
/*
* Compute the Gram matrix G = B·B*. Formulas are:
* Compute the Gram matrix G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)

View File

@ -267,7 +267,7 @@ PQCLEAN_FALCON512_AVX2_expand_privkey(fpr *expanded_key,
PQCLEAN_FALCON512_AVX2_poly_neg(rF, logn);
/*
* The Gram matrix is G = B·B*. Formulas are:
* The Gram matrix is G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)
@ -781,7 +781,7 @@ do_sign_dyn(samplerZ samp, void *samp_ctx, int16_t *s2,
PQCLEAN_FALCON512_AVX2_poly_neg(b11, logn);
/*
* Compute the Gram matrix G = B·B*. Formulas are:
* Compute the Gram matrix G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)

View File

@ -78,6 +78,66 @@
(e) += (int)(nt); \
} while (0)
uint64_t
fpr_ursh(uint64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(uint64_t)(n >> 5);
return x >> (n & 31);
}
int64_t
fpr_irsh(int64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(int64_t)(n >> 5);
return x >> (n & 31);
}
uint64_t
fpr_ulsh(uint64_t x, int n) {
x ^= (x ^ (x << 32)) & -(uint64_t)(n >> 5);
return x << (n & 31);
}
fpr
FPR(int s, int e, uint64_t m) {
fpr x;
uint32_t t;
unsigned f;
/*
* If e >= -1076, then the value is "normal"; otherwise, it
* should be a subnormal, which we clamp down to zero.
*/
e += 1076;
t = (uint32_t)e >> 31;
m &= (uint64_t)t - 1;
/*
* If m = 0 then we want a zero; make e = 0 too, but conserve
* the sign.
*/
t = (uint32_t)(m >> 54);
e &= -(int)t;
/*
* The 52 mantissa bits come from m. Value m has its top bit set
* (unless it is a zero); we leave it "as is": the top bit will
* increment the exponent by 1, except when m = 0, which is
* exactly what we want.
*/
x = (((uint64_t)s << 63) | (m >> 2)) + ((uint64_t)(uint32_t)e << 52);
/*
* Rounding: if the low three bits of m are 011, 110 or 111,
* then the value should be incremented to get the next
* representable value. This implements the usual
* round-to-nearest rule (with preference to even values in case
* of a tie). Note that the increment may make a carry spill
* into the exponent field, which is again exactly what we want
* in that case.
*/
f = (unsigned)m & 7U;
x += (0xC8U >> f) & 1;
return x;
}
fpr
fpr_scaled(int64_t i, int sc) {
@ -134,7 +194,131 @@ fpr_scaled(int64_t i, int sc) {
return FPR(s, e, m);
}
fpr
fpr_of(int64_t i) {
return fpr_scaled(i, 0);
}
int64_t
fpr_rint(fpr x) {
uint64_t m, d;
int e;
uint32_t s, dd, f;
/*
* We assume that the value fits in -(2^63-1)..+(2^63-1). We can
* thus extract the mantissa as a 63-bit integer, then right-shift
* it as needed.
*/
m = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
e = 1085 - ((int)(x >> 52) & 0x7FF);
/*
* If a shift of more than 63 bits is needed, then simply set m
* to zero. This also covers the case of an input operand equal
* to zero.
*/
m &= -(uint64_t)((uint32_t)(e - 64) >> 31);
e &= 63;
/*
* Right-shift m as needed. Shift count is e. Proper rounding
* mandates that:
* - If the highest dropped bit is zero, then round low.
* - If the highest dropped bit is one, and at least one of the
* other dropped bits is one, then round up.
* - If the highest dropped bit is one, and all other dropped
* bits are zero, then round up if the lowest kept bit is 1,
* or low otherwise (i.e. ties are broken by "rounding to even").
*
* We thus first extract a word consisting of all the dropped bit
* AND the lowest kept bit; then we shrink it down to three bits,
* the lowest being "sticky".
*/
d = fpr_ulsh(m, 63 - e);
dd = (uint32_t)d | ((uint32_t)(d >> 32) & 0x1FFFFFFF);
f = (uint32_t)(d >> 61) | ((dd | -dd) >> 31);
m = fpr_ursh(m, e) + (uint64_t)((0xC8U >> f) & 1U);
/*
* Apply the sign bit.
*/
s = (uint32_t)(x >> 63);
return ((int64_t)m ^ -(int64_t)s) + (int64_t)s;
}
int64_t
fpr_floor(fpr x) {
uint64_t t;
int64_t xi;
int e, cc;
/*
* We extract the integer as a _signed_ 64-bit integer with
* a scaling factor. Since we assume that the value fits
* in the -(2^63-1)..+(2^63-1) range, we can left-shift the
* absolute value to make it in the 2^62..2^63-1 range: we
* will only need a right-shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
t = x >> 63;
xi = (int64_t)(((x << 10) | ((uint64_t)1 << 62))
& (((uint64_t)1 << 63) - 1));
xi = (xi ^ -(int64_t)t) + (int64_t)t;
cc = 1085 - e;
/*
* We perform an arithmetic right-shift on the value. This
* applies floor() semantics on both positive and negative values
* (rounding toward minus infinity).
*/
xi = fpr_irsh(xi, cc & 63);
/*
* If the true shift count was 64 or more, then we should instead
* replace xi with 0 (if nonnegative) or -1 (if negative). Edge
* case: -0 will be floored to -1, not 0 (whether this is correct
* is debatable; in any case, the other functions normalize zero
* to +0).
*
* For an input of zero, the non-shifted xi was incorrect (we used
* a top implicit bit of value 1, not 0), but this does not matter
* since this operation will clamp it down.
*/
xi ^= (xi ^ -(int64_t)t) & -(int64_t)((uint32_t)(63 - cc) >> 31);
return xi;
}
int64_t
fpr_trunc(fpr x) {
uint64_t t, xu;
int e, cc;
/*
* Extract the absolute value. Since we assume that the value
* fits in the -(2^63-1)..+(2^63-1) range, we can left-shift
* the absolute value into the 2^62..2^63-1 range, and then
* do a right shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
xu = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
cc = 1085 - e;
xu = fpr_ursh(xu, cc & 63);
/*
* If the exponent is too low (cc > 63), then the shift was wrong
* and we must clamp the value to 0. This also covers the case
* of an input equal to zero.
*/
xu &= -(uint64_t)((uint32_t)(cc - 64) >> 31);
/*
* Apply back the sign, if the source value is negative.
*/
t = x >> 63;
xu = (xu ^ -t) + t;
return *(int64_t *)&xu;
}
fpr
fpr_add(fpr x, fpr y) {
@ -243,7 +427,42 @@ fpr_add(fpr x, fpr y) {
return FPR(sx, ex, xu);
}
fpr
fpr_sub(fpr x, fpr y) {
y ^= (uint64_t)1 << 63;
return fpr_add(x, y);
}
fpr
fpr_neg(fpr x) {
x ^= (uint64_t)1 << 63;
return x;
}
fpr
fpr_half(fpr x) {
/*
* To divide a value by 2, we just have to subtract 1 from its
* exponent, but we have to take care of zero.
*/
uint32_t t;
x -= (uint64_t)1 << 52;
t = (((uint32_t)(x >> 52) & 0x7FF) + 1) >> 11;
x &= (uint64_t)t - 1;
return x;
}
fpr
fpr_double(fpr x) {
/*
* To double a value, we just increment by one the exponent. We
* don't care about infinites or NaNs; however, 0 is a
* special case.
*/
x += (uint64_t)((((unsigned)(x >> 52) & 0x7FFU) + 0x7FFU) >> 11) << 52;
return x;
}
fpr
fpr_mul(fpr x, fpr y) {
@ -340,7 +559,10 @@ fpr_mul(fpr x, fpr y) {
return FPR(s, e, zu);
}
fpr
fpr_sqr(fpr x) {
return fpr_mul(x, x);
}
fpr
fpr_div(fpr x, fpr y) {
@ -428,7 +650,10 @@ fpr_div(fpr x, fpr y) {
return FPR(s, e, q);
}
fpr
fpr_inv(fpr x) {
return fpr_div(4607182418800017408u, x);
}
fpr
fpr_sqrt(fpr x) {
@ -506,6 +731,37 @@ fpr_sqrt(fpr x) {
return FPR(0, e, q);
}
int
fpr_lt(fpr x, fpr y) {
/*
* If both x and y are positive, then a signed comparison yields
* the proper result:
* - For positive values, the order is preserved.
* - The sign bit is at the same place as in integers, so
* sign is preserved.
* Moreover, we can compute [x < y] as sgn(x-y) and the computation
* of x-y will not overflow.
*
* If the signs differ, then sgn(x) gives the proper result.
*
* If both x and y are negative, then the order is reversed.
* Hence [x < y] = sgn(y-x). We must compute this separately from
* sgn(x-y); simply inverting sgn(x-y) would not handle the edge
* case x = y properly.
*/
int cc0, cc1;
int64_t sx;
int64_t sy;
sx = *(int64_t *)&x;
sy = *(int64_t *)&y;
sy &= ~((sx ^ sy) >> 63); /* set sy=0 if 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));
}
uint64_t
fpr_expm_p63(fpr x, fpr ccs) {

View File

@ -126,11 +126,8 @@ typedef uint64_t fpr;
*
* Shift count n MUST be in the 0..63 range.
*/
static inline uint64_t
fpr_ursh(uint64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(uint64_t)(n >> 5);
return x >> (n & 31);
}
#define fpr_ursh PQCLEAN_FALCON512_CLEAN_fpr_ursh
uint64_t fpr_ursh(uint64_t x, int n);
/*
* Right-shift a 64-bit signed value by a possibly secret shift count
@ -138,11 +135,8 @@ fpr_ursh(uint64_t x, int n) {
*
* Shift count n MUST be in the 0..63 range.
*/
static inline int64_t
fpr_irsh(int64_t x, int n) {
x ^= (x ^ (x >> 32)) & -(int64_t)(n >> 5);
return x >> (n & 31);
}
#define fpr_irsh PQCLEAN_FALCON512_CLEAN_fpr_irsh
int64_t fpr_irsh(int64_t x, int n);
/*
* Left-shift a 64-bit unsigned value by a possibly secret shift count
@ -150,11 +144,8 @@ fpr_irsh(int64_t x, int n) {
*
* Shift count n MUST be in the 0..63 range.
*/
static inline uint64_t
fpr_ulsh(uint64_t x, int n) {
x ^= (x ^ (x << 32)) & -(uint64_t)(n >> 5);
return x << (n & 31);
}
#define fpr_ulsh PQCLEAN_FALCON512_CLEAN_fpr_ulsh
uint64_t fpr_ulsh(uint64_t x, int n);
/*
* Expectations:
@ -171,56 +162,15 @@ fpr_ulsh(uint64_t x, int n) {
* If e >= -1076 and e != 0, m must be within the expected range
* (2^54 to 2^55-1).
*/
static inline fpr
FPR(int s, int e, uint64_t m) {
fpr x;
uint32_t t;
unsigned f;
#define FPR PQCLEAN_FALCON512_CLEAN_FPR
fpr FPR(int s, int e, uint64_t m);
/*
* If e >= -1076, then the value is "normal"; otherwise, it
* should be a subnormal, which we clamp down to zero.
*/
e += 1076;
t = (uint32_t)e >> 31;
m &= (uint64_t)t - 1;
/*
* If m = 0 then we want a zero; make e = 0 too, but conserve
* the sign.
*/
t = (uint32_t)(m >> 54);
e &= -(int)t;
/*
* The 52 mantissa bits come from m. Value m has its top bit set
* (unless it is a zero); we leave it "as is": the top bit will
* increment the exponent by 1, except when m = 0, which is
* exactly what we want.
*/
x = (((uint64_t)s << 63) | (m >> 2)) + ((uint64_t)(uint32_t)e << 52);
/*
* Rounding: if the low three bits of m are 011, 110 or 111,
* then the value should be incremented to get the next
* representable value. This implements the usual
* round-to-nearest rule (with preference to even values in case
* of a tie). Note that the increment may make a carry spill
* into the exponent field, which is again exactly what we want
* in that case.
*/
f = (unsigned)m & 7U;
x += (0xC8U >> f) & 1;
return x;
}
#define fpr_scaled PQCLEAN_FALCON512_CLEAN_fpr_scaled
fpr fpr_scaled(int64_t i, int sc);
static inline fpr
fpr_of(int64_t i) {
return fpr_scaled(i, 0);
}
#define fpr_of PQCLEAN_FALCON512_CLEAN_fpr_of
fpr fpr_of(int64_t i);
static const fpr fpr_q = 4667981563525332992;
static const fpr fpr_inverse_of_q = 4545632735260551042;
@ -244,217 +194,47 @@ static const fpr fpr_ptwo63m1 = 4890909195324358656;
static const fpr fpr_mtwo63m1 = 14114281232179134464U;
static const fpr fpr_ptwo63 = 4890909195324358656;
static inline int64_t
fpr_rint(fpr x) {
uint64_t m, d;
int e;
uint32_t s, dd, f;
#define fpr_rint PQCLEAN_FALCON512_CLEAN_fpr_rint
int64_t fpr_rint(fpr x);
/*
* We assume that the value fits in -(2^63-1)..+(2^63-1). We can
* thus extract the mantissa as a 63-bit integer, then right-shift
* it as needed.
*/
m = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
e = 1085 - ((int)(x >> 52) & 0x7FF);
#define fpr_floor PQCLEAN_FALCON512_CLEAN_fpr_floor
int64_t fpr_floor(fpr x);
/*
* If a shift of more than 63 bits is needed, then simply set m
* to zero. This also covers the case of an input operand equal
* to zero.
*/
m &= -(uint64_t)((uint32_t)(e - 64) >> 31);
e &= 63;
/*
* Right-shift m as needed. Shift count is e. Proper rounding
* mandates that:
* - If the highest dropped bit is zero, then round low.
* - If the highest dropped bit is one, and at least one of the
* other dropped bits is one, then round up.
* - If the highest dropped bit is one, and all other dropped
* bits are zero, then round up if the lowest kept bit is 1,
* or low otherwise (i.e. ties are broken by "rounding to even").
*
* We thus first extract a word consisting of all the dropped bit
* AND the lowest kept bit; then we shrink it down to three bits,
* the lowest being "sticky".
*/
d = fpr_ulsh(m, 63 - e);
dd = (uint32_t)d | ((uint32_t)(d >> 32) & 0x1FFFFFFF);
f = (uint32_t)(d >> 61) | ((dd | -dd) >> 31);
m = fpr_ursh(m, e) + (uint64_t)((0xC8U >> f) & 1U);
/*
* Apply the sign bit.
*/
s = (uint32_t)(x >> 63);
return ((int64_t)m ^ -(int64_t)s) + (int64_t)s;
}
static inline int64_t
fpr_floor(fpr x) {
uint64_t t;
int64_t xi;
int e, cc;
/*
* We extract the integer as a _signed_ 64-bit integer with
* a scaling factor. Since we assume that the value fits
* in the -(2^63-1)..+(2^63-1) range, we can left-shift the
* absolute value to make it in the 2^62..2^63-1 range: we
* will only need a right-shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
t = x >> 63;
xi = (int64_t)(((x << 10) | ((uint64_t)1 << 62))
& (((uint64_t)1 << 63) - 1));
xi = (xi ^ -(int64_t)t) + (int64_t)t;
cc = 1085 - e;
/*
* We perform an arithmetic right-shift on the value. This
* applies floor() semantics on both positive and negative values
* (rounding toward minus infinity).
*/
xi = fpr_irsh(xi, cc & 63);
/*
* If the true shift count was 64 or more, then we should instead
* replace xi with 0 (if nonnegative) or -1 (if negative). Edge
* case: -0 will be floored to -1, not 0 (whether this is correct
* is debatable; in any case, the other functions normalize zero
* to +0).
*
* For an input of zero, the non-shifted xi was incorrect (we used
* a top implicit bit of value 1, not 0), but this does not matter
* since this operation will clamp it down.
*/
xi ^= (xi ^ -(int64_t)t) & -(int64_t)((uint32_t)(63 - cc) >> 31);
return xi;
}
static inline int64_t
fpr_trunc(fpr x) {
uint64_t t, xu;
int e, cc;
/*
* Extract the absolute value. Since we assume that the value
* fits in the -(2^63-1)..+(2^63-1) range, we can left-shift
* the absolute value into the 2^62..2^63-1 range, and then
* do a right shift afterwards.
*/
e = (int)(x >> 52) & 0x7FF;
xu = ((x << 10) | ((uint64_t)1 << 62)) & (((uint64_t)1 << 63) - 1);
cc = 1085 - e;
xu = fpr_ursh(xu, cc & 63);
/*
* If the exponent is too low (cc > 63), then the shift was wrong
* and we must clamp the value to 0. This also covers the case
* of an input equal to zero.
*/
xu &= -(uint64_t)((uint32_t)(cc - 64) >> 31);
/*
* Apply back the sign, if the source value is negative.
*/
t = x >> 63;
xu = (xu ^ -t) + t;
return *(int64_t *)&xu;
}
#define fpr_trunc PQCLEAN_FALCON512_CLEAN_fpr_trunc
int64_t fpr_trunc(fpr x);
#define fpr_add PQCLEAN_FALCON512_CLEAN_fpr_add
fpr fpr_add(fpr x, fpr y);
static inline fpr
fpr_sub(fpr x, fpr y) {
y ^= (uint64_t)1 << 63;
return fpr_add(x, y);
}
#define fpr_sub PQCLEAN_FALCON512_CLEAN_fpr_sub
fpr fpr_sub(fpr x, fpr y);
static inline fpr
fpr_neg(fpr x) {
x ^= (uint64_t)1 << 63;
return x;
}
#define fpr_neg PQCLEAN_FALCON512_CLEAN_fpr_neg
fpr fpr_neg(fpr x);
static inline fpr
fpr_half(fpr x) {
/*
* To divide a value by 2, we just have to subtract 1 from its
* exponent, but we have to take care of zero.
*/
uint32_t t;
#define fpr_half PQCLEAN_FALCON512_CLEAN_fpr_half
fpr fpr_half(fpr x);
x -= (uint64_t)1 << 52;
t = (((uint32_t)(x >> 52) & 0x7FF) + 1) >> 11;
x &= (uint64_t)t - 1;
return x;
}
static inline fpr
fpr_double(fpr x) {
/*
* To double a value, we just increment by one the exponent. We
* don't care about infinites or NaNs; however, 0 is a
* special case.
*/
x += (uint64_t)((((unsigned)(x >> 52) & 0x7FFU) + 0x7FFU) >> 11) << 52;
return x;
}
#define fpr_double PQCLEAN_FALCON512_CLEAN_fpr_double
fpr fpr_double(fpr x);
#define fpr_mul PQCLEAN_FALCON512_CLEAN_fpr_mul
fpr fpr_mul(fpr x, fpr y);
static inline fpr
fpr_sqr(fpr x) {
return fpr_mul(x, x);
}
#define fpr_sqr PQCLEAN_FALCON512_CLEAN_fpr_sqr
fpr fpr_sqr(fpr x);
#define fpr_div PQCLEAN_FALCON512_CLEAN_fpr_div
fpr fpr_div(fpr x, fpr y);
static inline fpr
fpr_inv(fpr x) {
return fpr_div(4607182418800017408u, x);
}
#define fpr_inv PQCLEAN_FALCON512_CLEAN_fpr_inv
fpr fpr_inv(fpr x);
#define fpr_sqrt PQCLEAN_FALCON512_CLEAN_fpr_sqrt
fpr fpr_sqrt(fpr x);
static inline int
fpr_lt(fpr x, fpr y) {
/*
* If both x and y are positive, then a signed comparison yields
* the proper result:
* - For positive values, the order is preserved.
* - The sign bit is at the same place as in integers, so
* sign is preserved.
* Moreover, we can compute [x < y] as sgn(x-y) and the computation
* of x-y will not overflow.
*
* If the signs differ, then sgn(x) gives the proper result.
*
* If both x and y are negative, then the order is reversed.
* Hence [x < y] = sgn(y-x). We must compute this separately from
* sgn(x-y); simply inverting sgn(x-y) would not handle the edge
* case x = y properly.
*/
int cc0, cc1;
int64_t sx;
int64_t sy;
sx = *(int64_t *)&x;
sy = *(int64_t *)&y;
sy &= ~((sx ^ sy) >> 63); /* set sy=0 if 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));
}
#define fpr_lt PQCLEAN_FALCON512_CLEAN_fpr_lt
int fpr_lt(fpr x, fpr y);
/*
* Compute exp(x) for x such that |x| <= ln 2. We want a precision of 50

View File

@ -0,0 +1,70 @@
#include "inner.h"
/*
* ==========================(LICENSE BEGIN)============================
*
* Copyright (c) 2017-2019 Falcon Project
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* ===========================(LICENSE END)=============================
*/
unsigned set_fpu_cw(unsigned x) {
return x;
}
uint64_t prng_get_u64(prng *p) {
size_t u;
/*
* If there are less than 9 bytes in the buffer, we refill it.
* This means that we may drop the last few bytes, but this allows
* for faster extraction code. Also, it means that we never leave
* an empty buffer.
*/
u = p->ptr;
if (u >= (sizeof p->buf.d) - 9) {
PQCLEAN_FALCON512_CLEAN_prng_refill(p);
u = 0;
}
p->ptr = u + 8;
return (uint64_t)p->buf.d[u + 0]
| ((uint64_t)p->buf.d[u + 1] << 8)
| ((uint64_t)p->buf.d[u + 2] << 16)
| ((uint64_t)p->buf.d[u + 3] << 24)
| ((uint64_t)p->buf.d[u + 4] << 32)
| ((uint64_t)p->buf.d[u + 5] << 40)
| ((uint64_t)p->buf.d[u + 6] << 48)
| ((uint64_t)p->buf.d[u + 7] << 56);
}
unsigned prng_get_u8(prng *p) {
unsigned v;
v = p->buf.d[p->ptr ++];
if (p->ptr == sizeof p->buf.d) {
PQCLEAN_FALCON512_CLEAN_prng_refill(p);
}
return v;
}

View File

@ -99,13 +99,8 @@
* targets other than 32-bit x86, or when the native 'double' type is
* not used, the set_fpu_cw() function does nothing at all.
*/
static inline unsigned
set_fpu_cw(unsigned x) {
return x;
}
#define set_fpu_cw PQCLEAN_FALCON512_CLEAN_set_fpu_cw
unsigned set_fpu_cw(unsigned x);
/* ==================================================================== */
/*
@ -496,46 +491,14 @@ void PQCLEAN_FALCON512_CLEAN_prng_get_bytes(prng *p, void *dst, size_t len);
/*
* Get a 64-bit random value from a PRNG.
*/
static inline uint64_t
prng_get_u64(prng *p) {
size_t u;
/*
* If there are less than 9 bytes in the buffer, we refill it.
* This means that we may drop the last few bytes, but this allows
* for faster extraction code. Also, it means that we never leave
* an empty buffer.
*/
u = p->ptr;
if (u >= (sizeof p->buf.d) - 9) {
PQCLEAN_FALCON512_CLEAN_prng_refill(p);
u = 0;
}
p->ptr = u + 8;
return (uint64_t)p->buf.d[u + 0]
| ((uint64_t)p->buf.d[u + 1] << 8)
| ((uint64_t)p->buf.d[u + 2] << 16)
| ((uint64_t)p->buf.d[u + 3] << 24)
| ((uint64_t)p->buf.d[u + 4] << 32)
| ((uint64_t)p->buf.d[u + 5] << 40)
| ((uint64_t)p->buf.d[u + 6] << 48)
| ((uint64_t)p->buf.d[u + 7] << 56);
}
#define prng_get_u64 PQCLEAN_FALCON512_CLEAN_prng_get_u64
uint64_t prng_get_u64(prng *p);
/*
* Get an 8-bit random value from a PRNG.
*/
static inline unsigned
prng_get_u8(prng *p) {
unsigned v;
v = p->buf.d[p->ptr ++];
if (p->ptr == sizeof p->buf.d) {
PQCLEAN_FALCON512_CLEAN_prng_refill(p);
}
return v;
}
#define prng_get_u8 PQCLEAN_FALCON512_CLEAN_prng_get_u8
unsigned prng_get_u8(prng *p);
/* ==================================================================== */
/*

View File

@ -267,7 +267,7 @@ PQCLEAN_FALCON512_CLEAN_expand_privkey(fpr *expanded_key,
PQCLEAN_FALCON512_CLEAN_poly_neg(rF, logn);
/*
* The Gram matrix is G = B·B*. Formulas are:
* The Gram matrix is G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)
@ -788,7 +788,7 @@ do_sign_dyn(samplerZ samp, void *samp_ctx, int16_t *s2,
PQCLEAN_FALCON512_CLEAN_poly_neg(b11, logn);
/*
* Compute the Gram matrix G = B·B*. Formulas are:
* Compute the Gram matrix G = B x B*. Formulas are:
* g00 = b00*adj(b00) + b01*adj(b01)
* g01 = b00*adj(b10) + b01*adj(b11)
* g10 = b10*adj(b00) + b11*adj(b01)