pq_crypto 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/SECURITY.md +7 -0
  4. data/ext/pqcrypto/pqcrypto_version.h +1 -1
  5. data/ext/pqcrypto/vendor/.vendored +4 -4
  6. data/ext/pqcrypto/vendor/mldsa-native/README.md +23 -10
  7. data/ext/pqcrypto/vendor/mldsa-native/mldsa/README.md +23 -0
  8. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +114 -58
  9. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +498 -461
  10. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +145 -85
  11. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +456 -422
  12. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +47 -25
  13. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +26 -14
  14. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +56 -81
  15. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +17 -24
  16. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.c +33 -40
  17. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.h +67 -87
  18. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +19 -14
  19. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +13 -5
  20. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +84 -10
  21. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +10 -5
  22. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +6 -0
  23. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +22 -15
  24. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +376 -0
  25. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +204 -0
  26. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +259 -0
  27. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +1077 -0
  28. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +987 -0
  29. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +16 -10
  30. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +2 -1
  31. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +1 -1
  32. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +4 -2
  33. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +2 -2
  34. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +1 -1
  35. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +60 -0
  36. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +48 -0
  37. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +18 -1
  38. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +658 -582
  39. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +5 -100
  40. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +26 -25
  41. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/state_extract_bytes_x4_mve.S +334 -0
  42. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/state_xor_bytes_x4_mve.S +355 -0
  43. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +8 -3
  44. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/{xkcp.h → keccak_f1600_x4_avx2.h} +11 -8
  45. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +44 -0
  46. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +454 -0
  47. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccakf1600_constants.c +52 -0
  48. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +37 -28
  49. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +213 -196
  50. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +248 -64
  51. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt_aarch64_asm.S +753 -0
  52. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S +129 -0
  53. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S +145 -0
  54. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S +177 -0
  55. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt_aarch64_asm.S +653 -0
  56. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery_aarch64_asm.S +84 -0
  57. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_aarch64_asm.S +53 -0
  58. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_aarch64_asm.S +55 -0
  59. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_aarch64_asm.S +86 -0
  60. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_aarch64_asm.S +86 -0
  61. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_aarch64_asm.S +103 -0
  62. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_aarch64_asm.S +111 -0
  63. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_aarch64_asm.S +75 -0
  64. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_aarch64_asm.S +72 -0
  65. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +23 -11
  66. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_aarch64_asm.S +189 -0
  67. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_aarch64_asm.S +137 -0
  68. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_aarch64_asm.S +130 -0
  69. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +520 -516
  70. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +34 -33
  71. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +202 -242
  72. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +25 -17
  73. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +112 -28
  74. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +1 -1
  75. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +1 -1
  76. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt_avx2_asm.S +2311 -0
  77. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt_avx2_asm.S +2383 -0
  78. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack_avx2_asm.S +238 -0
  79. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4_avx2_asm.S +139 -0
  80. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5_avx2_asm.S +155 -0
  81. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7_avx2_asm.S +187 -0
  82. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_avx2_asm.S +130 -0
  83. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_caddq_avx2_asm.S +190 -0
  84. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +6 -4
  85. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +6 -4
  86. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +9 -8
  87. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +10 -9
  88. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +8 -5
  89. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +8 -5
  90. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +6 -4
  91. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +6 -4
  92. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +130 -129
  93. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +109 -180
  94. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +169 -150
  95. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +56 -40
  96. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +149 -164
  97. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +52 -57
  98. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +132 -167
  99. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +57 -424
  100. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +167 -474
  101. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +308 -0
  102. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +653 -0
  103. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +22 -29
  104. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +37 -43
  105. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +511 -367
  106. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +456 -417
  107. data/lib/pq_crypto/version.rb +1 -1
  108. data/script/vendor_libs.rb +3 -3
  109. metadata +41 -35
  110. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm.S +0 -376
  111. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm.S +0 -204
  112. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm.S +0 -259
  113. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm.S +0 -1077
  114. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm.S +0 -987
  115. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.c +0 -488
  116. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.h +0 -16
  117. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt.S +0 -753
  118. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4.S +0 -129
  119. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5.S +0 -145
  120. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7.S +0 -177
  121. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt.S +0 -653
  122. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery.S +0 -79
  123. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_asm.S +0 -53
  124. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_asm.S +0 -55
  125. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_asm.S +0 -85
  126. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_asm.S +0 -85
  127. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_asm.S +0 -102
  128. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_asm.S +0 -110
  129. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_asm.S +0 -72
  130. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_asm.S +0 -69
  131. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_asm.S +0 -189
  132. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_asm.S +0 -135
  133. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_asm.S +0 -128
  134. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt.S +0 -2311
  135. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt.S +0 -2383
  136. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack.S +0 -239
  137. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise.S +0 -131
  138. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4.S +0 -139
  139. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5.S +0 -155
  140. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7.S +0 -187
  141. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_caddq_avx2.c +0 -61
@@ -6,113 +6,115 @@
6
6
  #define MLD_PACKING_H
7
7
 
