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.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +88 -0
  4. data/ext/mldsa_gh_native/extconf.rb +14 -0
  5. data/ext/mldsa_gh_native/mldsa_gh_native.c +222 -0
  6. data/ext/mldsa_gh_native/mldsa_gh_native_all.c +24 -0
  7. data/ext/mldsa_gh_native/mldsa_gh_native_all.h +26 -0
  8. data/ext/mldsa_gh_native/vendor/mldsa-native/BUILDING.md +108 -0
  9. data/ext/mldsa_gh_native/vendor/mldsa-native/LICENSE +305 -0
  10. data/ext/mldsa_gh_native/vendor/mldsa-native/README.md +247 -0
  11. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/README.md +23 -0
  12. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native.c +803 -0
  13. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native.h +956 -0
  14. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native_asm.S +830 -0
  15. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native_config.h +855 -0
  16. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/cbmc.h +233 -0
  17. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/common.h +301 -0
  18. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/context.h +152 -0
  19. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/ct.c +21 -0
  20. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/ct.h +373 -0
  21. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/debug.c +75 -0
  22. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/debug.h +125 -0
  23. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202.c +270 -0
  24. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202.h +224 -0
  25. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +187 -0
  26. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +125 -0
  27. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +510 -0
  28. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +110 -0
  29. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +85 -0
  30. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +69 -0
  31. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +378 -0
  32. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +207 -0
  33. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +262 -0
  34. 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
  35. 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
  36. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +47 -0
  37. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +27 -0
  38. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +36 -0
  39. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +40 -0
  40. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +32 -0
  41. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +37 -0
  42. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/api.h +129 -0
  43. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/README.md +10 -0
  44. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +67 -0
  45. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +37 -0
  46. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +717 -0
  47. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +42 -0
  48. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_state_extract_bytes_mve.S +334 -0
  49. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_state_xor_bytes_mve.S +355 -0
  50. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +53 -0
  51. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +35 -0
  52. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +34 -0
  53. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +45 -0
  54. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +488 -0
  55. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccakf1600_constants.c +52 -0
  56. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +314 -0
  57. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +248 -0
  58. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +367 -0
  59. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_intt_aarch64_asm.S +786 -0
  60. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_ntt_aarch64_asm.S +686 -0
  61. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_pointwise_montgomery_aarch64_asm.S +106 -0
  62. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_caddq_aarch64_asm.S +69 -0
  63. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_chknorm_aarch64_asm.S +76 -0
  64. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_decompose_32_aarch64_asm.S +108 -0
  65. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_decompose_88_aarch64_asm.S +108 -0
  66. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_use_hint_32_aarch64_asm.S +125 -0
  67. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_use_hint_88_aarch64_asm.S +133 -0
  68. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S +157 -0
  69. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S +173 -0
  70. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S +205 -0
  71. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyz_unpack_17_aarch64_asm.S +103 -0
  72. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyz_unpack_19_aarch64_asm.S +100 -0
  73. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_aarch64_asm.S +222 -0
  74. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_eta2_aarch64_asm.S +170 -0
  75. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_eta4_aarch64_asm.S +163 -0
  76. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +52 -0
  77. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +547 -0
  78. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +63 -0
  79. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/api.h +617 -0
  80. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/meta.h +24 -0
  81. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +323 -0
  82. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +330 -0
  83. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +157 -0
  84. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +27 -0
  85. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_intt_avx2_asm.S +2333 -0
  86. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_ntt_avx2_asm.S +2405 -0
  87. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_nttunpack_avx2_asm.S +254 -0
  88. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l4_avx2_asm.S +173 -0
  89. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l5_avx2_asm.S +189 -0
  90. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l7_avx2_asm.S +221 -0
  91. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_avx2_asm.S +158 -0
  92. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_caddq_avx2_asm.S +199 -0
  93. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_chknorm_avx2_asm.S +176 -0
  94. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_32_avx2_asm.S +490 -0
  95. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_88_avx2_asm.S +489 -0
  96. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_32_avx2_asm.S +123 -0
  97. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_88_avx2_asm.S +125 -0
  98. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_17_avx2_asm.S +355 -0
  99. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_19_avx2_asm.S +355 -0
  100. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_avx2_asm.S +132 -0
  101. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta2_avx2_asm.S +205 -0
  102. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta4_avx2_asm.S +176 -0
  103. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +161 -0
  104. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/packing.c +213 -0
  105. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/packing.h +277 -0
  106. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/params.h +153 -0
  107. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly.c +1066 -0
  108. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly.h +464 -0
  109. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly_kl.c +910 -0
  110. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly_kl.h +367 -0
  111. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec.c +509 -0
  112. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec.h +435 -0
  113. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +311 -0
  114. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +652 -0
  115. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/randombytes.h +26 -0
  116. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/reduce.h +144 -0
  117. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/rounding.h +265 -0
  118. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sign.c +1720 -0
  119. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sign.h +850 -0
  120. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/symmetric.h +68 -0
  121. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sys.h +327 -0
  122. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/zetas.inc +55 -0
  123. data/lib/mldsa/parameter_set.rb +82 -0
  124. data/lib/mldsa/signing_key.rb +147 -0
  125. data/lib/mldsa/verify_key.rb +72 -0
  126. data/lib/mldsa/version.rb +7 -0
  127. data/lib/mldsa_gh.rb +93 -0
  128. metadata +225 -0
