pq_crypto 0.6.1 → 0.6.2

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.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/SECURITY.md +7 -0
  4. data/ext/pqcrypto/pqcrypto_version.h +1 -1
  5. data/ext/pqcrypto/vendor/.vendored +4 -4
  6. data/ext/pqcrypto/vendor/mldsa-native/README.md +23 -10
  7. data/ext/pqcrypto/vendor/mldsa-native/mldsa/README.md +23 -0
  8. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +114 -58
  9. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +498 -461
  10. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +145 -85
  11. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +456 -422
  12. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +47 -25
  13. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +26 -14
  14. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +56 -81
  15. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +17 -24
  16. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.c +33 -40
  17. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.h +67 -87
  18. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +19 -14
  19. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +13 -5
  20. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +84 -10
  21. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +10 -5
  22. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +6 -0
  23. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +22 -15
  24. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +376 -0
  25. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +204 -0
  26. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +259 -0
  27. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +1077 -0
  28. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +987 -0
  29. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +16 -10
  30. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +2 -1
  31. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +1 -1
  32. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +4 -2
  33. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +2 -2
  34. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +1 -1
  35. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +60 -0
  36. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +48 -0
  37. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +18 -1
  38. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +658 -582
  39. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +5 -100
  40. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +26 -25
  41. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/state_extract_bytes_x4_mve.S +334 -0
  42. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/state_xor_bytes_x4_mve.S +355 -0
  43. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +8 -3
  44. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/{xkcp.h → keccak_f1600_x4_avx2.h} +11 -8
  45. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +44 -0
  46. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +454 -0
  47. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccakf1600_constants.c +52 -0
  48. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +37 -28
  49. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +213 -196
  50. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +248 -64
  51. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt_aarch64_asm.S +753 -0
  52. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S +129 -0
  53. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S +145 -0
  54. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S +177 -0
  55. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt_aarch64_asm.S +653 -0
  56. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery_aarch64_asm.S +84 -0
  57. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_aarch64_asm.S +53 -0
  58. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_aarch64_asm.S +55 -0
  59. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_aarch64_asm.S +86 -0
  60. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_aarch64_asm.S +86 -0
  61. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_aarch64_asm.S +103 -0
  62. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_aarch64_asm.S +111 -0
  63. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_aarch64_asm.S +75 -0
  64. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_aarch64_asm.S +72 -0
  65. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +23 -11
  66. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_aarch64_asm.S +189 -0
  67. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_aarch64_asm.S +137 -0
  68. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_aarch64_asm.S +130 -0
  69. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +520 -516
  70. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +34 -33
  71. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +202 -242
  72. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +25 -17
  73. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +112 -28
  74. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +1 -1
  75. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +1 -1
  76. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt_avx2_asm.S +2311 -0
  77. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt_avx2_asm.S +2383 -0
  78. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack_avx2_asm.S +238 -0
  79. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4_avx2_asm.S +139 -0
  80. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5_avx2_asm.S +155 -0
  81. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7_avx2_asm.S +187 -0
  82. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_avx2_asm.S +130 -0
  83. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_caddq_avx2_asm.S +190 -0
  84. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +6 -4
  85. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +6 -4
  86. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +9 -8
  87. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +10 -9
  88. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +8 -5
  89. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +8 -5
  90. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +6 -4
  91. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +6 -4
  92. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +130 -129
  93. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +109 -180
  94. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +169 -150
  95. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +56 -40
  96. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +149 -164
  97. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +52 -57
  98. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +132 -167
  99. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +57 -424
  100. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +167 -474
  101. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +308 -0
  102. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +653 -0
  103. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +22 -29
  104. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +37 -43
  105. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +511 -367
  106. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +456 -417
  107. data/lib/pq_crypto/version.rb +1 -1
  108. data/script/vendor_libs.rb +3 -3
  109. metadata +41 -35
  110. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm.S +0 -376
  111. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm.S +0 -204
  112. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm.S +0 -259
  113. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm.S +0 -1077
  114. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm.S +0 -987
  115. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.c +0 -488
  116. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.h +0 -16
  117. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt.S +0 -753
  118. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4.S +0 -129
  119. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5.S +0 -145
  120. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7.S +0 -177
  121. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt.S +0 -653
  122. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery.S +0 -79
  123. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_asm.S +0 -53
  124. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_asm.S +0 -55
  125. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_asm.S +0 -85
  126. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_asm.S +0 -85
  127. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_asm.S +0 -102
  128. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_asm.S +0 -110
  129. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_asm.S +0 -72
  130. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_asm.S +0 -69
  131. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_asm.S +0 -189
  132. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_asm.S +0 -135
  133. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_asm.S +0 -128
  134. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt.S +0 -2311
  135. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt.S +0 -2383
  136. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack.S +0 -239
  137. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise.S +0 -131
  138. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4.S +0 -139
  139. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5.S +0 -155
  140. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7.S +0 -187
  141. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_caddq_avx2.c +0 -61
