mldsa_gh 0.1.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +88 -0
- data/ext/mldsa_gh_native/extconf.rb +14 -0
- data/ext/mldsa_gh_native/mldsa_gh_native.c +222 -0
- data/ext/mldsa_gh_native/mldsa_gh_native_all.c +24 -0
- data/ext/mldsa_gh_native/mldsa_gh_native_all.h +26 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/BUILDING.md +108 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/LICENSE +305 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/README.md +247 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/README.md +23 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native.c +803 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native.h +956 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native_asm.S +830 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native_config.h +855 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/cbmc.h +233 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/common.h +301 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/context.h +152 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/ct.c +21 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/ct.h +373 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/debug.c +75 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/debug.h +125 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202.c +270 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202.h +224 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +187 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +125 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +510 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +110 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +85 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +69 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +378 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +207 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +262 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +1080 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +990 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +47 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +27 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +36 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +40 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +32 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +37 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/api.h +129 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/README.md +10 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +67 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +37 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +717 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +42 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_state_extract_bytes_mve.S +334 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_state_xor_bytes_mve.S +355 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +53 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +35 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +34 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +45 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +488 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccakf1600_constants.c +52 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +314 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +248 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +367 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_intt_aarch64_asm.S +786 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_ntt_aarch64_asm.S +686 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_pointwise_montgomery_aarch64_asm.S +106 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_caddq_aarch64_asm.S +69 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_chknorm_aarch64_asm.S +76 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_decompose_32_aarch64_asm.S +108 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_decompose_88_aarch64_asm.S +108 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_use_hint_32_aarch64_asm.S +125 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_use_hint_88_aarch64_asm.S +133 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S +157 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S +173 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S +205 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyz_unpack_17_aarch64_asm.S +103 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyz_unpack_19_aarch64_asm.S +100 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_aarch64_asm.S +222 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_eta2_aarch64_asm.S +170 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_eta4_aarch64_asm.S +163 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +52 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +547 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +63 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/api.h +617 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/meta.h +24 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +323 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +330 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +157 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +27 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_intt_avx2_asm.S +2333 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_ntt_avx2_asm.S +2405 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_nttunpack_avx2_asm.S +254 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l4_avx2_asm.S +173 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l5_avx2_asm.S +189 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l7_avx2_asm.S +221 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_avx2_asm.S +158 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_caddq_avx2_asm.S +199 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_chknorm_avx2_asm.S +176 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_32_avx2_asm.S +490 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_88_avx2_asm.S +489 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_32_avx2_asm.S +123 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_88_avx2_asm.S +125 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_17_avx2_asm.S +355 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_19_avx2_asm.S +355 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_avx2_asm.S +132 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta2_avx2_asm.S +205 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta4_avx2_asm.S +176 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +161 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/packing.c +213 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/packing.h +277 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/params.h +153 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly.c +1066 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly.h +464 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly_kl.c +910 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly_kl.h +367 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec.c +509 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec.h +435 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +311 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +652 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/randombytes.h +26 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/reduce.h +144 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/rounding.h +265 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sign.c +1720 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sign.h +850 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/symmetric.h +68 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sys.h +327 -0
- data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/zetas.inc +55 -0
- data/lib/mldsa/parameter_set.rb +82 -0
- data/lib/mldsa/signing_key.rb +147 -0
- data/lib/mldsa/verify_key.rb +72 -0
- data/lib/mldsa/version.rb +7 -0
- data/lib/mldsa_gh.rb +93 -0
- metadata +225 -0
|
@@ -0,0 +1,910 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) The mldsa-native project authors
|
|
3
|
+
* Copyright (c) The mlkem-native project authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* References
|
|
8
|
+
* ==========
|
|
9
|
+
*
|
|
10
|
+
* - [FIPS204]
|
|
11
|
+
* FIPS 204 Module-Lattice-Based Digital Signature Standard
|
|
12
|
+
* National Institute of Standards and Technology
|
|
13
|
+
* https://csrc.nist.gov/pubs/fips/204/final
|
|
14
|
+
*
|
|
15
|
+
* - [REF]
|
|
16
|
+
* CRYSTALS-Dilithium reference implementation
|
|
17
|
+
* Bai, Ducas, Kiltz, Lepoint, Lyubashevsky, Schwabe, Seiler, Stehlé
|
|
18
|
+
* https://github.com/pq-crystals/dilithium/tree/master/ref
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
#include "poly_kl.h"
|
|
22
|
+
|
|
23
|
+
#include "ct.h"
|
|
24
|
+
#include "debug.h"
|
|
25
|
+
#include "rounding.h"
|
|
26
|
+
#include "symmetric.h"
|
|
27
|
+
|
|
28
|
+
/* Parameter set namespacing
|
|
29
|
+
* This is to facilitate building multiple instances
|
|
30
|
+
* of mldsa-native (e.g. with varying parameter sets)
|
|
31
|
+
* within a single compilation unit. */
|
|
32
|
+
#define mld_rej_eta MLD_ADD_PARAM_SET(mld_rej_eta)
|
|
33
|
+
#define mld_rej_eta_c MLD_ADD_PARAM_SET(mld_rej_eta_c)
|
|
34
|
+
#define mld_poly_decompose_c MLD_ADD_PARAM_SET(mld_poly_decompose_c)
|
|
35
|
+
#define mld_poly_use_hint_c MLD_ADD_PARAM_SET(mld_poly_use_hint_c)
|
|
36
|
+
#define mld_polyz_unpack_c MLD_ADD_PARAM_SET(mld_polyz_unpack_c)
|
|
37
|
+
/* End of parameter set namespacing */
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
#if !defined(MLD_CONFIG_NO_SIGN_API)
|
|
41
|
+
MLD_STATIC_TESTABLE
|
|
42
|
+
void mld_poly_decompose_c(mld_poly *a1, mld_poly *a0)
|
|
43
|
+
__contract__(
|
|
44
|
+
requires(memory_no_alias(a1, sizeof(mld_poly)))
|
|
45
|
+
requires(memory_no_alias(a0, sizeof(mld_poly)))
|
|
46
|
+
requires(array_bound(a0->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
|
|
47
|
+
assigns(memory_slice(a1, sizeof(mld_poly)))
|
|
48
|
+
assigns(memory_slice(a0, sizeof(mld_poly)))
|
|
49
|
+
ensures(array_bound(a1->coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
|
|
50
|
+
ensures(array_abs_bound(a0->coeffs, 0, MLDSA_N, MLDSA_GAMMA2+1))
|
|
51
|
+
)
|
|
52
|
+
{
|
|
53
|
+
unsigned int i;
|
|
54
|
+
mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
|
|
55
|
+
for (i = 0; i < MLDSA_N; ++i)
|
|
56
|
+
__loop__(
|
|
57
|
+
assigns(i, memory_slice(a0, sizeof(mld_poly)), memory_slice(a1, sizeof(mld_poly)))
|
|
58
|
+
invariant(i <= MLDSA_N)
|
|
59
|
+
invariant(array_bound(a0->coeffs, i, MLDSA_N, 0, MLDSA_Q))
|
|
60
|
+
invariant(array_bound(a1->coeffs, 0, i, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
|
|
61
|
+
invariant(array_abs_bound(a0->coeffs, 0, i, MLDSA_GAMMA2+1))
|
|
62
|
+
decreases(MLDSA_N - i)
|
|
63
|
+
)
|
|
64
|
+
{
|
|
65
|
+
mld_decompose(&a0->coeffs[i], &a1->coeffs[i], a0->coeffs[i]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
|
|
69
|
+
mld_assert_bound(a1->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
MLD_INTERNAL_API
|
|
73
|
+
void mld_poly_decompose(mld_poly *a1, mld_poly *a0)
|
|
74
|
+
{
|
|
75
|
+
#if defined(MLD_USE_NATIVE_POLY_DECOMPOSE_88) && MLD_CONFIG_PARAMETER_SET == 44
|
|
76
|
+
int ret;
|
|
77
|
+
mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
|
|
78
|
+
ret = mld_poly_decompose_88_native(a1->coeffs, a0->coeffs);
|
|
79
|
+
if (ret == MLD_NATIVE_FUNC_SUCCESS)
|
|
80
|
+
{
|
|
81
|
+
mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
|
|
82
|
+
mld_assert_bound(a1->coeffs, MLDSA_N, 0,
|
|
83
|
+
(MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
#elif defined(MLD_USE_NATIVE_POLY_DECOMPOSE_32) && \
|
|
87
|
+
(MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
|
|
88
|
+
int ret;
|
|
89
|
+
mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
|
|
90
|
+
ret = mld_poly_decompose_32_native(a1->coeffs, a0->coeffs);
|
|
91
|
+
if (ret == MLD_NATIVE_FUNC_SUCCESS)
|
|
92
|
+
{
|
|
93
|
+
mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
|
|
94
|
+
mld_assert_bound(a1->coeffs, MLDSA_N, 0,
|
|
95
|
+
(MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
#endif /* !(MLD_USE_NATIVE_POLY_DECOMPOSE_88 && MLD_CONFIG_PARAMETER_SET == \
|
|
99
|
+
44) && MLD_USE_NATIVE_POLY_DECOMPOSE_32 && (MLD_CONFIG_PARAMETER_SET \
|
|
100
|
+
== 65 || MLD_CONFIG_PARAMETER_SET == 87) */
|
|
101
|
+
mld_poly_decompose_c(a1, a0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#endif /* !MLD_CONFIG_NO_SIGN_API */
|
|
105
|
+
|
|
106
|
+
#if !defined(MLD_CONFIG_NO_VERIFY_API)
|
|
107
|
+
MLD_STATIC_TESTABLE void mld_poly_use_hint_c(mld_poly *a, const mld_poly *h)
|
|
108
|
+
__contract__(
|
|
109
|
+
requires(memory_no_alias(a, sizeof(mld_poly)))
|
|
110
|
+
requires(memory_no_alias(h, sizeof(mld_poly)))
|
|
111
|
+
requires(array_bound(a->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
|
|
112
|
+
requires(array_bound(h->coeffs, 0, MLDSA_N, 0, 2))
|
|
113
|
+
assigns(memory_slice(a, sizeof(mld_poly)))
|
|
114
|
+
ensures(array_bound(a->coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
|
|
115
|
+
)
|
|
116
|
+
{
|
|
117
|
+
unsigned int i;
|
|
118
|
+
mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
|
|
119
|
+
mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
|
|
120
|
+
|
|
121
|
+
for (i = 0; i < MLDSA_N; ++i)
|
|
122
|
+
__loop__(
|
|
123
|
+
invariant(i <= MLDSA_N)
|
|
124
|
+
invariant(array_bound(a->coeffs, 0, i, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
|
|
125
|
+
invariant(array_bound(a->coeffs, i, MLDSA_N, 0, MLDSA_Q))
|
|
126
|
+
decreases(MLDSA_N - i)
|
|
127
|
+
)
|
|
128
|
+
{
|
|
129
|
+
a->coeffs[i] = mld_use_hint(a->coeffs[i], h->coeffs[i]);
|
|
130
|
+
}
|
|
131
|
+
mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
MLD_INTERNAL_API
|
|
135
|
+
void mld_poly_use_hint(mld_poly *a, const mld_poly *h)
|
|
136
|
+
{
|
|
137
|
+
#if defined(MLD_USE_NATIVE_POLY_USE_HINT_88) && MLD_CONFIG_PARAMETER_SET == 44
|
|
138
|
+
int ret;
|
|
139
|
+
mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
|
|
140
|
+
mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
|
|
141
|
+
ret = mld_poly_use_hint_88_native(a->coeffs, h->coeffs);
|
|
142
|
+
if (ret == MLD_NATIVE_FUNC_SUCCESS)
|
|
143
|
+
{
|
|
144
|
+
mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
#elif defined(MLD_USE_NATIVE_POLY_USE_HINT_32) && \
|
|
148
|
+
(MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
|
|
149
|
+
int ret;
|
|
150
|
+
mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
|
|
151
|
+
mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
|
|
152
|
+
ret = mld_poly_use_hint_32_native(a->coeffs, h->coeffs);
|
|
153
|
+
if (ret == MLD_NATIVE_FUNC_SUCCESS)
|
|
154
|
+
{
|
|
155
|
+
mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
#endif /* !(MLD_USE_NATIVE_POLY_USE_HINT_88 && MLD_CONFIG_PARAMETER_SET == 44) \
|
|
159
|
+
&& MLD_USE_NATIVE_POLY_USE_HINT_32 && (MLD_CONFIG_PARAMETER_SET == \
|
|
160
|
+
65 || MLD_CONFIG_PARAMETER_SET == 87) */
|
|
161
|
+
mld_poly_use_hint_c(a, h);
|
|
162
|
+
}
|
|
163
|
+
#endif /* !MLD_CONFIG_NO_VERIFY_API */
|
|
164
|
+
|
|
165
|
+
#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
|
|
166
|
+
/**
|
|
167
|
+
* Sample uniformly random coefficients in [-MLDSA_ETA, MLDSA_ETA] by
|
|
168
|
+
* performing rejection sampling on an array of random bytes.
|
|
169
|
+
*
|
|
170
|
+
* @param[out] a Pointer to output array (allocated).
|
|
171
|
+
* @param target Requested number of coefficients to sample.
|
|
172
|
+
* @param offset Number of coefficients already sampled.
|
|
173
|
+
* @param[in] buf Array of random bytes to sample from.
|
|
174
|
+
* @param buflen Length of array of random bytes.
|
|
175
|
+
*
|
|
176
|
+
* @return Number of sampled coefficients. Can be smaller than target if not
|
|
177
|
+
* enough random bytes were given.
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
/* Reference: `mld_rej_eta()` in the reference implementation @[REF].
|
|
181
|
+
* - Our signature differs from the reference implementation
|
|
182
|
+
* in that it adds the offset and always expects the base of the
|
|
183
|
+
* target buffer. This avoids shifting the buffer base in the
|
|
184
|
+
* caller, which appears tricky to reason about. */
|
|
185
|
+
#if MLDSA_ETA == 2
|
|
186
|
+
/*
|
|
187
|
+
* Sampling 256 coefficients mod 15 using rejection sampling from 4 bits.
|
|
188
|
+
* Expected number of required bytes: (256 * (16/15))/2 = 136.5 bytes.
|
|
189
|
+
* We sample 1 block (=136 bytes) of SHAKE256_RATE output initially.
|
|
190
|
+
* Sampling 2 blocks initially results in slightly worse performance.
|
|
191
|
+
*/
|
|
192
|
+
#define MLD_POLY_UNIFORM_ETA_NBLOCKS 1
|
|
193
|
+
#elif MLDSA_ETA == 4
|
|
194
|
+
/*
|
|
195
|
+
* Sampling 256 coefficients mod 9 using rejection sampling from 4 bits.
|
|
196
|
+
* Expected number of required bytes: (256 * (16/9))/2 = 227.5 bytes.
|
|
197
|
+
* We sample 2 blocks (=272 bytes) of SHAKE256_RATE output initially.
|
|
198
|
+
*/
|
|
199
|
+
#define MLD_POLY_UNIFORM_ETA_NBLOCKS 2
|
|
200
|
+
#else /* MLDSA_ETA == 4 */
|
|
201
|
+
#error "Invalid value of MLDSA_ETA"
|
|
202
|
+
#endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
|
|
203
|
+
|
|
204
|
+
MLD_STATIC_TESTABLE unsigned int mld_rej_eta_c(int32_t *a, unsigned int target,
|
|
205
|
+
unsigned int offset,
|
|
206
|
+
const uint8_t *buf,
|
|
207
|
+
unsigned int buflen)
|
|
208
|
+
__contract__(
|
|
209
|
+
requires(offset <= target && target <= MLDSA_N)
|
|
210
|
+
requires(buflen <= (MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES))
|
|
211
|
+
requires(memory_no_alias(a, sizeof(int32_t) * target))
|
|
212
|
+
requires(memory_no_alias(buf, buflen))
|
|
213
|
+
requires(array_abs_bound(a, 0, offset, MLDSA_ETA + 1))
|
|
214
|
+
assigns(memory_slice(a, sizeof(int32_t) * target))
|
|
215
|
+
ensures(offset <= return_value && return_value <= target)
|
|
216
|
+
ensures(array_abs_bound(a, 0, return_value, MLDSA_ETA + 1))
|
|
217
|
+
)
|
|
218
|
+
{
|
|
219
|
+
unsigned int ctr, pos;
|
|
220
|
+
int t_valid;
|
|
221
|
+
uint32_t t0, t1;
|
|
222
|
+
mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
|
|
223
|
+
ctr = offset;
|
|
224
|
+
pos = 0;
|
|
225
|
+
while (ctr < target && pos < buflen)
|
|
226
|
+
__loop__(
|
|
227
|
+
invariant(offset <= ctr && ctr <= target && pos <= buflen)
|
|
228
|
+
invariant(array_abs_bound(a, 0, ctr, MLDSA_ETA + 1))
|
|
229
|
+
decreases(buflen - pos)
|
|
230
|
+
)
|
|
231
|
+
{
|
|
232
|
+
t0 = buf[pos] & 0x0F;
|
|
233
|
+
t1 = buf[pos++] >> 4;
|
|
234
|
+
|
|
235
|
+
/* Constant time: The inputs and outputs to the rejection sampling are
|
|
236
|
+
* secret. However, it is fine to leak which coefficients have been
|
|
237
|
+
* rejected. For constant-time testing, we declassify the result of
|
|
238
|
+
* the comparison.
|
|
239
|
+
*/
|
|
240
|
+
#if MLDSA_ETA == 2
|
|
241
|
+
t_valid = t0 < 15;
|
|
242
|
+
MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
|
|
243
|
+
if (t_valid) /* t0 < 15 */
|
|
244
|
+
{
|
|
245
|
+
t0 = t0 - (205 * t0 >> 10) * 5;
|
|
246
|
+
a[ctr++] = 2 - (int32_t)t0;
|
|
247
|
+
}
|
|
248
|
+
t_valid = t1 < 15;
|
|
249
|
+
MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
|
|
250
|
+
if (t_valid && ctr < target) /* t1 < 15 */
|
|
251
|
+
{
|
|
252
|
+
t1 = t1 - (205 * t1 >> 10) * 5;
|
|
253
|
+
a[ctr++] = 2 - (int32_t)t1;
|
|
254
|
+
}
|
|
255
|
+
#elif MLDSA_ETA == 4
|
|
256
|
+
t_valid = t0 < 9;
|
|
257
|
+
MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
|
|
258
|
+
if (t_valid) /* t0 < 9 */
|
|
259
|
+
{
|
|
260
|
+
a[ctr++] = 4 - (int32_t)t0;
|
|
261
|
+
}
|
|
262
|
+
t_valid = t1 < 9; /* t1 < 9 */
|
|
263
|
+
MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
|
|
264
|
+
if (t_valid && ctr < target)
|
|
265
|
+
{
|
|
266
|
+
a[ctr++] = 4 - (int32_t)t1;
|
|
267
|
+
}
|
|
268
|
+
#else /* MLDSA_ETA == 4 */
|
|
269
|
+
#error "Invalid value of MLDSA_ETA"
|
|
270
|
+
#endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
mld_assert_abs_bound(a, ctr, MLDSA_ETA + 1);
|
|
274
|
+
|
|
275
|
+
return ctr;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
static unsigned int mld_rej_eta(int32_t *a, unsigned int target,
|
|
279
|
+
unsigned int offset, const uint8_t *buf,
|
|
280
|
+
unsigned int buflen)
|
|
281
|
+
__contract__(
|
|
282
|
+
requires(offset <= target && target <= MLDSA_N)
|
|
283
|
+
requires(buflen <= (MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES))
|
|
284
|
+
requires(memory_no_alias(a, sizeof(int32_t) * target))
|
|
285
|
+
requires(memory_no_alias(buf, buflen))
|
|
286
|
+
requires(array_abs_bound(a, 0, offset, MLDSA_ETA + 1))
|
|
287
|
+
assigns(memory_slice(a, sizeof(int32_t) * target))
|
|
288
|
+
ensures(offset <= return_value && return_value <= target)
|
|
289
|
+
ensures(array_abs_bound(a, 0, return_value, MLDSA_ETA + 1))
|
|
290
|
+
)
|
|
291
|
+
{
|
|
292
|
+
#if MLDSA_ETA == 2 && defined(MLD_USE_NATIVE_REJ_UNIFORM_ETA2)
|
|
293
|
+
int ret;
|
|
294
|
+
mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
|
|
295
|
+
if (offset == 0)
|
|
296
|
+
{
|
|
297
|
+
ret = mld_rej_uniform_eta2_native(a, target, buf, buflen);
|
|
298
|
+
if (ret != MLD_NATIVE_FUNC_FALLBACK)
|
|
299
|
+
{
|
|
300
|
+
unsigned res = (unsigned)ret;
|
|
301
|
+
mld_assert_abs_bound(a, res, MLDSA_ETA + 1);
|
|
302
|
+
return res;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
#elif MLDSA_ETA == 4 && defined(MLD_USE_NATIVE_REJ_UNIFORM_ETA4)
|
|
306
|
+
int ret;
|
|
307
|
+
mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
|
|
308
|
+
if (offset == 0)
|
|
309
|
+
{
|
|
310
|
+
ret = mld_rej_uniform_eta4_native(a, target, buf, buflen);
|
|
311
|
+
if (ret != MLD_NATIVE_FUNC_FALLBACK)
|
|
312
|
+
{
|
|
313
|
+
unsigned res = (unsigned)ret;
|
|
314
|
+
mld_assert_abs_bound(a, res, MLDSA_ETA + 1);
|
|
315
|
+
return res;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
#endif /* !(MLDSA_ETA == 2 && MLD_USE_NATIVE_REJ_UNIFORM_ETA2) && MLDSA_ETA == \
|
|
319
|
+
4 && MLD_USE_NATIVE_REJ_UNIFORM_ETA4 */
|
|
320
|
+
|
|
321
|
+
return mld_rej_eta_c(a, target, offset, buf, buflen);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
#if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
|
|
325
|
+
MLD_INTERNAL_API
|
|
326
|
+
void mld_poly_uniform_eta_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
|
|
327
|
+
mld_poly *r3, const uint8_t seed[MLDSA_CRHBYTES],
|
|
328
|
+
uint8_t nonce0, uint8_t nonce1, uint8_t nonce2,
|
|
329
|
+
uint8_t nonce3)
|
|
330
|
+
{
|
|
331
|
+
/* Temporary buffers for XOF output before rejection sampling */
|
|
332
|
+
MLD_ALIGN uint8_t buf[4][MLD_ALIGN_UP(MLD_POLY_UNIFORM_ETA_NBLOCKS *
|
|
333
|
+
MLD_STREAM256_BLOCKBYTES)];
|
|
334
|
+
|
|
335
|
+
MLD_ALIGN uint8_t extseed[4][MLD_ALIGN_UP(MLDSA_CRHBYTES + 2)];
|
|
336
|
+
|
|
337
|
+
/* Tracks the number of coefficients we have already sampled */
|
|
338
|
+
unsigned ctr[4];
|
|
339
|
+
mld_xof256_x4_ctx state;
|
|
340
|
+
unsigned buflen;
|
|
341
|
+
|
|
342
|
+
mld_memcpy(extseed[0], seed, MLDSA_CRHBYTES);
|
|
343
|
+
mld_memcpy(extseed[1], seed, MLDSA_CRHBYTES);
|
|
344
|
+
mld_memcpy(extseed[2], seed, MLDSA_CRHBYTES);
|
|
345
|
+
mld_memcpy(extseed[3], seed, MLDSA_CRHBYTES);
|
|
346
|
+
extseed[0][MLDSA_CRHBYTES] = nonce0;
|
|
347
|
+
extseed[1][MLDSA_CRHBYTES] = nonce1;
|
|
348
|
+
extseed[2][MLDSA_CRHBYTES] = nonce2;
|
|
349
|
+
extseed[3][MLDSA_CRHBYTES] = nonce3;
|
|
350
|
+
extseed[0][MLDSA_CRHBYTES + 1] = 0;
|
|
351
|
+
extseed[1][MLDSA_CRHBYTES + 1] = 0;
|
|
352
|
+
extseed[2][MLDSA_CRHBYTES + 1] = 0;
|
|
353
|
+
extseed[3][MLDSA_CRHBYTES + 1] = 0;
|
|
354
|
+
|
|
355
|
+
mld_xof256_x4_init(&state);
|
|
356
|
+
mld_xof256_x4_absorb(&state, extseed, MLDSA_CRHBYTES + 2);
|
|
357
|
+
|
|
358
|
+
/*
|
|
359
|
+
* Initially, squeeze heuristic number of MLD_POLY_UNIFORM_ETA_NBLOCKS.
|
|
360
|
+
* This should generate the coefficients with high probability.
|
|
361
|
+
*/
|
|
362
|
+
mld_xof256_x4_squeezeblocks(buf, MLD_POLY_UNIFORM_ETA_NBLOCKS, &state);
|
|
363
|
+
buflen = MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES;
|
|
364
|
+
|
|
365
|
+
ctr[0] = mld_rej_eta(r0->coeffs, MLDSA_N, 0, buf[0], buflen);
|
|
366
|
+
ctr[1] = mld_rej_eta(r1->coeffs, MLDSA_N, 0, buf[1], buflen);
|
|
367
|
+
ctr[2] = mld_rej_eta(r2->coeffs, MLDSA_N, 0, buf[2], buflen);
|
|
368
|
+
ctr[3] = mld_rej_eta(r3->coeffs, MLDSA_N, 0, buf[3], buflen);
|
|
369
|
+
|
|
370
|
+
/*
|
|
371
|
+
* So long as not all entries have been generated, squeeze
|
|
372
|
+
* one more block at a time until we're done.
|
|
373
|
+
*/
|
|
374
|
+
buflen = MLD_STREAM256_BLOCKBYTES;
|
|
375
|
+
while (ctr[0] < MLDSA_N || ctr[1] < MLDSA_N || ctr[2] < MLDSA_N ||
|
|
376
|
+
ctr[3] < MLDSA_N)
|
|
377
|
+
__loop__(
|
|
378
|
+
assigns(ctr, state, memory_slice(r0, sizeof(mld_poly)),
|
|
379
|
+
memory_slice(r1, sizeof(mld_poly)), memory_slice(r2, sizeof(mld_poly)),
|
|
380
|
+
memory_slice(r3, sizeof(mld_poly)), object_whole(buf[0]),
|
|
381
|
+
object_whole(buf[1]), object_whole(buf[2]),
|
|
382
|
+
object_whole(buf[3]))
|
|
383
|
+
invariant(ctr[0] <= MLDSA_N && ctr[1] <= MLDSA_N)
|
|
384
|
+
invariant(ctr[2] <= MLDSA_N && ctr[3] <= MLDSA_N)
|
|
385
|
+
invariant(array_abs_bound(r0->coeffs, 0, ctr[0], MLDSA_ETA + 1))
|
|
386
|
+
invariant(array_abs_bound(r1->coeffs, 0, ctr[1], MLDSA_ETA + 1))
|
|
387
|
+
invariant(array_abs_bound(r2->coeffs, 0, ctr[2], MLDSA_ETA + 1))
|
|
388
|
+
invariant(array_abs_bound(r3->coeffs, 0, ctr[3], MLDSA_ETA + 1)))
|
|
389
|
+
{
|
|
390
|
+
mld_xof256_x4_squeezeblocks(buf, 1, &state);
|
|
391
|
+
ctr[0] = mld_rej_eta(r0->coeffs, MLDSA_N, ctr[0], buf[0], buflen);
|
|
392
|
+
ctr[1] = mld_rej_eta(r1->coeffs, MLDSA_N, ctr[1], buf[1], buflen);
|
|
393
|
+
ctr[2] = mld_rej_eta(r2->coeffs, MLDSA_N, ctr[2], buf[2], buflen);
|
|
394
|
+
ctr[3] = mld_rej_eta(r3->coeffs, MLDSA_N, ctr[3], buf[3], buflen);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
mld_xof256_x4_release(&state);
|
|
398
|
+
|
|
399
|
+
mld_assert_abs_bound(r0->coeffs, MLDSA_N, MLDSA_ETA + 1);
|
|
400
|
+
mld_assert_abs_bound(r1->coeffs, MLDSA_N, MLDSA_ETA + 1);
|
|
401
|
+
mld_assert_abs_bound(r2->coeffs, MLDSA_N, MLDSA_ETA + 1);
|
|
402
|
+
mld_assert_abs_bound(r3->coeffs, MLDSA_N, MLDSA_ETA + 1);
|
|
403
|
+
|
|
404
|
+
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
|
|
405
|
+
mld_zeroize(buf, sizeof(buf));
|
|
406
|
+
mld_zeroize(extseed, sizeof(extseed));
|
|
407
|
+
}
|
|
408
|
+
#else /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
|
|
409
|
+
|
|
410
|
+
MLD_INTERNAL_API
|
|
411
|
+
void mld_poly_uniform_eta(mld_poly *r, const uint8_t seed[MLDSA_CRHBYTES],
|
|
412
|
+
uint8_t nonce)
|
|
413
|
+
{
|
|
414
|
+
/* Temporary buffer for XOF output before rejection sampling */
|
|
415
|
+
MLD_ALIGN uint8_t
|
|
416
|
+
buf[MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES];
|
|
417
|
+
MLD_ALIGN uint8_t extseed[MLDSA_CRHBYTES + 2];
|
|
418
|
+
|
|
419
|
+
/* Tracks the number of coefficients we have already sampled */
|
|
420
|
+
unsigned ctr;
|
|
421
|
+
mld_xof256_ctx state;
|
|
422
|
+
unsigned buflen;
|
|
423
|
+
|
|
424
|
+
mld_memcpy(extseed, seed, MLDSA_CRHBYTES);
|
|
425
|
+
extseed[MLDSA_CRHBYTES] = nonce;
|
|
426
|
+
extseed[MLDSA_CRHBYTES + 1] = 0;
|
|
427
|
+
|
|
428
|
+
mld_xof256_init(&state);
|
|
429
|
+
mld_xof256_absorb_once(&state, extseed, MLDSA_CRHBYTES + 2);
|
|
430
|
+
|
|
431
|
+
/*
|
|
432
|
+
* Initially, squeeze heuristic number of MLD_POLY_UNIFORM_ETA_NBLOCKS.
|
|
433
|
+
* This should generate the coefficients with high probability.
|
|
434
|
+
*/
|
|
435
|
+
mld_xof256_squeezeblocks(buf, MLD_POLY_UNIFORM_ETA_NBLOCKS, &state);
|
|
436
|
+
buflen = MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES;
|
|
437
|
+
|
|
438
|
+
ctr = mld_rej_eta(r->coeffs, MLDSA_N, 0, buf, buflen);
|
|
439
|
+
|
|
440
|
+
/*
|
|
441
|
+
* So long as not all entries have been generated, squeeze
|
|
442
|
+
* one more block at a time until we're done.
|
|
443
|
+
*/
|
|
444
|
+
buflen = MLD_STREAM256_BLOCKBYTES;
|
|
445
|
+
while (ctr < MLDSA_N)
|
|
446
|
+
__loop__(
|
|
447
|
+
assigns(ctr, object_whole(&state),
|
|
448
|
+
object_whole(buf), memory_slice(r, sizeof(mld_poly)))
|
|
449
|
+
invariant(ctr <= MLDSA_N)
|
|
450
|
+
invariant(state.pos <= SHAKE256_RATE)
|
|
451
|
+
invariant(array_abs_bound(r->coeffs, 0, ctr, MLDSA_ETA + 1)))
|
|
452
|
+
{
|
|
453
|
+
mld_xof256_squeezeblocks(buf, 1, &state);
|
|
454
|
+
ctr = mld_rej_eta(r->coeffs, MLDSA_N, ctr, buf, buflen);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
mld_xof256_release(&state);
|
|
458
|
+
|
|
459
|
+
mld_assert_abs_bound(r->coeffs, MLDSA_N, MLDSA_ETA + 1);
|
|
460
|
+
|
|
461
|
+
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
|
|
462
|
+
mld_zeroize(buf, sizeof(buf));
|
|
463
|
+
mld_zeroize(extseed, sizeof(extseed));
|
|
464
|
+
}
|
|
465
|
+
#endif /* MLD_CONFIG_SERIAL_FIPS202_ONLY */
|
|
466
|
+
#endif /* !MLD_CONFIG_NO_KEYPAIR_API */
|
|
467
|
+
|
|
468
|
+
#if !defined(MLD_CONFIG_NO_SIGN_API)
|
|
469
|
+
#define MLD_POLY_UNIFORM_GAMMA1_NBLOCKS \
|
|
470
|
+
((MLDSA_POLYZ_PACKEDBYTES + MLD_STREAM256_BLOCKBYTES - 1) / \
|
|
471
|
+
MLD_STREAM256_BLOCKBYTES)
|
|
472
|
+
|
|
473
|
+
#if MLD_CONFIG_PARAMETER_SET == 65 || \
|
|
474
|
+
defined(MLD_CONFIG_SERIAL_FIPS202_ONLY) || \
|
|
475
|
+
defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
|
|
476
|
+
MLD_INTERNAL_API
|
|
477
|
+
void mld_poly_uniform_gamma1(mld_poly *a, const uint8_t seed[MLDSA_CRHBYTES],
|
|
478
|
+
uint16_t nonce)
|
|
479
|
+
{
|
|
480
|
+
MLD_ALIGN uint8_t
|
|
481
|
+
buf[MLD_POLY_UNIFORM_GAMMA1_NBLOCKS * MLD_STREAM256_BLOCKBYTES];
|
|
482
|
+
MLD_ALIGN uint8_t extseed[MLDSA_CRHBYTES + 2];
|
|
483
|
+
mld_xof256_ctx state;
|
|
484
|
+
|
|
485
|
+
mld_memcpy(extseed, seed, MLDSA_CRHBYTES);
|
|
486
|
+
extseed[MLDSA_CRHBYTES] = (uint8_t)(nonce & 0xFF);
|
|
487
|
+
extseed[MLDSA_CRHBYTES + 1] = (uint8_t)(nonce >> 8);
|
|
488
|
+
|
|
489
|
+
mld_xof256_init(&state);
|
|
490
|
+
mld_xof256_absorb_once(&state, extseed, MLDSA_CRHBYTES + 2);
|
|
491
|
+
|
|
492
|
+
mld_xof256_squeezeblocks(buf, MLD_POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
|
|
493
|
+
mld_polyz_unpack(a, buf);
|
|
494
|
+
|
|
495
|
+
mld_xof256_release(&state);
|
|
496
|
+
|
|
497
|
+
mld_assert_bound(a->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
498
|
+
|
|
499
|
+
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
|
|
500
|
+
mld_zeroize(buf, sizeof(buf));
|
|
501
|
+
mld_zeroize(extseed, sizeof(extseed));
|
|
502
|
+
}
|
|
503
|
+
#endif /* MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_SERIAL_FIPS202_ONLY || \
|
|
504
|
+
MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
#if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY) && \
|
|
508
|
+
(!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
|
|
509
|
+
MLD_INTERNAL_API
|
|
510
|
+
void mld_poly_uniform_gamma1_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
|
|
511
|
+
mld_poly *r3,
|
|
512
|
+
const uint8_t seed[MLDSA_CRHBYTES],
|
|
513
|
+
uint16_t nonce0, uint16_t nonce1,
|
|
514
|
+
uint16_t nonce2, uint16_t nonce3)
|
|
515
|
+
{
|
|
516
|
+
/* Temporary buffers for XOF output before rejection sampling */
|
|
517
|
+
MLD_ALIGN uint8_t buf[4][MLD_ALIGN_UP(MLD_POLY_UNIFORM_GAMMA1_NBLOCKS *
|
|
518
|
+
MLD_STREAM256_BLOCKBYTES)];
|
|
519
|
+
|
|
520
|
+
MLD_ALIGN uint8_t extseed[4][MLD_ALIGN_UP(MLDSA_CRHBYTES + 2)];
|
|
521
|
+
|
|
522
|
+
/* Tracks the number of coefficients we have already sampled */
|
|
523
|
+
mld_xof256_x4_ctx state;
|
|
524
|
+
|
|
525
|
+
mld_memcpy(extseed[0], seed, MLDSA_CRHBYTES);
|
|
526
|
+
mld_memcpy(extseed[1], seed, MLDSA_CRHBYTES);
|
|
527
|
+
mld_memcpy(extseed[2], seed, MLDSA_CRHBYTES);
|
|
528
|
+
mld_memcpy(extseed[3], seed, MLDSA_CRHBYTES);
|
|
529
|
+
extseed[0][MLDSA_CRHBYTES] = (uint8_t)(nonce0 & 0xFF);
|
|
530
|
+
extseed[1][MLDSA_CRHBYTES] = (uint8_t)(nonce1 & 0xFF);
|
|
531
|
+
extseed[2][MLDSA_CRHBYTES] = (uint8_t)(nonce2 & 0xFF);
|
|
532
|
+
extseed[3][MLDSA_CRHBYTES] = (uint8_t)(nonce3 & 0xFF);
|
|
533
|
+
extseed[0][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce0 >> 8);
|
|
534
|
+
extseed[1][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce1 >> 8);
|
|
535
|
+
extseed[2][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce2 >> 8);
|
|
536
|
+
extseed[3][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce3 >> 8);
|
|
537
|
+
|
|
538
|
+
mld_xof256_x4_init(&state);
|
|
539
|
+
mld_xof256_x4_absorb(&state, extseed, MLDSA_CRHBYTES + 2);
|
|
540
|
+
mld_xof256_x4_squeezeblocks(buf, MLD_POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
|
|
541
|
+
|
|
542
|
+
mld_polyz_unpack(r0, buf[0]);
|
|
543
|
+
mld_polyz_unpack(r1, buf[1]);
|
|
544
|
+
mld_polyz_unpack(r2, buf[2]);
|
|
545
|
+
mld_polyz_unpack(r3, buf[3]);
|
|
546
|
+
mld_xof256_x4_release(&state);
|
|
547
|
+
|
|
548
|
+
mld_assert_bound(r0->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
549
|
+
mld_assert_bound(r1->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
550
|
+
mld_assert_bound(r2->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
551
|
+
mld_assert_bound(r3->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
552
|
+
|
|
553
|
+
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
|
|
554
|
+
mld_zeroize(buf, sizeof(buf));
|
|
555
|
+
mld_zeroize(extseed, sizeof(extseed));
|
|
556
|
+
}
|
|
557
|
+
#endif /* !MLD_CONFIG_SERIAL_FIPS202_ONLY && (!MLD_CONFIG_REDUCE_RAM || \
|
|
558
|
+
MLD_UNIT_TEST) */
|
|
559
|
+
#endif /* !MLD_CONFIG_NO_SIGN_API */
|
|
560
|
+
|
|
561
|
+
#if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
|
|
562
|
+
MLD_INTERNAL_API
|
|
563
|
+
void mld_poly_challenge(mld_poly *c, const uint8_t seed[MLDSA_CTILDEBYTES])
|
|
564
|
+
{
|
|
565
|
+
unsigned int i, j, pos;
|
|
566
|
+
uint64_t signs;
|
|
567
|
+
uint64_t offset;
|
|
568
|
+
MLD_ALIGN uint8_t buf[SHAKE256_RATE];
|
|
569
|
+
mld_shake256ctx state;
|
|
570
|
+
|
|
571
|
+
mld_shake256_init(&state);
|
|
572
|
+
mld_shake256_absorb(&state, seed, MLDSA_CTILDEBYTES);
|
|
573
|
+
mld_shake256_finalize(&state);
|
|
574
|
+
mld_shake256_squeeze(buf, SHAKE256_RATE, &state);
|
|
575
|
+
|
|
576
|
+
/* Convert the first 8 bytes of buf[] into an unsigned 64-bit value. */
|
|
577
|
+
/* Each bit of that dictates the sign of the resulting challenge value */
|
|
578
|
+
signs = 0;
|
|
579
|
+
for (i = 0; i < 8; ++i)
|
|
580
|
+
__loop__(
|
|
581
|
+
assigns(i, signs)
|
|
582
|
+
invariant(i <= 8)
|
|
583
|
+
decreases(8 - i)
|
|
584
|
+
)
|
|
585
|
+
{
|
|
586
|
+
signs |= (uint64_t)buf[i] << 8 * i;
|
|
587
|
+
}
|
|
588
|
+
pos = 8;
|
|
589
|
+
|
|
590
|
+
mld_memset(c, 0, sizeof(mld_poly));
|
|
591
|
+
|
|
592
|
+
for (i = MLDSA_N - MLDSA_TAU; i < MLDSA_N; ++i)
|
|
593
|
+
__loop__(
|
|
594
|
+
assigns(i, j, object_whole(buf), state, pos, memory_slice(c, sizeof(mld_poly)), signs)
|
|
595
|
+
invariant(i >= MLDSA_N - MLDSA_TAU)
|
|
596
|
+
invariant(i <= MLDSA_N)
|
|
597
|
+
invariant(pos >= 1)
|
|
598
|
+
invariant(pos <= SHAKE256_RATE)
|
|
599
|
+
invariant(array_bound(c->coeffs, 0, MLDSA_N, -1, 2))
|
|
600
|
+
invariant(state.pos <= SHAKE256_RATE)
|
|
601
|
+
decreases(MLDSA_N - i)
|
|
602
|
+
)
|
|
603
|
+
{
|
|
604
|
+
/* This loop terminates only probabilistically, hence no decreases
|
|
605
|
+
* clause. */
|
|
606
|
+
do
|
|
607
|
+
__loop__(
|
|
608
|
+
assigns(j, object_whole(buf), state, pos)
|
|
609
|
+
invariant(state.pos <= SHAKE256_RATE)
|
|
610
|
+
)
|
|
611
|
+
{
|
|
612
|
+
if (pos >= SHAKE256_RATE)
|
|
613
|
+
{
|
|
614
|
+
mld_shake256_squeeze(buf, SHAKE256_RATE, &state);
|
|
615
|
+
pos = 0;
|
|
616
|
+
}
|
|
617
|
+
j = buf[pos++];
|
|
618
|
+
} while (j > i);
|
|
619
|
+
|
|
620
|
+
c->coeffs[i] = c->coeffs[j];
|
|
621
|
+
|
|
622
|
+
/* Reference: Compute coefficient value here in two steps to */
|
|
623
|
+
/* avoid mixing unsigned and signed arithmetic with implicit */
|
|
624
|
+
/* conversions, and so that CBMC can keep track of ranges */
|
|
625
|
+
/* to complete type-safety proof here. */
|
|
626
|
+
|
|
627
|
+
/* The least-significant bit of signs tells us if we want -1 or +1 */
|
|
628
|
+
offset = 2 * (signs & 1);
|
|
629
|
+
|
|
630
|
+
/* offset has value 0 or 2 here, so (1 - (int32_t) offset) has
|
|
631
|
+
* value -1 or +1 */
|
|
632
|
+
c->coeffs[j] = 1 - (int32_t)offset;
|
|
633
|
+
|
|
634
|
+
/* Move to the next bit of signs for next time */
|
|
635
|
+
signs >>= 1;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
mld_assert_bound(c->coeffs, MLDSA_N, -1, 2);
|
|
639
|
+
mld_shake256_release(&state);
|
|
640
|
+
|
|
641
|
+
/* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
|
|
642
|
+
mld_zeroize(buf, sizeof(buf));
|
|
643
|
+
mld_zeroize(&signs, sizeof(signs));
|
|
644
|
+
}
|
|
645
|
+
#endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */
|
|
646
|
+
|
|
647
|
+
#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
|
|
648
|
+
MLD_INTERNAL_API
|
|
649
|
+
void mld_polyeta_pack(uint8_t r[MLDSA_POLYETA_PACKEDBYTES], const mld_poly *a)
|
|
650
|
+
{
|
|
651
|
+
unsigned int i;
|
|
652
|
+
uint8_t t[8];
|
|
653
|
+
|
|
654
|
+
mld_assert_abs_bound(a->coeffs, MLDSA_N, MLDSA_ETA + 1);
|
|
655
|
+
|
|
656
|
+
#if MLDSA_ETA == 2
|
|
657
|
+
for (i = 0; i < MLDSA_N / 8; ++i)
|
|
658
|
+
__loop__(
|
|
659
|
+
invariant(i <= MLDSA_N/8)
|
|
660
|
+
decreases(MLDSA_N / 8 - i))
|
|
661
|
+
{
|
|
662
|
+
/* The casts are safe since we assume that the coefficients
|
|
663
|
+
* of a are <= MLDSA_ETA in absolute value. */
|
|
664
|
+
t[0] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 0]);
|
|
665
|
+
t[1] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 1]);
|
|
666
|
+
t[2] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 2]);
|
|
667
|
+
t[3] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 3]);
|
|
668
|
+
t[4] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 4]);
|
|
669
|
+
t[5] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 5]);
|
|
670
|
+
t[6] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 6]);
|
|
671
|
+
t[7] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 7]);
|
|
672
|
+
|
|
673
|
+
r[3 * i + 0] = (uint8_t)(((t[0] >> 0) | (t[1] << 3) | (t[2] << 6)) & 0xFF);
|
|
674
|
+
r[3 * i + 1] =
|
|
675
|
+
(uint8_t)(((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7)) &
|
|
676
|
+
0xFF);
|
|
677
|
+
r[3 * i + 2] = (uint8_t)(((t[5] >> 1) | (t[6] << 2) | (t[7] << 5)) & 0xFF);
|
|
678
|
+
}
|
|
679
|
+
#elif MLDSA_ETA == 4
|
|
680
|
+
for (i = 0; i < MLDSA_N / 2; ++i)
|
|
681
|
+
__loop__(
|
|
682
|
+
invariant(i <= MLDSA_N/2)
|
|
683
|
+
decreases(MLDSA_N / 2 - i))
|
|
684
|
+
{
|
|
685
|
+
/* The casts are safe since we assume that the coefficients
|
|
686
|
+
* of a are <= MLDSA_ETA in absolute value. */
|
|
687
|
+
t[0] = (uint8_t)(MLDSA_ETA - a->coeffs[2 * i + 0]);
|
|
688
|
+
t[1] = (uint8_t)(MLDSA_ETA - a->coeffs[2 * i + 1]);
|
|
689
|
+
r[i] = (uint8_t)(t[0] | (t[1] << 4));
|
|
690
|
+
}
|
|
691
|
+
#else /* MLDSA_ETA == 4 */
|
|
692
|
+
#error "Invalid value of MLDSA_ETA"
|
|
693
|
+
#endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
|
|
694
|
+
}
|
|
695
|
+
#endif /* !MLD_CONFIG_NO_KEYPAIR_API */
|
|
696
|
+
|
|
697
|
+
#if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API)
|
|
698
|
+
MLD_INTERNAL_API
|
|
699
|
+
void mld_polyeta_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYETA_PACKEDBYTES])
|
|
700
|
+
{
|
|
701
|
+
unsigned int i;
|
|
702
|
+
|
|
703
|
+
#if MLDSA_ETA == 2
|
|
704
|
+
for (i = 0; i < MLDSA_N / 8; ++i)
|
|
705
|
+
__loop__(
|
|
706
|
+
invariant(i <= MLDSA_N/8)
|
|
707
|
+
invariant(array_bound(r->coeffs, 0, i*8, -5, MLDSA_ETA + 1))
|
|
708
|
+
decreases(MLDSA_N / 8 - i))
|
|
709
|
+
{
|
|
710
|
+
r->coeffs[8 * i + 0] = (a[3 * i + 0] >> 0) & 7;
|
|
711
|
+
r->coeffs[8 * i + 1] = (a[3 * i + 0] >> 3) & 7;
|
|
712
|
+
r->coeffs[8 * i + 2] = ((a[3 * i + 0] >> 6) | (a[3 * i + 1] << 2)) & 7;
|
|
713
|
+
r->coeffs[8 * i + 3] = (a[3 * i + 1] >> 1) & 7;
|
|
714
|
+
r->coeffs[8 * i + 4] = (a[3 * i + 1] >> 4) & 7;
|
|
715
|
+
r->coeffs[8 * i + 5] = ((a[3 * i + 1] >> 7) | (a[3 * i + 2] << 1)) & 7;
|
|
716
|
+
r->coeffs[8 * i + 6] = (a[3 * i + 2] >> 2) & 7;
|
|
717
|
+
r->coeffs[8 * i + 7] = (a[3 * i + 2] >> 5) & 7;
|
|
718
|
+
|
|
719
|
+
r->coeffs[8 * i + 0] = MLDSA_ETA - r->coeffs[8 * i + 0];
|
|
720
|
+
r->coeffs[8 * i + 1] = MLDSA_ETA - r->coeffs[8 * i + 1];
|
|
721
|
+
r->coeffs[8 * i + 2] = MLDSA_ETA - r->coeffs[8 * i + 2];
|
|
722
|
+
r->coeffs[8 * i + 3] = MLDSA_ETA - r->coeffs[8 * i + 3];
|
|
723
|
+
r->coeffs[8 * i + 4] = MLDSA_ETA - r->coeffs[8 * i + 4];
|
|
724
|
+
r->coeffs[8 * i + 5] = MLDSA_ETA - r->coeffs[8 * i + 5];
|
|
725
|
+
r->coeffs[8 * i + 6] = MLDSA_ETA - r->coeffs[8 * i + 6];
|
|
726
|
+
r->coeffs[8 * i + 7] = MLDSA_ETA - r->coeffs[8 * i + 7];
|
|
727
|
+
}
|
|
728
|
+
#elif MLDSA_ETA == 4
|
|
729
|
+
for (i = 0; i < MLDSA_N / 2; ++i)
|
|
730
|
+
__loop__(
|
|
731
|
+
invariant(i <= MLDSA_N/2)
|
|
732
|
+
invariant(array_bound(r->coeffs, 0, i*2, -11, MLDSA_ETA + 1))
|
|
733
|
+
decreases(MLDSA_N / 2 - i))
|
|
734
|
+
{
|
|
735
|
+
r->coeffs[2 * i + 0] = a[i] & 0x0F;
|
|
736
|
+
r->coeffs[2 * i + 1] = a[i] >> 4;
|
|
737
|
+
r->coeffs[2 * i + 0] = MLDSA_ETA - r->coeffs[2 * i + 0];
|
|
738
|
+
r->coeffs[2 * i + 1] = MLDSA_ETA - r->coeffs[2 * i + 1];
|
|
739
|
+
}
|
|
740
|
+
#else /* MLDSA_ETA == 4 */
|
|
741
|
+
#error "Invalid value of MLDSA_ETA"
|
|
742
|
+
#endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
|
|
743
|
+
|
|
744
|
+
mld_assert_bound(r->coeffs, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND,
|
|
745
|
+
MLDSA_ETA + 1);
|
|
746
|
+
}
|
|
747
|
+
#endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_SIGN_API */
|
|
748
|
+
|
|
749
|
+
#if !defined(MLD_CONFIG_NO_SIGN_API)
|
|
750
|
+
MLD_INTERNAL_API
|
|
751
|
+
void mld_polyz_pack(uint8_t r[MLDSA_POLYZ_PACKEDBYTES], const mld_poly *a)
|
|
752
|
+
{
|
|
753
|
+
unsigned int i;
|
|
754
|
+
uint32_t t[4];
|
|
755
|
+
|
|
756
|
+
mld_assert_bound(a->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
757
|
+
|
|
758
|
+
#if MLD_CONFIG_PARAMETER_SET == 44
|
|
759
|
+
for (i = 0; i < MLDSA_N / 4; ++i)
|
|
760
|
+
__loop__(
|
|
761
|
+
invariant(i <= MLDSA_N/4)
|
|
762
|
+
decreases(MLDSA_N / 4 - i))
|
|
763
|
+
{
|
|
764
|
+
/* Safety: a->coeffs[i] <= MLDSA_GAMMA1, hence, these casts are safe. */
|
|
765
|
+
t[0] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 0]);
|
|
766
|
+
t[1] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 1]);
|
|
767
|
+
t[2] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 2]);
|
|
768
|
+
t[3] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 3]);
|
|
769
|
+
|
|
770
|
+
r[9 * i + 0] = (uint8_t)((t[0]) & 0xFF);
|
|
771
|
+
r[9 * i + 1] = (uint8_t)((t[0] >> 8) & 0xFF);
|
|
772
|
+
r[9 * i + 2] = (uint8_t)((t[0] >> 16) & 0xFF);
|
|
773
|
+
r[9 * i + 2] |= (uint8_t)((t[1] << 2) & 0xFF);
|
|
774
|
+
r[9 * i + 3] = (uint8_t)((t[1] >> 6) & 0xFF);
|
|
775
|
+
r[9 * i + 4] = (uint8_t)((t[1] >> 14) & 0xFF);
|
|
776
|
+
r[9 * i + 4] |= (uint8_t)((t[2] << 4) & 0xFF);
|
|
777
|
+
r[9 * i + 5] = (uint8_t)((t[2] >> 4) & 0xFF);
|
|
778
|
+
r[9 * i + 6] = (uint8_t)((t[2] >> 12) & 0xFF);
|
|
779
|
+
r[9 * i + 6] |= (uint8_t)((t[3] << 6) & 0xFF);
|
|
780
|
+
r[9 * i + 7] = (uint8_t)((t[3] >> 2) & 0xFF);
|
|
781
|
+
r[9 * i + 8] = (uint8_t)((t[3] >> 10) & 0xFF);
|
|
782
|
+
}
|
|
783
|
+
#else /* MLD_CONFIG_PARAMETER_SET == 44 */
|
|
784
|
+
for (i = 0; i < MLDSA_N / 2; ++i)
|
|
785
|
+
__loop__(
|
|
786
|
+
invariant(i <= MLDSA_N/2)
|
|
787
|
+
decreases(MLDSA_N / 2 - i))
|
|
788
|
+
{
|
|
789
|
+
/* Safety: a->coeffs[i] <= MLDSA_GAMMA1, hence, these casts are safe. */
|
|
790
|
+
t[0] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[2 * i + 0]);
|
|
791
|
+
t[1] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[2 * i + 1]);
|
|
792
|
+
|
|
793
|
+
r[5 * i + 0] = (uint8_t)((t[0]) & 0xFF);
|
|
794
|
+
r[5 * i + 1] = (uint8_t)((t[0] >> 8) & 0xFF);
|
|
795
|
+
r[5 * i + 2] = (uint8_t)((t[0] >> 16) & 0xFF);
|
|
796
|
+
r[5 * i + 2] |= (uint8_t)((t[1] << 4) & 0xFF);
|
|
797
|
+
r[5 * i + 3] = (uint8_t)((t[1] >> 4) & 0xFF);
|
|
798
|
+
r[5 * i + 4] = (uint8_t)((t[1] >> 12) & 0xFF);
|
|
799
|
+
}
|
|
800
|
+
#endif /* MLD_CONFIG_PARAMETER_SET != 44 */
|
|
801
|
+
}
|
|
802
|
+
#endif /* !MLD_CONFIG_NO_SIGN_API */
|
|
803
|
+
|
|
804
|
+
#if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
|
|
805
|
+
MLD_STATIC_TESTABLE void mld_polyz_unpack_c(
|
|
806
|
+
mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES])
|
|
807
|
+
__contract__(
|
|
808
|
+
requires(memory_no_alias(r, sizeof(mld_poly)))
|
|
809
|
+
requires(memory_no_alias(a, MLDSA_POLYZ_PACKEDBYTES))
|
|
810
|
+
assigns(memory_slice(r, sizeof(mld_poly)))
|
|
811
|
+
ensures(array_bound(r->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
|
|
812
|
+
)
|
|
813
|
+
{
|
|
814
|
+
unsigned int i;
|
|
815
|
+
#if MLD_CONFIG_PARAMETER_SET == 44
|
|
816
|
+
for (i = 0; i < MLDSA_N / 4; ++i)
|
|
817
|
+
__loop__(
|
|
818
|
+
invariant(i <= MLDSA_N/4)
|
|
819
|
+
invariant(array_bound(r->coeffs, 0, i*4, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
|
|
820
|
+
decreases(MLDSA_N / 4 - i))
|
|
821
|
+
{
|
|
822
|
+
r->coeffs[4 * i + 0] = a[9 * i + 0];
|
|
823
|
+
r->coeffs[4 * i + 0] |= (int32_t)a[9 * i + 1] << 8;
|
|
824
|
+
r->coeffs[4 * i + 0] |= (int32_t)a[9 * i + 2] << 16;
|
|
825
|
+
r->coeffs[4 * i + 0] &= 0x3FFFF;
|
|
826
|
+
|
|
827
|
+
r->coeffs[4 * i + 1] = a[9 * i + 2] >> 2;
|
|
828
|
+
r->coeffs[4 * i + 1] |= (int32_t)a[9 * i + 3] << 6;
|
|
829
|
+
r->coeffs[4 * i + 1] |= (int32_t)a[9 * i + 4] << 14;
|
|
830
|
+
r->coeffs[4 * i + 1] &= 0x3FFFF;
|
|
831
|
+
|
|
832
|
+
r->coeffs[4 * i + 2] = a[9 * i + 4] >> 4;
|
|
833
|
+
r->coeffs[4 * i + 2] |= (int32_t)a[9 * i + 5] << 4;
|
|
834
|
+
r->coeffs[4 * i + 2] |= (int32_t)a[9 * i + 6] << 12;
|
|
835
|
+
r->coeffs[4 * i + 2] &= 0x3FFFF;
|
|
836
|
+
|
|
837
|
+
r->coeffs[4 * i + 3] = a[9 * i + 6] >> 6;
|
|
838
|
+
r->coeffs[4 * i + 3] |= (int32_t)a[9 * i + 7] << 2;
|
|
839
|
+
r->coeffs[4 * i + 3] |= (int32_t)a[9 * i + 8] << 10;
|
|
840
|
+
r->coeffs[4 * i + 3] &= 0x3FFFF;
|
|
841
|
+
|
|
842
|
+
r->coeffs[4 * i + 0] = MLDSA_GAMMA1 - r->coeffs[4 * i + 0];
|
|
843
|
+
r->coeffs[4 * i + 1] = MLDSA_GAMMA1 - r->coeffs[4 * i + 1];
|
|
844
|
+
r->coeffs[4 * i + 2] = MLDSA_GAMMA1 - r->coeffs[4 * i + 2];
|
|
845
|
+
r->coeffs[4 * i + 3] = MLDSA_GAMMA1 - r->coeffs[4 * i + 3];
|
|
846
|
+
}
|
|
847
|
+
#else /* MLD_CONFIG_PARAMETER_SET == 44 */
|
|
848
|
+
for (i = 0; i < MLDSA_N / 2; ++i)
|
|
849
|
+
__loop__(
|
|
850
|
+
invariant(i <= MLDSA_N/2)
|
|
851
|
+
invariant(array_bound(r->coeffs, 0, i*2, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
|
|
852
|
+
decreases(MLDSA_N / 2 - i))
|
|
853
|
+
{
|
|
854
|
+
r->coeffs[2 * i + 0] = a[5 * i + 0];
|
|
855
|
+
r->coeffs[2 * i + 0] |= (int32_t)a[5 * i + 1] << 8;
|
|
856
|
+
r->coeffs[2 * i + 0] |= (int32_t)a[5 * i + 2] << 16;
|
|
857
|
+
r->coeffs[2 * i + 0] &= 0xFFFFF;
|
|
858
|
+
|
|
859
|
+
r->coeffs[2 * i + 1] = a[5 * i + 2] >> 4;
|
|
860
|
+
r->coeffs[2 * i + 1] |= (int32_t)a[5 * i + 3] << 4;
|
|
861
|
+
r->coeffs[2 * i + 1] |= (int32_t)a[5 * i + 4] << 12;
|
|
862
|
+
/* r->coeffs[2*i+1] &= 0xFFFFF; */ /* No effect, since we're anyway at 20
|
|
863
|
+
bits */
|
|
864
|
+
|
|
865
|
+
r->coeffs[2 * i + 0] = MLDSA_GAMMA1 - r->coeffs[2 * i + 0];
|
|
866
|
+
r->coeffs[2 * i + 1] = MLDSA_GAMMA1 - r->coeffs[2 * i + 1];
|
|
867
|
+
}
|
|
868
|
+
#endif /* MLD_CONFIG_PARAMETER_SET != 44 */
|
|
869
|
+
mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
MLD_INTERNAL_API
|
|
873
|
+
void mld_polyz_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES])
|
|
874
|
+
{
|
|
875
|
+
#if defined(MLD_USE_NATIVE_POLYZ_UNPACK_17) && MLD_CONFIG_PARAMETER_SET == 44
|
|
876
|
+
int ret;
|
|
877
|
+
ret = mld_polyz_unpack_17_native(r->coeffs, a);
|
|
878
|
+
if (ret == MLD_NATIVE_FUNC_SUCCESS)
|
|
879
|
+
{
|
|
880
|
+
mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
#elif defined(MLD_USE_NATIVE_POLYZ_UNPACK_19) && \
|
|
884
|
+
(MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
|
|
885
|
+
int ret;
|
|
886
|
+
ret = mld_polyz_unpack_19_native(r->coeffs, a);
|
|
887
|
+
if (ret == MLD_NATIVE_FUNC_SUCCESS)
|
|
888
|
+
{
|
|
889
|
+
mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
#endif /* !(MLD_USE_NATIVE_POLYZ_UNPACK_17 && MLD_CONFIG_PARAMETER_SET == 44) \
|
|
893
|
+
&& MLD_USE_NATIVE_POLYZ_UNPACK_19 && (MLD_CONFIG_PARAMETER_SET == 65 \
|
|
894
|
+
|| MLD_CONFIG_PARAMETER_SET == 87) */
|
|
895
|
+
|
|
896
|
+
mld_polyz_unpack_c(r, a);
|
|
897
|
+
}
|
|
898
|
+
#endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */
|
|
899
|
+
|
|
900
|
+
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros. */
|
|
901
|
+
|
|
902
|
+
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
|
|
903
|
+
* Don't modify by hand -- this is auto-generated by scripts/autogen. */
|
|
904
|
+
#undef mld_rej_eta
|
|
905
|
+
#undef mld_rej_eta_c
|
|
906
|
+
#undef mld_poly_decompose_c
|
|
907
|
+
#undef mld_poly_use_hint_c
|
|
908
|
+
#undef mld_polyz_unpack_c
|
|
909
|
+
#undef MLD_POLY_UNIFORM_ETA_NBLOCKS
|
|
910
|
+
#undef MLD_POLY_UNIFORM_GAMMA1_NBLOCKS
|