pq_crypto 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/ext/pqcrypto/pqcrypto_version.h +1 -1
- data/ext/pqcrypto/vendor/.vendored +4 -4
- data/ext/pqcrypto/vendor/mlkem-native/README.md +6 -3
- data/ext/pqcrypto/vendor/mlkem-native/RELEASE.md +22 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.c +77 -36
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.h +135 -146
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_asm.S +116 -72
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_config.h +351 -415
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/cbmc.h +43 -20
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/common.h +16 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/compress.c +57 -31
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/compress.h +260 -349
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/debug.h +17 -24
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.c +35 -37
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.h +43 -57
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202x4.c +14 -15
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202x4.h +5 -4
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/keccakf1600.c +42 -6
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/fips202_native_aarch64.h +31 -20
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/{keccak_f1600_x1_scalar_asm.S → keccak_f1600_x1_scalar_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/{keccak_f1600_x1_v84a_asm.S → keccak_f1600_x1_v84a_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/{keccak_f1600_x2_v84a_asm.S → keccak_f1600_x2_v84a_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/{keccak_f1600_x4_v8a_scalar_hybrid_asm.S → keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/{keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm.S → keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +10 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_scalar.h +2 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_v84a.h +1 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x2_v84a.h +4 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_scalar.h +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +1 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/fips202_native_armv81m.h +2 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +55 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +26 -25
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/state_extract_bytes_x4_mve.S +58 -14
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/state_xor_bytes_x4_mve.S +57 -16
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/auto.h +2 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/fips202_native_x86_64.h +10 -7
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/{keccak_f1600_x4_avx2.S → keccak_f1600_x4_avx2_asm.S} +13 -11
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/keccakf1600_constants.c +12 -11
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.c +167 -136
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.h +75 -68
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.h +135 -157
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/meta.h +15 -13
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/aarch64_zetas.c +143 -135
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/arith_native_aarch64.h +52 -46
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{intt.S → intt_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{ntt.S → ntt_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_mulcache_compute_asm.S → poly_mulcache_compute_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_reduce_asm.S → poly_reduce_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_tobytes_asm.S → poly_tobytes_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_tomont_asm.S → poly_tomont_aarch64_asm.S} +10 -12
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{polyvec_basemul_acc_montgomery_cached_asm_k2.S → polyvec_basemul_acc_montgomery_cached_k2_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{polyvec_basemul_acc_montgomery_cached_asm_k3.S → polyvec_basemul_acc_montgomery_cached_k3_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{polyvec_basemul_acc_montgomery_cached_asm_k4.S → polyvec_basemul_acc_montgomery_cached_k4_aarch64_asm.S} +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{rej_uniform_asm.S → rej_uniform_aarch64_asm.S} +12 -12
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/rej_uniform_table.c +514 -513
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/api.h +254 -253
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/meta.h +6 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/README.md +6 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/meta.h +77 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/arith_native_ppc64le.h +24 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/consts.c +299 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/consts.h +34 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/intt_ppc_asm.S +3222 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/ntt_ppc_asm.S +1651 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/poly_tomont_ppc_asm.S +294 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/reduce_ppc_asm.S +710 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/meta.h +5 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_debug.c +18 -16
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_debug.h +19 -24
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_poly.c +53 -65
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/meta.h +20 -20
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/arith_native_x86_64.h +106 -88
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/compress_consts.c +45 -35
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/compress_consts.h +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/consts.c +1 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/consts.h +1 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{intt.S → intt_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{ntt.S → ntt_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{nttfrombytes.S → nttfrombytes_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{ntttobytes.S → ntttobytes_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{nttunpack.S → nttunpack_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d10.S → poly_compress_d10_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d11.S → poly_compress_d11_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d4.S → poly_compress_d4_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d5.S → poly_compress_d5_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d10.S → poly_decompress_d10_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d11.S → poly_decompress_d11_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d4.S → poly_decompress_d4_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d5.S → poly_decompress_d5_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{mulcache_compute.S → poly_mulcache_compute_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{polyvec_basemul_acc_montgomery_cached_asm_k2.S → polyvec_basemul_acc_montgomery_cached_k2_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{polyvec_basemul_acc_montgomery_cached_asm_k3.S → polyvec_basemul_acc_montgomery_cached_k3_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{polyvec_basemul_acc_montgomery_cached_asm_k4.S → polyvec_basemul_acc_montgomery_cached_k4_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{reduce.S → reduce_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{rej_uniform_asm.S → rej_uniform_avx2_asm.S} +9 -9
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/rej_uniform_table.c +514 -513
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{tomont.S → tomont_avx2_asm.S} +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly.c +61 -57
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly.h +89 -116
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly_k.c +31 -32
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly_k.h +226 -301
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/randombytes.h +21 -29
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sampling.c +68 -63
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sampling.h +37 -48
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sys.h +44 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/verify.h +141 -159
- data/lib/pq_crypto/version.rb +1 -1
- data/script/vendor_libs.rb +3 -3
- metadata +47 -38
|
@@ -11,45 +11,37 @@
|
|
|
11
11
|
|
|
12
12
|
#if !defined(MLK_CONFIG_NO_RANDOMIZED_API)
|
|
13
13
|
#if !defined(MLK_CONFIG_CUSTOM_RANDOMBYTES)
|
|
14
|
-
|
|
15
|
-
*
|
|
14
|
+
/**
|
|
15
|
+
* Fill a buffer with cryptographically secure random bytes.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
17
|
+
* mlkem-native does not provide an implementation of this function.
|
|
18
|
+
* It must be provided by the consumer.
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
20
|
+
* To use a custom random byte source with a different name or signature,
|
|
21
|
+
* set MLK_CONFIG_CUSTOM_RANDOMBYTES and define mlk_randombytes directly.
|
|
21
22
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* mlk_randombytes directly.
|
|
23
|
+
* @param[out] out Output buffer.
|
|
24
|
+
* @param outlen Number of random bytes to write.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
|
|
29
|
-
* Returns: 0 on success, non-zero on failure.
|
|
30
|
-
* On failure, top-level APIs return MLK_ERR_RNG_FAIL.
|
|
31
|
-
*
|
|
32
|
-
**************************************************/
|
|
26
|
+
* @retval 0 Success.
|
|
27
|
+
* @retval other Failure; top-level APIs propagate this as MLK_ERR_RNG_FAIL.
|
|
28
|
+
*/
|
|
33
29
|
int randombytes(uint8_t *out, size_t outlen);
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
*
|
|
31
|
+
/**
|
|
32
|
+
* Internal wrapper around randombytes().
|
|
37
33
|
*
|
|
38
|
-
*
|
|
34
|
+
* Fills a buffer with cryptographically secure random bytes.
|
|
39
35
|
*
|
|
40
|
-
*
|
|
36
|
+
* This function can be replaced by setting MLK_CONFIG_CUSTOM_RANDOMBYTES
|
|
37
|
+
* and defining mlk_randombytes directly.
|
|
41
38
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* directly.
|
|
39
|
+
* @param[out] out Output buffer.
|
|
40
|
+
* @param outlen Number of random bytes to write.
|
|
45
41
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
|
|
49
|
-
* Returns: 0 on success, non-zero on failure.
|
|
50
|
-
* On failure, top-level APIs return MLK_ERR_RNG_FAIL.
|
|
51
|
-
*
|
|
52
|
-
**************************************************/
|
|
42
|
+
* @retval 0 Success.
|
|
43
|
+
* @retval other Failure; top-level APIs propagate this as MLK_ERR_RNG_FAIL.
|
|
44
|
+
*/
|
|
53
45
|
MLK_MUST_CHECK_RETURN_VALUE
|
|
54
46
|
static MLK_INLINE int mlk_randombytes(uint8_t *out, size_t outlen)
|
|
55
47
|
__contract__(
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
#include "debug.h"
|
|
24
24
|
#include "sampling.h"
|
|
25
25
|
#include "symmetric.h"
|
|
26
|
+
#include "verify.h"
|
|
26
27
|
|
|
27
28
|
/* Reference: `rej_uniform()` in the reference implementation @[REF].
|
|
28
29
|
* - Our signature differs from the reference implementation
|
|
@@ -53,10 +54,18 @@ __contract__(
|
|
|
53
54
|
while (ctr < target && pos + 3 <= buflen)
|
|
54
55
|
__loop__(
|
|
55
56
|
invariant(offset <= ctr && ctr <= target && pos <= buflen)
|
|
56
|
-
invariant(array_bound(r, 0, ctr, 0, MLKEM_Q))
|
|
57
|
+
invariant(array_bound(r, 0, ctr, 0, MLKEM_Q))
|
|
58
|
+
decreases(buflen - pos))
|
|
57
59
|
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
/* Safety:
|
|
61
|
+
* - The explicit cast to uint16_t ensures that << 8 does
|
|
62
|
+
* not signed-overflow even on a 16-bit system.
|
|
63
|
+
* - The conversion to int16_t is safe due to the explicit 0xFFF
|
|
64
|
+
* truncation.
|
|
65
|
+
*/
|
|
66
|
+
val0 = (int16_t)(((buf[pos + 0] >> 0) | ((uint16_t)buf[pos + 1] << 8)) &
|
|
67
|
+
0xFFF);
|
|
68
|
+
val1 = (int16_t)(((buf[pos + 1] >> 4) | (buf[pos + 2] << 4)) & 0xFFF);
|
|
60
69
|
pos += 3;
|
|
61
70
|
|
|
62
71
|
if (val0 < MLKEM_Q)
|
|
@@ -73,42 +82,36 @@ __contract__(
|
|
|
73
82
|
return ctr;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
|
-
|
|
77
|
-
*
|
|
85
|
+
/**
|
|
86
|
+
* Run rejection sampling on uniform random bytes to generate uniform random
|
|
87
|
+
* integers mod MLKEM_Q.
|
|
78
88
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
89
|
+
* @reference{`rej_uniform()` in the reference implementation @[REF]. Our
|
|
90
|
+
* signature differs from the reference in that it adds the offset and always
|
|
91
|
+
* expects the base of the target buffer; this avoids shifting the buffer
|
|
92
|
+
* base in the caller, which is tricky to reason about. Has an optional
|
|
93
|
+
* fallback to a native implementation.}
|
|
81
94
|
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* (assumed to be uniform random bytes)
|
|
91
|
-
* - unsigned buflen: length of input buffer in bytes
|
|
92
|
-
* Must be <= 4096.
|
|
93
|
-
* Must be a multiple of 3.
|
|
95
|
+
* @param[out] r Output buffer.
|
|
96
|
+
* @param target Requested number of 16-bit integers (uniform mod MLKEM_Q).
|
|
97
|
+
* Must be <= 4096.
|
|
98
|
+
* @param offset Number of 16-bit integers that have already been
|
|
99
|
+
* sampled. Must be <= @p target.
|
|
100
|
+
* @param[in] buf Input buffer (assumed to be uniform random bytes).
|
|
101
|
+
* @param buflen Length of input buffer in bytes. Must be <= 4096 and a
|
|
102
|
+
* multiple of 3.
|
|
94
103
|
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* uses of this function. Similarly, the actual limit for
|
|
104
|
+
* @note Strictly speaking, only a few values of @p buflen near UINT_MAX need
|
|
105
|
+
* excluding. The limit of 4096 is somewhat arbitrary but sufficient
|
|
106
|
+
* for all uses of this function. Similarly, the actual limit for
|
|
107
|
+
* @p target is UINT_MAX/2.
|
|
98
108
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
/* Reference: `rej_uniform()` in the reference implementation @[REF].
|
|
107
|
-
* - Our signature differs from the reference implementation
|
|
108
|
-
* in that it adds the offset and always expects the base of the
|
|
109
|
-
* target buffer. This avoids shifting the buffer base in the
|
|
110
|
-
* caller, which appears tricky to reason about.
|
|
111
|
-
* - Optional fallback to native implementation. */
|
|
109
|
+
* @return New offset of sampled 16-bit integers, at most @p target and at
|
|
110
|
+
* least the initial @p offset. If the new offset is strictly less
|
|
111
|
+
* than @p target, the entire input buffer is guaranteed to have been
|
|
112
|
+
* consumed; otherwise no information is provided on how many bytes
|
|
113
|
+
* of the input buffer have been consumed.
|
|
114
|
+
*/
|
|
112
115
|
static unsigned mlk_rej_uniform(int16_t *r, unsigned target, unsigned offset,
|
|
113
116
|
const uint8_t *buf, unsigned buflen)
|
|
114
117
|
__contract__(
|
|
@@ -248,19 +251,15 @@ void mlk_poly_rej_uniform(mlk_poly *entry, uint8_t seed[MLKEM_SYMBYTES + 2])
|
|
|
248
251
|
mlk_zeroize(buf, sizeof(buf));
|
|
249
252
|
}
|
|
250
253
|
|
|
251
|
-
|
|
252
|
-
*
|
|
254
|
+
/**
|
|
255
|
+
* Load 4 bytes into a 32-bit integer in little-endian order.
|
|
253
256
|
*
|
|
254
|
-
*
|
|
255
|
-
* in little-endian order
|
|
257
|
+
* @reference{`load32_littleendian()` in the reference implementation @[REF].}
|
|
256
258
|
*
|
|
257
|
-
*
|
|
259
|
+
* @param[in] x Input byte array.
|
|
258
260
|
*
|
|
259
|
-
*
|
|
260
|
-
|
|
261
|
-
**************************************************/
|
|
262
|
-
|
|
263
|
-
/* Reference: `load32_littleendian()` in the reference implementation @[REF]. */
|
|
261
|
+
* @return 32-bit unsigned integer loaded from @p x.
|
|
262
|
+
*/
|
|
264
263
|
static uint32_t mlk_load32_littleendian(const uint8_t x[4])
|
|
265
264
|
{
|
|
266
265
|
uint32_t r;
|
|
@@ -279,7 +278,8 @@ void mlk_poly_cbd2(mlk_poly *r, const uint8_t buf[2 * MLKEM_N / 4])
|
|
|
279
278
|
for (i = 0; i < MLKEM_N / 8; i++)
|
|
280
279
|
__loop__(
|
|
281
280
|
invariant(i <= MLKEM_N / 8)
|
|
282
|
-
invariant(array_abs_bound(r->coeffs, 0, 8 * i, 3))
|
|
281
|
+
invariant(array_abs_bound(r->coeffs, 0, 8 * i, 3))
|
|
282
|
+
decreases(MLKEM_N / 8 - i))
|
|
283
283
|
{
|
|
284
284
|
unsigned j;
|
|
285
285
|
uint32_t t = mlk_load32_littleendian(buf + 4 * i);
|
|
@@ -289,30 +289,31 @@ void mlk_poly_cbd2(mlk_poly *r, const uint8_t buf[2 * MLKEM_N / 4])
|
|
|
289
289
|
for (j = 0; j < 8; j++)
|
|
290
290
|
__loop__(
|
|
291
291
|
invariant(i <= MLKEM_N / 8 && j <= 8)
|
|
292
|
-
invariant(array_abs_bound(r->coeffs, 0, 8 * i + j, 3))
|
|
292
|
+
invariant(array_abs_bound(r->coeffs, 0, 8 * i + j, 3))
|
|
293
|
+
decreases(8 - j))
|
|
293
294
|
{
|
|
294
|
-
|
|
295
|
-
|
|
295
|
+
/* Safety: The & 0x3 masks each value to 2 bits (range [0, 3]), so the
|
|
296
|
+
* truncation and subsequent subtraction in int16_t is lossless. */
|
|
297
|
+
const int16_t a = (int16_t)((d >> (4 * j + 0)) & 0x3);
|
|
298
|
+
const int16_t b = (int16_t)((d >> (4 * j + 2)) & 0x3);
|
|
296
299
|
r->coeffs[8 * i + j] = (int16_t)(a - b);
|
|
297
300
|
}
|
|
298
301
|
}
|
|
299
302
|
}
|
|
300
303
|
|
|
301
304
|
#if defined(MLK_CONFIG_MULTILEVEL_WITH_SHARED) || MLKEM_ETA1 == 3
|
|
302
|
-
|
|
303
|
-
*
|
|
305
|
+
/**
|
|
306
|
+
* Load 3 bytes into a 32-bit integer in little-endian order.
|
|
304
307
|
*
|
|
305
|
-
*
|
|
306
|
-
* in little-endian order.
|
|
307
|
-
* This function is only needed for ML-KEM-512
|
|
308
|
+
* This function is only needed for ML-KEM-512.
|
|
308
309
|
*
|
|
309
|
-
*
|
|
310
|
+
* @reference{`load24_littleendian()` in the reference implementation @[REF].}
|
|
310
311
|
*
|
|
311
|
-
*
|
|
312
|
+
* @param[in] x Input byte array.
|
|
312
313
|
*
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
* @return 32-bit unsigned integer loaded from @p x (most significant byte
|
|
315
|
+
* is zero).
|
|
316
|
+
*/
|
|
316
317
|
static uint32_t mlk_load24_littleendian(const uint8_t x[3])
|
|
317
318
|
{
|
|
318
319
|
uint32_t r;
|
|
@@ -330,7 +331,8 @@ void mlk_poly_cbd3(mlk_poly *r, const uint8_t buf[3 * MLKEM_N / 4])
|
|
|
330
331
|
for (i = 0; i < MLKEM_N / 4; i++)
|
|
331
332
|
__loop__(
|
|
332
333
|
invariant(i <= MLKEM_N / 4)
|
|
333
|
-
invariant(array_abs_bound(r->coeffs, 0, 4 * i, 4))
|
|
334
|
+
invariant(array_abs_bound(r->coeffs, 0, 4 * i, 4))
|
|
335
|
+
decreases(MLKEM_N / 4 - i))
|
|
334
336
|
{
|
|
335
337
|
unsigned j;
|
|
336
338
|
const uint32_t t = mlk_load24_littleendian(buf + 3 * i);
|
|
@@ -341,10 +343,13 @@ void mlk_poly_cbd3(mlk_poly *r, const uint8_t buf[3 * MLKEM_N / 4])
|
|
|
341
343
|
for (j = 0; j < 4; j++)
|
|
342
344
|
__loop__(
|
|
343
345
|
invariant(i <= MLKEM_N / 4 && j <= 4)
|
|
344
|
-
invariant(array_abs_bound(r->coeffs, 0, 4 * i + j, 4))
|
|
346
|
+
invariant(array_abs_bound(r->coeffs, 0, 4 * i + j, 4))
|
|
347
|
+
decreases(4 - j))
|
|
345
348
|
{
|
|
346
|
-
|
|
347
|
-
|
|
349
|
+
/* Safety: The & 0x7 masks each value to 3 bits (range [0, 7]), so the
|
|
350
|
+
* truncation and subsequent subtraction in int16_t is lossless. */
|
|
351
|
+
const int16_t a = (int16_t)((d >> (6 * j + 0)) & 0x7);
|
|
352
|
+
const int16_t b = (int16_t)((d >> (6 * j + 3)) & 0x7);
|
|
348
353
|
r->coeffs[4 * i + j] = (int16_t)(a - b);
|
|
349
354
|
}
|
|
350
355
|
}
|
|
@@ -20,59 +20,52 @@
|
|
|
20
20
|
#include "poly.h"
|
|
21
21
|
|
|
22
22
|
#define mlk_poly_cbd2 MLK_NAMESPACE(poly_cbd2)
|
|
23
|
-
|
|
24
|
-
*
|
|
23
|
+
/**
|
|
24
|
+
* Given an array of uniformly random bytes, compute a polynomial with
|
|
25
|
+
* coefficients distributed according to a centered binomial distribution
|
|
26
|
+
* with parameter eta=2.
|
|
25
27
|
*
|
|
26
|
-
*
|
|
27
|
-
* polynomial with coefficients distributed according to
|
|
28
|
-
* a centered binomial distribution with parameter eta=2
|
|
28
|
+
* @spec{Implements @[FIPS203, Algorithm 8, SamplePolyCBD_2].}
|
|
29
29
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
|
|
33
|
-
* Specification: Implements @[FIPS203, Algorithm 8, SamplePolyCBD_2]
|
|
34
|
-
*
|
|
35
|
-
**************************************************/
|
|
30
|
+
* @param[out] r Output polynomial.
|
|
31
|
+
* @param[in] buf Input byte array.
|
|
32
|
+
*/
|
|
36
33
|
MLK_INTERNAL_API
|
|
37
34
|
void mlk_poly_cbd2(mlk_poly *r, const uint8_t buf[2 * MLKEM_N / 4]);
|
|
38
35
|
|
|
39
36
|
#if defined(MLK_CONFIG_MULTILEVEL_WITH_SHARED) || MLKEM_ETA1 == 3
|
|
40
37
|
#define mlk_poly_cbd3 MLK_NAMESPACE(poly_cbd3)
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* polynomial with coefficients distributed according to
|
|
46
|
-
* a centered binomial distribution with parameter eta=3.
|
|
47
|
-
* This function is only needed for ML-KEM-512
|
|
38
|
+
/**
|
|
39
|
+
* Given an array of uniformly random bytes, compute a polynomial with
|
|
40
|
+
* coefficients distributed according to a centered binomial distribution
|
|
41
|
+
* with parameter eta=3.
|
|
48
42
|
*
|
|
49
|
-
*
|
|
50
|
-
* - const uint8_t *buf: pointer to input byte array
|
|
43
|
+
* This function is only needed for ML-KEM-512.
|
|
51
44
|
*
|
|
52
|
-
*
|
|
45
|
+
* @spec{Implements @[FIPS203, Algorithm 8, SamplePolyCBD_3].}
|
|
53
46
|
*
|
|
54
|
-
|
|
47
|
+
* @param[out] r Output polynomial.
|
|
48
|
+
* @param[in] buf Input byte array.
|
|
49
|
+
*/
|
|
55
50
|
MLK_INTERNAL_API
|
|
56
51
|
void mlk_poly_cbd3(mlk_poly *r, const uint8_t buf[3 * MLKEM_N / 4]);
|
|
57
52
|
#endif /* MLK_CONFIG_MULTILEVEL_WITH_SHARED || MLKEM_ETA1 == 3 */
|
|
58
53
|
|
|
59
54
|
#if !defined(MLK_CONFIG_SERIAL_FIPS202_ONLY)
|
|
60
55
|
#define mlk_poly_rej_uniform_x4 MLK_NAMESPACE(poly_rej_uniform_x4)
|
|
61
|
-
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
|
|
74
|
-
*
|
|
75
|
-
**************************************************/
|
|
56
|
+
/**
|
|
57
|
+
* Generate four polynomials using rejection sampling on (pseudo-)uniformly
|
|
58
|
+
* random bytes sampled from a seed.
|
|
59
|
+
*
|
|
60
|
+
* @spec{Implements @[FIPS203, Algorithm 7, SampleNTT].}
|
|
61
|
+
*
|
|
62
|
+
* @param[out] vec0 Polynomial to be sampled.
|
|
63
|
+
* @param[out] vec1 Polynomial to be sampled.
|
|
64
|
+
* @param[out] vec2 Polynomial to be sampled.
|
|
65
|
+
* @param[out] vec3 Polynomial to be sampled.
|
|
66
|
+
* @param[in] seed Consecutive array of 4 seed buffers of size
|
|
67
|
+
* MLKEM_SYMBYTES + 2 each, plus padding for alignment.
|
|
68
|
+
*/
|
|
76
69
|
MLK_INTERNAL_API
|
|
77
70
|
void mlk_poly_rej_uniform_x4(mlk_poly *vec0, mlk_poly *vec1, mlk_poly *vec2,
|
|
78
71
|
mlk_poly *vec3,
|
|
@@ -94,19 +87,15 @@ __contract__(
|
|
|
94
87
|
#endif /* !MLK_CONFIG_SERIAL_FIPS202_ONLY */
|
|
95
88
|
|
|
96
89
|
#define mlk_poly_rej_uniform MLK_NAMESPACE(poly_rej_uniform)
|
|
97
|
-
|
|
98
|
-
*
|
|
90
|
+
/**
|
|
91
|
+
* Generate a polynomial using rejection sampling on (pseudo-)uniformly
|
|
92
|
+
* random bytes sampled from a seed.
|
|
99
93
|
*
|
|
100
|
-
*
|
|
101
|
-
* on (pseudo-)uniformly random bytes sampled from a seed.
|
|
94
|
+
* @spec{Implements @[FIPS203, Algorithm 7, SampleNTT].}
|
|
102
95
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
|
|
106
|
-
*
|
|
107
|
-
* Specification: Implements @[FIPS203, Algorithm 7, SampleNTT]
|
|
108
|
-
*
|
|
109
|
-
**************************************************/
|
|
96
|
+
* @param[out] entry Polynomial to be sampled.
|
|
97
|
+
* @param[in] seed Seed buffer of size MLKEM_SYMBYTES + 2.
|
|
98
|
+
*/
|
|
110
99
|
MLK_INTERNAL_API
|
|
111
100
|
void mlk_poly_rej_uniform(mlk_poly *entry, uint8_t seed[MLKEM_SYMBYTES + 2])
|
|
112
101
|
__contract__(
|
|
@@ -47,12 +47,13 @@
|
|
|
47
47
|
#define MLK_SYS_ARMV81M_MVE
|
|
48
48
|
#endif
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
/* Check if we're running on an x86_64 system. */
|
|
51
|
+
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64)
|
|
51
52
|
#define MLK_SYS_X86_64
|
|
52
53
|
#if defined(__AVX2__)
|
|
53
54
|
#define MLK_SYS_X86_64_AVX2
|
|
54
55
|
#endif
|
|
55
|
-
#endif /* __x86_64__ */
|
|
56
|
+
#endif /* __x86_64__ || _M_X64 || _M_AMD64 */
|
|
56
57
|
|
|
57
58
|
#if defined(MLK_SYS_LITTLE_ENDIAN) && defined(__powerpc64__)
|
|
58
59
|
#define MLK_SYS_PPC64LE
|
|
@@ -146,6 +147,22 @@
|
|
|
146
147
|
#endif
|
|
147
148
|
#endif /* !MLK_ALWAYS_INLINE */
|
|
148
149
|
|
|
150
|
+
/*
|
|
151
|
+
* MLK_NOINLINE: Prevent inlining.
|
|
152
|
+
* - MSVC: __declspec(noinline)
|
|
153
|
+
* - GCC/Clang: __attribute__((noinline))
|
|
154
|
+
* - Other: empty
|
|
155
|
+
*/
|
|
156
|
+
#if !defined(MLK_NOINLINE)
|
|
157
|
+
#if defined(_MSC_VER)
|
|
158
|
+
#define MLK_NOINLINE __declspec(noinline)
|
|
159
|
+
#elif defined(__GNUC__) || defined(__clang__)
|
|
160
|
+
#define MLK_NOINLINE __attribute__((noinline))
|
|
161
|
+
#else
|
|
162
|
+
#define MLK_NOINLINE
|
|
163
|
+
#endif
|
|
164
|
+
#endif /* !MLK_NOINLINE */
|
|
165
|
+
|
|
149
166
|
#ifndef MLK_STATIC_TESTABLE
|
|
150
167
|
#define MLK_STATIC_TESTABLE static
|
|
151
168
|
#endif
|
|
@@ -226,6 +243,31 @@
|
|
|
226
243
|
#define MLK_MUST_CHECK_RETURN_VALUE
|
|
227
244
|
#endif
|
|
228
245
|
|
|
246
|
+
/* The x86_64 assembly backend uses the SysV calling convention. On Windows,
|
|
247
|
+
* where the Microsoft x64 calling convention is the default, it can still be
|
|
248
|
+
* used with compilers that allow choosing the calling convention per
|
|
249
|
+
* function: GCC and Clang support __attribute__((sysv_abi)), which makes
|
|
250
|
+
* calls to the annotated function follow the SysV calling convention.
|
|
251
|
+
*
|
|
252
|
+
* MLK_SYSV_ABI_SUPPORTED signals that the toolchain can call SysV assembly
|
|
253
|
+
* routines; the x86_64 assembly backend is only enabled if it is defined.
|
|
254
|
+
* MLK_SYSV_ABI is the attribute carried by declarations of x86_64 assembly
|
|
255
|
+
* routines. Both macros can be set externally for toolchains offering an
|
|
256
|
+
* equivalent mechanism that is not recognized here. */
|
|
257
|
+
#if defined(MLK_SYS_X86_64) && !defined(MLK_SYSV_ABI_SUPPORTED)
|
|
258
|
+
#if !defined(MLK_SYS_WINDOWS) || defined(__GNUC__) || defined(__clang__)
|
|
259
|
+
#define MLK_SYSV_ABI_SUPPORTED
|
|
260
|
+
#endif
|
|
261
|
+
#endif
|
|
262
|
+
|
|
263
|
+
#if !defined(MLK_SYSV_ABI)
|
|
264
|
+
#if defined(MLK_SYS_WINDOWS) && defined(MLK_SYSV_ABI_SUPPORTED)
|
|
265
|
+
#define MLK_SYSV_ABI __attribute__((sysv_abi))
|
|
266
|
+
#else
|
|
267
|
+
#define MLK_SYSV_ABI
|
|
268
|
+
#endif
|
|
269
|
+
#endif /* !MLK_SYSV_ABI */
|
|
270
|
+
|
|
229
271
|
#if !defined(__ASSEMBLER__)
|
|
230
272
|
/* System capability enumeration */
|
|
231
273
|
typedef enum
|