@@ -0,0 +1,308 @@
1
+ /*
2
+ * Copyright (c) The mldsa-native project authors
3
+ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4
+ */
5
+
6
+ /* References
7
+ * ==========
8
+ *
9
+ * - [FIPS204]
10
+ * FIPS 204 Module-Lattice-Based Digital Signature Standard
11
+ * National Institute of Standards and Technology
12
+ * https://csrc.nist.gov/pubs/fips/204/final
13
+ */
14
+
15
+ #include "polyvec_lazy.h"
16
+
17
+ #include "debug.h"
18
+
19
+ /* This namespacing is not done at the top to avoid a naming conflict
20
+ * with native backends, which are currently not yet namespaced. */
21
+ #define mld_polymat_expand_entry MLD_ADD_PARAM_SET(mld_polymat_expand_entry)
22
+
23
+ /**
24
+ * Sample a single matrix entry A[k][l] of ExpandA(rho) by rejection sampling
25
+ * from SHAKE128(rho|l|k), and apply the custom-order permutation when a
26
+ * native NTT backend is in use.
27
+ *
28
+ * The caller is expected to have copied rho into the first MLDSA_SEEDBYTES
29
+ * of seed_ext. This function writes the domain-separation bytes
30
+ * seed_ext[SEEDBYTES..+2] = {l, k} before sampling.
31
+ *
32
+ * @param[out] p Pointer to output polynomial.
33
+ * @param[in,out] seed_ext Seed buffer pre-filled with rho in the first
34
+ * MLDSA_SEEDBYTES; the final two bytes are
35
+ * overwritten.
36
+ * @param l Column index (inner, aka nonce low byte).
37
+ * @param k Row index (outer, aka nonce high byte).
38
+ */
39
+ static MLD_INLINE void mld_polymat_expand_entry(
40
+ mld_poly *p, uint8_t seed_ext[MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)], uint8_t l,
41
+ uint8_t k)
42
+ __contract__(
43
+ requires(memory_no_alias(p, sizeof(mld_poly)))
44
+ requires(memory_no_alias(seed_ext, MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)))
45
+ assigns(memory_slice(p, sizeof(mld_poly)))
46
+ assigns(memory_slice(seed_ext, MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)))
47
+ ensures(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
48
+ )
49
+ {
50
+ seed_ext[MLDSA_SEEDBYTES + 0] = l;
51
+ seed_ext[MLDSA_SEEDBYTES + 1] = k;
52
+ mld_poly_uniform(p, seed_ext);
53
+ mld_poly_permute_bitrev_to_custom_optional(p);
54
+ }
55
+
56
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
57
+
58
+ MLD_INTERNAL_API
59
+ void mld_polyvec_matrix_expand_eager(mld_polymat_eager *mat,
60
+ const uint8_t rho[MLDSA_SEEDBYTES])
61
+ {
62
+ unsigned int i, j;
63
+ MLD_ALIGN uint8_t seed_ext[4][MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)];
64
+
65
+ for (j = 0; j < 4; j++)
66
+ __loop__(
67
+ assigns(j, object_whole(seed_ext))
68
+ invariant(j <= 4)
69
+ decreases(4 - j)
70
+ )
71
+ {
72
+ mld_memcpy(seed_ext[j], rho, MLDSA_SEEDBYTES);
73
+ }
74
+
75
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
76
+ /* Sample 4 matrix entries a time. */
77
+ for (i = 0; i < (MLDSA_K * MLDSA_L / 4) * 4; i += 4)
78
+ __loop__(
79
+ assigns(i, j, object_whole(seed_ext), memory_slice(mat, sizeof(mld_polymat_eager)))
80
+ invariant(i <= (MLDSA_K * MLDSA_L / 4) * 4 && i % 4 == 0)
81
+ /* vectors 0 .. i / MLDSA_L are completely sampled */
82
+ invariant(forall(k1, 0, i / MLDSA_L, forall(l1, 0, MLDSA_L,
83
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
84
+ /* last vector is sampled up to i % MLDSA_L */
85
+ invariant(forall(k2, i / MLDSA_L, i / MLDSA_L + 1, forall(l2, 0, i % MLDSA_L,
86
+ array_bound(mat->vec[k2].vec[l2].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
87
+ decreases((MLDSA_K * MLDSA_L / 4) * 4 - i)
88
+ )
89
+ {
90
+ for (j = 0; j < 4; j++)
91
+ __loop__(
92
+ assigns(j, object_whole(seed_ext))
93
+ invariant(j <= 4)
94
+ decreases(4 - j)
95
+ )
96
+ {
97
+ uint8_t x = (uint8_t)((i + j) / MLDSA_L);
98
+ uint8_t y = (uint8_t)((i + j) % MLDSA_L);
99
+
100
+ seed_ext[j][MLDSA_SEEDBYTES + 0] = y;
101
+ seed_ext[j][MLDSA_SEEDBYTES + 1] = x;
102
+ }
103
+
104
+ mld_poly_uniform_4x(&mat->vec[i / MLDSA_L].vec[i % MLDSA_L],
105
+ &mat->vec[(i + 1) / MLDSA_L].vec[(i + 1) % MLDSA_L],
106
+ &mat->vec[(i + 2) / MLDSA_L].vec[(i + 2) % MLDSA_L],
107
+ &mat->vec[(i + 3) / MLDSA_L].vec[(i + 3) % MLDSA_L],
108
+ seed_ext);
109
+ mld_poly_permute_bitrev_to_custom_optional(
110
+ &mat->vec[i / MLDSA_L].vec[i % MLDSA_L]);
111
+ mld_poly_permute_bitrev_to_custom_optional(
112
+ &mat->vec[(i + 1) / MLDSA_L].vec[(i + 1) % MLDSA_L]);
113
+ mld_poly_permute_bitrev_to_custom_optional(
114
+ &mat->vec[(i + 2) / MLDSA_L].vec[(i + 2) % MLDSA_L]);
115
+ mld_poly_permute_bitrev_to_custom_optional(
116
+ &mat->vec[(i + 3) / MLDSA_L].vec[(i + 3) % MLDSA_L]);
117
+ }
118
+ #else /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
119
+ i = 0;
120
+ #endif /* MLD_CONFIG_SERIAL_FIPS202_ONLY */
121
+
122
+ /* Entries omitted by the batch-sampling are sampled individually. */
123
+ while (i < MLDSA_K * MLDSA_L)
124
+ __loop__(
125
+ assigns(i, object_whole(seed_ext), memory_slice(mat, sizeof(mld_polymat_eager)))
126
+ invariant(i <= MLDSA_K * MLDSA_L)
127
+ /* vectors 0 .. i / MLDSA_L are completely sampled */
128
+ invariant(forall(k1, 0, i / MLDSA_L, forall(l1, 0, MLDSA_L,
129
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
130
+ /* last vector is sampled up to i % MLDSA_L */
131
+ invariant(forall(k2, i / MLDSA_L, i / MLDSA_L + 1, forall(l2, 0, i % MLDSA_L,
132
+ array_bound(mat->vec[k2].vec[l2].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
133
+ decreases(MLDSA_K * MLDSA_L - i)
134
+ )
135
+ {
136
+ uint8_t x = (uint8_t)(i / MLDSA_L);
137
+ uint8_t y = (uint8_t)(i % MLDSA_L);
138
+ mld_polymat_expand_entry(&mat->vec[x].vec[y], seed_ext[0], y, x);
139
+ i++;
140
+ }
141
+
142
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
143
+ mld_zeroize(seed_ext, sizeof(seed_ext));
144
+ }
145
+
146
+ MLD_INTERNAL_API
147
+ void mld_polyvec_matrix_pointwise_montgomery_row_eager(mld_poly *t_row,
148
+ mld_polymat_eager *mat,
149
+ const mld_polyvecl *v,
150
+ unsigned int i)
151
+ {
152
+ mld_polyvecl_pointwise_acc_montgomery(t_row, &mat->vec[i], v);
153
+ }
154
+
155
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
156
+ MLD_INTERNAL_API
157
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_eager(mld_polyveck *w,
158
+ mld_polymat_eager *mat,
159
+ const mld_yvec_eager *y,
160
+ mld_polyvecl *scratch)
161
+ {
162
+ unsigned int i;
163
+ *scratch = y->vec;
164
+ mld_polyvecl_ntt(scratch);
165
+
166
+ for (i = 0; i < MLDSA_K; ++i)
167
+ __loop__(
168
+ assigns(i, memory_slice(w, sizeof(mld_polyveck)))
169
+ invariant(i <= MLDSA_K)
170
+ invariant(forall(k0, 0, i,
171
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLDSA_Q)))
172
+ decreases(MLDSA_K - i)
173
+ )
174
+ {
175
+ mld_polyvec_matrix_pointwise_montgomery_row_eager(&w->vec[i], mat, scratch,
176
+ i);
177
+ }
178
+
179
+ mld_polyveck_invntt_tomont(w);
180
+ }
181
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
182
+
183
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
184
+
185
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
186
+
187
+ MLD_INTERNAL_API
188
+ void mld_polyvec_matrix_expand_lazy(mld_polymat_lazy *mat,
189
+ const uint8_t rho[MLDSA_SEEDBYTES])
190
+ {
191
+ mld_memcpy(mat->rho, rho, MLDSA_SEEDBYTES);
192
+ }
193
+
194
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
195
+ MLD_INTERNAL_API
196
+ void mld_polyvec_matrix_pointwise_montgomery_row_lazy(mld_poly *t_row,
197
+ mld_polymat_lazy *mat,
198
+ const mld_polyvecl *v,
199
+ unsigned int i)
200
+ {
201
+ unsigned int l;
202
+ MLD_ALIGN uint8_t seed_ext[MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)];
203
+ mld_memcpy(seed_ext, mat->rho, MLDSA_SEEDBYTES);
204
+
205
+ mld_polymat_expand_entry(t_row, seed_ext, 0, (uint8_t)i);
206
+ mld_poly_pointwise_montgomery(t_row, &v->vec[0]);
207
+
208
+ for (l = 1; l < MLDSA_L; ++l)
209
+ __loop__(
210
+ assigns(l, object_whole(seed_ext),
211
+ memory_slice(t_row, sizeof(mld_poly)),
212
+ memory_slice(mat, sizeof(mld_polymat_lazy)))
213
+ invariant(l >= 1 && l <= MLDSA_L)
214
+ invariant(array_abs_bound(t_row->coeffs, 0, MLDSA_N, l * MLDSA_Q))
215
+ decreases(MLDSA_L - l)
216
+ )
217
+ {
218
+ mld_polymat_expand_entry(&mat->cur, seed_ext, (uint8_t)l, (uint8_t)i);
219
+ mld_poly_pointwise_montgomery(&mat->cur, &v->vec[l]);
220
+ mld_poly_add(t_row, &mat->cur);
221
+ }
222
+ mld_poly_reduce(t_row);
223
+
224
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
225
+ mld_zeroize(seed_ext, sizeof(seed_ext));
226
+ }
227
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_VERIFY_API */
228
+
229
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
230
+ MLD_INTERNAL_API
231
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_lazy(mld_polyveck *w,
232
+ mld_polymat_lazy *mat,
233
+ const mld_yvec_lazy *y,
234
+ mld_polyvecl *scratch)
235
+ {
236
+ unsigned int k, l;
237
+ MLD_ALIGN uint8_t seed_ext[MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)];
238
+ /* Only the first poly of the polyvecl scratch is used. The polyvecl type
239
+ * matches the eager variant for API uniformity; in REDUCE_RAM mode the
240
+ * polyvecl storage is provided "for free" by the caller's polyveck/polyvecl
241
+ * union. */
242
+ mld_poly *y_ntt = &scratch->vec[0];
243
+
244
+ mld_memcpy(seed_ext, mat->rho, MLDSA_SEEDBYTES);
245
+
246
+ /* Column-by-column: sample y[l], NTT, accumulate column l of A into w. */
247
+ for (l = 0; l < MLDSA_L; l++)
248
+ __loop__(
249
+ assigns(k, l, object_whole(seed_ext),
250
+ memory_slice(w, sizeof(mld_polyveck)),
251
+ memory_slice(mat, sizeof(mld_polymat_lazy)),
252
+ memory_slice(scratch, sizeof(mld_polyvecl)))
253
+ invariant(l <= MLDSA_L)
254
+ invariant(l == 0 ||
255
+ forall(k0, 0, MLDSA_K,
256
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N,
257
+ (int)l * MLDSA_Q)))
258
+ decreases(MLDSA_L - l)
259
+ )
260
+ {
261
+ mld_yvec_get_poly_lazy(y_ntt, y, l);
262
+ mld_poly_ntt(y_ntt);
263
+ for (k = 0; k < MLDSA_K; k++)
264
+ __loop__(
265
+ assigns(k, object_whole(seed_ext),
266
+ memory_slice(w, sizeof(mld_polyveck)),
267
+ memory_slice(mat, sizeof(mld_polymat_lazy)))
268
+ invariant(k <= MLDSA_K)
269
+ invariant(l != 0 ||
270
+ forall(k1, 0, k,
271
+ array_abs_bound(w->vec[k1].coeffs, 0, MLDSA_N, MLDSA_Q)))
272
+ invariant(l == 0 ||
273
+ forall(k2, 0, k,
274
+ array_abs_bound(w->vec[k2].coeffs, 0, MLDSA_N,
275
+ ((int)l + 1) * MLDSA_Q)))
276
+ invariant(l == 0 ||
277
+ forall(k3, k, MLDSA_K,
278
+ array_abs_bound(w->vec[k3].coeffs, 0, MLDSA_N,
279
+ (int)l * MLDSA_Q)))
280
+ decreases(MLDSA_K - k)
281
+ )
282
+ {
283
+ if (l == 0)
284
+ {
285
+ mld_polymat_expand_entry(&w->vec[k], seed_ext, 0, (uint8_t)k);
286
+ mld_poly_pointwise_montgomery(&w->vec[k], y_ntt);
287
+ }
288
+ else
289
+ {
290
+ mld_polymat_expand_entry(&mat->cur, seed_ext, (uint8_t)l, (uint8_t)k);
291
+ mld_poly_pointwise_montgomery(&mat->cur, y_ntt);
292
+ mld_poly_add(&w->vec[k], &mat->cur);
293
+ }
294
+ }
295
+ }
296
+
297
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
298
+ mld_zeroize(seed_ext, sizeof(seed_ext));
299
+ mld_polyveck_reduce(w);
300
+ mld_polyveck_invntt_tomont(w);
301
+ }
302
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
303
+
304
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
305
+
306
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
307
+ * Don't modify by hand -- this is auto-generated by scripts/autogen. */
308
+ #undef mld_polymat_expand_entry