8
8
  #include "polyvec.h"
9
+ #include "polyvec_lazy.h"
9
10
 
10
- #define mld_pack_pk MLD_NAMESPACE_KL(pack_pk)
11
- /*************************************************
12
- * Name: mld_pack_pk
11
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
12
+ #define mld_pack_sk_s1 MLD_NAMESPACE_KL(pack_sk_s1)
13
+ /**
14
+ * Bit-pack the s1 component into the secret key.
13
15
  *
14
- * Description: Bit-pack public key pk = (rho, t1).
15
- *
16
- * Arguments: - uint8_t pk[]: output byte array
17
- * - const uint8_t rho[]: byte array containing rho
18
- * - const mld_polyveck *t1: pointer to vector t1
19
- **************************************************/
16
+ * @param[out] sk Output byte array.
17
+ * @param[in] s1 Pointer to vector s1.
18
+ */
20
19
  MLD_INTERNAL_API
21
- void mld_pack_pk(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
22
- const uint8_t rho[MLDSA_SEEDBYTES], const mld_polyveck *t1)
20
+ void mld_pack_sk_s1(uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
21
+ const mld_polyvecl *s1)
23
22
  __contract__(
24
- requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
25
- requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
26
- requires(memory_no_alias(t1, sizeof(mld_polyveck)))
27
- requires(forall(k0, 0, MLDSA_K,
28
- array_bound(t1->vec[k0].coeffs, 0, MLDSA_N, 0, 1 << 10)))
29
- assigns(memory_slice(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
23
+ requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
24
+ requires(memory_no_alias(s1, sizeof(mld_polyvecl)))
25
+ requires(forall(k1, 0, MLDSA_L,
26
+ array_abs_bound(s1->vec[k1].coeffs, 0, MLDSA_N, MLDSA_ETA + 1)))
27
+ assigns(memory_slice(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
30
28
  );
31
29
 
32
-
33
- #define mld_pack_sk MLD_NAMESPACE_KL(pack_sk)
34
- /*************************************************
35
- * Name: mld_pack_sk
36
- *
37
- * Description: Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
38
- *
39
- * Arguments: - uint8_t sk[]: output byte array
40
- * - const uint8_t rho[]: byte array containing rho
41
- * - const uint8_t tr[]: byte array containing tr
42
- * - const uint8_t key[]: byte array containing key
43
- * - const mld_polyveck *t0: pointer to vector t0
44
- * - const mld_polyvecl *s1: pointer to vector s1
45
- * - const mld_polyveck *s2: pointer to vector s2
46
- **************************************************/
30
+ #define mld_pack_sk_rho_key_tr_s2 MLD_NAMESPACE_KL(pack_sk_rho_key_tr_s2)
31
+ /**
32
+ * Bit-pack rho, key, tr, s2 into the secret key.
33
+ *
34
+ * s1 must already be packed via mld_pack_sk_s1, and t0 via
35
+ * mld_compute_pack_t0_t1.
36
+ *
37
+ * @param[out] sk Output byte array.
38
+ * @param[in] rho Byte array containing rho.
39
+ * @param[in] tr Byte array containing tr.
40
+ * @param[in] key Byte array containing key.
41
+ * @param[in] s2 Pointer to vector s2.
42
+ */
47
43
  MLD_INTERNAL_API
48
- void mld_pack_sk(uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
49
- const uint8_t rho[MLDSA_SEEDBYTES],
50
- const uint8_t tr[MLDSA_TRBYTES],
51
- const uint8_t key[MLDSA_SEEDBYTES], const mld_polyveck *t0,
52
- const mld_polyvecl *s1, const mld_polyveck *s2)
44
+ void mld_pack_sk_rho_key_tr_s2(uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
45
+ const uint8_t rho[MLDSA_SEEDBYTES],
46
+ const uint8_t tr[MLDSA_TRBYTES],
47
+ const uint8_t key[MLDSA_SEEDBYTES],
48
+ const mld_polyveck *s2)
53
49
  __contract__(
54
50
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
55
51
  requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
56
52
  requires(memory_no_alias(tr, MLDSA_TRBYTES))
57
53
  requires(memory_no_alias(key, MLDSA_SEEDBYTES))
58
- requires(memory_no_alias(t0, sizeof(mld_polyveck)))
59
- requires(memory_no_alias(s1, sizeof(mld_polyvecl)))
60
54
  requires(memory_no_alias(s2, sizeof(mld_polyveck)))
61
- requires(forall(k0, 0, MLDSA_K,
62
- array_bound(t0->vec[k0].coeffs, 0, MLDSA_N, -(1<<(MLDSA_D-1)) + 1, (1<<(MLDSA_D-1)) + 1)))
63
- requires(forall(k1, 0, MLDSA_L,
64
- array_abs_bound(s1->vec[k1].coeffs, 0, MLDSA_N, MLDSA_ETA + 1)))
65
55
  requires(forall(k2, 0, MLDSA_K,
66
56
  array_abs_bound(s2->vec[k2].coeffs, 0, MLDSA_N, MLDSA_ETA + 1)))
67
57
  assigns(memory_slice(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
68
58
  );
59
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
69
60
 
70
61
 
71
- #define mld_pack_sig_c_h MLD_NAMESPACE_KL(pack_sig_c_h)
72
- /*************************************************
73
- * Name: mld_pack_sig_c_h
74
- *
75
- * Description: Bit-pack c and h component of sig = (c, z, h).
76
- * The z component is packed separately using mld_pack_sig_z.
77
- *
78
- * Arguments: - uint8_t sig[]: output byte array
79
- * - const uint8_t *c: pointer to challenge hash length
80
- * MLDSA_SEEDBYTES
81
- * - const mld_polyveck *h: pointer to hint vector h
82
- * - const unsigned int number_of_hints: total
83
- * hints in *h
62
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
63
+ #define mld_pack_sig_c MLD_NAMESPACE_KL(pack_sig_c)
64
+ /**
65
+ * Bit-pack challenge c into sig = (c, z, h).
84
66
  *
85
- * Note that the number_of_hints argument is not present
86
- * in the reference implementation. It is added here to ease
87
- * proof of type safety.
88
- **************************************************/
67
+ * @param[out] sig Output byte array.
68
+ * @param[in] c Pointer to challenge hash.
69
+ */
89
70
  MLD_INTERNAL_API
90
- void mld_pack_sig_c_h(uint8_t sig[MLDSA_CRYPTO_BYTES],
91
- const uint8_t c[MLDSA_CTILDEBYTES], const mld_polyveck *h,
92
- const unsigned int number_of_hints)
71
+ void mld_pack_sig_c(uint8_t sig[MLDSA_CRYPTO_BYTES],
72
+ const uint8_t c[MLDSA_CTILDEBYTES])
93
73
  __contract__(
94
74
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
95
75
  requires(memory_no_alias(c, MLDSA_CTILDEBYTES))
96
- requires(memory_no_alias(h, sizeof(mld_polyveck)))
97
- requires(forall(k1, 0, MLDSA_K,
98
- array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
99
- requires(number_of_hints <= MLDSA_OMEGA)
100
76
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
101
77
  );
102
78
 
79
+ #define mld_pack_sig_h MLD_NAMESPACE_KL(pack_sig_h)
80
+ /**
81
+ * Compute hints from (w0, w1) and pack them into the hint section of sig.
82
+ *
83
+ * @param[in,out] sig Byte array containing signature.
84
+ * @param[in] w0 Pointer to low part of input vector.
85
+ * @param[in] w1 Pointer to high part of input vector.
86
+ *
87
+ * @retval 0 Success.
88
+ * @retval MLD_ERR_FAIL The total number of hints exceeds MLDSA_OMEGA. In this
89
+ * case the hint section of sig is left in a
90
+ * partially-written state and the caller must reject the
91
+ * signature.
92
+ */
93
+ MLD_INTERNAL_API
94
+ MLD_MUST_CHECK_RETURN_VALUE
95
+ int mld_pack_sig_h(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_polyveck *w0,
96
+ const mld_polyveck *w1)
97
+ __contract__(
98
+ requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
99
+ requires(memory_no_alias(w0, sizeof(mld_polyveck)))
100
+ requires(memory_no_alias(w1, sizeof(mld_polyveck)))
101
+ assigns(memory_slice(
102
+ sig + MLDSA_CTILDEBYTES + MLDSA_L * MLDSA_POLYZ_PACKEDBYTES,
103
+ MLDSA_POLYVECH_PACKEDBYTES))
104
+ ensures(return_value == 0 || return_value == MLD_ERR_FAIL)
105
+ );
106
+
103
107
  #define mld_pack_sig_z MLD_NAMESPACE_KL(pack_sig_z)
104
- /*************************************************
105
- * Name: mld_pack_sig_z
108
+ /**
109
+ * Bit-pack single polynomial of z component of sig = (c, z, h).
106
110
  *
107
- * Description: Bit-pack single polynomial of z component of sig = (c, z, h).
108
- * The c and h components are packed separately using
109
- * mld_pack_sig_c_h.
111
+ * The c and h components are packed separately using mld_pack_sig_c and
112
+ * mld_pack_sig_h.
110
113
  *
111
- * Arguments: - uint8_t sig[]: output byte array
112
- * - const mld_poly *zi: pointer to a single polynomial in z
113
- * - const unsigned int i: index of zi in vector z
114
- *
115
- **************************************************/
114
+ * @param[in,out] sig Output byte array.
115
+ * @param[in] zi Pointer to a single polynomial in z.
116
+ * @param i Index of zi in vector z.
117
+ */
116
118
  MLD_INTERNAL_API
117
119
  void mld_pack_sig_z(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_poly *zi,
118
120
  unsigned i)
@@ -123,102 +125,119 @@ __contract__(
123
125
  requires(array_bound(zi->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
124
126
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
125
127
  );
128
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
126
129
 
127
- #define mld_unpack_pk MLD_NAMESPACE_KL(unpack_pk)
128
- /*************************************************
129
- * Name: mld_unpack_pk
130
- *
131
- * Description: Unpack public key pk = (rho, t1).
132
- *
133
- * Arguments: - const uint8_t rho[]: output byte array for rho
134
- * - const mld_polyveck *t1: pointer to output vector t1
135
- * - uint8_t pk[]: byte array containing bit-packed pk
136
- **************************************************/
130
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
131
+ #define mld_unpack_pk_t1 MLD_NAMESPACE_KL(unpack_pk_t1)
132
+ /**
133
+ * Unpack a single polynomial of the t1 component of a public key
134
+ * pk = (rho, t1).
135
+ *
136
+ * @param[out] t1 Pointer to output polynomial t1[i].
137
+ * @param[in] pk Byte array containing bit-packed pk.
138
+ * @param i Row index, must be < MLDSA_K.
139
+ */
137
140
  MLD_INTERNAL_API
138
- void mld_unpack_pk(uint8_t rho[MLDSA_SEEDBYTES], mld_polyveck *t1,
139
- const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES])
141
+ void mld_unpack_pk_t1(mld_poly *t1,
142
+ const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
143
+ unsigned int i)
140
144
  __contract__(
141
145
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
142
- requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
143
- requires(memory_no_alias(t1, sizeof(mld_polyveck)))
144
- assigns(memory_slice(rho, MLDSA_SEEDBYTES))
145
- assigns(memory_slice(t1, sizeof(mld_polyveck)))
146
- ensures(forall(k0, 0, MLDSA_K,
147
- array_bound(t1->vec[k0].coeffs, 0, MLDSA_N, 0, 1 << 10)))
146
+ requires(memory_no_alias(t1, sizeof(mld_poly)))
147
+ requires(i < MLDSA_K)
148
+ assigns(memory_slice(t1, sizeof(mld_poly)))
149
+ ensures(array_bound(t1->coeffs, 0, MLDSA_N, 0, 1 << 10))
148
150
  );
151
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
149
152
 
150
-
153
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
151
154
  #define mld_unpack_sk MLD_NAMESPACE_KL(unpack_sk)
152
- /*************************************************
153
- * Name: mld_unpack_sk
154
- *
155
- * Description: Unpack secret key sk = (rho, tr, key, t0, s1, s2).
156
- *
157
- * Arguments: - const uint8_t rho[]: output byte array for rho
158
- * - const uint8_t tr[]: output byte array for tr
159
- * - const uint8_t key[]: output byte array for key
160
- * - const mld_polyveck *t0: pointer to output vector t0
161
- * - const mld_polyvecl *s1: pointer to output vector s1
162
- * - const mld_polyveck *s2: pointer to output vector s2
163
- * - uint8_t sk[]: byte array containing bit-packed sk
164
- **************************************************/
155
+ /**
156
+ * Unpack secret key sk = (rho, tr, key, t0, s1, s2).
157
+ *
158
+ * NOTE: In REDUCE_RAM mode, s1/s2/t0 borrow from sk rather than copying.
159
+ *
160
+ * @param[out] rho Output byte array for rho.
161
+ * @param[out] tr Output byte array for tr.
162
+ * @param[out] key Output byte array for key.
163
+ * @param[out] t0 Pointer to output vector t0.
164
+ * @param[out] s1 Pointer to output vector s1.
165
+ * @param[out] s2 Pointer to output vector s2.
166
+ * @param[in] sk Byte array containing bit-packed sk.
167
+ */
165
168
  MLD_INTERNAL_API
166
169
  void mld_unpack_sk(uint8_t rho[MLDSA_SEEDBYTES], uint8_t tr[MLDSA_TRBYTES],
167
- uint8_t key[MLDSA_SEEDBYTES], mld_polyveck *t0,
168
- mld_polyvecl *s1, mld_polyveck *s2,
170
+ uint8_t key[MLDSA_SEEDBYTES], mld_sk_t0hat *t0,
171
+ mld_sk_s1hat *s1, mld_sk_s2hat *s2,
169
172
  const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES])
170
173
  __contract__(
171
174
  requires(memory_no_alias(rho, MLDSA_SEEDBYTES))
172
175
  requires(memory_no_alias(tr, MLDSA_TRBYTES))
173
176
  requires(memory_no_alias(key, MLDSA_SEEDBYTES))
174
- requires(memory_no_alias(t0, sizeof(mld_polyveck)))
175
- requires(memory_no_alias(s1, sizeof(mld_polyvecl)))
176
- requires(memory_no_alias(s2, sizeof(mld_polyveck)))
177
+ requires(memory_no_alias(t0, sizeof(mld_sk_t0hat)))
178
+ requires(memory_no_alias(s1, sizeof(mld_sk_s1hat)))
179
+ requires(memory_no_alias(s2, sizeof(mld_sk_s2hat)))
177
180
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
178
181
  assigns(memory_slice(rho, MLDSA_SEEDBYTES))
179
182
  assigns(memory_slice(tr, MLDSA_TRBYTES))
180
183
  assigns(memory_slice(key, MLDSA_SEEDBYTES))
181
- assigns(memory_slice(t0, sizeof(mld_polyveck)))
182
- assigns(memory_slice(s1, sizeof(mld_polyvecl)))
183
- assigns(memory_slice(s2, sizeof(mld_polyveck)))
184
- ensures(forall(k0, 0, MLDSA_K,
185
- array_bound(t0->vec[k0].coeffs, 0, MLDSA_N, -(1<<(MLDSA_D-1)) + 1, (1<<(MLDSA_D-1)) + 1)))
186
- ensures(forall(k1, 0, MLDSA_L,
187
- array_bound(s1->vec[k1].coeffs, 0, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND, MLDSA_ETA + 1)))
188
- ensures(forall(k2, 0, MLDSA_K,
189
- array_bound(s2->vec[k2].coeffs, 0, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND, MLDSA_ETA + 1)))
184
+ assigns(memory_slice(t0, sizeof(mld_sk_t0hat)))
185
+ assigns(memory_slice(s1, sizeof(mld_sk_s1hat)))
186
+ assigns(memory_slice(s2, sizeof(mld_sk_s2hat)))
187
+ MLD_IF_NOT_REDUCE_RAM(
188
+ ensures(forall(k0, 0, MLDSA_K,
189
+ array_abs_bound(t0->vec.vec[k0].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
190
+ ensures(forall(k1, 0, MLDSA_L,
191
+ array_abs_bound(s1->vec.vec[k1].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
192
+ ensures(forall(k2, 0, MLDSA_K,
193
+ array_abs_bound(s2->vec.vec[k2].coeffs, 0, MLDSA_N, MLD_NTT_BOUND)))
194
+ )
195
+ MLD_IF_REDUCE_RAM(
196
+ ensures(s1->packed == old(sk) + 2 * MLDSA_SEEDBYTES + MLDSA_TRBYTES)
197
+ ensures(s2->packed == old(sk) + 2 * MLDSA_SEEDBYTES + MLDSA_TRBYTES +
198
+ MLDSA_L * MLDSA_POLYETA_PACKEDBYTES)
199
+ ensures(t0->packed == old(sk) + 2 * MLDSA_SEEDBYTES + MLDSA_TRBYTES +
200
+ (MLDSA_L + MLDSA_K) * MLDSA_POLYETA_PACKEDBYTES)
201
+ )
190
202
  );
203
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
191
204
 
192
- #define mld_unpack_sig MLD_NAMESPACE_KL(unpack_sig)
193
- /*************************************************
194
- * Name: mld_unpack_sig
195
- *
196
- * Description: Unpack signature sig = (c, z, h).
197
- *
198
- * Arguments: - uint8_t *c: pointer to output challenge hash
199
- * - mld_polyvecl *z: pointer to output vector z
200
- * - mld_polyveck *h: pointer to output hint vector h
201
- * - const uint8_t sig[]: byte array containing
202
- * bit-packed signature
203
- *
204
- * Returns 1 in case of malformed signature; otherwise 0.
205
- **************************************************/
205
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
206
+ #define mld_sig_unpack_hints MLD_NAMESPACE_KL(sig_unpack_hints)
207
+ /**
208
+ * Decode and validate a single row of the hint vector h from a signature
209
+ * buffer.
210
+ *
211
+ * The hint encoding is shared across all rows (a count array followed by a
212
+ * single index list), so this function performs the validation relevant to
213
+ * row i:
214
+ * - the i'th hint count is non-decreasing and bounded by MLDSA_OMEGA;
215
+ * - the indices for row i are strictly ascending;
216
+ * - on i == MLDSA_K - 1, the trailing index slots are zero.
217
+ *
218
+ * Callers must invoke this for every i in [0, 1, .., MLDSA_K - 1]; if any
219
+ * call returns MLD_ERR_FAIL the encoding is malformed and the signature must
220
+ * be rejected.
221
+ *
222
+ * @param[out] h Pointer to output polynomial h[i].
223
+ * @param[in] sig Signature buffer.
224
+ * @param i Row index, must be < MLDSA_K.
225
+ *
226
+ * @retval 0 Hints were decoded successfully.
227
+ * @retval MLD_ERR_FAIL Hints are malformed.
228
+ */
206
229
  MLD_INTERNAL_API
207
230
  MLD_MUST_CHECK_RETURN_VALUE
208
- int mld_unpack_sig(uint8_t c[MLDSA_CTILDEBYTES], mld_polyvecl *z,
209
- mld_polyveck *h, const uint8_t sig[MLDSA_CRYPTO_BYTES])
231
+ int mld_sig_unpack_hints(mld_poly *h, const uint8_t sig[MLDSA_CRYPTO_BYTES],
232
+ unsigned int i)
210
233
  __contract__(
211
234
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
212
- requires(memory_no_alias(c, MLDSA_CTILDEBYTES))
213
- requires(memory_no_alias(z, sizeof(mld_polyvecl)))
214
- requires(memory_no_alias(h, sizeof(mld_polyveck)))
215
- assigns(memory_slice(c, MLDSA_CTILDEBYTES))
216
- assigns(memory_slice(z, sizeof(mld_polyvecl)))
217
- assigns(memory_slice(h, sizeof(mld_polyveck)))
218
- ensures(forall(k0, 0, MLDSA_L,
219
- array_bound(z->vec[k0].coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1)))
220
- ensures(forall(k1, 0, MLDSA_K,
221
- array_bound(h->vec[k1].coeffs, 0, MLDSA_N, 0, 2)))
222
- ensures(return_value >= 0 && return_value <= 1)
235
+ requires(memory_no_alias(h, sizeof(mld_poly)))
236
+ requires(i < MLDSA_K)
237
+ assigns(memory_slice(h, sizeof(mld_poly)))
238
+ ensures(return_value == 0 || return_value == MLD_ERR_FAIL)
239
+ ensures(return_value == 0 ==> array_bound(h->coeffs, 0, MLDSA_N, 0, 2))
223
240
  );
241
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
242
+
224
243
  #endif /* !MLD_PACKING_H */
@@ -91,6 +91,8 @@ void mld_poly_caddq(mld_poly *a)
91
91
  mld_poly_caddq_c(a);
92
92
  }
93
93
 
94
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API) || !defined(MLD_CONFIG_NO_SIGN_API) || \
95
+ defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
94
96
  /* Reference: We use destructive version (output=first input) to avoid
95
97
  * reasoning about aliasing in the CBMC specification */
96
98
  MLD_INTERNAL_API
@@ -111,7 +113,10 @@ void mld_poly_add(mld_poly *r, const mld_poly *b)
111
113
  r->coeffs[i] = r->coeffs[i] + b->coeffs[i];
112
114
  }
113
115
  }
116
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API || !MLD_CONFIG_NO_SIGN_API || \
117
+ MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
114
118
 
119
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
115
120
  /* Reference: We use destructive version (output=first input) to avoid
116
121
  * reasoning about aliasing in the CBMC specification */
117
122
  MLD_INTERNAL_API
@@ -134,7 +139,9 @@ void mld_poly_sub(mld_poly *r, const mld_poly *b)
134
139
 
135
140
  mld_assert_bound(r->coeffs, MLDSA_N, INT32_MIN, MLD_REDUCE32_DOMAIN_MAX);
136
141
  }
142
+ #endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */
137
143
 
144
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
138
145
  MLD_INTERNAL_API
139
146
  void mld_poly_shiftl(mld_poly *a)
140
147
  {
@@ -155,7 +162,7 @@ void mld_poly_shiftl(mld_poly *a)
155
162
  }
156
163
  mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
157
164
  }
158
-
165
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
159
166
 
160
167
  static MLD_INLINE int32_t mld_fqmul(int32_t a, int32_t b)
161
168
  __contract__(
@@ -324,17 +331,15 @@ void mld_poly_ntt(mld_poly *a)
324
331
  mld_poly_ntt_c(a);
325
332
  }
326
333
 
327
- /*************************************************
328
- * Name: mld_fqscale
334
+ /**
335
+ * Scale a field element by mont/256, i.e., perform Montgomery multiplication
336
+ * by mont^2/256.
329
337
  *
330
- * Description: Scales a field element by mont/256 , i.e., performs Montgomery
331
- * multiplication by mont^2/256.
332
- * Input is expected to have absolute value smaller than
333
- * 256 * MLDSA_Q.
334
- * Output has absolute value smaller than MLD_INTT_BOUND.
338
+ * Input is expected to have absolute value smaller than 256 * MLDSA_Q. Output
339
+ * has absolute value smaller than MLD_INTT_BOUND.
335
340
  *
336
- * Arguments: - int32_t a: Field element to be scaled.
337
- **************************************************/
341
+ * @param a Field element to be scaled.
342
+ */
338
343
  static MLD_INLINE int32_t mld_fqscale(int32_t a)
339
344
  __contract__(
340
345
  requires(a > -256*MLDSA_Q && a < 256*MLDSA_Q)
@@ -451,17 +456,17 @@ void mld_poly_invntt_tomont(mld_poly *a)
451
456
  mld_poly_invntt_tomont_c(a);
452
457
  }
453
458
 
454
- MLD_STATIC_TESTABLE void mld_poly_pointwise_montgomery_c(mld_poly *c,
455
- const mld_poly *a,
459
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API) || \
460
+ defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST)
461
+ MLD_STATIC_TESTABLE void mld_poly_pointwise_montgomery_c(mld_poly *a,
456
462
  const mld_poly *b)
457
463
  __contract__(
458
464
  requires(memory_no_alias(a, sizeof(mld_poly)))
459
465
  requires(memory_no_alias(b, sizeof(mld_poly)))
460
- requires(memory_no_alias(c, sizeof(mld_poly)))
461
466
  requires(array_abs_bound(a->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
462
467
  requires(array_abs_bound(b->coeffs, 0, MLDSA_N, MLD_NTT_BOUND))
463
- assigns(memory_slice(c, sizeof(mld_poly)))
464
- ensures(array_abs_bound(c->coeffs, 0, MLDSA_N, MLDSA_Q))
468
+ assigns(memory_slice(a, sizeof(mld_poly)))
469
+ ensures(array_abs_bound(a->coeffs, 0, MLDSA_N, MLDSA_Q))
465
470
  )
466
471
  {
467
472
  unsigned int i;
@@ -471,33 +476,36 @@ __contract__(
471
476
  for (i = 0; i < MLDSA_N; ++i)
472
477
  __loop__(
473
478
  invariant(i <= MLDSA_N)
474
- invariant(array_abs_bound(c->coeffs, 0, i, MLDSA_Q))
479
+ invariant(array_abs_bound(a->coeffs, 0, i, MLDSA_Q))
480
+ invariant(array_abs_bound(a->coeffs, i, MLDSA_N, MLD_NTT_BOUND))
475
481
  decreases(MLDSA_N - i)
476
482
  )
477
483
  {
478
- c->coeffs[i] = mld_montgomery_reduce((int64_t)a->coeffs[i] * b->coeffs[i]);
484
+ a->coeffs[i] = mld_montgomery_reduce((int64_t)a->coeffs[i] * b->coeffs[i]);
479
485
  }
480
- mld_assert_abs_bound(c->coeffs, MLDSA_N, MLDSA_Q);
486
+ mld_assert_abs_bound(a->coeffs, MLDSA_N, MLDSA_Q);
481
487
  }
482
488
 
483
489
  MLD_INTERNAL_API
484
- void mld_poly_pointwise_montgomery(mld_poly *c, const mld_poly *a,
485
- const mld_poly *b)
490
+ void mld_poly_pointwise_montgomery(mld_poly *a, const mld_poly *b)
486
491
  {
487
492
  #if defined(MLD_USE_NATIVE_POINTWISE_MONTGOMERY)
488
493
  int ret;
489
494
  mld_assert_abs_bound(a->coeffs, MLDSA_N, MLD_NTT_BOUND);
490
495
  mld_assert_abs_bound(b->coeffs, MLDSA_N, MLD_NTT_BOUND);
491
- ret = mld_poly_pointwise_montgomery_native(c->coeffs, a->coeffs, b->coeffs);
496
+ ret = mld_poly_pointwise_montgomery_native(a->coeffs, b->coeffs);
492
497
  if (ret == MLD_NATIVE_FUNC_SUCCESS)
493
498
  {
494
- mld_assert_abs_bound(c->coeffs, MLDSA_N, MLDSA_Q);
499
+ mld_assert_abs_bound(a->coeffs, MLDSA_N, MLDSA_Q);
495
500
  return;
496
501
  }
497
502
  #endif /* MLD_USE_NATIVE_POINTWISE_MONTGOMERY */
498
- mld_poly_pointwise_montgomery_c(c, a, b);
503
+ mld_poly_pointwise_montgomery_c(a, b);
499
504
  }
505
+ #endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API || \
506
+ MLD_CONFIG_REDUCE_RAM || MLD_UNIT_TEST */
500
507
 
508
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
501
509
  MLD_INTERNAL_API
502
510
  void mld_poly_power2round(mld_poly *a1, mld_poly *a0, const mld_poly *a)
503
511
  {
@@ -508,6 +516,7 @@ void mld_poly_power2round(mld_poly *a1, mld_poly *a0, const mld_poly *a)
508
516
  __loop__(
509
517
  assigns(i, memory_slice(a0, sizeof(mld_poly)), memory_slice(a1, sizeof(mld_poly)))
510
518
  invariant(i <= MLDSA_N)
519
+ invariant(forall(k0, i, MLDSA_N, a->coeffs[k0] == loop_entry(*a).coeffs[k0]))
511
520
  invariant(array_bound(a0->coeffs, 0, i, -(MLD_2_POW_D/2)+1, (MLD_2_POW_D/2)+1))
512
521
  invariant(array_bound(a1->coeffs, 0, i, 0, ((MLDSA_Q - 1) / MLD_2_POW_D) + 1))
513
522
  decreases(MLDSA_N - i)
@@ -520,6 +529,7 @@ void mld_poly_power2round(mld_poly *a1, mld_poly *a0, const mld_poly *a)
520
529
  (MLD_2_POW_D / 2) + 1);
521
530
  mld_assert_bound(a1->coeffs, MLDSA_N, 0, ((MLDSA_Q - 1) / MLD_2_POW_D) + 1);
522
531
  }
532
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
523
533
 
524
534
  #ifndef MLD_POLY_UNIFORM_NBLOCKS
525
535
  #define MLD_POLY_UNIFORM_NBLOCKS \
@@ -575,23 +585,19 @@ __contract__(
575
585
 
576
586
  return ctr;
577
587
  }
578
- /*************************************************
579
- * Name: mld_rej_uniform
580
- *
581
- * Description: Sample uniformly random coefficients in [0, MLDSA_Q-1] by
582
- * performing rejection sampling on array of random bytes.
588
+ /**
589
+ * Sample uniformly random coefficients in [0, MLDSA_Q-1] by performing
590
+ * rejection sampling on an array of random bytes.
583
591
  *
584
- * Arguments: - int32_t *a: pointer to output array (allocated)
585
- * - unsigned int target: requested number of coefficients to
586
- *sample
587
- * - unsigned int offset: number of coefficients already sampled
588
- * - const uint8_t *buf: array of random bytes to sample from
589
- * - unsigned int buflen: length of array of random bytes (must be
590
- * multiple of 3)
592
+ * @param[out] a Pointer to output array (allocated).
593
+ * @param target Requested number of coefficients to sample.
594
+ * @param offset Number of coefficients already sampled.
595
+ * @param[in] buf Array of random bytes to sample from.
596
+ * @param buflen Length of array of random bytes (must be multiple of 3).
591
597
  *
592
- * Returns number of sampled coefficients. Can be smaller than len if not enough
593
- * random bytes were given.
594
- **************************************************/
598
+ * @return Number of sampled coefficients. Can be smaller than len if not
599
+ * enough random bytes were given.
600
+ */
595
601
 
596
602
  /* Reference: `mld_rej_uniform()` in the reference implementation @[REF].
597
603
  * - Our signature differs from the reference implementation
@@ -670,7 +676,8 @@ void mld_poly_uniform(mld_poly *a, const uint8_t seed[MLDSA_SEEDBYTES + 2])
670
676
  mld_zeroize(buf, sizeof(buf));
671
677
  }
672
678
 
673
- #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY) && !defined(MLD_CONFIG_REDUCE_RAM)
679
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY) && \
680
+ (!defined(MLD_CONFIG_REDUCE_RAM) || defined(MLD_UNIT_TEST))
674
681
  MLD_INTERNAL_API
675
682
  void mld_poly_uniform_4x(mld_poly *vec0, mld_poly *vec1, mld_poly *vec2,
676
683
  mld_poly *vec3,
@@ -735,8 +742,10 @@ void mld_poly_uniform_4x(mld_poly *vec0, mld_poly *vec1, mld_poly *vec2,
735
742
  mld_zeroize(buf, sizeof(buf));
736
743
  }
737
744
 
738
- #endif /* !MLD_CONFIG_SERIAL_FIPS202_ONLY && !MLD_CONFIG_REDUCE_RAM */
745
+ #endif /* !MLD_CONFIG_SERIAL_FIPS202_ONLY && (!MLD_CONFIG_REDUCE_RAM || \
746
+ MLD_UNIT_TEST) */
739
747
 
748
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
740
749
  MLD_INTERNAL_API
741
750
  void mld_polyt1_pack(uint8_t r[MLDSA_POLYT1_PACKEDBYTES], const mld_poly *a)
742
751
  {
@@ -761,7 +770,9 @@ void mld_polyt1_pack(uint8_t r[MLDSA_POLYT1_PACKEDBYTES], const mld_poly *a)
761
770
  r[5 * i + 4] = (uint8_t)((a->coeffs[4 * i + 3] >> 2) & 0xFF);
762
771
  }
763
772
  }
773
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
764
774
 
775
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
765
776
  MLD_INTERNAL_API
766
777
  void mld_polyt1_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYT1_PACKEDBYTES])
767
778
  {
@@ -785,7 +796,9 @@ void mld_polyt1_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYT1_PACKEDBYTES])
785
796
 
786
797
  mld_assert_bound(r->coeffs, MLDSA_N, 0, 1 << 10);
787
798
  }
799
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
788
800
 
801
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
789
802
  MLD_INTERNAL_API
790
803
  void mld_polyt0_pack(uint8_t r[MLDSA_POLYT0_PACKEDBYTES], const mld_poly *a)
791
804
  {
@@ -833,7 +846,9 @@ void mld_polyt0_pack(uint8_t r[MLDSA_POLYT0_PACKEDBYTES], const mld_poly *a)
833
846
  r[13 * i + 12] = (uint8_t)((t[7] >> 5) & 0xFF);
834
847
  }
835
848
  }
849
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
836
850
 
851
+ #if !defined(MLD_CONFIG_NO_SIGN_API) || defined(MLD_UNIT_TEST)
837
852
  MLD_INTERNAL_API
838
853
  void mld_polyt0_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYT0_PACKEDBYTES])
839
854
  {
@@ -894,6 +909,7 @@ void mld_polyt0_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYT0_PACKEDBYTES])
894
909
  mld_assert_bound(r->coeffs, MLDSA_N, -(1 << (MLDSA_D - 1)) + 1,
895
910
  (1 << (MLDSA_D - 1)) + 1);
896
911
  }
912
+ #endif /* !MLD_CONFIG_NO_SIGN_API || MLD_UNIT_TEST */
897
913
 
898
914
  MLD_STATIC_TESTABLE uint32_t mld_poly_chknorm_c(const mld_poly *a, int32_t B)
899
915
  __contract__(