@@ -0,0 +1,311 @@
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
+ * @spec{Partially implements @[FIPS204, Algorithm 32, ExpandA] (samples one
33
+ * matrix entry via @[FIPS204, Algorithm 30, RejNTTPoly]).}
34
+ *
35
+ * @param[out] p Pointer to output polynomial.
36
+ * @param[in,out] seed_ext Seed buffer pre-filled with rho in the first
37
+ * MLDSA_SEEDBYTES; the final two bytes are
38
+ * overwritten.
39
+ * @param l Column index (inner, aka nonce low byte).
40
+ * @param k Row index (outer, aka nonce high byte).
41
+ */
42
+ static MLD_INLINE void mld_polymat_expand_entry(
43
+ mld_poly *p, uint8_t seed_ext[MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)], uint8_t l,
44
+ uint8_t k)
45
+ __contract__(
46
+ requires(memory_no_alias(p, sizeof(mld_poly)))
47
+ requires(memory_no_alias(seed_ext, MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)))
48
+ assigns(memory_slice(p, sizeof(mld_poly)))
49
+ assigns(memory_slice(seed_ext, MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)))
50
+ ensures(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
51
+ )
52
+ {
53
+ seed_ext[MLDSA_SEEDBYTES + 0] = l;
54
+ seed_ext[MLDSA_SEEDBYTES + 1] = k;
55
+ mld_poly_uniform(p, seed_ext);
56
+ mld_poly_permute_bitrev_to_custom_optional(p);
57
+ }
58
+
59
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
60
+
61
+ MLD_INTERNAL_API
62
+ void mld_polyvec_matrix_expand_eager(mld_polymat_eager *mat,
63
+ const uint8_t rho[MLDSA_SEEDBYTES])
64
+ {
65
+ unsigned int i, j;
66
+ MLD_ALIGN uint8_t seed_ext[4][MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)];
67
+
68
+ for (j = 0; j < 4; j++)
69
+ __loop__(
70
+ assigns(j, object_whole(seed_ext))
71
+ invariant(j <= 4)
72
+ decreases(4 - j)
73
+ )
74
+ {
75
+ mld_memcpy(seed_ext[j], rho, MLDSA_SEEDBYTES);
76
+ }
77
+
78
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
79
+ /* Sample 4 matrix entries a time. */
80
+ for (i = 0; i < (MLDSA_K * MLDSA_L / 4) * 4; i += 4)
81
+ __loop__(
82
+ assigns(i, j, object_whole(seed_ext), memory_slice(mat, sizeof(mld_polymat_eager)))
83
+ invariant(i <= (MLDSA_K * MLDSA_L / 4) * 4 && i % 4 == 0)
84
+ /* vectors 0 .. i / MLDSA_L are completely sampled */
85
+ invariant(forall(k1, 0, i / MLDSA_L, forall(l1, 0, MLDSA_L,
86
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
87
+ /* last vector is sampled up to i % MLDSA_L */
88
+ invariant(forall(k2, i / MLDSA_L, i / MLDSA_L + 1, forall(l2, 0, i % MLDSA_L,
89
+ array_bound(mat->vec[k2].vec[l2].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
90
+ decreases((MLDSA_K * MLDSA_L / 4) * 4 - i)
91
+ )
92
+ {
93
+ for (j = 0; j < 4; j++)
94
+ __loop__(
95
+ assigns(j, object_whole(seed_ext))
96
+ invariant(j <= 4)
97
+ decreases(4 - j)
98
+ )
99
+ {
100
+ uint8_t x = (uint8_t)((i + j) / MLDSA_L);
101
+ uint8_t y = (uint8_t)((i + j) % MLDSA_L);
102
+
103
+ seed_ext[j][MLDSA_SEEDBYTES + 0] = y;
104
+ seed_ext[j][MLDSA_SEEDBYTES + 1] = x;
105
+ }
106
+
107
+ mld_poly_uniform_4x(&mat->vec[i / MLDSA_L].vec[i % MLDSA_L],
108
+ &mat->vec[(i + 1) / MLDSA_L].vec[(i + 1) % MLDSA_L],
109
+ &mat->vec[(i + 2) / MLDSA_L].vec[(i + 2) % MLDSA_L],
110
+ &mat->vec[(i + 3) / MLDSA_L].vec[(i + 3) % MLDSA_L],
111
+ seed_ext);
112
+ mld_poly_permute_bitrev_to_custom_optional(
113
+ &mat->vec[i / MLDSA_L].vec[i % MLDSA_L]);
114
+ mld_poly_permute_bitrev_to_custom_optional(
115
+ &mat->vec[(i + 1) / MLDSA_L].vec[(i + 1) % MLDSA_L]);
116
+ mld_poly_permute_bitrev_to_custom_optional(
117
+ &mat->vec[(i + 2) / MLDSA_L].vec[(i + 2) % MLDSA_L]);
118
+ mld_poly_permute_bitrev_to_custom_optional(
119
+ &mat->vec[(i + 3) / MLDSA_L].vec[(i + 3) % MLDSA_L]);
120
+ }
121
+ #else /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
122
+ i = 0;
123
+ #endif /* MLD_CONFIG_SERIAL_FIPS202_ONLY */
124
+
125
+ /* Entries omitted by the batch-sampling are sampled individually. */
126
+ while (i < MLDSA_K * MLDSA_L)
127
+ __loop__(
128
+ assigns(i, object_whole(seed_ext), memory_slice(mat, sizeof(mld_polymat_eager)))
129
+ invariant(i <= MLDSA_K * MLDSA_L)
130
+ /* vectors 0 .. i / MLDSA_L are completely sampled */
131
+ invariant(forall(k1, 0, i / MLDSA_L, forall(l1, 0, MLDSA_L,
132
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
133
+ /* last vector is sampled up to i % MLDSA_L */
134
+ invariant(forall(k2, i / MLDSA_L, i / MLDSA_L + 1, forall(l2, 0, i % MLDSA_L,
135
+ array_bound(mat->vec[k2].vec[l2].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
136
+ decreases(MLDSA_K * MLDSA_L - i)
137
+ )
138
+ {
139
+ uint8_t x = (uint8_t)(i / MLDSA_L);
140
+ uint8_t y = (uint8_t)(i % MLDSA_L);
141
+ mld_polymat_expand_entry(&mat->vec[x].vec[y], seed_ext[0], y, x);
142
+ i++;
143
+ }
144
+
145
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
146
+ mld_zeroize(seed_ext, sizeof(seed_ext));
147
+ }
148
+
149
+ MLD_INTERNAL_API
150
+ void mld_polyvec_matrix_pointwise_montgomery_row_eager(mld_poly *t_row,
151
+ mld_polymat_eager *mat,
152
+ const mld_polyvecl *v,
153
+ unsigned int i)
154
+ {
155
+ mld_polyvecl_pointwise_acc_montgomery(t_row, &mat->vec[i], v);
156
+ }
157
+
158
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
159
+ MLD_INTERNAL_API
160
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_eager(mld_polyveck *w,
161
+ mld_polymat_eager *mat,
162
+ const mld_yvec_eager *y,
163
+ mld_polyvecl *scratch)
164
+ {
165
+ unsigned int i;
166
+ *scratch = y->vec;
167
+ mld_polyvecl_ntt(scratch);
168
+
169
+ for (i = 0; i < MLDSA_K; ++i)
170
+ __loop__(
171
+ assigns(i, memory_slice(w, sizeof(mld_polyveck)))
172
+ invariant(i <= MLDSA_K)
173
+ invariant(forall(k0, 0, i,
174
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLDSA_Q)))
175
+ decreases(MLDSA_K - i)
176
+ )
177
+ {
178
+ mld_polyvec_matrix_pointwise_montgomery_row_eager(&w->vec[i], mat, scratch,
179
+ i);
180
+ }
181
+
182
+ mld_polyveck_invntt_tomont(w);
183
+ }
184
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
185
+
186
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
187
+
188
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
189
+
190
+ MLD_INTERNAL_API
191
+ void mld_polyvec_matrix_expand_lazy(mld_polymat_lazy *mat,
192
+ const uint8_t rho[MLDSA_SEEDBYTES])
193
+ {
194
+ mld_memcpy(mat->rho, rho, MLDSA_SEEDBYTES);
195
+ }
196
+
197
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
198
+ MLD_INTERNAL_API
199
+ void mld_polyvec_matrix_pointwise_montgomery_row_lazy(mld_poly *t_row,
200
+ mld_polymat_lazy *mat,
201
+ const mld_polyvecl *v,
202
+ unsigned int i)
203
+ {
204
+ unsigned int l;
205
+ MLD_ALIGN uint8_t seed_ext[MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)];
206
+ mld_memcpy(seed_ext, mat->rho, MLDSA_SEEDBYTES);
207
+
208
+ mld_polymat_expand_entry(t_row, seed_ext, 0, (uint8_t)i);
209
+ mld_poly_pointwise_montgomery(t_row, &v->vec[0]);
210
+
211
+ for (l = 1; l < MLDSA_L; ++l)
212
+ __loop__(
213
+ assigns(l, object_whole(seed_ext),
214
+ memory_slice(t_row, sizeof(mld_poly)),
215
+ memory_slice(mat, sizeof(mld_polymat_lazy)))
216
+ invariant(l >= 1 && l <= MLDSA_L)
217
+ invariant(array_abs_bound(t_row->coeffs, 0, MLDSA_N, l * MLDSA_Q))
218
+ decreases(MLDSA_L - l)
219
+ )
220
+ {
221
+ mld_polymat_expand_entry(&mat->cur, seed_ext, (uint8_t)l, (uint8_t)i);
222
+ mld_poly_pointwise_montgomery(&mat->cur, &v->vec[l]);
223
+ mld_poly_add(t_row, &mat->cur);
224
+ }
225
+ mld_poly_reduce(t_row);
226
+
227
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
228
+ mld_zeroize(seed_ext, sizeof(seed_ext));
229
+ }
230
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_VERIFY_API */
231
+
232
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
233
+ MLD_INTERNAL_API
234
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_lazy(mld_polyveck *w,
235
+ mld_polymat_lazy *mat,
236
+ const mld_yvec_lazy *y,
237
+ mld_polyvecl *scratch)
238
+ {
239
+ unsigned int k, l;
240
+ MLD_ALIGN uint8_t seed_ext[MLD_ALIGN_UP(MLDSA_SEEDBYTES + 2)];
241
+ /* Only the first poly of the polyvecl scratch is used. The polyvecl type
242
+ * matches the eager variant for API uniformity; in REDUCE_RAM mode the
243
+ * polyvecl storage is provided "for free" by the caller's polyveck/polyvecl
244
+ * union. */
245
+ mld_poly *y_ntt = &scratch->vec[0];
246
+
247
+ mld_memcpy(seed_ext, mat->rho, MLDSA_SEEDBYTES);
248
+
249
+ /* Column-by-column: sample y[l], NTT, accumulate column l of A into w. */
250
+ for (l = 0; l < MLDSA_L; l++)
251
+ __loop__(
252
+ assigns(k, l, object_whole(seed_ext),
253
+ memory_slice(w, sizeof(mld_polyveck)),
254
+ memory_slice(mat, sizeof(mld_polymat_lazy)),
255
+ memory_slice(scratch, sizeof(mld_polyvecl)))
256
+ invariant(l <= MLDSA_L)
257
+ invariant(l == 0 ||
258
+ forall(k0, 0, MLDSA_K,
259
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N,
260
+ (int)l * MLDSA_Q)))
261
+ decreases(MLDSA_L - l)
262
+ )
263
+ {
264
+ mld_yvec_get_poly_lazy(y_ntt, y, l);
265
+ mld_poly_ntt(y_ntt);
266
+ for (k = 0; k < MLDSA_K; k++)
267
+ __loop__(
268
+ assigns(k, object_whole(seed_ext),
269
+ memory_slice(w, sizeof(mld_polyveck)),
270
+ memory_slice(mat, sizeof(mld_polymat_lazy)))
271
+ invariant(k <= MLDSA_K)
272
+ invariant(l != 0 ||
273
+ forall(k1, 0, k,
274
+ array_abs_bound(w->vec[k1].coeffs, 0, MLDSA_N, MLDSA_Q)))
275
+ invariant(l == 0 ||
276
+ forall(k2, 0, k,
277
+ array_abs_bound(w->vec[k2].coeffs, 0, MLDSA_N,
278
+ ((int)l + 1) * MLDSA_Q)))
279
+ invariant(l == 0 ||
280
+ forall(k3, k, MLDSA_K,
281
+ array_abs_bound(w->vec[k3].coeffs, 0, MLDSA_N,
282
+ (int)l * MLDSA_Q)))
283
+ decreases(MLDSA_K - k)
284
+ )
285
+ {
286
+ if (l == 0)
287
+ {
288
+ mld_polymat_expand_entry(&w->vec[k], seed_ext, 0, (uint8_t)k);
289
+ mld_poly_pointwise_montgomery(&w->vec[k], y_ntt);
290
+ }
291
+ else
292
+ {
293
+ mld_polymat_expand_entry(&mat->cur, seed_ext, (uint8_t)l, (uint8_t)k);
294
+ mld_poly_pointwise_montgomery(&mat->cur, y_ntt);
295
+ mld_poly_add(&w->vec[k], &mat->cur);
296
+ }
297
+ }
298
+ }
299
+
300
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
301
+ mld_zeroize(seed_ext, sizeof(seed_ext));
302
+ mld_polyveck_reduce(w);
303
+ mld_polyveck_invntt_tomont(w);
304
+ }
305
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
306
+
307
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
308
+
309
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
310
+ * Don't modify by hand -- this is auto-generated by scripts/autogen. */
311
+ #undef mld_polymat_expand_entry