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,653 @@
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
+ /*
16
+ * Eager and lazy variants of polynomial vector types.
17
+ *
18
+ * In eager mode, full vectors are precomputed and stored in memory.
19
+ * In lazy mode, data is stored in packed form and expanded on demand,
20
+ * trading computation for reduced memory usage.
21
+ *
22
+ * MLD_CONFIG_REDUCE_RAM selects which variant is used.
23
+ */
24
+
25
+ #ifndef MLD_POLYVEC_LAZY_H
26
+ #define MLD_POLYVEC_LAZY_H
27
+
28
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API) || \
29
+ !defined(MLD_CONFIG_NO_VERIFY_API)
30
+
31
+ #include "poly.h"
32
+ #include "poly_kl.h"
33
+ #include "polyvec.h"
34
+
35
+ /* Parameter set namespacing */
36
+ #define mld_sk_s1hat_eager MLD_ADD_PARAM_SET(mld_sk_s1hat_eager)
37
+ #define mld_sk_s1hat_lazy MLD_ADD_PARAM_SET(mld_sk_s1hat_lazy)
38
+ #define mld_sk_s1hat MLD_ADD_PARAM_SET(mld_sk_s1hat)
39
+ #define mld_unpack_sk_s1hat_eager MLD_ADD_PARAM_SET(mld_unpack_sk_s1hat_eager)
40
+ #define mld_unpack_sk_s1hat_lazy MLD_ADD_PARAM_SET(mld_unpack_sk_s1hat_lazy)
41
+ #define mld_sk_s1hat_get_poly_eager \
42
+ MLD_ADD_PARAM_SET(mld_sk_s1hat_get_poly_eager)
43
+ #define mld_sk_s1hat_get_poly_lazy MLD_ADD_PARAM_SET(mld_sk_s1hat_get_poly_lazy)
44
+ #define mld_sk_s2hat_eager MLD_ADD_PARAM_SET(mld_sk_s2hat_eager)
45
+ #define mld_sk_s2hat_lazy MLD_ADD_PARAM_SET(mld_sk_s2hat_lazy)
46
+ #define mld_sk_s2hat MLD_ADD_PARAM_SET(mld_sk_s2hat)
47
+ #define mld_unpack_sk_s2hat_eager MLD_ADD_PARAM_SET(mld_unpack_sk_s2hat_eager)
48
+ #define mld_unpack_sk_s2hat_lazy MLD_ADD_PARAM_SET(mld_unpack_sk_s2hat_lazy)
49
+ #define mld_sk_s2hat_get_poly_eager \
50
+ MLD_ADD_PARAM_SET(mld_sk_s2hat_get_poly_eager)
51
+ #define mld_sk_s2hat_get_poly_lazy MLD_ADD_PARAM_SET(mld_sk_s2hat_get_poly_lazy)
52
+ #define mld_sk_t0hat_eager MLD_ADD_PARAM_SET(mld_sk_t0hat_eager)
53
+ #define mld_sk_t0hat_lazy MLD_ADD_PARAM_SET(mld_sk_t0hat_lazy)
54
+ #define mld_sk_t0hat MLD_ADD_PARAM_SET(mld_sk_t0hat)
55
+ #define mld_unpack_sk_t0hat_eager MLD_ADD_PARAM_SET(mld_unpack_sk_t0hat_eager)
56
+ #define mld_unpack_sk_t0hat_lazy MLD_ADD_PARAM_SET(mld_unpack_sk_t0hat_lazy)
57
+ #define mld_sk_t0hat_get_poly_eager \
58
+ MLD_ADD_PARAM_SET(mld_sk_t0hat_get_poly_eager)
59
+ #define mld_sk_t0hat_get_poly_lazy MLD_ADD_PARAM_SET(mld_sk_t0hat_get_poly_lazy)
60
+ #define mld_polymat MLD_ADD_PARAM_SET(mld_polymat)
61
+ #define mld_polymat_eager MLD_ADD_PARAM_SET(mld_polymat_eager)
62
+ #define mld_polymat_lazy MLD_ADD_PARAM_SET(mld_polymat_lazy)
63
+ #define mld_poly_permute_bitrev_to_custom_optional \
64
+ MLD_ADD_PARAM_SET(mld_poly_permute_bitrev_to_custom_optional)
65
+ #define mld_polyvec_matrix_expand_eager \
66
+ MLD_NAMESPACE_KL(polyvec_matrix_expand_eager)
67
+ #define mld_polyvec_matrix_expand_lazy \
68
+ MLD_NAMESPACE_KL(polyvec_matrix_expand_lazy)
69
+ #define mld_polyvec_matrix_pointwise_montgomery \
70
+ MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery)
71
+ #define mld_polyvec_matrix_pointwise_montgomery_row_eager \
72
+ MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_row_eager)
73
+ #define mld_polyvec_matrix_pointwise_montgomery_row_lazy \
74
+ MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_row_lazy)
75
+ #define mld_polyvec_matrix_pointwise_montgomery_yvec_eager \
76
+ MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_yvec_eager)
77
+ #define mld_polyvec_matrix_pointwise_montgomery_yvec_lazy \
78
+ MLD_NAMESPACE_KL(polyvec_matrix_pointwise_montgomery_yvec_lazy)
79
+ #define mld_yvec_eager MLD_ADD_PARAM_SET(mld_yvec_eager)
80
+ #define mld_yvec_lazy MLD_ADD_PARAM_SET(mld_yvec_lazy)
81
+ #define mld_yvec MLD_ADD_PARAM_SET(mld_yvec)
82
+ #define mld_yvec_init_eager MLD_ADD_PARAM_SET(mld_yvec_init_eager)
83
+ #define mld_yvec_init_lazy MLD_ADD_PARAM_SET(mld_yvec_init_lazy)
84
+ #define mld_yvec_get_poly_eager MLD_ADD_PARAM_SET(mld_yvec_get_poly_eager)
85
+ #define mld_yvec_get_poly_lazy MLD_ADD_PARAM_SET(mld_yvec_get_poly_lazy)
86
+ /* End of parameter set namespacing */
87
+
88
+ /** Eager s1hat: precomputed s1 vector in NTT domain. */
89
+ typedef struct
90
+ {
91
+ mld_polyvecl vec; /**< s1 vector in NTT domain. */
92
+ } mld_sk_s1hat_eager;
93
+
94
+ /** Eager s2hat: precomputed s2 vector in NTT domain. */
95
+ typedef struct
96
+ {
97
+ mld_polyveck vec; /**< s2 vector in NTT domain. */
98
+ } mld_sk_s2hat_eager;
99
+
100
+ /** Eager t0hat: precomputed t0 vector in NTT domain. */
101
+ typedef struct
102
+ {
103
+ mld_polyveck vec; /**< t0 vector in NTT domain. */
104
+ } mld_sk_t0hat_eager;
105
+
106
+ /** Lazy s1hat: borrow packed s1, unpack and convert to NTT domain on demand. */
107
+ typedef struct
108
+ {
109
+ const uint8_t *packed; /**< Pointer to packed s1 in the secret key. */
110
+ } mld_sk_s1hat_lazy;
111
+
112
+ /** Lazy s2hat: borrow packed s2, unpack and convert to NTT domain on demand. */
113
+ typedef struct
114
+ {
115
+ const uint8_t *packed; /**< Pointer to packed s2 in the secret key. */
116
+ } mld_sk_s2hat_lazy;
117
+
118
+ /** Lazy t0hat: borrow packed t0, unpack and convert to NTT domain on demand. */
119
+ typedef struct
120
+ {
121
+ const uint8_t *packed; /**< Pointer to packed t0 in the secret key. */
122
+ } mld_sk_t0hat_lazy;
123
+
124
+ /** Eager yvec: precomputed and stored full signing masking vector y. */
125
+ typedef struct
126
+ {
127
+ mld_polyvecl vec; /**< Masking vector y. */
128
+ } mld_yvec_eager;
129
+
130
+ /** Lazy yvec: store seed and nonce, regenerate y[i] on demand. */
131
+ typedef struct
132
+ {
133
+ const uint8_t *rhoprime; /**< Pointer to seed used to derive y. */
134
+ uint16_t nonce; /**< Base nonce; component i uses MLDSA_L*nonce + i. */
135
+ } mld_yvec_lazy;
136
+
137
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API)
138
+ /* s1vec */
139
+
140
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
141
+ static MLD_INLINE void mld_unpack_sk_s1hat_eager(
142
+ mld_sk_s1hat_eager *s1,
143
+ const uint8_t packed_s1[MLDSA_L * MLDSA_POLYETA_PACKEDBYTES])
144
+ __contract__(
145
+ requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_eager)))
146
+ requires(memory_no_alias(packed_s1, MLDSA_L * MLDSA_POLYETA_PACKEDBYTES))
147
+ assigns(memory_slice(s1, sizeof(mld_sk_s1hat_eager)))
148
+ ensures(forall(k1, 0, MLDSA_L,
149
+ array_abs_bound(s1->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
150
+ )
151
+ {
152
+ mld_polyvecl_unpack_eta(&s1->vec, packed_s1);
153
+ mld_polyvecl_ntt(&s1->vec);
154
+ }
155
+
156
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
157
+ static MLD_INLINE void mld_sk_s1hat_get_poly_eager(mld_poly *buf,
158
+ const mld_sk_s1hat_eager *s1,
159
+ unsigned int i)
160
+ __contract__(
161
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
162
+ requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_eager)))
163
+ requires(i < MLDSA_L)
164
+ requires(array_abs_bound(s1->vec.vec[i].coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
165
+ assigns(memory_slice(buf, sizeof(mld_poly)))
166
+ ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
167
+ ) { *buf = s1->vec.vec[i]; }
168
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
169
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
170
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
171
+ static MLD_INLINE void mld_unpack_sk_s1hat_lazy(
172
+ mld_sk_s1hat_lazy *s1,
173
+ const uint8_t packed_s1[MLDSA_L * MLDSA_POLYETA_PACKEDBYTES])
174
+ __contract__(
175
+ requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_lazy)))
176
+ assigns(memory_slice(s1, sizeof(mld_sk_s1hat_lazy)))
177
+ ensures(s1->packed == old(packed_s1))
178
+ ) { s1->packed = packed_s1; }
179
+
180
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
181
+ static MLD_INLINE void mld_sk_s1hat_get_poly_lazy(mld_poly *buf,
182
+ const mld_sk_s1hat_lazy *s1,
183
+ unsigned int i)
184
+ __contract__(
185
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
186
+ requires(memory_no_alias(s1, sizeof(mld_sk_s1hat_lazy)))
187
+ requires(i < MLDSA_L)
188
+ requires(memory_no_alias(s1->packed, MLDSA_L * MLDSA_POLYETA_PACKEDBYTES))
189
+ assigns(memory_slice(buf, sizeof(mld_poly)))
190
+ ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
191
+ )
192
+ {
193
+ mld_polyeta_unpack(buf, s1->packed + i * MLDSA_POLYETA_PACKEDBYTES);
194
+ mld_poly_ntt(buf);
195
+ }
196
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
197
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
198
+
199
+ /* s2vec */
200
+
201
+ #if (!defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)) && \
202
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
203
+ static MLD_INLINE void mld_unpack_sk_s2hat_eager(
204
+ mld_sk_s2hat_eager *s2,
205
+ const uint8_t packed_s2[MLDSA_K * MLDSA_POLYETA_PACKEDBYTES])
206
+ __contract__(
207
+ requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_eager)))
208
+ requires(memory_no_alias(packed_s2, MLDSA_K * MLDSA_POLYETA_PACKEDBYTES))
209
+ assigns(memory_slice(s2, sizeof(mld_sk_s2hat_eager)))
210
+ ensures(forall(k1, 0, MLDSA_K,
211
+ array_abs_bound(s2->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
212
+ )
213
+ {
214
+ mld_polyveck_unpack_eta(&s2->vec, packed_s2);
215
+ mld_polyveck_ntt(&s2->vec);
216
+ }
217
+
218
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
219
+ static MLD_INLINE void mld_sk_s2hat_get_poly_eager(mld_poly *buf,
220
+ const mld_sk_s2hat_eager *s2,
221
+ unsigned int i)
222
+ __contract__(
223
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
224
+ requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_eager)))
225
+ requires(i < MLDSA_K)
226
+ requires(array_abs_bound(s2->vec.vec[i].coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
227
+ assigns(memory_slice(buf, sizeof(mld_poly)))
228
+ ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
229
+ ) { *buf = s2->vec.vec[i]; }
230
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
231
+ #endif /* (!MLD_CONFIG_NO_SIGN_API || MLD_UNIT_TEST) && \
232
+ (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) */
233
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
234
+ static MLD_INLINE void mld_unpack_sk_s2hat_lazy(
235
+ mld_sk_s2hat_lazy *s2,
236
+ const uint8_t packed_s2[MLDSA_K * MLDSA_POLYETA_PACKEDBYTES])
237
+ __contract__(
238
+ requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_lazy)))
239
+ assigns(memory_slice(s2, sizeof(mld_sk_s2hat_lazy)))
240
+ ensures(s2->packed == old(packed_s2))
241
+ ) { s2->packed = packed_s2; }
242
+
243
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
244
+ static MLD_INLINE void mld_sk_s2hat_get_poly_lazy(mld_poly *buf,
245
+ const mld_sk_s2hat_lazy *s2,
246
+ unsigned int i)
247
+ __contract__(
248
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
249
+ requires(memory_no_alias(s2, sizeof(mld_sk_s2hat_lazy)))
250
+ requires(i < MLDSA_K)
251
+ requires(memory_no_alias(s2->packed, MLDSA_K * MLDSA_POLYETA_PACKEDBYTES))
252
+ assigns(memory_slice(buf, sizeof(mld_poly)))
253
+ ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
254
+ )
255
+ {
256
+ mld_polyeta_unpack(buf, s2->packed + i * MLDSA_POLYETA_PACKEDBYTES);
257
+ mld_poly_ntt(buf);
258
+ }
259
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
260
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
261
+
262
+ /* t0vec */
263
+
264
+ #if (!defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)) && \
265
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
266
+ static MLD_INLINE void mld_unpack_sk_t0hat_eager(
267
+ mld_sk_t0hat_eager *t0,
268
+ const uint8_t packed_t0[MLDSA_K * MLDSA_POLYT0_PACKEDBYTES])
269
+ __contract__(
270
+ requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_eager)))
271
+ requires(memory_no_alias(packed_t0, MLDSA_K * MLDSA_POLYT0_PACKEDBYTES))
272
+ assigns(memory_slice(t0, sizeof(mld_sk_t0hat_eager)))
273
+ ensures(forall(k1, 0, MLDSA_K,
274
+ array_abs_bound(t0->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
275
+ )
276
+ {
277
+ unsigned int i;
278
+ for (i = 0; i < MLDSA_K; ++i)
279
+ __loop__(
280
+ assigns(i, memory_slice(t0, sizeof(mld_sk_t0hat_eager)))
281
+ invariant(i <= MLDSA_K)
282
+ invariant(forall(k0, 0, i,
283
+ array_bound(t0->vec.vec[k0].coeffs, 0, MLDSA_N,
284
+ -(1 << (MLDSA_D - 1)) + 1, (1 << (MLDSA_D - 1)) + 1)))
285
+ decreases(MLDSA_K - i)
286
+ )
287
+ {
288
+ mld_polyt0_unpack(&t0->vec.vec[i],
289
+ packed_t0 + i * MLDSA_POLYT0_PACKEDBYTES);
290
+ }
291
+ mld_polyveck_ntt(&t0->vec);
292
+ }
293
+
294
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
295
+ static MLD_INLINE void mld_sk_t0hat_get_poly_eager(mld_poly *buf,
296
+ const mld_sk_t0hat_eager *t0,
297
+ unsigned int i)
298
+ __contract__(
299
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
300
+ requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_eager)))
301
+ requires(i < MLDSA_K)
302
+ requires(array_abs_bound(t0->vec.vec[i].coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
303
+ assigns(memory_slice(buf, sizeof(mld_poly)))
304
+ ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
305
+ ) { *buf = t0->vec.vec[i]; }
306
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
307
+ #endif /* (!MLD_CONFIG_NO_SIGN_API || MLD_UNIT_TEST) && \
308
+ (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) */
309
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
310
+ static MLD_INLINE void mld_unpack_sk_t0hat_lazy(
311
+ mld_sk_t0hat_lazy *t0,
312
+ const uint8_t packed_t0[MLDSA_K * MLDSA_POLYT0_PACKEDBYTES])
313
+ __contract__(
314
+ requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_lazy)))
315
+ assigns(memory_slice(t0, sizeof(mld_sk_t0hat_lazy)))
316
+ ensures(t0->packed == old(packed_t0))
317
+ ) { t0->packed = packed_t0; }
318
+
319
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
320
+ static MLD_INLINE void mld_sk_t0hat_get_poly_lazy(mld_poly *buf,
321
+ const mld_sk_t0hat_lazy *t0,
322
+ unsigned int i)
323
+ __contract__(
324
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
325
+ requires(memory_no_alias(t0, sizeof(mld_sk_t0hat_lazy)))
326
+ requires(i < MLDSA_K)
327
+ requires(memory_no_alias(t0->packed, MLDSA_K * MLDSA_POLYT0_PACKEDBYTES))
328
+ assigns(memory_slice(buf, sizeof(mld_poly)))
329
+ ensures(array_abs_bound(buf->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
330
+ )
331
+ {
332
+ mld_polyt0_unpack(buf, t0->packed + i * MLDSA_POLYT0_PACKEDBYTES);
333
+ mld_poly_ntt(buf);
334
+ }
335
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
336
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
337
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_SIGN_API */
338
+
339
+ /* yvec */
340
+
341
+ #if !defined(MLD_CONFIG_NO_SIGN_API) && \
342
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
343
+ static MLD_INLINE void mld_yvec_init_eager(
344
+ mld_yvec_eager *y, const uint8_t rhoprime[MLDSA_CRHBYTES], uint16_t nonce)
345
+ __contract__(
346
+ requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
347
+ requires(memory_no_alias(rhoprime, MLDSA_CRHBYTES))
348
+ requires(nonce <= (UINT16_MAX - MLDSA_L) / MLDSA_L)
349
+ assigns(memory_slice(y, sizeof(mld_yvec_eager)))
350
+ ensures(forall(k1, 0, MLDSA_L,
351
+ array_bound(y->vec.vec[k1].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
352
+ )
353
+ {
354
+ mld_polyvecl_uniform_gamma1(&y->vec, rhoprime, nonce);
355
+ }
356
+
357
+ static MLD_INLINE void mld_yvec_get_poly_eager(mld_poly *buf,
358
+ const mld_yvec_eager *y,
359
+ unsigned int i)
360
+ __contract__(
361
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
362
+ requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
363
+ requires(i < MLDSA_L)
364
+ requires(array_bound(y->vec.vec[i].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
365
+ assigns(memory_slice(buf, sizeof(mld_poly)))
366
+ ensures(array_bound(buf->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
367
+ ) { *buf = y->vec.vec[i]; }
368
+ #endif /* !MLD_CONFIG_NO_SIGN_API && (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) \
369
+ */
370
+ #if !defined(MLD_CONFIG_NO_SIGN_API) && \
371
+ (defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
372
+ static MLD_INLINE void mld_yvec_init_lazy(
373
+ mld_yvec_lazy *y, const uint8_t rhoprime[MLDSA_CRHBYTES], uint16_t nonce)
374
+ __contract__(
375
+ requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
376
+ assigns(memory_slice(y, sizeof(mld_yvec_lazy)))
377
+ ensures(y->rhoprime == old(rhoprime))
378
+ ensures(y->nonce == old(nonce))
379
+ )
380
+ {
381
+ y->rhoprime = rhoprime;
382
+ y->nonce = nonce;
383
+ }
384
+
385
+ static MLD_INLINE void mld_yvec_get_poly_lazy(mld_poly *buf,
386
+ const mld_yvec_lazy *y,
387
+ unsigned int i)
388
+ __contract__(
389
+ requires(memory_no_alias(buf, sizeof(mld_poly)))
390
+ requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
391
+ requires(i < MLDSA_L)
392
+ requires(memory_no_alias(y->rhoprime, MLDSA_CRHBYTES))
393
+ requires(y->nonce <= ((UINT16_MAX - MLDSA_L) / MLDSA_L))
394
+ assigns(memory_slice(buf, sizeof(mld_poly)))
395
+ ensures(array_bound(buf->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
396
+ )
397
+ {
398
+ /* Safety: y->nonce is at most ((UINT16_MAX - MLDSA_L) / MLDSA_L) and
399
+ * i < MLDSA_L, so MLDSA_L * y->nonce + i fits in uint16_t. See
400
+ * MLD_NONCE_UB comment in sign.c. */
401
+ mld_poly_uniform_gamma1(buf, y->rhoprime,
402
+ (uint16_t)(MLDSA_L * y->nonce + (int)i));
403
+ }
404
+ #endif /* !MLD_CONFIG_NO_SIGN_API && (MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) \
405
+ */
406
+
407
+ /* polymat */
408
+
409
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
410
+ /** Eager polymat: precomputed and stored full MLDSA_K x MLDSA_L matrix. */
411
+ typedef struct
412
+ {
413
+ mld_polyvecl vec[MLDSA_K]; /**< Rows of the matrix. */
414
+ } mld_polymat_eager;
415
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
416
+
417
+ /** Lazy polymat: store seed, sample elements A[k][l] on demand. */
418
+ typedef struct
419
+ {
420
+ mld_poly cur; /**< On-demand sampled matrix element A[k][l]. */
421
+ uint8_t rho[MLDSA_SEEDBYTES]; /**< Public seed used to expand A. */
422
+ } mld_polymat_lazy;
423
+
424
+ static MLD_INLINE void mld_poly_permute_bitrev_to_custom_optional(mld_poly *p)
425
+ __contract__(
426
+ /* We don't specify that this is a permutation, only that it preserves
427
+ * the bounds.
428
+ * When the native NTT backend does not use the custom order, this is a no-op. */
429
+ requires(memory_no_alias(p, sizeof(mld_poly)))
430
+ requires(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
431
+ assigns(memory_slice(p, sizeof(mld_poly)))
432
+ ensures(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
433
+ )
434
+ {
435
+ #if defined(MLD_USE_NATIVE_NTT_CUSTOM_ORDER)
436
+ mld_poly_permute_bitrev_to_custom(p->coeffs);
437
+ #else
438
+ (void)p;
439
+ #endif
440
+ }
441
+
442
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
443
+ /**
444
+ * Implementation of ExpandA. Generates matrix A with uniformly random
445
+ * coefficients a_{i,j} by performing rejection sampling on the output stream
446
+ * of SHAKE128(rho|j|i).
447
+ *
448
+ * @param[out] mat Pointer to output matrix.
449
+ * @param[in] rho Byte array containing seed rho.
450
+ */
451
+ MLD_INTERNAL_API
452
+ void mld_polyvec_matrix_expand_eager(mld_polymat_eager *mat,
453
+ const uint8_t rho[MLDSA_SEEDBYTES])
454
+ __contract__(
455
+ requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
456
+ requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
457
+ assigns(memory_slice(mat, sizeof(mld_polymat_eager)))
458
+ ensures(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
459
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
460
+ );
461
+
462
+ /**
463
+ * Compute row i of matrix-vector multiplication in NTT domain with pointwise
464
+ * multiplication and multiplication by 2^{-32}.
465
+ *
466
+ * Input matrix and vector must be in NTT domain representation. Output
467
+ * coefficients are bounded by MLDSA_Q in absolute value.
468
+ *
469
+ * @param[out] t_row Pointer to output row polynomial.
470
+ * @param[in] mat Pointer to input matrix.
471
+ * @param[in] v Pointer to input vector v.
472
+ * @param i Row index, 0 <= i < MLDSA_K.
473
+ */
474
+ MLD_INTERNAL_API
475
+ void mld_polyvec_matrix_pointwise_montgomery_row_eager(mld_poly *t_row,
476
+ mld_polymat_eager *mat,
477
+ const mld_polyvecl *v,
478
+ unsigned int i)
479
+ __contract__(
480
+ requires(memory_no_alias(t_row, sizeof(mld_poly)))
481
+ requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
482
+ requires(memory_no_alias(v, sizeof(mld_polyvecl)))
483
+ requires(i < MLDSA_K)
484
+ requires(forall(l1, 0, MLDSA_L,
485
+ array_bound(mat->vec[i].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
486
+ requires(forall(l2, 0, MLDSA_L,
487
+ array_abs_bound(v->vec[l2].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
488
+ assigns(memory_slice(t_row, sizeof(mld_poly)))
489
+ ensures(array_abs_bound(t_row->coeffs, 0, MLDSA_N, MLDSA_Q))
490
+ );
491
+
492
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
493
+ /**
494
+ * Compute w = invNTT(A * NTT(y)) for the signing y vector.
495
+ *
496
+ * The eager variant copies y into the scratch polyvecl, NTTs it in place,
497
+ * calls the standard matrix-vector multiply, and finally inverse-NTTs the
498
+ * result into w.
499
+ *
500
+ * @param[out] w Pointer to output vector.
501
+ * @param[in] mat Pointer to input matrix.
502
+ * @param[in] y Pointer to (non-NTT) y vector.
503
+ * @param[out] scratch Scratch polyvecl for NTT'd copy of y.
504
+ */
505
+ MLD_INTERNAL_API
506
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_eager(mld_polyveck *w,
507
+ mld_polymat_eager *mat,
508
+ const mld_yvec_eager *y,
509
+ mld_polyvecl *scratch)
510
+ __contract__(
511
+ requires(memory_no_alias(w, sizeof(mld_polyveck)))
512
+ requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
513
+ requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
514
+ requires(memory_no_alias(scratch, sizeof(mld_polyvecl)))
515
+ requires(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
516
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
517
+ requires(forall(l2, 0, MLDSA_L,
518
+ array_bound(y->vec.vec[l2].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
519
+ assigns(memory_slice(w, sizeof(mld_polyveck)))
520
+ assigns(memory_slice(scratch, sizeof(mld_polyvecl)))
521
+ ensures(forall(k0, 0, MLDSA_K,
522
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
523
+ );
524
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
525
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
526
+
527
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
528
+ MLD_INTERNAL_API
529
+ void mld_polyvec_matrix_expand_lazy(mld_polymat_lazy *mat,
530
+ const uint8_t rho[MLDSA_SEEDBYTES])
531
+ __contract__(
532
+ requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
533
+ requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
534
+ assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
535
+ );
536
+
537
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
538
+ /**
539
+ * Compute row i of matrix-vector multiplication in NTT domain with pointwise
540
+ * multiplication and multiplication by 2^{-32}.
541
+ *
542
+ * Input vector must be in NTT domain representation; the matrix entries are
543
+ * sampled on demand from the seed stored in mat->rho, using mat->cur as
544
+ * scratch. Output coefficients are bounded by MLDSA_Q in absolute value.
545
+ *
546
+ * @param[out] t_row Pointer to output row polynomial.
547
+ * @param[in,out] mat Pointer to input matrix (seed + scratch).
548
+ * @param[in] v Pointer to input vector v.
549
+ * @param i Row index, 0 <= i < MLDSA_K.
550
+ */
551
+ MLD_INTERNAL_API
552
+ void mld_polyvec_matrix_pointwise_montgomery_row_lazy(mld_poly *t_row,
553
+ mld_polymat_lazy *mat,
554
+ const mld_polyvecl *v,
555
+ unsigned int i)
556
+ __contract__(
557
+ requires(memory_no_alias(t_row, sizeof(mld_poly)))
558
+ requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
559
+ requires(memory_no_alias(v, sizeof(mld_polyvecl)))
560
+ requires(i < MLDSA_K)
561
+ requires(forall(l1, 0, MLDSA_L,
562
+ array_abs_bound(v->vec[l1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
563
+ assigns(memory_slice(t_row, sizeof(mld_poly)))
564
+ assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
565
+ ensures(array_abs_bound(t_row->coeffs, 0, MLDSA_N, MLDSA_Q))
566
+ );
567
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_VERIFY_API */
568
+
569
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
570
+ /**
571
+ * Compute w = invNTT(A * NTT(y)) for the signing y vector.
572
+ *
573
+ * The lazy variant samples one column of y at a time, NTTs it into
574
+ * &scratch->vec[0], and accumulates the matrix-vector product
575
+ * column-by-column with on-demand sampling of A[k][l]. Only the first poly of
576
+ * the polyvecl scratch is used; the polyvecl type is shared with the eager
577
+ * variant for API uniformity (the storage is provided "for free" by the
578
+ * caller's polyveck/polyvecl union in REDUCE_RAM mode).
579
+ *
580
+ * @param[out] w Pointer to output vector.
581
+ * @param[in,out] mat Pointer to input matrix.
582
+ * @param[in] y Pointer to y seed/nonce.
583
+ * @param[out] scratch Scratch (only &scratch->vec[0] used).
584
+ */
585
+ MLD_INTERNAL_API
586
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_lazy(mld_polyveck *w,
587
+ mld_polymat_lazy *mat,
588
+ const mld_yvec_lazy *y,
589
+ mld_polyvecl *scratch)
590
+ __contract__(
591
+ requires(memory_no_alias(w, sizeof(mld_polyveck)))
592
+ requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
593
+ requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
594
+ requires(memory_no_alias(scratch, sizeof(mld_polyvecl)))
595
+ requires(memory_no_alias(y->rhoprime, MLDSA_CRHBYTES))
596
+ requires(y->nonce <= ((UINT16_MAX - MLDSA_L) / MLDSA_L))
597
+ assigns(memory_slice(w, sizeof(mld_polyveck)))
598
+ assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
599
+ assigns(memory_slice(scratch, sizeof(mld_polyvecl)))
600
+ ensures(forall(k0, 0, MLDSA_K,
601
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
602
+ );
603
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
604
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
605
+
606
+ /* Dispatch: typedef and define based on MLD_CONFIG_REDUCE_RAM */
607
+ #if defined(MLD_CONFIG_REDUCE_RAM)
608
+ typedef mld_sk_s1hat_lazy mld_sk_s1hat;
609
+ typedef mld_sk_s2hat_lazy mld_sk_s2hat;
610
+ typedef mld_sk_t0hat_lazy mld_sk_t0hat;
611
+ typedef mld_polymat_lazy mld_polymat;
612
+ typedef mld_yvec_lazy mld_yvec;
613
+ #define mld_unpack_sk_s1hat mld_unpack_sk_s1hat_lazy
614
+ #define mld_unpack_sk_s2hat mld_unpack_sk_s2hat_lazy
615
+ #define mld_unpack_sk_t0hat mld_unpack_sk_t0hat_lazy
616
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
617
+ #define mld_sk_s1hat_get_poly mld_sk_s1hat_get_poly_lazy
618
+ #define mld_sk_s2hat_get_poly mld_sk_s2hat_get_poly_lazy
619
+ #define mld_sk_t0hat_get_poly mld_sk_t0hat_get_poly_lazy
620
+ #endif
621
+ #define mld_polyvec_matrix_expand mld_polyvec_matrix_expand_lazy
622
+ #define mld_polyvec_matrix_pointwise_montgomery_row \
623
+ mld_polyvec_matrix_pointwise_montgomery_row_lazy
624
+ #define mld_yvec_init mld_yvec_init_lazy
625
+ #define mld_yvec_get_poly mld_yvec_get_poly_lazy
626
+ #define mld_polyvec_matrix_pointwise_montgomery_yvec \
627
+ mld_polyvec_matrix_pointwise_montgomery_yvec_lazy
628
+ #else /* MLD_CONFIG_REDUCE_RAM */
629
+ typedef mld_sk_s1hat_eager mld_sk_s1hat;
630
+ typedef mld_sk_s2hat_eager mld_sk_s2hat;
631
+ typedef mld_sk_t0hat_eager mld_sk_t0hat;
632
+ typedef mld_polymat_eager mld_polymat;
633
+ typedef mld_yvec_eager mld_yvec;
634
+ #define mld_unpack_sk_s1hat mld_unpack_sk_s1hat_eager
635
+ #define mld_unpack_sk_s2hat mld_unpack_sk_s2hat_eager
636
+ #define mld_unpack_sk_t0hat mld_unpack_sk_t0hat_eager
637
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
638
+ #define mld_sk_s2hat_get_poly mld_sk_s2hat_get_poly_eager
639
+ #define mld_sk_s1hat_get_poly mld_sk_s1hat_get_poly_eager
640
+ #define mld_sk_t0hat_get_poly mld_sk_t0hat_get_poly_eager
641
+ #endif
642
+ #define mld_polyvec_matrix_expand mld_polyvec_matrix_expand_eager
643
+ #define mld_polyvec_matrix_pointwise_montgomery_row \
644
+ mld_polyvec_matrix_pointwise_montgomery_row_eager
645
+ #define mld_yvec_init mld_yvec_init_eager
646
+ #define mld_yvec_get_poly mld_yvec_get_poly_eager
647
+ #define mld_polyvec_matrix_pointwise_montgomery_yvec \
648
+ mld_polyvec_matrix_pointwise_montgomery_yvec_eager
649
+ #endif /* !MLD_CONFIG_REDUCE_RAM */
650
+
651
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_SIGN_API || \
652
+ !MLD_CONFIG_NO_VERIFY_API */
653
+ #endif /* !MLD_POLYVEC_LAZY_H */