pq_crypto 0.6.0 → 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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/SECURITY.md +7 -0
  4. data/ext/pqcrypto/extconf.rb +2 -0
  5. data/ext/pqcrypto/pqcrypto_ruby_secure.c +139 -0
  6. data/ext/pqcrypto/pqcrypto_secure.c +532 -0
  7. data/ext/pqcrypto/pqcrypto_secure.h +20 -0
  8. data/ext/pqcrypto/pqcrypto_version.h +1 -1
  9. data/ext/pqcrypto/vendor/.vendored +4 -4
  10. data/ext/pqcrypto/vendor/mldsa-native/README.md +23 -10
  11. data/ext/pqcrypto/vendor/mldsa-native/mldsa/README.md +23 -0
  12. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +114 -58
  13. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +498 -461
  14. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +145 -85
  15. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +456 -422
  16. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +47 -25
  17. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +26 -14
  18. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +56 -81
  19. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +17 -24
  20. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.c +33 -40
  21. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.h +67 -87
  22. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +19 -14
  23. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +13 -5
  24. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +84 -10
  25. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +10 -5
  26. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +6 -0
  27. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +22 -15
  28. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +376 -0
  29. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +204 -0
  30. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +259 -0
  31. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +1077 -0
  32. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +987 -0
  33. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +16 -10
  34. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +2 -1
  35. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +1 -1
  36. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +4 -2
  37. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +2 -2
  38. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +1 -1
  39. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +60 -0
  40. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +48 -0
  41. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +18 -1
  42. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +658 -582
  43. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +5 -100
  44. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +26 -25
  45. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/state_extract_bytes_x4_mve.S +334 -0
  46. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/state_xor_bytes_x4_mve.S +355 -0
  47. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +8 -3
  48. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/{xkcp.h → keccak_f1600_x4_avx2.h} +11 -8
  49. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +44 -0
  50. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +454 -0
  51. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccakf1600_constants.c +52 -0
  52. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +37 -28
  53. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +213 -196
  54. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +248 -64
  55. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt_aarch64_asm.S +753 -0
  56. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S +129 -0
  57. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S +145 -0
  58. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S +177 -0
  59. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt_aarch64_asm.S +653 -0
  60. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery_aarch64_asm.S +84 -0
  61. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_aarch64_asm.S +53 -0
  62. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_aarch64_asm.S +55 -0
  63. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_aarch64_asm.S +86 -0
  64. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_aarch64_asm.S +86 -0
  65. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_aarch64_asm.S +103 -0
  66. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_aarch64_asm.S +111 -0
  67. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_aarch64_asm.S +75 -0
  68. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_aarch64_asm.S +72 -0
  69. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +23 -11
  70. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_aarch64_asm.S +189 -0
  71. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_aarch64_asm.S +137 -0
  72. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_aarch64_asm.S +130 -0
  73. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +520 -516
  74. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +34 -33
  75. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +202 -242
  76. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +25 -17
  77. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +112 -28
  78. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +1 -1
  79. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +1 -1
  80. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt_avx2_asm.S +2311 -0
  81. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt_avx2_asm.S +2383 -0
  82. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack_avx2_asm.S +238 -0
  83. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4_avx2_asm.S +139 -0
  84. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5_avx2_asm.S +155 -0
  85. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7_avx2_asm.S +187 -0
  86. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_avx2_asm.S +130 -0
  87. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_caddq_avx2_asm.S +190 -0
  88. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +6 -4
  89. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +6 -4
  90. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +9 -8
  91. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +10 -9
  92. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +8 -5
  93. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +8 -5
  94. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +6 -4
  95. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +6 -4
  96. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +130 -129
  97. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +109 -180
  98. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +169 -150
  99. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +56 -40
  100. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +149 -164
  101. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +52 -57
  102. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +132 -167
  103. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +57 -424
  104. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +167 -474
  105. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +308 -0
  106. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +653 -0
  107. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +22 -29
  108. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +37 -43
  109. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +511 -367
  110. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +456 -417
  111. data/lib/pq_crypto/hybrid_kem.rb +1 -1
  112. data/lib/pq_crypto/internal.rb +23 -0
  113. data/lib/pq_crypto/kem.rb +27 -34
  114. data/lib/pq_crypto/pkcs8/der.rb +68 -0
  115. data/lib/pq_crypto/pkcs8/private_key_choice.rb +186 -0
  116. data/lib/pq_crypto/pkcs8.rb +51 -468
  117. data/lib/pq_crypto/serialization.rb +19 -29
  118. data/lib/pq_crypto/signature.rb +28 -35
  119. data/lib/pq_crypto/version.rb +1 -1
  120. data/lib/pq_crypto.rb +10 -0
  121. data/script/vendor_libs.rb +3 -3
  122. metadata +44 -35
  123. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm.S +0 -376
  124. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm.S +0 -204
  125. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm.S +0 -259
  126. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm.S +0 -1077
  127. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm.S +0 -987
  128. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.c +0 -488
  129. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.h +0 -16
  130. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt.S +0 -753
  131. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4.S +0 -129
  132. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5.S +0 -145
  133. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7.S +0 -177
  134. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt.S +0 -653
  135. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery.S +0 -79
  136. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_asm.S +0 -53
  137. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_asm.S +0 -55
  138. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_asm.S +0 -85
  139. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_asm.S +0 -85
  140. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_asm.S +0 -102
  141. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_asm.S +0 -110
  142. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_asm.S +0 -72
  143. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_asm.S +0 -69
  144. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_asm.S +0 -189
  145. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_asm.S +0 -135
  146. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_asm.S +0 -128
  147. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt.S +0 -2311
  148. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt.S +0 -2383
  149. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack.S +0 -239
  150. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise.S +0 -131
  151. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4.S +0 -139
  152. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5.S +0 -155
  153. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7.S +0 -187
  154. 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