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,652 @@
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 base counter kappa, regenerate y[i] on demand. */
131
+ typedef struct
132
+ {
133
+ const uint8_t *rhoprime; /**< Pointer to seed used to derive y. */
134
+ uint16_t kappa; /**< Base counter; component i uses kappa + 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 kappa)
345
+ __contract__(
346
+ requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
347
+ requires(memory_no_alias(rhoprime, MLDSA_CRHBYTES))
348
+ requires(kappa <= MLD_MAX_KAPPA)
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, kappa);
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 kappa)
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->kappa == old(kappa))
379
+ )
380
+ {
381
+ y->rhoprime = rhoprime;
382
+ y->kappa = kappa;
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->kappa <= MLD_MAX_KAPPA)
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->kappa <= MLD_MAX_KAPPA and i < MLDSA_L, so y->kappa + i
399
+ * fits in uint16_t. See MLD_MAX_KAPPA comment in params.h. */
400
+ mld_poly_uniform_gamma1(buf, y->rhoprime, (uint16_t)(y->kappa + i));
401
+ }
402
+ #endif /* !MLD_CONFIG_NO_SIGN_API && (MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) \
403
+ */
404
+
405
+ /* polymat */
406
+
407
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
408
+ /** Eager polymat: precomputed and stored full MLDSA_K x MLDSA_L matrix. */
409
+ typedef struct
410
+ {
411
+ mld_polyvecl vec[MLDSA_K]; /**< Rows of the matrix. */
412
+ } mld_polymat_eager;
413
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
414
+
415
+ /** Lazy polymat: store seed, sample elements A[k][l] on demand. */
416
+ typedef struct
417
+ {
418
+ mld_poly cur; /**< On-demand sampled matrix element A[k][l]. */
419
+ uint8_t rho[MLDSA_SEEDBYTES]; /**< Public seed used to expand A. */
420
+ } mld_polymat_lazy;
421
+
422
+ static MLD_INLINE void mld_poly_permute_bitrev_to_custom_optional(mld_poly *p)
423
+ __contract__(
424
+ /* We don't specify that this is a permutation, only that it preserves
425
+ * the bounds.
426
+ * When the native NTT backend does not use the custom order, this is a no-op. */
427
+ requires(memory_no_alias(p, sizeof(mld_poly)))
428
+ requires(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
429
+ assigns(memory_slice(p, sizeof(mld_poly)))
430
+ ensures(array_bound(p->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
431
+ )
432
+ {
433
+ #if defined(MLD_USE_NATIVE_NTT_CUSTOM_ORDER)
434
+ mld_poly_permute_bitrev_to_custom(p->coeffs);
435
+ #else
436
+ (void)p;
437
+ #endif
438
+ }
439
+
440
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
441
+ /**
442
+ * Generates matrix A with uniformly random coefficients a_{i,j} by performing
443
+ * rejection sampling on the output stream of SHAKE128(rho|j|i).
444
+ *
445
+ * @spec{Implements @[FIPS204, Algorithm 32, ExpandA].}
446
+ *
447
+ * @param[out] mat Pointer to output matrix.
448
+ * @param[in] rho Byte array containing seed rho.
449
+ */
450
+ MLD_INTERNAL_API
451
+ void mld_polyvec_matrix_expand_eager(mld_polymat_eager *mat,
452
+ const uint8_t rho[MLDSA_SEEDBYTES])
453
+ __contract__(
454
+ requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
455
+ requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
456
+ assigns(memory_slice(mat, sizeof(mld_polymat_eager)))
457
+ ensures(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
458
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
459
+ );
460
+
461
+ /**
462
+ * Compute row i of matrix-vector multiplication in NTT domain with pointwise
463
+ * multiplication and multiplication by 2^{-32}.
464
+ *
465
+ * Input matrix and vector must be in NTT domain representation. Output
466
+ * coefficients are bounded by MLDSA_Q in absolute value.
467
+ *
468
+ * @param[out] t_row Pointer to output row polynomial.
469
+ * @param[in] mat Pointer to input matrix.
470
+ * @param[in] v Pointer to input vector v.
471
+ * @param i Row index, 0 <= i < MLDSA_K.
472
+ */
473
+ MLD_INTERNAL_API
474
+ void mld_polyvec_matrix_pointwise_montgomery_row_eager(mld_poly *t_row,
475
+ mld_polymat_eager *mat,
476
+ const mld_polyvecl *v,
477
+ unsigned int i)
478
+ __contract__(
479
+ requires(memory_no_alias(t_row, sizeof(mld_poly)))
480
+ requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
481
+ requires(memory_no_alias(v, sizeof(mld_polyvecl)))
482
+ requires(i < MLDSA_K)
483
+ requires(forall(l1, 0, MLDSA_L,
484
+ array_bound(mat->vec[i].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
485
+ requires(forall(l2, 0, MLDSA_L,
486
+ array_abs_bound(v->vec[l2].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
487
+ assigns(memory_slice(t_row, sizeof(mld_poly)))
488
+ ensures(array_abs_bound(t_row->coeffs, 0, MLDSA_N, MLDSA_Q))
489
+ );
490
+
491
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
492
+ /**
493
+ * Compute w = invNTT(A * NTT(y)) for the signing y vector.
494
+ *
495
+ * The eager variant copies y into the scratch polyvecl, NTTs it in place,
496
+ * calls the standard matrix-vector multiply, and finally inverse-NTTs the
497
+ * result into w.
498
+ *
499
+ * @param[out] w Pointer to output vector.
500
+ * @param[in] mat Pointer to input matrix.
501
+ * @param[in] y Pointer to (non-NTT) y vector.
502
+ * @param[out] scratch Scratch polyvecl for NTT'd copy of y.
503
+ */
504
+ MLD_INTERNAL_API
505
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_eager(mld_polyveck *w,
506
+ mld_polymat_eager *mat,
507
+ const mld_yvec_eager *y,
508
+ mld_polyvecl *scratch)
509
+ __contract__(
510
+ requires(memory_no_alias(w, sizeof(mld_polyveck)))
511
+ requires(memory_no_alias(mat, sizeof(mld_polymat_eager)))
512
+ requires(memory_no_alias(y, sizeof(mld_yvec_eager)))
513
+ requires(memory_no_alias(scratch, sizeof(mld_polyvecl)))
514
+ requires(forall(k1, 0, MLDSA_K, forall(l1, 0, MLDSA_L,
515
+ array_bound(mat->vec[k1].vec[l1].coeffs, 0, MLDSA_N, 0, MLDSA_Q))))
516
+ requires(forall(l2, 0, MLDSA_L,
517
+ array_bound(y->vec.vec[l2].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
518
+ assigns(memory_slice(w, sizeof(mld_polyveck)))
519
+ assigns(memory_slice(scratch, sizeof(mld_polyvecl)))
520
+ ensures(forall(k0, 0, MLDSA_K,
521
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
522
+ );
523
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
524
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
525
+
526
+ #if defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
527
+ MLD_INTERNAL_API
528
+ void mld_polyvec_matrix_expand_lazy(mld_polymat_lazy *mat,
529
+ const uint8_t rho[MLDSA_SEEDBYTES])
530
+ __contract__(
531
+ requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
532
+ requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
533
+ assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
534
+ );
535
+
536
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
537
+ /**
538
+ * Compute row i of matrix-vector multiplication in NTT domain with pointwise
539
+ * multiplication and multiplication by 2^{-32}.
540
+ *
541
+ * Input vector must be in NTT domain representation; the matrix entries are
542
+ * sampled on demand from the seed stored in mat->rho, using mat->cur as
543
+ * scratch. Output coefficients are bounded by MLDSA_Q in absolute value.
544
+ *
545
+ * @param[out] t_row Pointer to output row polynomial.
546
+ * @param[in,out] mat Pointer to input matrix (seed + scratch).
547
+ * @param[in] v Pointer to input vector v.
548
+ * @param i Row index, 0 <= i < MLDSA_K.
549
+ */
550
+ MLD_INTERNAL_API
551
+ void mld_polyvec_matrix_pointwise_montgomery_row_lazy(mld_poly *t_row,
552
+ mld_polymat_lazy *mat,
553
+ const mld_polyvecl *v,
554
+ unsigned int i)
555
+ __contract__(
556
+ requires(memory_no_alias(t_row, sizeof(mld_poly)))
557
+ requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
558
+ requires(memory_no_alias(v, sizeof(mld_polyvecl)))
559
+ requires(i < MLDSA_K)
560
+ requires(forall(l1, 0, MLDSA_L,
561
+ array_abs_bound(v->vec[l1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
562
+ assigns(memory_slice(t_row, sizeof(mld_poly)))
563
+ assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
564
+ ensures(array_abs_bound(t_row->coeffs, 0, MLDSA_N, MLDSA_Q))
565
+ );
566
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_VERIFY_API */
567
+
568
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
569
+ /**
570
+ * Compute w = invNTT(A * NTT(y)) for the signing y vector.
571
+ *
572
+ * The lazy variant samples one column of y at a time, NTTs it into
573
+ * &scratch->vec[0], and accumulates the matrix-vector product
574
+ * column-by-column with on-demand sampling of A[k][l]. Only the first poly of
575
+ * the polyvecl scratch is used; the polyvecl type is shared with the eager
576
+ * variant for API uniformity (the storage is provided "for free" by the
577
+ * caller's polyveck/polyvecl union in REDUCE_RAM mode).
578
+ *
579
+ * @param[out] w Pointer to output vector.
580
+ * @param[in,out] mat Pointer to input matrix.
581
+ * @param[in] y Pointer to y seed/kappa.
582
+ * @param[out] scratch Scratch (only &scratch->vec[0] used).
583
+ */
584
+ MLD_INTERNAL_API
585
+ void mld_polyvec_matrix_pointwise_montgomery_yvec_lazy(mld_polyveck *w,
586
+ mld_polymat_lazy *mat,
587
+ const mld_yvec_lazy *y,
588
+ mld_polyvecl *scratch)
589
+ __contract__(
590
+ requires(memory_no_alias(w, sizeof(mld_polyveck)))
591
+ requires(memory_no_alias(mat, sizeof(mld_polymat_lazy)))
592
+ requires(memory_no_alias(y, sizeof(mld_yvec_lazy)))
593
+ requires(memory_no_alias(scratch, sizeof(mld_polyvecl)))
594
+ requires(memory_no_alias(y->rhoprime, MLDSA_CRHBYTES))
595
+ requires(y->kappa <= MLD_MAX_KAPPA)
596
+ assigns(memory_slice(w, sizeof(mld_polyveck)))
597
+ assigns(memory_slice(mat, sizeof(mld_polymat_lazy)))
598
+ assigns(memory_slice(scratch, sizeof(mld_polyvecl)))
599
+ ensures(forall(k0, 0, MLDSA_K,
600
+ array_abs_bound(w->vec[k0].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
601
+ );
602
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
603
+ #endif /* MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
604
+
605
+ /* Dispatch: typedef and define based on MLD_CONFIG_REDUCE_RAM */
606
+ #if defined(MLD_CONFIG_REDUCE_RAM)
607
+ typedef mld_sk_s1hat_lazy mld_sk_s1hat;
608
+ typedef mld_sk_s2hat_lazy mld_sk_s2hat;
609
+ typedef mld_sk_t0hat_lazy mld_sk_t0hat;
610
+ typedef mld_polymat_lazy mld_polymat;
611
+ typedef mld_yvec_lazy mld_yvec;
612
+ #define mld_unpack_sk_s1hat mld_unpack_sk_s1hat_lazy
613
+ #define mld_unpack_sk_s2hat mld_unpack_sk_s2hat_lazy
614
+ #define mld_unpack_sk_t0hat mld_unpack_sk_t0hat_lazy
615
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
616
+ #define mld_sk_s1hat_get_poly mld_sk_s1hat_get_poly_lazy
617
+ #define mld_sk_s2hat_get_poly mld_sk_s2hat_get_poly_lazy
618
+ #define mld_sk_t0hat_get_poly mld_sk_t0hat_get_poly_lazy
619
+ #endif
620
+ #define mld_polyvec_matrix_expand mld_polyvec_matrix_expand_lazy
621
+ #define mld_polyvec_matrix_pointwise_montgomery_row \
622
+ mld_polyvec_matrix_pointwise_montgomery_row_lazy
623
+ #define mld_yvec_init mld_yvec_init_lazy
624
+ #define mld_yvec_get_poly mld_yvec_get_poly_lazy
625
+ #define mld_polyvec_matrix_pointwise_montgomery_yvec \
626
+ mld_polyvec_matrix_pointwise_montgomery_yvec_lazy
627
+ #else /* MLD_CONFIG_REDUCE_RAM */
628
+ typedef mld_sk_s1hat_eager mld_sk_s1hat;
629
+ typedef mld_sk_s2hat_eager mld_sk_s2hat;
630
+ typedef mld_sk_t0hat_eager mld_sk_t0hat;
631
+ typedef mld_polymat_eager mld_polymat;
632
+ typedef mld_yvec_eager mld_yvec;
633
+ #define mld_unpack_sk_s1hat mld_unpack_sk_s1hat_eager
634
+ #define mld_unpack_sk_s2hat mld_unpack_sk_s2hat_eager
635
+ #define mld_unpack_sk_t0hat mld_unpack_sk_t0hat_eager
636
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
637
+ #define mld_sk_s2hat_get_poly mld_sk_s2hat_get_poly_eager
638
+ #define mld_sk_s1hat_get_poly mld_sk_s1hat_get_poly_eager
639
+ #define mld_sk_t0hat_get_poly mld_sk_t0hat_get_poly_eager
640
+ #endif
641
+ #define mld_polyvec_matrix_expand mld_polyvec_matrix_expand_eager
642
+ #define mld_polyvec_matrix_pointwise_montgomery_row \
643
+ mld_polyvec_matrix_pointwise_montgomery_row_eager
644
+ #define mld_yvec_init mld_yvec_init_eager
645
+ #define mld_yvec_get_poly mld_yvec_get_poly_eager
646
+ #define mld_polyvec_matrix_pointwise_montgomery_yvec \
647
+ mld_polyvec_matrix_pointwise_montgomery_yvec_eager
648
+ #endif /* !MLD_CONFIG_REDUCE_RAM */
649
+
650
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_SIGN_API || \
651
+ !MLD_CONFIG_NO_VERIFY_API */
652
+ #endif /* !MLD_POLYVEC_LAZY_H */
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright (c) The mldsa-native project authors
3
+ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4
+ */
5
+ #ifndef MLD_RANDOMBYTES_H
6
+ #define MLD_RANDOMBYTES_H
7
+
8
+ #include <stddef.h>
9
+
10
+ #include "cbmc.h"
11
+ #include "common.h"
12
+
13
+ #if !defined(MLD_CONFIG_NO_RANDOMIZED_API)
14
+ #if !defined(MLD_CONFIG_CUSTOM_RANDOMBYTES)
15
+ MLD_MUST_CHECK_RETURN_VALUE
16
+ int randombytes(uint8_t *out, size_t outlen);
17
+
18
+ MLD_MUST_CHECK_RETURN_VALUE
19
+ static MLD_INLINE int mld_randombytes(uint8_t *out, size_t outlen)
20
+ __contract__(
21
+ requires(memory_no_alias(out, outlen))
22
+ assigns(memory_slice(out, outlen))
23
+ ) { return randombytes(out, outlen); }
24
+ #endif /* !MLD_CONFIG_CUSTOM_RANDOMBYTES */
25
+ #endif /* !MLD_CONFIG_NO_RANDOMIZED_API */
26
+ #endif /* !MLD_RANDOMBYTES_H */