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,910 @@
1
+ /*
2
+ * Copyright (c) The mldsa-native project authors
3
+ * Copyright (c) The mlkem-native project authors
4
+ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
5
+ */
6
+
7
+ /* References
8
+ * ==========
9
+ *
10
+ * - [FIPS204]
11
+ * FIPS 204 Module-Lattice-Based Digital Signature Standard
12
+ * National Institute of Standards and Technology
13
+ * https://csrc.nist.gov/pubs/fips/204/final
14
+ *
15
+ * - [REF]
16
+ * CRYSTALS-Dilithium reference implementation
17
+ * Bai, Ducas, Kiltz, Lepoint, Lyubashevsky, Schwabe, Seiler, Stehlé
18
+ * https://github.com/pq-crystals/dilithium/tree/master/ref
19
+ */
20
+
21
+ #include "poly_kl.h"
22
+
23
+ #include "ct.h"
24
+ #include "debug.h"
25
+ #include "rounding.h"
26
+ #include "symmetric.h"
27
+
28
+ /* Parameter set namespacing
29
+ * This is to facilitate building multiple instances
30
+ * of mldsa-native (e.g. with varying parameter sets)
31
+ * within a single compilation unit. */
32
+ #define mld_rej_eta MLD_ADD_PARAM_SET(mld_rej_eta)
33
+ #define mld_rej_eta_c MLD_ADD_PARAM_SET(mld_rej_eta_c)
34
+ #define mld_poly_decompose_c MLD_ADD_PARAM_SET(mld_poly_decompose_c)
35
+ #define mld_poly_use_hint_c MLD_ADD_PARAM_SET(mld_poly_use_hint_c)
36
+ #define mld_polyz_unpack_c MLD_ADD_PARAM_SET(mld_polyz_unpack_c)
37
+ /* End of parameter set namespacing */
38
+
39
+
40
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
41
+ MLD_STATIC_TESTABLE
42
+ void mld_poly_decompose_c(mld_poly *a1, mld_poly *a0)
43
+ __contract__(
44
+ requires(memory_no_alias(a1, sizeof(mld_poly)))
45
+ requires(memory_no_alias(a0, sizeof(mld_poly)))
46
+ requires(array_bound(a0->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
47
+ assigns(memory_slice(a1, sizeof(mld_poly)))
48
+ assigns(memory_slice(a0, sizeof(mld_poly)))
49
+ ensures(array_bound(a1->coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
50
+ ensures(array_abs_bound(a0->coeffs, 0, MLDSA_N, MLDSA_GAMMA2+1))
51
+ )
52
+ {
53
+ unsigned int i;
54
+ mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
55
+ for (i = 0; i < MLDSA_N; ++i)
56
+ __loop__(
57
+ assigns(i, memory_slice(a0, sizeof(mld_poly)), memory_slice(a1, sizeof(mld_poly)))
58
+ invariant(i <= MLDSA_N)
59
+ invariant(array_bound(a0->coeffs, i, MLDSA_N, 0, MLDSA_Q))
60
+ invariant(array_bound(a1->coeffs, 0, i, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
61
+ invariant(array_abs_bound(a0->coeffs, 0, i, MLDSA_GAMMA2+1))
62
+ decreases(MLDSA_N - i)
63
+ )
64
+ {
65
+ mld_decompose(&a0->coeffs[i], &a1->coeffs[i], a0->coeffs[i]);
66
+ }
67
+
68
+ mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
69
+ mld_assert_bound(a1->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
70
+ }
71
+
72
+ MLD_INTERNAL_API
73
+ void mld_poly_decompose(mld_poly *a1, mld_poly *a0)
74
+ {
75
+ #if defined(MLD_USE_NATIVE_POLY_DECOMPOSE_88) && MLD_CONFIG_PARAMETER_SET == 44
76
+ int ret;
77
+ mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
78
+ ret = mld_poly_decompose_88_native(a1->coeffs, a0->coeffs);
79
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
80
+ {
81
+ mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
82
+ mld_assert_bound(a1->coeffs, MLDSA_N, 0,
83
+ (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
84
+ return;
85
+ }
86
+ #elif defined(MLD_USE_NATIVE_POLY_DECOMPOSE_32) && \
87
+ (MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
88
+ int ret;
89
+ mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
90
+ ret = mld_poly_decompose_32_native(a1->coeffs, a0->coeffs);
91
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
92
+ {
93
+ mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
94
+ mld_assert_bound(a1->coeffs, MLDSA_N, 0,
95
+ (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
96
+ return;
97
+ }
98
+ #endif /* !(MLD_USE_NATIVE_POLY_DECOMPOSE_88 && MLD_CONFIG_PARAMETER_SET == \
99
+ 44) && MLD_USE_NATIVE_POLY_DECOMPOSE_32 && (MLD_CONFIG_PARAMETER_SET \
100
+ == 65 || MLD_CONFIG_PARAMETER_SET == 87) */
101
+ mld_poly_decompose_c(a1, a0);
102
+ }
103
+
104
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
105
+
106
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
107
+ MLD_STATIC_TESTABLE void mld_poly_use_hint_c(mld_poly *a, const mld_poly *h)
108
+ __contract__(
109
+ requires(memory_no_alias(a, sizeof(mld_poly)))
110
+ requires(memory_no_alias(h, sizeof(mld_poly)))
111
+ requires(array_bound(a->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
112
+ requires(array_bound(h->coeffs, 0, MLDSA_N, 0, 2))
113
+ assigns(memory_slice(a, sizeof(mld_poly)))
114
+ ensures(array_bound(a->coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
115
+ )
116
+ {
117
+ unsigned int i;
118
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
119
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
120
+
121
+ for (i = 0; i < MLDSA_N; ++i)
122
+ __loop__(
123
+ invariant(i <= MLDSA_N)
124
+ invariant(array_bound(a->coeffs, 0, i, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
125
+ invariant(array_bound(a->coeffs, i, MLDSA_N, 0, MLDSA_Q))
126
+ decreases(MLDSA_N - i)
127
+ )
128
+ {
129
+ a->coeffs[i] = mld_use_hint(a->coeffs[i], h->coeffs[i]);
130
+ }
131
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
132
+ }
133
+
134
+ MLD_INTERNAL_API
135
+ void mld_poly_use_hint(mld_poly *a, const mld_poly *h)
136
+ {
137
+ #if defined(MLD_USE_NATIVE_POLY_USE_HINT_88) && MLD_CONFIG_PARAMETER_SET == 44
138
+ int ret;
139
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
140
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
141
+ ret = mld_poly_use_hint_88_native(a->coeffs, h->coeffs);
142
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
143
+ {
144
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
145
+ return;
146
+ }
147
+ #elif defined(MLD_USE_NATIVE_POLY_USE_HINT_32) && \
148
+ (MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
149
+ int ret;
150
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
151
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
152
+ ret = mld_poly_use_hint_32_native(a->coeffs, h->coeffs);
153
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
154
+ {
155
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
156
+ return;
157
+ }
158
+ #endif /* !(MLD_USE_NATIVE_POLY_USE_HINT_88 && MLD_CONFIG_PARAMETER_SET == 44) \
159
+ && MLD_USE_NATIVE_POLY_USE_HINT_32 && (MLD_CONFIG_PARAMETER_SET == \
160
+ 65 || MLD_CONFIG_PARAMETER_SET == 87) */
161
+ mld_poly_use_hint_c(a, h);
162
+ }
163
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
164
+
165
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
166
+ /**
167
+ * Sample uniformly random coefficients in [-MLDSA_ETA, MLDSA_ETA] by
168
+ * performing rejection sampling on an array of random bytes.
169
+ *
170
+ * @param[out] a Pointer to output array (allocated).
171
+ * @param target Requested number of coefficients to sample.
172
+ * @param offset Number of coefficients already sampled.
173
+ * @param[in] buf Array of random bytes to sample from.
174
+ * @param buflen Length of array of random bytes.
175
+ *
176
+ * @return Number of sampled coefficients. Can be smaller than target if not
177
+ * enough random bytes were given.
178
+ */
179
+
180
+ /* Reference: `mld_rej_eta()` in the reference implementation @[REF].
181
+ * - Our signature differs from the reference implementation
182
+ * in that it adds the offset and always expects the base of the
183
+ * target buffer. This avoids shifting the buffer base in the
184
+ * caller, which appears tricky to reason about. */
185
+ #if MLDSA_ETA == 2
186
+ /*
187
+ * Sampling 256 coefficients mod 15 using rejection sampling from 4 bits.
188
+ * Expected number of required bytes: (256 * (16/15))/2 = 136.5 bytes.
189
+ * We sample 1 block (=136 bytes) of SHAKE256_RATE output initially.
190
+ * Sampling 2 blocks initially results in slightly worse performance.
191
+ */
192
+ #define MLD_POLY_UNIFORM_ETA_NBLOCKS 1
193
+ #elif MLDSA_ETA == 4
194
+ /*
195
+ * Sampling 256 coefficients mod 9 using rejection sampling from 4 bits.
196
+ * Expected number of required bytes: (256 * (16/9))/2 = 227.5 bytes.
197
+ * We sample 2 blocks (=272 bytes) of SHAKE256_RATE output initially.
198
+ */
199
+ #define MLD_POLY_UNIFORM_ETA_NBLOCKS 2
200
+ #else /* MLDSA_ETA == 4 */
201
+ #error "Invalid value of MLDSA_ETA"
202
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
203
+
204
+ MLD_STATIC_TESTABLE unsigned int mld_rej_eta_c(int32_t *a, unsigned int target,
205
+ unsigned int offset,
206
+ const uint8_t *buf,
207
+ unsigned int buflen)
208
+ __contract__(
209
+ requires(offset <= target && target <= MLDSA_N)
210
+ requires(buflen <= (MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES))
211
+ requires(memory_no_alias(a, sizeof(int32_t) * target))
212
+ requires(memory_no_alias(buf, buflen))
213
+ requires(array_abs_bound(a, 0, offset, MLDSA_ETA + 1))
214
+ assigns(memory_slice(a, sizeof(int32_t) * target))
215
+ ensures(offset <= return_value && return_value <= target)
216
+ ensures(array_abs_bound(a, 0, return_value, MLDSA_ETA + 1))
217
+ )
218
+ {
219
+ unsigned int ctr, pos;
220
+ int t_valid;
221
+ uint32_t t0, t1;
222
+ mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
223
+ ctr = offset;
224
+ pos = 0;
225
+ while (ctr < target && pos < buflen)
226
+ __loop__(
227
+ invariant(offset <= ctr && ctr <= target && pos <= buflen)
228
+ invariant(array_abs_bound(a, 0, ctr, MLDSA_ETA + 1))
229
+ decreases(buflen - pos)
230
+ )
231
+ {
232
+ t0 = buf[pos] & 0x0F;
233
+ t1 = buf[pos++] >> 4;
234
+
235
+ /* Constant time: The inputs and outputs to the rejection sampling are
236
+ * secret. However, it is fine to leak which coefficients have been
237
+ * rejected. For constant-time testing, we declassify the result of
238
+ * the comparison.
239
+ */
240
+ #if MLDSA_ETA == 2
241
+ t_valid = t0 < 15;
242
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
243
+ if (t_valid) /* t0 < 15 */
244
+ {
245
+ t0 = t0 - (205 * t0 >> 10) * 5;
246
+ a[ctr++] = 2 - (int32_t)t0;
247
+ }
248
+ t_valid = t1 < 15;
249
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
250
+ if (t_valid && ctr < target) /* t1 < 15 */
251
+ {
252
+ t1 = t1 - (205 * t1 >> 10) * 5;
253
+ a[ctr++] = 2 - (int32_t)t1;
254
+ }
255
+ #elif MLDSA_ETA == 4
256
+ t_valid = t0 < 9;
257
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
258
+ if (t_valid) /* t0 < 9 */
259
+ {
260
+ a[ctr++] = 4 - (int32_t)t0;
261
+ }
262
+ t_valid = t1 < 9; /* t1 < 9 */
263
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
264
+ if (t_valid && ctr < target)
265
+ {
266
+ a[ctr++] = 4 - (int32_t)t1;
267
+ }
268
+ #else /* MLDSA_ETA == 4 */
269
+ #error "Invalid value of MLDSA_ETA"
270
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
271
+ }
272
+
273
+ mld_assert_abs_bound(a, ctr, MLDSA_ETA + 1);
274
+
275
+ return ctr;
276
+ }
277
+
278
+ static unsigned int mld_rej_eta(int32_t *a, unsigned int target,
279
+ unsigned int offset, const uint8_t *buf,
280
+ unsigned int buflen)
281
+ __contract__(
282
+ requires(offset <= target && target <= MLDSA_N)
283
+ requires(buflen <= (MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES))
284
+ requires(memory_no_alias(a, sizeof(int32_t) * target))
285
+ requires(memory_no_alias(buf, buflen))
286
+ requires(array_abs_bound(a, 0, offset, MLDSA_ETA + 1))
287
+ assigns(memory_slice(a, sizeof(int32_t) * target))
288
+ ensures(offset <= return_value && return_value <= target)
289
+ ensures(array_abs_bound(a, 0, return_value, MLDSA_ETA + 1))
290
+ )
291
+ {
292
+ #if MLDSA_ETA == 2 && defined(MLD_USE_NATIVE_REJ_UNIFORM_ETA2)
293
+ int ret;
294
+ mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
295
+ if (offset == 0)
296
+ {
297
+ ret = mld_rej_uniform_eta2_native(a, target, buf, buflen);
298
+ if (ret != MLD_NATIVE_FUNC_FALLBACK)
299
+ {
300
+ unsigned res = (unsigned)ret;
301
+ mld_assert_abs_bound(a, res, MLDSA_ETA + 1);
302
+ return res;
303
+ }
304
+ }
305
+ #elif MLDSA_ETA == 4 && defined(MLD_USE_NATIVE_REJ_UNIFORM_ETA4)
306
+ int ret;
307
+ mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
308
+ if (offset == 0)
309
+ {
310
+ ret = mld_rej_uniform_eta4_native(a, target, buf, buflen);
311
+ if (ret != MLD_NATIVE_FUNC_FALLBACK)
312
+ {
313
+ unsigned res = (unsigned)ret;
314
+ mld_assert_abs_bound(a, res, MLDSA_ETA + 1);
315
+ return res;
316
+ }
317
+ }
318
+ #endif /* !(MLDSA_ETA == 2 && MLD_USE_NATIVE_REJ_UNIFORM_ETA2) && MLDSA_ETA == \
319
+ 4 && MLD_USE_NATIVE_REJ_UNIFORM_ETA4 */
320
+
321
+ return mld_rej_eta_c(a, target, offset, buf, buflen);
322
+ }
323
+
324
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
325
+ MLD_INTERNAL_API
326
+ void mld_poly_uniform_eta_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
327
+ mld_poly *r3, const uint8_t seed[MLDSA_CRHBYTES],
328
+ uint8_t nonce0, uint8_t nonce1, uint8_t nonce2,
329
+ uint8_t nonce3)
330
+ {
331
+ /* Temporary buffers for XOF output before rejection sampling */
332
+ MLD_ALIGN uint8_t buf[4][MLD_ALIGN_UP(MLD_POLY_UNIFORM_ETA_NBLOCKS *
333
+ MLD_STREAM256_BLOCKBYTES)];
334
+
335
+ MLD_ALIGN uint8_t extseed[4][MLD_ALIGN_UP(MLDSA_CRHBYTES + 2)];
336
+
337
+ /* Tracks the number of coefficients we have already sampled */
338
+ unsigned ctr[4];
339
+ mld_xof256_x4_ctx state;
340
+ unsigned buflen;
341
+
342
+ mld_memcpy(extseed[0], seed, MLDSA_CRHBYTES);
343
+ mld_memcpy(extseed[1], seed, MLDSA_CRHBYTES);
344
+ mld_memcpy(extseed[2], seed, MLDSA_CRHBYTES);
345
+ mld_memcpy(extseed[3], seed, MLDSA_CRHBYTES);
346
+ extseed[0][MLDSA_CRHBYTES] = nonce0;
347
+ extseed[1][MLDSA_CRHBYTES] = nonce1;
348
+ extseed[2][MLDSA_CRHBYTES] = nonce2;
349
+ extseed[3][MLDSA_CRHBYTES] = nonce3;
350
+ extseed[0][MLDSA_CRHBYTES + 1] = 0;
351
+ extseed[1][MLDSA_CRHBYTES + 1] = 0;
352
+ extseed[2][MLDSA_CRHBYTES + 1] = 0;
353
+ extseed[3][MLDSA_CRHBYTES + 1] = 0;
354
+
355
+ mld_xof256_x4_init(&state);
356
+ mld_xof256_x4_absorb(&state, extseed, MLDSA_CRHBYTES + 2);
357
+
358
+ /*
359
+ * Initially, squeeze heuristic number of MLD_POLY_UNIFORM_ETA_NBLOCKS.
360
+ * This should generate the coefficients with high probability.
361
+ */
362
+ mld_xof256_x4_squeezeblocks(buf, MLD_POLY_UNIFORM_ETA_NBLOCKS, &state);
363
+ buflen = MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES;
364
+
365
+ ctr[0] = mld_rej_eta(r0->coeffs, MLDSA_N, 0, buf[0], buflen);
366
+ ctr[1] = mld_rej_eta(r1->coeffs, MLDSA_N, 0, buf[1], buflen);
367
+ ctr[2] = mld_rej_eta(r2->coeffs, MLDSA_N, 0, buf[2], buflen);
368
+ ctr[3] = mld_rej_eta(r3->coeffs, MLDSA_N, 0, buf[3], buflen);
369
+
370
+ /*
371
+ * So long as not all entries have been generated, squeeze
372
+ * one more block at a time until we're done.
373
+ */
374
+ buflen = MLD_STREAM256_BLOCKBYTES;
375
+ while (ctr[0] < MLDSA_N || ctr[1] < MLDSA_N || ctr[2] < MLDSA_N ||
376
+ ctr[3] < MLDSA_N)
377
+ __loop__(
378
+ assigns(ctr, state, memory_slice(r0, sizeof(mld_poly)),
379
+ memory_slice(r1, sizeof(mld_poly)), memory_slice(r2, sizeof(mld_poly)),
380
+ memory_slice(r3, sizeof(mld_poly)), object_whole(buf[0]),
381
+ object_whole(buf[1]), object_whole(buf[2]),
382
+ object_whole(buf[3]))
383
+ invariant(ctr[0] <= MLDSA_N && ctr[1] <= MLDSA_N)
384
+ invariant(ctr[2] <= MLDSA_N && ctr[3] <= MLDSA_N)
385
+ invariant(array_abs_bound(r0->coeffs, 0, ctr[0], MLDSA_ETA + 1))
386
+ invariant(array_abs_bound(r1->coeffs, 0, ctr[1], MLDSA_ETA + 1))
387
+ invariant(array_abs_bound(r2->coeffs, 0, ctr[2], MLDSA_ETA + 1))
388
+ invariant(array_abs_bound(r3->coeffs, 0, ctr[3], MLDSA_ETA + 1)))
389
+ {
390
+ mld_xof256_x4_squeezeblocks(buf, 1, &state);
391
+ ctr[0] = mld_rej_eta(r0->coeffs, MLDSA_N, ctr[0], buf[0], buflen);
392
+ ctr[1] = mld_rej_eta(r1->coeffs, MLDSA_N, ctr[1], buf[1], buflen);
393
+ ctr[2] = mld_rej_eta(r2->coeffs, MLDSA_N, ctr[2], buf[2], buflen);
394
+ ctr[3] = mld_rej_eta(r3->coeffs, MLDSA_N, ctr[3], buf[3], buflen);
395
+ }
396
+
397
+ mld_xof256_x4_release(&state);
398
+
399
+ mld_assert_abs_bound(r0->coeffs, MLDSA_N, MLDSA_ETA + 1);
400
+ mld_assert_abs_bound(r1->coeffs, MLDSA_N, MLDSA_ETA + 1);
401
+ mld_assert_abs_bound(r2->coeffs, MLDSA_N, MLDSA_ETA + 1);
402
+ mld_assert_abs_bound(r3->coeffs, MLDSA_N, MLDSA_ETA + 1);
403
+
404
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
405
+ mld_zeroize(buf, sizeof(buf));
406
+ mld_zeroize(extseed, sizeof(extseed));
407
+ }
408
+ #else /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
409
+
410
+ MLD_INTERNAL_API
411
+ void mld_poly_uniform_eta(mld_poly *r, const uint8_t seed[MLDSA_CRHBYTES],
412
+ uint8_t nonce)
413
+ {
414
+ /* Temporary buffer for XOF output before rejection sampling */
415
+ MLD_ALIGN uint8_t
416
+ buf[MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES];
417
+ MLD_ALIGN uint8_t extseed[MLDSA_CRHBYTES + 2];
418
+
419
+ /* Tracks the number of coefficients we have already sampled */
420
+ unsigned ctr;
421
+ mld_xof256_ctx state;
422
+ unsigned buflen;
423
+
424
+ mld_memcpy(extseed, seed, MLDSA_CRHBYTES);
425
+ extseed[MLDSA_CRHBYTES] = nonce;
426
+ extseed[MLDSA_CRHBYTES + 1] = 0;
427
+
428
+ mld_xof256_init(&state);
429
+ mld_xof256_absorb_once(&state, extseed, MLDSA_CRHBYTES + 2);
430
+
431
+ /*
432
+ * Initially, squeeze heuristic number of MLD_POLY_UNIFORM_ETA_NBLOCKS.
433
+ * This should generate the coefficients with high probability.
434
+ */
435
+ mld_xof256_squeezeblocks(buf, MLD_POLY_UNIFORM_ETA_NBLOCKS, &state);
436
+ buflen = MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES;
437
+
438
+ ctr = mld_rej_eta(r->coeffs, MLDSA_N, 0, buf, buflen);
439
+
440
+ /*
441
+ * So long as not all entries have been generated, squeeze
442
+ * one more block at a time until we're done.
443
+ */
444
+ buflen = MLD_STREAM256_BLOCKBYTES;
445
+ while (ctr < MLDSA_N)
446
+ __loop__(
447
+ assigns(ctr, object_whole(&state),
448
+ object_whole(buf), memory_slice(r, sizeof(mld_poly)))
449
+ invariant(ctr <= MLDSA_N)
450
+ invariant(state.pos <= SHAKE256_RATE)
451
+ invariant(array_abs_bound(r->coeffs, 0, ctr, MLDSA_ETA + 1)))
452
+ {
453
+ mld_xof256_squeezeblocks(buf, 1, &state);
454
+ ctr = mld_rej_eta(r->coeffs, MLDSA_N, ctr, buf, buflen);
455
+ }
456
+
457
+ mld_xof256_release(&state);
458
+
459
+ mld_assert_abs_bound(r->coeffs, MLDSA_N, MLDSA_ETA + 1);
460
+
461
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
462
+ mld_zeroize(buf, sizeof(buf));
463
+ mld_zeroize(extseed, sizeof(extseed));
464
+ }
465
+ #endif /* MLD_CONFIG_SERIAL_FIPS202_ONLY */
466
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
467
+
468
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
469
+ #define MLD_POLY_UNIFORM_GAMMA1_NBLOCKS \
470
+ ((MLDSA_POLYZ_PACKEDBYTES + MLD_STREAM256_BLOCKBYTES - 1) / \
471
+ MLD_STREAM256_BLOCKBYTES)
472
+
473
+ #if MLD_CONFIG_PARAMETER_SET == 65 || \
474
+ defined(MLD_CONFIG_SERIAL_FIPS202_ONLY) || \
475
+ defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
476
+ MLD_INTERNAL_API
477
+ void mld_poly_uniform_gamma1(mld_poly *a, const uint8_t seed[MLDSA_CRHBYTES],
478
+ uint16_t nonce)
479
+ {
480
+ MLD_ALIGN uint8_t
481
+ buf[MLD_POLY_UNIFORM_GAMMA1_NBLOCKS * MLD_STREAM256_BLOCKBYTES];
482
+ MLD_ALIGN uint8_t extseed[MLDSA_CRHBYTES + 2];
483
+ mld_xof256_ctx state;
484
+
485
+ mld_memcpy(extseed, seed, MLDSA_CRHBYTES);
486
+ extseed[MLDSA_CRHBYTES] = (uint8_t)(nonce & 0xFF);
487
+ extseed[MLDSA_CRHBYTES + 1] = (uint8_t)(nonce >> 8);
488
+
489
+ mld_xof256_init(&state);
490
+ mld_xof256_absorb_once(&state, extseed, MLDSA_CRHBYTES + 2);
491
+
492
+ mld_xof256_squeezeblocks(buf, MLD_POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
493
+ mld_polyz_unpack(a, buf);
494
+
495
+ mld_xof256_release(&state);
496
+
497
+ mld_assert_bound(a->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
498
+
499
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
500
+ mld_zeroize(buf, sizeof(buf));
501
+ mld_zeroize(extseed, sizeof(extseed));
502
+ }
503
+ #endif /* MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_SERIAL_FIPS202_ONLY || \
504
+ MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
505
+
506
+
507
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY) && \
508
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
509
+ MLD_INTERNAL_API
510
+ void mld_poly_uniform_gamma1_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
511
+ mld_poly *r3,
512
+ const uint8_t seed[MLDSA_CRHBYTES],
513
+ uint16_t nonce0, uint16_t nonce1,
514
+ uint16_t nonce2, uint16_t nonce3)
515
+ {
516
+ /* Temporary buffers for XOF output before rejection sampling */
517
+ MLD_ALIGN uint8_t buf[4][MLD_ALIGN_UP(MLD_POLY_UNIFORM_GAMMA1_NBLOCKS *
518
+ MLD_STREAM256_BLOCKBYTES)];
519
+
520
+ MLD_ALIGN uint8_t extseed[4][MLD_ALIGN_UP(MLDSA_CRHBYTES + 2)];
521
+
522
+ /* Tracks the number of coefficients we have already sampled */
523
+ mld_xof256_x4_ctx state;
524
+
525
+ mld_memcpy(extseed[0], seed, MLDSA_CRHBYTES);
526
+ mld_memcpy(extseed[1], seed, MLDSA_CRHBYTES);
527
+ mld_memcpy(extseed[2], seed, MLDSA_CRHBYTES);
528
+ mld_memcpy(extseed[3], seed, MLDSA_CRHBYTES);
529
+ extseed[0][MLDSA_CRHBYTES] = (uint8_t)(nonce0 & 0xFF);
530
+ extseed[1][MLDSA_CRHBYTES] = (uint8_t)(nonce1 & 0xFF);
531
+ extseed[2][MLDSA_CRHBYTES] = (uint8_t)(nonce2 & 0xFF);
532
+ extseed[3][MLDSA_CRHBYTES] = (uint8_t)(nonce3 & 0xFF);
533
+ extseed[0][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce0 >> 8);
534
+ extseed[1][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce1 >> 8);
535
+ extseed[2][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce2 >> 8);
536
+ extseed[3][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce3 >> 8);
537
+
538
+ mld_xof256_x4_init(&state);
539
+ mld_xof256_x4_absorb(&state, extseed, MLDSA_CRHBYTES + 2);
540
+ mld_xof256_x4_squeezeblocks(buf, MLD_POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
541
+
542
+ mld_polyz_unpack(r0, buf[0]);
543
+ mld_polyz_unpack(r1, buf[1]);
544
+ mld_polyz_unpack(r2, buf[2]);
545
+ mld_polyz_unpack(r3, buf[3]);
546
+ mld_xof256_x4_release(&state);
547
+
548
+ mld_assert_bound(r0->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
549
+ mld_assert_bound(r1->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
550
+ mld_assert_bound(r2->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
551
+ mld_assert_bound(r3->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
552
+
553
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
554
+ mld_zeroize(buf, sizeof(buf));
555
+ mld_zeroize(extseed, sizeof(extseed));
556
+ }
557
+ #endif /* !MLD_CONFIG_SERIAL_FIPS202_ONLY && (!MLD_CONFIG_REDUCE_RAM || \
558
+ MLD_UNIT_TEST) */
559
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
560
+
561
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
562
+ MLD_INTERNAL_API
563
+ void mld_poly_challenge(mld_poly *c, const uint8_t seed[MLDSA_CTILDEBYTES])
564
+ {
565
+ unsigned int i, j, pos;
566
+ uint64_t signs;
567
+ uint64_t offset;
568
+ MLD_ALIGN uint8_t buf[SHAKE256_RATE];
569
+ mld_shake256ctx state;
570
+
571
+ mld_shake256_init(&state);
572
+ mld_shake256_absorb(&state, seed, MLDSA_CTILDEBYTES);
573
+ mld_shake256_finalize(&state);
574
+ mld_shake256_squeeze(buf, SHAKE256_RATE, &state);
575
+
576
+ /* Convert the first 8 bytes of buf[] into an unsigned 64-bit value. */
577
+ /* Each bit of that dictates the sign of the resulting challenge value */
578
+ signs = 0;
579
+ for (i = 0; i < 8; ++i)
580
+ __loop__(
581
+ assigns(i, signs)
582
+ invariant(i <= 8)
583
+ decreases(8 - i)
584
+ )
585
+ {
586
+ signs |= (uint64_t)buf[i] << 8 * i;
587
+ }
588
+ pos = 8;
589
+
590
+ mld_memset(c, 0, sizeof(mld_poly));
591
+
592
+ for (i = MLDSA_N - MLDSA_TAU; i < MLDSA_N; ++i)
593
+ __loop__(
594
+ assigns(i, j, object_whole(buf), state, pos, memory_slice(c, sizeof(mld_poly)), signs)
595
+ invariant(i >= MLDSA_N - MLDSA_TAU)
596
+ invariant(i <= MLDSA_N)
597
+ invariant(pos >= 1)
598
+ invariant(pos <= SHAKE256_RATE)
599
+ invariant(array_bound(c->coeffs, 0, MLDSA_N, -1, 2))
600
+ invariant(state.pos <= SHAKE256_RATE)
601
+ decreases(MLDSA_N - i)
602
+ )
603
+ {
604
+ /* This loop terminates only probabilistically, hence no decreases
605
+ * clause. */
606
+ do
607
+ __loop__(
608
+ assigns(j, object_whole(buf), state, pos)
609
+ invariant(state.pos <= SHAKE256_RATE)
610
+ )
611
+ {
612
+ if (pos >= SHAKE256_RATE)
613
+ {
614
+ mld_shake256_squeeze(buf, SHAKE256_RATE, &state);
615
+ pos = 0;
616
+ }
617
+ j = buf[pos++];
618
+ } while (j > i);
619
+
620
+ c->coeffs[i] = c->coeffs[j];
621
+
622
+ /* Reference: Compute coefficient value here in two steps to */
623
+ /* avoid mixing unsigned and signed arithmetic with implicit */
624
+ /* conversions, and so that CBMC can keep track of ranges */
625
+ /* to complete type-safety proof here. */
626
+
627
+ /* The least-significant bit of signs tells us if we want -1 or +1 */
628
+ offset = 2 * (signs & 1);
629
+
630
+ /* offset has value 0 or 2 here, so (1 - (int32_t) offset) has
631
+ * value -1 or +1 */
632
+ c->coeffs[j] = 1 - (int32_t)offset;
633
+
634
+ /* Move to the next bit of signs for next time */
635
+ signs >>= 1;
636
+ }
637
+
638
+ mld_assert_bound(c->coeffs, MLDSA_N, -1, 2);
639
+ mld_shake256_release(&state);
640
+
641
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
642
+ mld_zeroize(buf, sizeof(buf));
643
+ mld_zeroize(&signs, sizeof(signs));
644
+ }
645
+ #endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */
646
+
647
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
648
+ MLD_INTERNAL_API
649
+ void mld_polyeta_pack(uint8_t r[MLDSA_POLYETA_PACKEDBYTES], const mld_poly *a)
650
+ {
651
+ unsigned int i;
652
+ uint8_t t[8];
653
+
654
+ mld_assert_abs_bound(a->coeffs, MLDSA_N, MLDSA_ETA + 1);
655
+
656
+ #if MLDSA_ETA == 2
657
+ for (i = 0; i < MLDSA_N / 8; ++i)
658
+ __loop__(
659
+ invariant(i <= MLDSA_N/8)
660
+ decreases(MLDSA_N / 8 - i))
661
+ {
662
+ /* The casts are safe since we assume that the coefficients
663
+ * of a are <= MLDSA_ETA in absolute value. */
664
+ t[0] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 0]);
665
+ t[1] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 1]);
666
+ t[2] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 2]);
667
+ t[3] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 3]);
668
+ t[4] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 4]);
669
+ t[5] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 5]);
670
+ t[6] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 6]);
671
+ t[7] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 7]);
672
+
673
+ r[3 * i + 0] = (uint8_t)(((t[0] >> 0) | (t[1] << 3) | (t[2] << 6)) & 0xFF);
674
+ r[3 * i + 1] =
675
+ (uint8_t)(((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7)) &
676
+ 0xFF);
677
+ r[3 * i + 2] = (uint8_t)(((t[5] >> 1) | (t[6] << 2) | (t[7] << 5)) & 0xFF);
678
+ }
679
+ #elif MLDSA_ETA == 4
680
+ for (i = 0; i < MLDSA_N / 2; ++i)
681
+ __loop__(
682
+ invariant(i <= MLDSA_N/2)
683
+ decreases(MLDSA_N / 2 - i))
684
+ {
685
+ /* The casts are safe since we assume that the coefficients
686
+ * of a are <= MLDSA_ETA in absolute value. */
687
+ t[0] = (uint8_t)(MLDSA_ETA - a->coeffs[2 * i + 0]);
688
+ t[1] = (uint8_t)(MLDSA_ETA - a->coeffs[2 * i + 1]);
689
+ r[i] = (uint8_t)(t[0] | (t[1] << 4));
690
+ }
691
+ #else /* MLDSA_ETA == 4 */
692
+ #error "Invalid value of MLDSA_ETA"
693
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
694
+ }
695
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
696
+
697
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API)
698
+ MLD_INTERNAL_API
699
+ void mld_polyeta_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYETA_PACKEDBYTES])
700
+ {
701
+ unsigned int i;
702
+
703
+ #if MLDSA_ETA == 2
704
+ for (i = 0; i < MLDSA_N / 8; ++i)
705
+ __loop__(
706
+ invariant(i <= MLDSA_N/8)
707
+ invariant(array_bound(r->coeffs, 0, i*8, -5, MLDSA_ETA + 1))
708
+ decreases(MLDSA_N / 8 - i))
709
+ {
710
+ r->coeffs[8 * i + 0] = (a[3 * i + 0] >> 0) & 7;
711
+ r->coeffs[8 * i + 1] = (a[3 * i + 0] >> 3) & 7;
712
+ r->coeffs[8 * i + 2] = ((a[3 * i + 0] >> 6) | (a[3 * i + 1] << 2)) & 7;
713
+ r->coeffs[8 * i + 3] = (a[3 * i + 1] >> 1) & 7;
714
+ r->coeffs[8 * i + 4] = (a[3 * i + 1] >> 4) & 7;
715
+ r->coeffs[8 * i + 5] = ((a[3 * i + 1] >> 7) | (a[3 * i + 2] << 1)) & 7;
716
+ r->coeffs[8 * i + 6] = (a[3 * i + 2] >> 2) & 7;
717
+ r->coeffs[8 * i + 7] = (a[3 * i + 2] >> 5) & 7;
718
+
719
+ r->coeffs[8 * i + 0] = MLDSA_ETA - r->coeffs[8 * i + 0];
720
+ r->coeffs[8 * i + 1] = MLDSA_ETA - r->coeffs[8 * i + 1];
721
+ r->coeffs[8 * i + 2] = MLDSA_ETA - r->coeffs[8 * i + 2];
722
+ r->coeffs[8 * i + 3] = MLDSA_ETA - r->coeffs[8 * i + 3];
723
+ r->coeffs[8 * i + 4] = MLDSA_ETA - r->coeffs[8 * i + 4];
724
+ r->coeffs[8 * i + 5] = MLDSA_ETA - r->coeffs[8 * i + 5];
725
+ r->coeffs[8 * i + 6] = MLDSA_ETA - r->coeffs[8 * i + 6];
726
+ r->coeffs[8 * i + 7] = MLDSA_ETA - r->coeffs[8 * i + 7];
727
+ }
728
+ #elif MLDSA_ETA == 4
729
+ for (i = 0; i < MLDSA_N / 2; ++i)
730
+ __loop__(
731
+ invariant(i <= MLDSA_N/2)
732
+ invariant(array_bound(r->coeffs, 0, i*2, -11, MLDSA_ETA + 1))
733
+ decreases(MLDSA_N / 2 - i))
734
+ {
735
+ r->coeffs[2 * i + 0] = a[i] & 0x0F;
736
+ r->coeffs[2 * i + 1] = a[i] >> 4;
737
+ r->coeffs[2 * i + 0] = MLDSA_ETA - r->coeffs[2 * i + 0];
738
+ r->coeffs[2 * i + 1] = MLDSA_ETA - r->coeffs[2 * i + 1];
739
+ }
740
+ #else /* MLDSA_ETA == 4 */
741
+ #error "Invalid value of MLDSA_ETA"
742
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
743
+
744
+ mld_assert_bound(r->coeffs, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND,
745
+ MLDSA_ETA + 1);
746
+ }
747
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_SIGN_API */
748
+
749
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
750
+ MLD_INTERNAL_API
751
+ void mld_polyz_pack(uint8_t r[MLDSA_POLYZ_PACKEDBYTES], const mld_poly *a)
752
+ {
753
+ unsigned int i;
754
+ uint32_t t[4];
755
+
756
+ mld_assert_bound(a->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
757
+
758
+ #if MLD_CONFIG_PARAMETER_SET == 44
759
+ for (i = 0; i < MLDSA_N / 4; ++i)
760
+ __loop__(
761
+ invariant(i <= MLDSA_N/4)
762
+ decreases(MLDSA_N / 4 - i))
763
+ {
764
+ /* Safety: a->coeffs[i] <= MLDSA_GAMMA1, hence, these casts are safe. */
765
+ t[0] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 0]);
766
+ t[1] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 1]);
767
+ t[2] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 2]);
768
+ t[3] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 3]);
769
+
770
+ r[9 * i + 0] = (uint8_t)((t[0]) & 0xFF);
771
+ r[9 * i + 1] = (uint8_t)((t[0] >> 8) & 0xFF);
772
+ r[9 * i + 2] = (uint8_t)((t[0] >> 16) & 0xFF);
773
+ r[9 * i + 2] |= (uint8_t)((t[1] << 2) & 0xFF);
774
+ r[9 * i + 3] = (uint8_t)((t[1] >> 6) & 0xFF);
775
+ r[9 * i + 4] = (uint8_t)((t[1] >> 14) & 0xFF);
776
+ r[9 * i + 4] |= (uint8_t)((t[2] << 4) & 0xFF);
777
+ r[9 * i + 5] = (uint8_t)((t[2] >> 4) & 0xFF);
778
+ r[9 * i + 6] = (uint8_t)((t[2] >> 12) & 0xFF);
779
+ r[9 * i + 6] |= (uint8_t)((t[3] << 6) & 0xFF);
780
+ r[9 * i + 7] = (uint8_t)((t[3] >> 2) & 0xFF);
781
+ r[9 * i + 8] = (uint8_t)((t[3] >> 10) & 0xFF);
782
+ }
783
+ #else /* MLD_CONFIG_PARAMETER_SET == 44 */
784
+ for (i = 0; i < MLDSA_N / 2; ++i)
785
+ __loop__(
786
+ invariant(i <= MLDSA_N/2)
787
+ decreases(MLDSA_N / 2 - i))
788
+ {
789
+ /* Safety: a->coeffs[i] <= MLDSA_GAMMA1, hence, these casts are safe. */
790
+ t[0] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[2 * i + 0]);
791
+ t[1] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[2 * i + 1]);
792
+
793
+ r[5 * i + 0] = (uint8_t)((t[0]) & 0xFF);
794
+ r[5 * i + 1] = (uint8_t)((t[0] >> 8) & 0xFF);
795
+ r[5 * i + 2] = (uint8_t)((t[0] >> 16) & 0xFF);
796
+ r[5 * i + 2] |= (uint8_t)((t[1] << 4) & 0xFF);
797
+ r[5 * i + 3] = (uint8_t)((t[1] >> 4) & 0xFF);
798
+ r[5 * i + 4] = (uint8_t)((t[1] >> 12) & 0xFF);
799
+ }
800
+ #endif /* MLD_CONFIG_PARAMETER_SET != 44 */
801
+ }
802
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
803
+
804
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
805
+ MLD_STATIC_TESTABLE void mld_polyz_unpack_c(
806
+ mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES])
807
+ __contract__(
808
+ requires(memory_no_alias(r, sizeof(mld_poly)))
809
+ requires(memory_no_alias(a, MLDSA_POLYZ_PACKEDBYTES))
810
+ assigns(memory_slice(r, sizeof(mld_poly)))
811
+ ensures(array_bound(r->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
812
+ )
813
+ {
814
+ unsigned int i;
815
+ #if MLD_CONFIG_PARAMETER_SET == 44
816
+ for (i = 0; i < MLDSA_N / 4; ++i)
817
+ __loop__(
818
+ invariant(i <= MLDSA_N/4)
819
+ invariant(array_bound(r->coeffs, 0, i*4, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
820
+ decreases(MLDSA_N / 4 - i))
821
+ {
822
+ r->coeffs[4 * i + 0] = a[9 * i + 0];
823
+ r->coeffs[4 * i + 0] |= (int32_t)a[9 * i + 1] << 8;
824
+ r->coeffs[4 * i + 0] |= (int32_t)a[9 * i + 2] << 16;
825
+ r->coeffs[4 * i + 0] &= 0x3FFFF;
826
+
827
+ r->coeffs[4 * i + 1] = a[9 * i + 2] >> 2;
828
+ r->coeffs[4 * i + 1] |= (int32_t)a[9 * i + 3] << 6;
829
+ r->coeffs[4 * i + 1] |= (int32_t)a[9 * i + 4] << 14;
830
+ r->coeffs[4 * i + 1] &= 0x3FFFF;
831
+
832
+ r->coeffs[4 * i + 2] = a[9 * i + 4] >> 4;
833
+ r->coeffs[4 * i + 2] |= (int32_t)a[9 * i + 5] << 4;
834
+ r->coeffs[4 * i + 2] |= (int32_t)a[9 * i + 6] << 12;
835
+ r->coeffs[4 * i + 2] &= 0x3FFFF;
836
+
837
+ r->coeffs[4 * i + 3] = a[9 * i + 6] >> 6;
838
+ r->coeffs[4 * i + 3] |= (int32_t)a[9 * i + 7] << 2;
839
+ r->coeffs[4 * i + 3] |= (int32_t)a[9 * i + 8] << 10;
840
+ r->coeffs[4 * i + 3] &= 0x3FFFF;
841
+
842
+ r->coeffs[4 * i + 0] = MLDSA_GAMMA1 - r->coeffs[4 * i + 0];
843
+ r->coeffs[4 * i + 1] = MLDSA_GAMMA1 - r->coeffs[4 * i + 1];
844
+ r->coeffs[4 * i + 2] = MLDSA_GAMMA1 - r->coeffs[4 * i + 2];
845
+ r->coeffs[4 * i + 3] = MLDSA_GAMMA1 - r->coeffs[4 * i + 3];
846
+ }
847
+ #else /* MLD_CONFIG_PARAMETER_SET == 44 */
848
+ for (i = 0; i < MLDSA_N / 2; ++i)
849
+ __loop__(
850
+ invariant(i <= MLDSA_N/2)
851
+ invariant(array_bound(r->coeffs, 0, i*2, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
852
+ decreases(MLDSA_N / 2 - i))
853
+ {
854
+ r->coeffs[2 * i + 0] = a[5 * i + 0];
855
+ r->coeffs[2 * i + 0] |= (int32_t)a[5 * i + 1] << 8;
856
+ r->coeffs[2 * i + 0] |= (int32_t)a[5 * i + 2] << 16;
857
+ r->coeffs[2 * i + 0] &= 0xFFFFF;
858
+
859
+ r->coeffs[2 * i + 1] = a[5 * i + 2] >> 4;
860
+ r->coeffs[2 * i + 1] |= (int32_t)a[5 * i + 3] << 4;
861
+ r->coeffs[2 * i + 1] |= (int32_t)a[5 * i + 4] << 12;
862
+ /* r->coeffs[2*i+1] &= 0xFFFFF; */ /* No effect, since we're anyway at 20
863
+ bits */
864
+
865
+ r->coeffs[2 * i + 0] = MLDSA_GAMMA1 - r->coeffs[2 * i + 0];
866
+ r->coeffs[2 * i + 1] = MLDSA_GAMMA1 - r->coeffs[2 * i + 1];
867
+ }
868
+ #endif /* MLD_CONFIG_PARAMETER_SET != 44 */
869
+ mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
870
+ }
871
+
872
+ MLD_INTERNAL_API
873
+ void mld_polyz_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES])
874
+ {
875
+ #if defined(MLD_USE_NATIVE_POLYZ_UNPACK_17) && MLD_CONFIG_PARAMETER_SET == 44
876
+ int ret;
877
+ ret = mld_polyz_unpack_17_native(r->coeffs, a);
878
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
879
+ {
880
+ mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
881
+ return;
882
+ }
883
+ #elif defined(MLD_USE_NATIVE_POLYZ_UNPACK_19) && \
884
+ (MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
885
+ int ret;
886
+ ret = mld_polyz_unpack_19_native(r->coeffs, a);
887
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
888
+ {
889
+ mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
890
+ return;
891
+ }
892
+ #endif /* !(MLD_USE_NATIVE_POLYZ_UNPACK_17 && MLD_CONFIG_PARAMETER_SET == 44) \
893
+ && MLD_USE_NATIVE_POLYZ_UNPACK_19 && (MLD_CONFIG_PARAMETER_SET == 65 \
894
+ || MLD_CONFIG_PARAMETER_SET == 87) */
895
+
896
+ mld_polyz_unpack_c(r, a);
897
+ }
898
+ #endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */
899
+
900
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros. */
901
+
902
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
903
+ * Don't modify by hand -- this is auto-generated by scripts/autogen. */
904
+ #undef mld_rej_eta
905
+ #undef mld_rej_eta_c
906
+ #undef mld_poly_decompose_c
907
+ #undef mld_poly_use_hint_c
908
+ #undef mld_polyz_unpack_c
909
+ #undef MLD_POLY_UNIFORM_ETA_NBLOCKS
910
+ #undef MLD_POLY_UNIFORM_GAMMA1_NBLOCKS