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,509 @@
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.h"
16
+
17
+ #include "debug.h"
18
+ #include "polyvec_lazy.h"
19
+
20
+ /* This namespacing is not done at the top to avoid a naming conflict
21
+ * with native backends, which are currently not yet namespaced. */
22
+ #define mld_polyvecl_pointwise_acc_montgomery_c \
23
+ MLD_ADD_PARAM_SET(mld_polyvecl_pointwise_acc_montgomery_c)
24
+
25
+ /**************************************************************/
26
+ /************ Vectors of polynomials of length MLDSA_L **************/
27
+ /**************************************************************/
28
+ #if !defined(MLD_CONFIG_NO_SIGN_API) && \
29
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
30
+ MLD_INTERNAL_API
31
+ void mld_polyvecl_uniform_gamma1(mld_polyvecl *v,
32
+ const uint8_t seed[MLDSA_CRHBYTES],
33
+ uint16_t kappa)
34
+ {
35
+ #if defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
36
+ int i;
37
+ #endif
38
+
39
+ /* The caller passes the base counter kappa; component i is sampled from
40
+ * kappa + i. Safety: kappa <= MLD_MAX_KAPPA and i < MLDSA_L, so the
41
+ * casts below are safe. See MLD_MAX_KAPPA comment in params.h. */
42
+ #if defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
43
+ for (i = 0; i < MLDSA_L; i++)
44
+ {
45
+ mld_poly_uniform_gamma1(&v->vec[i], seed, (uint16_t)(kappa + i));
46
+ }
47
+ #else /* MLD_CONFIG_SERIAL_FIPS202_ONLY */
48
+ #if MLDSA_L == 4
49
+ mld_poly_uniform_gamma1_4x(&v->vec[0], &v->vec[1], &v->vec[2], &v->vec[3],
50
+ seed, kappa, (uint16_t)(kappa + 1),
51
+ (uint16_t)(kappa + 2), (uint16_t)(kappa + 3));
52
+ #elif MLDSA_L == 5
53
+ mld_poly_uniform_gamma1_4x(&v->vec[0], &v->vec[1], &v->vec[2], &v->vec[3],
54
+ seed, kappa, (uint16_t)(kappa + 1),
55
+ (uint16_t)(kappa + 2), (uint16_t)(kappa + 3));
56
+ mld_poly_uniform_gamma1(&v->vec[4], seed, (uint16_t)(kappa + 4));
57
+ #elif MLDSA_L == 7
58
+ mld_poly_uniform_gamma1_4x(&v->vec[0], &v->vec[1], &v->vec[2],
59
+ &v->vec[3 /* irrelevant */], seed, kappa,
60
+ (uint16_t)(kappa + 1), (uint16_t)(kappa + 2),
61
+ 0xFF /* irrelevant */);
62
+ mld_poly_uniform_gamma1_4x(&v->vec[3], &v->vec[4], &v->vec[5], &v->vec[6],
63
+ seed, (uint16_t)(kappa + 3), (uint16_t)(kappa + 4),
64
+ (uint16_t)(kappa + 5), (uint16_t)(kappa + 6));
65
+ #endif /* MLDSA_L == 7 */
66
+ #endif /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
67
+
68
+ mld_assert_bound_2d(v->vec, MLDSA_L, MLDSA_N, -(MLDSA_GAMMA1 - 1),
69
+ MLDSA_GAMMA1 + 1);
70
+ }
71
+ #endif /* !MLD_CONFIG_NO_SIGN_API && (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) \
72
+ */
73
+
74
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || \
75
+ !defined(MLD_CONFIG_NO_VERIFY_API) || \
76
+ (!defined(MLD_CONFIG_NO_SIGN_API) && \
77
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)))
78
+ MLD_INTERNAL_API
79
+ void mld_polyvecl_ntt(mld_polyvecl *v)
80
+ {
81
+ unsigned int i;
82
+ mld_assert_abs_bound_2d(v->vec, MLDSA_L, MLDSA_N, MLDSA_Q);
83
+
84
+ for (i = 0; i < MLDSA_L; ++i)
85
+ __loop__(
86
+ assigns(i, memory_slice(v, sizeof(mld_polyvecl)))
87
+ invariant(i <= MLDSA_L)
88
+ invariant(forall(k0, i, MLDSA_L, forall(k1, 0, MLDSA_N, v->vec[k0].coeffs[k1] == loop_entry(*v).vec[k0].coeffs[k1])))
89
+ invariant(forall(k1, 0, i, array_abs_bound(v->vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
90
+ decreases(MLDSA_L - i))
91
+ {
92
+ mld_poly_ntt(&v->vec[i]);
93
+ }
94
+
95
+ mld_assert_abs_bound_2d(v->vec, MLDSA_L, MLDSA_N, MLD_NTT_BOUND);
96
+ }
97
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_VERIFY_API || \
98
+ (!MLD_CONFIG_NO_SIGN_API && (!MLD_CONFIG_REDUCE_RAM || \
99
+ MLD_UNIT_TEST)) */
100
+
101
+ #if !defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
102
+ MLD_STATIC_TESTABLE void mld_polyvecl_pointwise_acc_montgomery_c(
103
+ mld_poly *w, const mld_polyvecl *u, const mld_polyvecl *v)
104
+ __contract__(
105
+ requires(memory_no_alias(w, sizeof(mld_poly)))
106
+ requires(memory_no_alias(u, sizeof(mld_polyvecl)))
107
+ requires(memory_no_alias(v, sizeof(mld_polyvecl)))
108
+ requires(forall(l0, 0, MLDSA_L,
109
+ array_bound(u->vec[l0].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
110
+ requires(forall(l1, 0, MLDSA_L,
111
+ array_abs_bound(v->vec[l1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
112
+ assigns(memory_slice(w, sizeof(mld_poly)))
113
+ ensures(array_abs_bound(w->coeffs, 0, MLDSA_N, MLDSA_Q))
114
+ )
115
+ {
116
+ unsigned int i, j;
117
+ mld_assert_bound_2d(u->vec, MLDSA_L, MLDSA_N, 0, MLDSA_Q);
118
+ mld_assert_abs_bound_2d(v->vec, MLDSA_L, MLDSA_N, MLD_NTT_BOUND);
119
+ for (i = 0; i < MLDSA_N; i++)
120
+ __loop__(
121
+ assigns(i, j, memory_slice(w, sizeof(mld_poly)))
122
+ invariant(i <= MLDSA_N)
123
+ invariant(array_abs_bound(w->coeffs, 0, i, MLDSA_Q))
124
+ decreases(MLDSA_N - i)
125
+ )
126
+ {
127
+ int64_t t = 0;
128
+ int32_t r;
129
+ for (j = 0; j < MLDSA_L; j++)
130
+ __loop__(
131
+ assigns(j, t)
132
+ invariant(j <= MLDSA_L)
133
+ invariant(t >= -(int64_t)j*(MLDSA_Q - 1)*(MLD_NTT_BOUND - 1))
134
+ invariant(t <= (int64_t)j*(MLDSA_Q - 1)*(MLD_NTT_BOUND - 1))
135
+ decreases(MLDSA_L - j)
136
+ )
137
+ {
138
+ t += (int64_t)u->vec[j].coeffs[i] * v->vec[j].coeffs[i];
139
+ }
140
+
141
+ r = mld_montgomery_reduce(t);
142
+ w->coeffs[i] = r;
143
+ }
144
+
145
+ mld_assert_abs_bound(w->coeffs, MLDSA_N, MLDSA_Q);
146
+ }
147
+
148
+ MLD_INTERNAL_API
149
+ void mld_polyvecl_pointwise_acc_montgomery(mld_poly *w, const mld_polyvecl *u,
150
+ const mld_polyvecl *v)
151
+ {
152
+ #if defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L4) && \
153
+ MLD_CONFIG_PARAMETER_SET == 44
154
+ int ret;
155
+ mld_assert_bound_2d(u->vec, MLDSA_L, MLDSA_N, 0, MLDSA_Q);
156
+ mld_assert_abs_bound_2d(v->vec, MLDSA_L, MLDSA_N, MLD_NTT_BOUND);
157
+ ret = mld_polyvecl_pointwise_acc_montgomery_l4_native(
158
+ w->coeffs, (const int32_t (*)[MLDSA_N])u->vec,
159
+ (const int32_t (*)[MLDSA_N])v->vec);
160
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
161
+ {
162
+ mld_assert_abs_bound(w->coeffs, MLDSA_N, MLDSA_Q);
163
+ return;
164
+ }
165
+ #elif defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5) && \
166
+ MLD_CONFIG_PARAMETER_SET == 65
167
+ int ret;
168
+ mld_assert_bound_2d(u->vec, MLDSA_L, MLDSA_N, 0, MLDSA_Q);
169
+ mld_assert_abs_bound_2d(v->vec, MLDSA_L, MLDSA_N, MLD_NTT_BOUND);
170
+ ret = mld_polyvecl_pointwise_acc_montgomery_l5_native(
171
+ w->coeffs, (const int32_t (*)[MLDSA_N])u->vec,
172
+ (const int32_t (*)[MLDSA_N])v->vec);
173
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
174
+ {
175
+ mld_assert_abs_bound(w->coeffs, MLDSA_N, MLDSA_Q);
176
+ return;
177
+ }
178
+ #elif defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7) && \
179
+ MLD_CONFIG_PARAMETER_SET == 87
180
+ int ret;
181
+ mld_assert_bound_2d(u->vec, MLDSA_L, MLDSA_N, 0, MLDSA_Q);
182
+ mld_assert_abs_bound_2d(v->vec, MLDSA_L, MLDSA_N, MLD_NTT_BOUND);
183
+ ret = mld_polyvecl_pointwise_acc_montgomery_l7_native(
184
+ w->coeffs, (const int32_t (*)[MLDSA_N])u->vec,
185
+ (const int32_t (*)[MLDSA_N])v->vec);
186
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
187
+ {
188
+ mld_assert_abs_bound(w->coeffs, MLDSA_N, MLDSA_Q);
189
+ return;
190
+ }
191
+ #endif /* !(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L4 && \
192
+ MLD_CONFIG_PARAMETER_SET == 44) && \
193
+ !(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 && \
194
+ MLD_CONFIG_PARAMETER_SET == 65) && \
195
+ MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 && \
196
+ MLD_CONFIG_PARAMETER_SET == 87 */
197
+ /* The first input is bounded by [0, MLDSA_Q-1] inclusive.
198
+ * The second input is bounded by [-(MLD_NTT_BOUND-1), MLD_NTT_BOUND-1].
199
+ * Hence, we can safely accumulate in 64-bits without intermediate reductions
200
+ * as MLDSA_L * (MLD_NTT_BOUND-1) * (MLDSA_Q-1) < INT64_MAX.
201
+ *
202
+ * The worst case is ML-DSA-87: 7 * (MLD_NTT_BOUND-1) * (MLDSA_Q-1) < 2**53
203
+ * (and likewise for negative values).
204
+ */
205
+ mld_polyvecl_pointwise_acc_montgomery_c(w, u, v);
206
+ }
207
+ #endif /* !MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
208
+
209
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_VERIFY_API) || \
210
+ defined(MLD_UNIT_TEST)
211
+ MLD_INTERNAL_API
212
+ uint32_t mld_polyvecl_chknorm(const mld_polyvecl *v, int32_t bound)
213
+ {
214
+ unsigned int i;
215
+ uint32_t t = 0;
216
+ mld_assert_bound_2d(v->vec, MLDSA_L, MLDSA_N, -MLD_REDUCE32_RANGE_MAX,
217
+ MLD_REDUCE32_RANGE_MAX);
218
+
219
+ for (i = 0; i < MLDSA_L; ++i)
220
+ __loop__(
221
+ invariant(i <= MLDSA_L)
222
+ invariant(t == 0 || t == 0xFFFFFFFF)
223
+ invariant((t == 0) == forall(k1, 0, i, array_abs_bound(v->vec[k1].coeffs, 0, MLDSA_N, bound)))
224
+ decreases(MLDSA_L - i)
225
+ )
226
+ {
227
+ /* Reference: Leaks which polynomial violates the bound via a conditional.
228
+ * We are more conservative to reduce the number of declassifications in
229
+ * constant-time testing.
230
+ */
231
+ t |= mld_poly_chknorm(&v->vec[i], bound);
232
+ }
233
+ return t;
234
+ }
235
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_VERIFY_API || \
236
+ MLD_UNIT_TEST */
237
+
238
+ /**************************************************************/
239
+ /************ Vectors of polynomials of length MLDSA_K **************/
240
+ /**************************************************************/
241
+ #if (!defined(MLD_CONFIG_NO_SIGN_API) && \
242
+ defined(MLD_CONFIG_REDUCE_RAM)) || \
243
+ defined(MLD_UNIT_TEST)
244
+ MLD_INTERNAL_API
245
+ void mld_polyveck_reduce(mld_polyveck *v)
246
+ {
247
+ unsigned int i;
248
+ mld_assert_bound_2d(v->vec, MLDSA_K, MLDSA_N, INT32_MIN,
249
+ MLD_REDUCE32_DOMAIN_MAX);
250
+
251
+ for (i = 0; i < MLDSA_K; ++i)
252
+ __loop__(
253
+ assigns(i, memory_slice(v, sizeof(mld_polyveck)))
254
+ invariant(i <= MLDSA_K)
255
+ invariant(forall(k0, i, MLDSA_K, forall(k1, 0, MLDSA_N, v->vec[k0].coeffs[k1] == loop_entry(*v).vec[k0].coeffs[k1])))
256
+ invariant(forall(k2, 0, i,
257
+ array_bound(v->vec[k2].coeffs, 0, MLDSA_N, -MLD_REDUCE32_RANGE_MAX, MLD_REDUCE32_RANGE_MAX)))
258
+ decreases(MLDSA_K - i)
259
+ )
260
+ {
261
+ mld_poly_reduce(&v->vec[i]);
262
+ }
263
+
264
+ mld_assert_bound_2d(v->vec, MLDSA_K, MLDSA_N, -MLD_REDUCE32_RANGE_MAX,
265
+ MLD_REDUCE32_RANGE_MAX);
266
+ }
267
+ #endif /* (!MLD_CONFIG_NO_SIGN_API && MLD_CONFIG_REDUCE_RAM) || MLD_UNIT_TEST \
268
+ */
269
+
270
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)
271
+ MLD_INTERNAL_API
272
+ void mld_polyveck_caddq(mld_polyveck *v)
273
+ {
274
+ unsigned int i;
275
+ mld_assert_abs_bound_2d(v->vec, MLDSA_K, MLDSA_N, MLDSA_Q);
276
+
277
+ for (i = 0; i < MLDSA_K; ++i)
278
+ __loop__(
279
+ assigns(i, memory_slice(v, sizeof(mld_polyveck)))
280
+ invariant(i <= MLDSA_K)
281
+ invariant(forall(k0, i, MLDSA_K, forall(k1, 0, MLDSA_N, v->vec[k0].coeffs[k1] == loop_entry(*v).vec[k0].coeffs[k1])))
282
+ invariant(forall(k1, 0, i, array_bound(v->vec[k1].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
283
+ decreases(MLDSA_K - i))
284
+ {
285
+ mld_poly_caddq(&v->vec[i]);
286
+ }
287
+
288
+ mld_assert_bound_2d(v->vec, MLDSA_K, MLDSA_N, 0, MLDSA_Q);
289
+ }
290
+ #endif /* !MLD_CONFIG_NO_SIGN_API || MLD_UNIT_TEST */
291
+
292
+ #if (!defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)) && \
293
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
294
+ MLD_INTERNAL_API
295
+ void mld_polyveck_ntt(mld_polyveck *v)
296
+ {
297
+ unsigned int i;
298
+ mld_assert_abs_bound_2d(v->vec, MLDSA_K, MLDSA_N, MLDSA_Q);
299
+
300
+ for (i = 0; i < MLDSA_K; ++i)
301
+ __loop__(
302
+ assigns(i, memory_slice(v, sizeof(mld_polyveck)))
303
+ invariant(i <= MLDSA_K)
304
+ invariant(forall(k0, i, MLDSA_K, forall(k1, 0, MLDSA_N, v->vec[k0].coeffs[k1] == loop_entry(*v).vec[k0].coeffs[k1])))
305
+ invariant(forall(k1, 0, i, array_abs_bound(v->vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
306
+ decreases(MLDSA_K - i))
307
+ {
308
+ mld_poly_ntt(&v->vec[i]);
309
+ }
310
+ mld_assert_abs_bound_2d(v->vec, MLDSA_K, MLDSA_N, MLD_NTT_BOUND);
311
+ }
312
+ #endif /* (!MLD_CONFIG_NO_SIGN_API || MLD_UNIT_TEST) && \
313
+ (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST) */
314
+
315
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)
316
+ MLD_INTERNAL_API
317
+ void mld_polyveck_invntt_tomont(mld_polyveck *v)
318
+ {
319
+ unsigned int i;
320
+ mld_assert_abs_bound_2d(v->vec, MLDSA_K, MLDSA_N, MLDSA_Q);
321
+
322
+ for (i = 0; i < MLDSA_K; ++i)
323
+ __loop__(
324
+ assigns(i, memory_slice(v, sizeof(mld_polyveck)))
325
+ invariant(i <= MLDSA_K)
326
+ invariant(forall(k0, i, MLDSA_K, forall(k1, 0, MLDSA_N, v->vec[k0].coeffs[k1] == loop_entry(*v).vec[k0].coeffs[k1])))
327
+ invariant(forall(k1, 0, i, array_abs_bound(v->vec[k1].coeffs, 0, MLDSA_N, MLD_INTT_BOUND)))
328
+ decreases(MLDSA_K - i))
329
+ {
330
+ mld_poly_invntt_tomont(&v->vec[i]);
331
+ }
332
+
333
+ mld_assert_abs_bound_2d(v->vec, MLDSA_K, MLDSA_N, MLD_INTT_BOUND);
334
+ }
335
+ #endif /* !MLD_CONFIG_NO_SIGN_API || MLD_UNIT_TEST */
336
+
337
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
338
+ MLD_INTERNAL_API
339
+ uint32_t mld_polyveck_chknorm(const mld_polyveck *v, int32_t bound)
340
+ {
341
+ unsigned int i;
342
+ uint32_t t = 0;
343
+ mld_assert_bound_2d(v->vec, MLDSA_K, MLDSA_N, -MLD_REDUCE32_RANGE_MAX,
344
+ MLD_REDUCE32_RANGE_MAX);
345
+
346
+ for (i = 0; i < MLDSA_K; ++i)
347
+ __loop__(
348
+ invariant(i <= MLDSA_K)
349
+ invariant(t == 0 || t == 0xFFFFFFFF)
350
+ invariant((t == 0) == forall(k1, 0, i, array_abs_bound(v->vec[k1].coeffs, 0, MLDSA_N, bound)))
351
+ decreases(MLDSA_K - i)
352
+ )
353
+ {
354
+ /* Reference: Leaks which polynomial violates the bound via a conditional.
355
+ * We are more conservative to reduce the number of declassifications in
356
+ * constant-time testing.
357
+ */
358
+ t |= mld_poly_chknorm(&v->vec[i], bound);
359
+ }
360
+
361
+ return t;
362
+ }
363
+
364
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
365
+
366
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
367
+ MLD_INTERNAL_API
368
+ void mld_polyveck_decompose(mld_polyveck *v1, mld_polyveck *v0)
369
+ {
370
+ unsigned int i;
371
+ mld_assert_bound_2d(v0->vec, MLDSA_K, MLDSA_N, 0, MLDSA_Q);
372
+
373
+ for (i = 0; i < MLDSA_K; ++i)
374
+ __loop__(
375
+ assigns(i, memory_slice(v0, sizeof(mld_polyveck)), memory_slice(v1, sizeof(mld_polyveck)))
376
+ invariant(i <= MLDSA_K)
377
+ invariant(forall(k1, 0, i,
378
+ array_bound(v1->vec[k1].coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2))))
379
+ invariant(forall(k2, 0, i,
380
+ array_abs_bound(v0->vec[k2].coeffs, 0, MLDSA_N, MLDSA_GAMMA2+1)))
381
+ invariant(forall(k3, i, MLDSA_K,
382
+ array_bound(v0->vec[k3].coeffs, 0, MLDSA_N, 0, MLDSA_Q)))
383
+ decreases(MLDSA_K - i)
384
+ )
385
+ {
386
+ mld_poly_decompose(&v1->vec[i], &v0->vec[i]);
387
+ }
388
+
389
+ mld_assert_bound_2d(v1->vec, MLDSA_K, MLDSA_N, 0,
390
+ (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
391
+ mld_assert_abs_bound_2d(v0->vec, MLDSA_K, MLDSA_N, MLDSA_GAMMA2 + 1);
392
+ }
393
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
394
+
395
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
396
+ MLD_INTERNAL_API
397
+ void mld_polyveck_pack_w1(uint8_t r[MLDSA_K * MLDSA_POLYW1_PACKEDBYTES],
398
+ const mld_polyveck *w1)
399
+ {
400
+ unsigned int i;
401
+ mld_assert_bound_2d(w1->vec, MLDSA_K, MLDSA_N, 0,
402
+ (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
403
+
404
+ for (i = 0; i < MLDSA_K; ++i)
405
+ __loop__(
406
+ assigns(i, memory_slice(r, MLDSA_K * MLDSA_POLYW1_PACKEDBYTES))
407
+ invariant(i <= MLDSA_K)
408
+ decreases(MLDSA_K - i)
409
+ )
410
+ {
411
+ mld_polyw1_pack(&r[i * MLDSA_POLYW1_PACKEDBYTES], &w1->vec[i]);
412
+ }
413
+ }
414
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
415
+
416
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
417
+ MLD_INTERNAL_API
418
+ void mld_polyveck_pack_eta(uint8_t r[MLDSA_K * MLDSA_POLYETA_PACKEDBYTES],
419
+ const mld_polyveck *p)
420
+ {
421
+ unsigned int i;
422
+ mld_assert_abs_bound_2d(p->vec, MLDSA_K, MLDSA_N, MLDSA_ETA + 1);
423
+ for (i = 0; i < MLDSA_K; ++i)
424
+ __loop__(
425
+ assigns(i, memory_slice(r, MLDSA_K * MLDSA_POLYETA_PACKEDBYTES))
426
+ invariant(i <= MLDSA_K)
427
+ decreases(MLDSA_K - i)
428
+ )
429
+ {
430
+ mld_polyeta_pack(&r[i * MLDSA_POLYETA_PACKEDBYTES], &p->vec[i]);
431
+ }
432
+ }
433
+
434
+ MLD_INTERNAL_API
435
+ void mld_polyvecl_pack_eta(uint8_t r[MLDSA_L * MLDSA_POLYETA_PACKEDBYTES],
436
+ const mld_polyvecl *p)
437
+ {
438
+ unsigned int i;
439
+ mld_assert_abs_bound_2d(p->vec, MLDSA_L, MLDSA_N, MLDSA_ETA + 1);
440
+ for (i = 0; i < MLDSA_L; ++i)
441
+ __loop__(
442
+ assigns(i, memory_slice(r, MLDSA_L * MLDSA_POLYETA_PACKEDBYTES))
443
+ invariant(i <= MLDSA_L)
444
+ decreases(MLDSA_L - i)
445
+ )
446
+ {
447
+ mld_polyeta_pack(&r[i * MLDSA_POLYETA_PACKEDBYTES], &p->vec[i]);
448
+ }
449
+ }
450
+
451
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
452
+
453
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || \
454
+ (!defined(MLD_CONFIG_NO_SIGN_API) && \
455
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)))
456
+ MLD_INTERNAL_API
457
+ void mld_polyvecl_unpack_eta(
458
+ mld_polyvecl *p, const uint8_t r[MLDSA_L * MLDSA_POLYETA_PACKEDBYTES])
459
+ {
460
+ unsigned int i;
461
+ for (i = 0; i < MLDSA_L; ++i)
462
+ {
463
+ mld_polyeta_unpack(&p->vec[i], r + i * MLDSA_POLYETA_PACKEDBYTES);
464
+ }
465
+
466
+ mld_assert_bound_2d(p->vec, MLDSA_L, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND,
467
+ MLDSA_ETA + 1);
468
+ }
469
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || (!MLD_CONFIG_NO_SIGN_API && \
470
+ (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST)) */
471
+
472
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
473
+ MLD_INTERNAL_API
474
+ void mld_polyvecl_unpack_z(mld_polyvecl *z,
475
+ const uint8_t r[MLDSA_L * MLDSA_POLYZ_PACKEDBYTES])
476
+ {
477
+ unsigned int i;
478
+ for (i = 0; i < MLDSA_L; ++i)
479
+ {
480
+ mld_polyz_unpack(&z->vec[i], r + i * MLDSA_POLYZ_PACKEDBYTES);
481
+ }
482
+
483
+ mld_assert_bound_2d(z->vec, MLDSA_L, MLDSA_N, -(MLDSA_GAMMA1 - 1),
484
+ MLDSA_GAMMA1 + 1);
485
+ }
486
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
487
+
488
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || \
489
+ (!defined(MLD_CONFIG_NO_SIGN_API) && \
490
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)))
491
+ MLD_INTERNAL_API
492
+ void mld_polyveck_unpack_eta(
493
+ mld_polyveck *p, const uint8_t r[MLDSA_K * MLDSA_POLYETA_PACKEDBYTES])
494
+ {
495
+ unsigned int i;
496
+ for (i = 0; i < MLDSA_K; ++i)
497
+ {
498
+ mld_polyeta_unpack(&p->vec[i], r + i * MLDSA_POLYETA_PACKEDBYTES);
499
+ }
500
+
501
+ mld_assert_bound_2d(p->vec, MLDSA_K, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND,
502
+ MLDSA_ETA + 1);
503
+ }
504
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || (!MLD_CONFIG_NO_SIGN_API && \
505
+ (!MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST)) */
506
+
507
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
508
+ * Don't modify by hand -- this is auto-generated by scripts/autogen. */
509
+ #undef mld_polyvecl_pointwise_acc_montgomery_c