pq_crypto 0.3.2 → 0.5.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 (328) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +56 -0
  3. data/CHANGELOG.md +62 -0
  4. data/GET_STARTED.md +366 -40
  5. data/README.md +76 -233
  6. data/SECURITY.md +107 -82
  7. data/ext/pqcrypto/extconf.rb +169 -87
  8. data/ext/pqcrypto/mldsa_api.h +1 -48
  9. data/ext/pqcrypto/mlkem_api.h +1 -18
  10. data/ext/pqcrypto/pq_externalmu.c +89 -204
  11. data/ext/pqcrypto/pqcrypto_native_api.h +129 -0
  12. data/ext/pqcrypto/pqcrypto_ruby_secure.c +484 -84
  13. data/ext/pqcrypto/pqcrypto_secure.c +203 -78
  14. data/ext/pqcrypto/pqcrypto_secure.h +53 -14
  15. data/ext/pqcrypto/pqcrypto_version.h +7 -0
  16. data/ext/pqcrypto/randombytes.h +9 -0
  17. data/ext/pqcrypto/vendor/.vendored +10 -5
  18. data/ext/pqcrypto/vendor/mldsa-native/BUILDING.md +105 -0
  19. data/ext/pqcrypto/vendor/mldsa-native/LICENSE +286 -0
  20. data/ext/pqcrypto/vendor/mldsa-native/META.yml +24 -0
  21. data/ext/pqcrypto/vendor/mldsa-native/README.md +221 -0
  22. data/ext/pqcrypto/vendor/mldsa-native/SECURITY.md +8 -0
  23. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +721 -0
  24. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +975 -0
  25. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +724 -0
  26. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +723 -0
  27. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +166 -0
  28. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +321 -0
  29. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.c +21 -0
  30. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +385 -0
  31. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.c +73 -0
  32. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +130 -0
  33. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.c +277 -0
  34. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202.h +244 -0
  35. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +182 -0
  36. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +117 -0
  37. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +438 -0
  38. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +105 -0
  39. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +71 -0
  40. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +62 -0
  41. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm.S +376 -0
  42. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm.S +204 -0
  43. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm.S +259 -0
  44. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm.S +1077 -0
  45. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm.S +987 -0
  46. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +41 -0
  47. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +26 -0
  48. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +35 -0
  49. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +37 -0
  50. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +27 -0
  51. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +36 -0
  52. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +69 -0
  53. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/README.md +10 -0
  54. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +32 -0
  55. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +20 -0
  56. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +638 -0
  57. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +136 -0
  58. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +52 -0
  59. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +29 -0
  60. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.c +488 -0
  61. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/KeccakP_1600_times4_SIMD256.h +16 -0
  62. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/xkcp.h +31 -0
  63. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +247 -0
  64. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +231 -0
  65. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +150 -0
  66. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/intt.S +753 -0
  67. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l4.S +129 -0
  68. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l5.S +145 -0
  69. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/mld_polyvecl_pointwise_acc_montgomery_l7.S +177 -0
  70. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/ntt.S +653 -0
  71. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/pointwise_montgomery.S +79 -0
  72. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_caddq_asm.S +53 -0
  73. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_chknorm_asm.S +55 -0
  74. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_32_asm.S +85 -0
  75. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_decompose_88_asm.S +85 -0
  76. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_32_asm.S +102 -0
  77. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/poly_use_hint_88_asm.S +110 -0
  78. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_17_asm.S +72 -0
  79. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_19_asm.S +69 -0
  80. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +40 -0
  81. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_asm.S +189 -0
  82. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta2_asm.S +135 -0
  83. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta4_asm.S +128 -0
  84. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +543 -0
  85. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +62 -0
  86. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +649 -0
  87. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/meta.h +23 -0
  88. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +315 -0
  89. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +124 -0
  90. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +157 -0
  91. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +27 -0
  92. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/intt.S +2311 -0
  93. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/ntt.S +2383 -0
  94. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/nttunpack.S +239 -0
  95. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise.S +131 -0
  96. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l4.S +139 -0
  97. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l5.S +155 -0
  98. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/pointwise_acc_l7.S +187 -0
  99. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_caddq_avx2.c +61 -0
  100. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_chknorm_avx2.c +52 -0
  101. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +155 -0
  102. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +155 -0
  103. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +102 -0
  104. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +104 -0
  105. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +91 -0
  106. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +93 -0
  107. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_avx2.c +126 -0
  108. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +155 -0
  109. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +139 -0
  110. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +160 -0
  111. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +293 -0
  112. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +224 -0
  113. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/params.h +77 -0
  114. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +991 -0
  115. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +393 -0
  116. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +946 -0
  117. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +360 -0
  118. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +877 -0
  119. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +725 -0
  120. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/randombytes.h +26 -0
  121. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +139 -0
  122. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +249 -0
  123. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +1511 -0
  124. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +806 -0
  125. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/symmetric.h +68 -0
  126. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sys.h +268 -0
  127. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/zetas.inc +55 -0
  128. data/ext/pqcrypto/vendor/mlkem-native/BUILDING.md +104 -0
  129. data/ext/pqcrypto/vendor/mlkem-native/LICENSE +294 -0
  130. data/ext/pqcrypto/vendor/mlkem-native/META.yml +30 -0
  131. data/ext/pqcrypto/vendor/mlkem-native/README.md +223 -0
  132. data/ext/pqcrypto/vendor/mlkem-native/RELEASE.md +86 -0
  133. data/ext/pqcrypto/vendor/mlkem-native/SECURITY.md +8 -0
  134. data/ext/pqcrypto/vendor/mlkem-native/mlkem/README.md +23 -0
  135. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.c +660 -0
  136. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.h +538 -0
  137. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_asm.S +681 -0
  138. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_config.h +709 -0
  139. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/cbmc.h +174 -0
  140. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/common.h +274 -0
  141. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/compress.c +717 -0
  142. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/compress.h +688 -0
  143. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/debug.c +64 -0
  144. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/debug.h +128 -0
  145. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.c +251 -0
  146. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.h +158 -0
  147. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202x4.c +208 -0
  148. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202x4.h +80 -0
  149. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/keccakf1600.c +463 -0
  150. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/keccakf1600.h +98 -0
  151. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/auto.h +70 -0
  152. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/fips202_native_aarch64.h +69 -0
  153. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm.S +375 -0
  154. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_asm.S +203 -0
  155. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_asm.S +258 -0
  156. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_asm.S +1076 -0
  157. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_asm.S +986 -0
  158. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +46 -0
  159. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_scalar.h +25 -0
  160. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_v84a.h +34 -0
  161. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x2_v84a.h +35 -0
  162. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_scalar.h +26 -0
  163. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +35 -0
  164. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/api.h +117 -0
  165. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/README.md +10 -0
  166. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/mve.h +79 -0
  167. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/fips202_native_armv81m.h +35 -0
  168. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +667 -0
  169. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +40 -0
  170. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +51 -0
  171. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/state_extract_bytes_x4_mve.S +290 -0
  172. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/state_xor_bytes_x4_mve.S +314 -0
  173. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/auto.h +28 -0
  174. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +33 -0
  175. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/fips202_native_x86_64.h +41 -0
  176. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2.S +451 -0
  177. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/keccakf1600_constants.c +51 -0
  178. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.c +622 -0
  179. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.h +156 -0
  180. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.c +446 -0
  181. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.h +326 -0
  182. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/README.md +16 -0
  183. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/meta.h +122 -0
  184. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/aarch64_zetas.c +174 -0
  185. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/arith_native_aarch64.h +177 -0
  186. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/intt.S +628 -0
  187. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/ntt.S +562 -0
  188. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/poly_mulcache_compute_asm.S +127 -0
  189. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/poly_reduce_asm.S +150 -0
  190. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/poly_tobytes_asm.S +117 -0
  191. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/poly_tomont_asm.S +98 -0
  192. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/polyvec_basemul_acc_montgomery_cached_asm_k2.S +261 -0
  193. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/polyvec_basemul_acc_montgomery_cached_asm_k3.S +314 -0
  194. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/polyvec_basemul_acc_montgomery_cached_asm_k4.S +368 -0
  195. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/rej_uniform_asm.S +226 -0
  196. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/rej_uniform_table.c +542 -0
  197. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/api.h +637 -0
  198. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/meta.h +25 -0
  199. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/README.md +11 -0
  200. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/meta.h +128 -0
  201. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/arith_native_riscv64.h +45 -0
  202. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_debug.c +81 -0
  203. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_debug.h +145 -0
  204. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_izetas.inc +27 -0
  205. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_poly.c +805 -0
  206. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_zetas.inc +27 -0
  207. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_zetas_basemul.inc +39 -0
  208. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/README.md +4 -0
  209. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/meta.h +304 -0
  210. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/arith_native_x86_64.h +309 -0
  211. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/compress_consts.c +94 -0
  212. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/compress_consts.h +45 -0
  213. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/consts.c +102 -0
  214. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/consts.h +25 -0
  215. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/intt.S +719 -0
  216. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/mulcache_compute.S +90 -0
  217. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/ntt.S +639 -0
  218. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/nttfrombytes.S +193 -0
  219. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/ntttobytes.S +181 -0
  220. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/nttunpack.S +174 -0
  221. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_compress_d10.S +382 -0
  222. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_compress_d11.S +448 -0
  223. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_compress_d4.S +163 -0
  224. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_compress_d5.S +220 -0
  225. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_decompress_d10.S +228 -0
  226. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_decompress_d11.S +277 -0
  227. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_decompress_d4.S +180 -0
  228. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/poly_decompress_d5.S +192 -0
  229. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/polyvec_basemul_acc_montgomery_cached_asm_k2.S +502 -0
  230. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/polyvec_basemul_acc_montgomery_cached_asm_k3.S +750 -0
  231. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/polyvec_basemul_acc_montgomery_cached_asm_k4.S +998 -0
  232. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/reduce.S +218 -0
  233. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/rej_uniform_asm.S +103 -0
  234. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/rej_uniform_table.c +544 -0
  235. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/tomont.S +155 -0
  236. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/params.h +76 -0
  237. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly.c +572 -0
  238. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly.h +317 -0
  239. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly_k.c +502 -0
  240. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly_k.h +668 -0
  241. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/randombytes.h +60 -0
  242. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sampling.c +362 -0
  243. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sampling.h +118 -0
  244. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/symmetric.h +70 -0
  245. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sys.h +260 -0
  246. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/verify.c +20 -0
  247. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/verify.h +464 -0
  248. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/zetas.inc +30 -0
  249. data/lib/pq_crypto/algorithm_registry.rb +200 -0
  250. data/lib/pq_crypto/hybrid_kem.rb +1 -12
  251. data/lib/pq_crypto/kem.rb +104 -13
  252. data/lib/pq_crypto/pkcs8.rb +387 -0
  253. data/lib/pq_crypto/serialization.rb +1 -14
  254. data/lib/pq_crypto/signature.rb +123 -17
  255. data/lib/pq_crypto/spki.rb +131 -0
  256. data/lib/pq_crypto/version.rb +1 -1
  257. data/lib/pq_crypto.rb +79 -20
  258. data/script/vendor_libs.rb +88 -155
  259. metadata +241 -73
  260. data/ext/pqcrypto/vendor/pqclean/common/aes.c +0 -639
  261. data/ext/pqcrypto/vendor/pqclean/common/aes.h +0 -64
  262. data/ext/pqcrypto/vendor/pqclean/common/compat.h +0 -73
  263. data/ext/pqcrypto/vendor/pqclean/common/crypto_declassify.h +0 -7
  264. data/ext/pqcrypto/vendor/pqclean/common/fips202.c +0 -928
  265. data/ext/pqcrypto/vendor/pqclean/common/fips202.h +0 -166
  266. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/feat.S +0 -168
  267. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.c +0 -684
  268. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.h +0 -60
  269. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SIMD256.c +0 -1028
  270. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SnP.h +0 -50
  271. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-unrolling.macros +0 -198
  272. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile +0 -8
  273. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile.Microsoft_nmake +0 -8
  274. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/SIMD256-config.h +0 -3
  275. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/align.h +0 -34
  276. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/brg_endian.h +0 -142
  277. data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.c +0 -101
  278. data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.h +0 -39
  279. data/ext/pqcrypto/vendor/pqclean/common/randombytes.c +0 -355
  280. data/ext/pqcrypto/vendor/pqclean/common/randombytes.h +0 -27
  281. data/ext/pqcrypto/vendor/pqclean/common/sha2.c +0 -769
  282. data/ext/pqcrypto/vendor/pqclean/common/sha2.h +0 -173
  283. data/ext/pqcrypto/vendor/pqclean/common/sp800-185.c +0 -156
  284. data/ext/pqcrypto/vendor/pqclean/common/sp800-185.h +0 -27
  285. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/LICENSE +0 -5
  286. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile +0 -19
  287. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile.Microsoft_nmake +0 -23
  288. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/api.h +0 -18
  289. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.c +0 -83
  290. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.h +0 -11
  291. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.c +0 -327
  292. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.h +0 -22
  293. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.c +0 -164
  294. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.h +0 -23
  295. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.c +0 -146
  296. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.h +0 -14
  297. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/params.h +0 -36
  298. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.c +0 -299
  299. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.h +0 -37
  300. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.c +0 -188
  301. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.h +0 -26
  302. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.c +0 -41
  303. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.h +0 -13
  304. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric-shake.c +0 -71
  305. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric.h +0 -30
  306. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.c +0 -67
  307. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.h +0 -13
  308. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/LICENSE +0 -5
  309. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile +0 -19
  310. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile.Microsoft_nmake +0 -23
  311. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/api.h +0 -50
  312. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.c +0 -98
  313. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.h +0 -10
  314. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.c +0 -261
  315. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.h +0 -31
  316. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/params.h +0 -44
  317. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.c +0 -799
  318. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.h +0 -52
  319. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.c +0 -415
  320. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.h +0 -65
  321. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.c +0 -69
  322. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.h +0 -17
  323. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.c +0 -92
  324. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.h +0 -14
  325. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.c +0 -407
  326. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.h +0 -47
  327. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric-shake.c +0 -26
  328. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric.h +0 -34
@@ -0,0 +1,946 @@
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
+ MLD_STATIC_TESTABLE
41
+ void mld_poly_decompose_c(mld_poly *a1, mld_poly *a0)
42
+ __contract__(
43
+ requires(memory_no_alias(a1, sizeof(mld_poly)))
44
+ requires(memory_no_alias(a0, sizeof(mld_poly)))
45
+ requires(array_bound(a0->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
46
+ assigns(memory_slice(a1, sizeof(mld_poly)))
47
+ assigns(memory_slice(a0, sizeof(mld_poly)))
48
+ ensures(array_bound(a1->coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
49
+ ensures(array_abs_bound(a0->coeffs, 0, MLDSA_N, MLDSA_GAMMA2+1))
50
+ )
51
+ {
52
+ unsigned int i;
53
+ mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
54
+ for (i = 0; i < MLDSA_N; ++i)
55
+ __loop__(
56
+ assigns(i, memory_slice(a0, sizeof(mld_poly)), memory_slice(a1, sizeof(mld_poly)))
57
+ invariant(i <= MLDSA_N)
58
+ invariant(array_bound(a0->coeffs, i, MLDSA_N, 0, MLDSA_Q))
59
+ invariant(array_bound(a1->coeffs, 0, i, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
60
+ invariant(array_abs_bound(a0->coeffs, 0, i, MLDSA_GAMMA2+1))
61
+ decreases(MLDSA_N - i)
62
+ )
63
+ {
64
+ mld_decompose(&a0->coeffs[i], &a1->coeffs[i], a0->coeffs[i]);
65
+ }
66
+
67
+ mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
68
+ mld_assert_bound(a1->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
69
+ }
70
+
71
+ MLD_INTERNAL_API
72
+ void mld_poly_decompose(mld_poly *a1, mld_poly *a0)
73
+ {
74
+ #if defined(MLD_USE_NATIVE_POLY_DECOMPOSE_88) && MLD_CONFIG_PARAMETER_SET == 44
75
+ int ret;
76
+ mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
77
+ ret = mld_poly_decompose_88_native(a1->coeffs, a0->coeffs);
78
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
79
+ {
80
+ mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
81
+ mld_assert_bound(a1->coeffs, MLDSA_N, 0,
82
+ (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
83
+ return;
84
+ }
85
+ #elif defined(MLD_USE_NATIVE_POLY_DECOMPOSE_32) && \
86
+ (MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
87
+ int ret;
88
+ mld_assert_bound(a0->coeffs, MLDSA_N, 0, MLDSA_Q);
89
+ ret = mld_poly_decompose_32_native(a1->coeffs, a0->coeffs);
90
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
91
+ {
92
+ mld_assert_abs_bound(a0->coeffs, MLDSA_N, MLDSA_GAMMA2 + 1);
93
+ mld_assert_bound(a1->coeffs, MLDSA_N, 0,
94
+ (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
95
+ return;
96
+ }
97
+ #endif /* !(MLD_USE_NATIVE_POLY_DECOMPOSE_88 && MLD_CONFIG_PARAMETER_SET == \
98
+ 44) && MLD_USE_NATIVE_POLY_DECOMPOSE_32 && (MLD_CONFIG_PARAMETER_SET \
99
+ == 65 || MLD_CONFIG_PARAMETER_SET == 87) */
100
+ mld_poly_decompose_c(a1, a0);
101
+ }
102
+
103
+ MLD_INTERNAL_API
104
+ unsigned int mld_poly_make_hint(mld_poly *h, const mld_poly *a0,
105
+ const mld_poly *a1)
106
+ {
107
+ unsigned int i, s = 0;
108
+
109
+ for (i = 0; i < MLDSA_N; ++i)
110
+ __loop__(
111
+ invariant(i <= MLDSA_N)
112
+ invariant(s <= i)
113
+ invariant(array_bound(h->coeffs, 0, i, 0, 2))
114
+ decreases(MLDSA_N - i)
115
+ )
116
+ {
117
+ const unsigned int hint_bit = mld_make_hint(a0->coeffs[i], a1->coeffs[i]);
118
+ h->coeffs[i] = (int32_t)hint_bit;
119
+ s += hint_bit;
120
+ }
121
+
122
+ mld_assert(s <= MLDSA_N);
123
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
124
+ return s;
125
+ }
126
+
127
+ MLD_STATIC_TESTABLE void mld_poly_use_hint_c(mld_poly *b, const mld_poly *a,
128
+ const mld_poly *h)
129
+ __contract__(
130
+ requires(memory_no_alias(a, sizeof(mld_poly)))
131
+ requires(memory_no_alias(b, sizeof(mld_poly)))
132
+ requires(memory_no_alias(h, sizeof(mld_poly)))
133
+ requires(array_bound(a->coeffs, 0, MLDSA_N, 0, MLDSA_Q))
134
+ requires(array_bound(h->coeffs, 0, MLDSA_N, 0, 2))
135
+ assigns(memory_slice(b, sizeof(mld_poly)))
136
+ ensures(array_bound(b->coeffs, 0, MLDSA_N, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
137
+ )
138
+ {
139
+ unsigned int i;
140
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
141
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
142
+
143
+ for (i = 0; i < MLDSA_N; ++i)
144
+ __loop__(
145
+ invariant(i <= MLDSA_N)
146
+ invariant(array_bound(b->coeffs, 0, i, 0, (MLDSA_Q-1)/(2*MLDSA_GAMMA2)))
147
+ decreases(MLDSA_N - i)
148
+ )
149
+ {
150
+ b->coeffs[i] = mld_use_hint(a->coeffs[i], h->coeffs[i]);
151
+ }
152
+ mld_assert_bound(b->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
153
+ }
154
+
155
+ MLD_INTERNAL_API
156
+ void mld_poly_use_hint(mld_poly *b, const mld_poly *a, const mld_poly *h)
157
+ {
158
+ #if defined(MLD_USE_NATIVE_POLY_USE_HINT_88) && MLD_CONFIG_PARAMETER_SET == 44
159
+ int ret;
160
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
161
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
162
+ ret = mld_poly_use_hint_88_native(b->coeffs, a->coeffs, h->coeffs);
163
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
164
+ {
165
+ mld_assert_bound(b->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
166
+ return;
167
+ }
168
+ #elif defined(MLD_USE_NATIVE_POLY_USE_HINT_32) && \
169
+ (MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
170
+ int ret;
171
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
172
+ mld_assert_bound(h->coeffs, MLDSA_N, 0, 2);
173
+ ret = mld_poly_use_hint_32_native(b->coeffs, a->coeffs, h->coeffs);
174
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
175
+ {
176
+ mld_assert_bound(b->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
177
+ return;
178
+ }
179
+ #endif /* !(MLD_USE_NATIVE_POLY_USE_HINT_88 && MLD_CONFIG_PARAMETER_SET == 44) \
180
+ && MLD_USE_NATIVE_POLY_USE_HINT_32 && (MLD_CONFIG_PARAMETER_SET == \
181
+ 65 || MLD_CONFIG_PARAMETER_SET == 87) */
182
+ mld_poly_use_hint_c(b, a, h);
183
+ }
184
+
185
+ /*************************************************
186
+ * Name: mld_rej_eta
187
+ *
188
+ * Description: Sample uniformly random coefficients in [-MLDSA_ETA, MLDSA_ETA]
189
+ *by performing rejection sampling on array of random bytes.
190
+ *
191
+ * Arguments: - int32_t *a: pointer to output array (allocated)
192
+ * - unsigned int target: requested number of coefficients to
193
+ *sample
194
+ * - unsigned int offset: number of coefficients already sampled
195
+ * - const uint8_t *buf: array of random bytes to sample from
196
+ * - unsigned int buflen: length of array of random bytes
197
+ *
198
+ * Returns number of sampled coefficients. Can be smaller than target if not
199
+ *enough random bytes were given.
200
+ **************************************************/
201
+
202
+ /* Reference: `mld_rej_eta()` in the reference implementation @[REF].
203
+ * - Our signature differs from the reference implementation
204
+ * in that it adds the offset and always expects the base of the
205
+ * target buffer. This avoids shifting the buffer base in the
206
+ * caller, which appears tricky to reason about. */
207
+ #if MLDSA_ETA == 2
208
+ /*
209
+ * Sampling 256 coefficients mod 15 using rejection sampling from 4 bits.
210
+ * Expected number of required bytes: (256 * (16/15))/2 = 136.5 bytes.
211
+ * We sample 1 block (=136 bytes) of SHAKE256_RATE output initially.
212
+ * Sampling 2 blocks initially results in slightly worse performance.
213
+ */
214
+ #define MLD_POLY_UNIFORM_ETA_NBLOCKS 1
215
+ #elif MLDSA_ETA == 4
216
+ /*
217
+ * Sampling 256 coefficients mod 9 using rejection sampling from 4 bits.
218
+ * Expected number of required bytes: (256 * (16/9))/2 = 227.5 bytes.
219
+ * We sample 2 blocks (=272 bytes) of SHAKE256_RATE output initially.
220
+ */
221
+ #define MLD_POLY_UNIFORM_ETA_NBLOCKS 2
222
+ #else /* MLDSA_ETA == 4 */
223
+ #error "Invalid value of MLDSA_ETA"
224
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
225
+
226
+ MLD_STATIC_TESTABLE unsigned int mld_rej_eta_c(int32_t *a, unsigned int target,
227
+ unsigned int offset,
228
+ const uint8_t *buf,
229
+ unsigned int buflen)
230
+ __contract__(
231
+ requires(offset <= target && target <= MLDSA_N)
232
+ requires(buflen <= (MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES))
233
+ requires(memory_no_alias(a, sizeof(int32_t) * target))
234
+ requires(memory_no_alias(buf, buflen))
235
+ requires(array_abs_bound(a, 0, offset, MLDSA_ETA + 1))
236
+ assigns(memory_slice(a, sizeof(int32_t) * target))
237
+ ensures(offset <= return_value && return_value <= target)
238
+ ensures(array_abs_bound(a, 0, return_value, MLDSA_ETA + 1))
239
+ )
240
+ {
241
+ unsigned int ctr, pos;
242
+ int t_valid;
243
+ uint32_t t0, t1;
244
+ mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
245
+ ctr = offset;
246
+ pos = 0;
247
+ while (ctr < target && pos < buflen)
248
+ __loop__(
249
+ invariant(offset <= ctr && ctr <= target && pos <= buflen)
250
+ invariant(array_abs_bound(a, 0, ctr, MLDSA_ETA + 1))
251
+ decreases(buflen - pos)
252
+ )
253
+ {
254
+ t0 = buf[pos] & 0x0F;
255
+ t1 = buf[pos++] >> 4;
256
+
257
+ /* Constant time: The inputs and outputs to the rejection sampling are
258
+ * secret. However, it is fine to leak which coefficients have been
259
+ * rejected. For constant-time testing, we declassify the result of
260
+ * the comparison.
261
+ */
262
+ #if MLDSA_ETA == 2
263
+ t_valid = t0 < 15;
264
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
265
+ if (t_valid) /* t0 < 15 */
266
+ {
267
+ t0 = t0 - (205 * t0 >> 10) * 5;
268
+ a[ctr++] = 2 - (int32_t)t0;
269
+ }
270
+ t_valid = t1 < 15;
271
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
272
+ if (t_valid && ctr < target) /* t1 < 15 */
273
+ {
274
+ t1 = t1 - (205 * t1 >> 10) * 5;
275
+ a[ctr++] = 2 - (int32_t)t1;
276
+ }
277
+ #elif MLDSA_ETA == 4
278
+ t_valid = t0 < 9;
279
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
280
+ if (t_valid) /* t0 < 9 */
281
+ {
282
+ a[ctr++] = 4 - (int32_t)t0;
283
+ }
284
+ t_valid = t1 < 9; /* t1 < 9 */
285
+ MLD_CT_TESTING_DECLASSIFY(&t_valid, sizeof(int));
286
+ if (t_valid && ctr < target)
287
+ {
288
+ a[ctr++] = 4 - (int32_t)t1;
289
+ }
290
+ #else /* MLDSA_ETA == 4 */
291
+ #error "Invalid value of MLDSA_ETA"
292
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
293
+ }
294
+
295
+ mld_assert_abs_bound(a, ctr, MLDSA_ETA + 1);
296
+
297
+ return ctr;
298
+ }
299
+
300
+ static unsigned int mld_rej_eta(int32_t *a, unsigned int target,
301
+ unsigned int offset, const uint8_t *buf,
302
+ unsigned int buflen)
303
+ __contract__(
304
+ requires(offset <= target && target <= MLDSA_N)
305
+ requires(buflen <= (MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES))
306
+ requires(memory_no_alias(a, sizeof(int32_t) * target))
307
+ requires(memory_no_alias(buf, buflen))
308
+ requires(array_abs_bound(a, 0, offset, MLDSA_ETA + 1))
309
+ assigns(memory_slice(a, sizeof(int32_t) * target))
310
+ ensures(offset <= return_value && return_value <= target)
311
+ ensures(array_abs_bound(a, 0, return_value, MLDSA_ETA + 1))
312
+ )
313
+ {
314
+ #if MLDSA_ETA == 2 && defined(MLD_USE_NATIVE_REJ_UNIFORM_ETA2)
315
+ int ret;
316
+ mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
317
+ if (offset == 0)
318
+ {
319
+ ret = mld_rej_uniform_eta2_native(a, target, buf, buflen);
320
+ if (ret != MLD_NATIVE_FUNC_FALLBACK)
321
+ {
322
+ unsigned res = (unsigned)ret;
323
+ mld_assert_abs_bound(a, res, MLDSA_ETA + 1);
324
+ return res;
325
+ }
326
+ }
327
+ #elif MLDSA_ETA == 4 && defined(MLD_USE_NATIVE_REJ_UNIFORM_ETA4)
328
+ int ret;
329
+ mld_assert_abs_bound(a, offset, MLDSA_ETA + 1);
330
+ if (offset == 0)
331
+ {
332
+ ret = mld_rej_uniform_eta4_native(a, target, buf, buflen);
333
+ if (ret != MLD_NATIVE_FUNC_FALLBACK)
334
+ {
335
+ unsigned res = (unsigned)ret;
336
+ mld_assert_abs_bound(a, res, MLDSA_ETA + 1);
337
+ return res;
338
+ }
339
+ }
340
+ #endif /* !(MLDSA_ETA == 2 && MLD_USE_NATIVE_REJ_UNIFORM_ETA2) && MLDSA_ETA == \
341
+ 4 && MLD_USE_NATIVE_REJ_UNIFORM_ETA4 */
342
+
343
+ return mld_rej_eta_c(a, target, offset, buf, buflen);
344
+ }
345
+
346
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
347
+ MLD_INTERNAL_API
348
+ void mld_poly_uniform_eta_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
349
+ mld_poly *r3, const uint8_t seed[MLDSA_CRHBYTES],
350
+ uint8_t nonce0, uint8_t nonce1, uint8_t nonce2,
351
+ uint8_t nonce3)
352
+ {
353
+ /* Temporary buffers for XOF output before rejection sampling */
354
+ MLD_ALIGN uint8_t buf[4][MLD_ALIGN_UP(MLD_POLY_UNIFORM_ETA_NBLOCKS *
355
+ MLD_STREAM256_BLOCKBYTES)];
356
+
357
+ MLD_ALIGN uint8_t extseed[4][MLD_ALIGN_UP(MLDSA_CRHBYTES + 2)];
358
+
359
+ /* Tracks the number of coefficients we have already sampled */
360
+ unsigned ctr[4];
361
+ mld_xof256_x4_ctx state;
362
+ unsigned buflen;
363
+
364
+ mld_memcpy(extseed[0], seed, MLDSA_CRHBYTES);
365
+ mld_memcpy(extseed[1], seed, MLDSA_CRHBYTES);
366
+ mld_memcpy(extseed[2], seed, MLDSA_CRHBYTES);
367
+ mld_memcpy(extseed[3], seed, MLDSA_CRHBYTES);
368
+ extseed[0][MLDSA_CRHBYTES] = nonce0;
369
+ extseed[1][MLDSA_CRHBYTES] = nonce1;
370
+ extseed[2][MLDSA_CRHBYTES] = nonce2;
371
+ extseed[3][MLDSA_CRHBYTES] = nonce3;
372
+ extseed[0][MLDSA_CRHBYTES + 1] = 0;
373
+ extseed[1][MLDSA_CRHBYTES + 1] = 0;
374
+ extseed[2][MLDSA_CRHBYTES + 1] = 0;
375
+ extseed[3][MLDSA_CRHBYTES + 1] = 0;
376
+
377
+ mld_xof256_x4_init(&state);
378
+ mld_xof256_x4_absorb(&state, extseed, MLDSA_CRHBYTES + 2);
379
+
380
+ /*
381
+ * Initially, squeeze heuristic number of MLD_POLY_UNIFORM_ETA_NBLOCKS.
382
+ * This should generate the coefficients with high probability.
383
+ */
384
+ mld_xof256_x4_squeezeblocks(buf, MLD_POLY_UNIFORM_ETA_NBLOCKS, &state);
385
+ buflen = MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES;
386
+
387
+ ctr[0] = mld_rej_eta(r0->coeffs, MLDSA_N, 0, buf[0], buflen);
388
+ ctr[1] = mld_rej_eta(r1->coeffs, MLDSA_N, 0, buf[1], buflen);
389
+ ctr[2] = mld_rej_eta(r2->coeffs, MLDSA_N, 0, buf[2], buflen);
390
+ ctr[3] = mld_rej_eta(r3->coeffs, MLDSA_N, 0, buf[3], buflen);
391
+
392
+ /*
393
+ * So long as not all entries have been generated, squeeze
394
+ * one more block at a time until we're done.
395
+ */
396
+ buflen = MLD_STREAM256_BLOCKBYTES;
397
+ while (ctr[0] < MLDSA_N || ctr[1] < MLDSA_N || ctr[2] < MLDSA_N ||
398
+ ctr[3] < MLDSA_N)
399
+ __loop__(
400
+ assigns(ctr, state, memory_slice(r0, sizeof(mld_poly)),
401
+ memory_slice(r1, sizeof(mld_poly)), memory_slice(r2, sizeof(mld_poly)),
402
+ memory_slice(r3, sizeof(mld_poly)), object_whole(buf[0]),
403
+ object_whole(buf[1]), object_whole(buf[2]),
404
+ object_whole(buf[3]))
405
+ invariant(ctr[0] <= MLDSA_N && ctr[1] <= MLDSA_N)
406
+ invariant(ctr[2] <= MLDSA_N && ctr[3] <= MLDSA_N)
407
+ invariant(array_abs_bound(r0->coeffs, 0, ctr[0], MLDSA_ETA + 1))
408
+ invariant(array_abs_bound(r1->coeffs, 0, ctr[1], MLDSA_ETA + 1))
409
+ invariant(array_abs_bound(r2->coeffs, 0, ctr[2], MLDSA_ETA + 1))
410
+ invariant(array_abs_bound(r3->coeffs, 0, ctr[3], MLDSA_ETA + 1)))
411
+ {
412
+ mld_xof256_x4_squeezeblocks(buf, 1, &state);
413
+ ctr[0] = mld_rej_eta(r0->coeffs, MLDSA_N, ctr[0], buf[0], buflen);
414
+ ctr[1] = mld_rej_eta(r1->coeffs, MLDSA_N, ctr[1], buf[1], buflen);
415
+ ctr[2] = mld_rej_eta(r2->coeffs, MLDSA_N, ctr[2], buf[2], buflen);
416
+ ctr[3] = mld_rej_eta(r3->coeffs, MLDSA_N, ctr[3], buf[3], buflen);
417
+ }
418
+
419
+ mld_xof256_x4_release(&state);
420
+
421
+ mld_assert_abs_bound(r0->coeffs, MLDSA_N, MLDSA_ETA + 1);
422
+ mld_assert_abs_bound(r1->coeffs, MLDSA_N, MLDSA_ETA + 1);
423
+ mld_assert_abs_bound(r2->coeffs, MLDSA_N, MLDSA_ETA + 1);
424
+ mld_assert_abs_bound(r3->coeffs, MLDSA_N, MLDSA_ETA + 1);
425
+
426
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
427
+ mld_zeroize(buf, sizeof(buf));
428
+ mld_zeroize(extseed, sizeof(extseed));
429
+ }
430
+ #else /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
431
+
432
+ MLD_INTERNAL_API
433
+ void mld_poly_uniform_eta(mld_poly *r, const uint8_t seed[MLDSA_CRHBYTES],
434
+ uint8_t nonce)
435
+ {
436
+ /* Temporary buffer for XOF output before rejection sampling */
437
+ MLD_ALIGN uint8_t
438
+ buf[MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES];
439
+ MLD_ALIGN uint8_t extseed[MLDSA_CRHBYTES + 2];
440
+
441
+ /* Tracks the number of coefficients we have already sampled */
442
+ unsigned ctr;
443
+ mld_xof256_ctx state;
444
+ unsigned buflen;
445
+
446
+ mld_memcpy(extseed, seed, MLDSA_CRHBYTES);
447
+ extseed[MLDSA_CRHBYTES] = nonce;
448
+ extseed[MLDSA_CRHBYTES + 1] = 0;
449
+
450
+ mld_xof256_init(&state);
451
+ mld_xof256_absorb_once(&state, extseed, MLDSA_CRHBYTES + 2);
452
+
453
+ /*
454
+ * Initially, squeeze heuristic number of MLD_POLY_UNIFORM_ETA_NBLOCKS.
455
+ * This should generate the coefficients with high probability.
456
+ */
457
+ mld_xof256_squeezeblocks(buf, MLD_POLY_UNIFORM_ETA_NBLOCKS, &state);
458
+ buflen = MLD_POLY_UNIFORM_ETA_NBLOCKS * MLD_STREAM256_BLOCKBYTES;
459
+
460
+ ctr = mld_rej_eta(r->coeffs, MLDSA_N, 0, buf, buflen);
461
+
462
+ /*
463
+ * So long as not all entries have been generated, squeeze
464
+ * one more block at a time until we're done.
465
+ */
466
+ buflen = MLD_STREAM256_BLOCKBYTES;
467
+ while (ctr < MLDSA_N)
468
+ __loop__(
469
+ assigns(ctr, object_whole(&state),
470
+ object_whole(buf), memory_slice(r, sizeof(mld_poly)))
471
+ invariant(ctr <= MLDSA_N)
472
+ invariant(state.pos <= SHAKE256_RATE)
473
+ invariant(array_abs_bound(r->coeffs, 0, ctr, MLDSA_ETA + 1)))
474
+ {
475
+ mld_xof256_squeezeblocks(buf, 1, &state);
476
+ ctr = mld_rej_eta(r->coeffs, MLDSA_N, ctr, buf, buflen);
477
+ }
478
+
479
+ mld_xof256_release(&state);
480
+
481
+ mld_assert_abs_bound(r->coeffs, MLDSA_N, MLDSA_ETA + 1);
482
+
483
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
484
+ mld_zeroize(buf, sizeof(buf));
485
+ mld_zeroize(extseed, sizeof(extseed));
486
+ }
487
+ #endif /* MLD_CONFIG_SERIAL_FIPS202_ONLY */
488
+
489
+ #define MLD_POLY_UNIFORM_GAMMA1_NBLOCKS \
490
+ ((MLDSA_POLYZ_PACKEDBYTES + MLD_STREAM256_BLOCKBYTES - 1) / \
491
+ MLD_STREAM256_BLOCKBYTES)
492
+
493
+ #if MLD_CONFIG_PARAMETER_SET == 65 || defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
494
+ MLD_INTERNAL_API
495
+ void mld_poly_uniform_gamma1(mld_poly *a, const uint8_t seed[MLDSA_CRHBYTES],
496
+ uint16_t nonce)
497
+ {
498
+ MLD_ALIGN uint8_t
499
+ buf[MLD_POLY_UNIFORM_GAMMA1_NBLOCKS * MLD_STREAM256_BLOCKBYTES];
500
+ MLD_ALIGN uint8_t extseed[MLDSA_CRHBYTES + 2];
501
+ mld_xof256_ctx state;
502
+
503
+ mld_memcpy(extseed, seed, MLDSA_CRHBYTES);
504
+ extseed[MLDSA_CRHBYTES] = (uint8_t)(nonce & 0xFF);
505
+ extseed[MLDSA_CRHBYTES + 1] = (uint8_t)(nonce >> 8);
506
+
507
+ mld_xof256_init(&state);
508
+ mld_xof256_absorb_once(&state, extseed, MLDSA_CRHBYTES + 2);
509
+
510
+ mld_xof256_squeezeblocks(buf, MLD_POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
511
+ mld_polyz_unpack(a, buf);
512
+
513
+ mld_xof256_release(&state);
514
+
515
+ mld_assert_bound(a->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
516
+
517
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
518
+ mld_zeroize(buf, sizeof(buf));
519
+ mld_zeroize(extseed, sizeof(extseed));
520
+ }
521
+ #endif /* MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_SERIAL_FIPS202_ONLY */
522
+
523
+
524
+ #if !defined(MLD_CONFIG_SERIAL_FIPS202_ONLY)
525
+ MLD_INTERNAL_API
526
+ void mld_poly_uniform_gamma1_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
527
+ mld_poly *r3,
528
+ const uint8_t seed[MLDSA_CRHBYTES],
529
+ uint16_t nonce0, uint16_t nonce1,
530
+ uint16_t nonce2, uint16_t nonce3)
531
+ {
532
+ /* Temporary buffers for XOF output before rejection sampling */
533
+ MLD_ALIGN uint8_t buf[4][MLD_ALIGN_UP(MLD_POLY_UNIFORM_GAMMA1_NBLOCKS *
534
+ MLD_STREAM256_BLOCKBYTES)];
535
+
536
+ MLD_ALIGN uint8_t extseed[4][MLD_ALIGN_UP(MLDSA_CRHBYTES + 2)];
537
+
538
+ /* Tracks the number of coefficients we have already sampled */
539
+ mld_xof256_x4_ctx state;
540
+
541
+ mld_memcpy(extseed[0], seed, MLDSA_CRHBYTES);
542
+ mld_memcpy(extseed[1], seed, MLDSA_CRHBYTES);
543
+ mld_memcpy(extseed[2], seed, MLDSA_CRHBYTES);
544
+ mld_memcpy(extseed[3], seed, MLDSA_CRHBYTES);
545
+ extseed[0][MLDSA_CRHBYTES] = (uint8_t)(nonce0 & 0xFF);
546
+ extseed[1][MLDSA_CRHBYTES] = (uint8_t)(nonce1 & 0xFF);
547
+ extseed[2][MLDSA_CRHBYTES] = (uint8_t)(nonce2 & 0xFF);
548
+ extseed[3][MLDSA_CRHBYTES] = (uint8_t)(nonce3 & 0xFF);
549
+ extseed[0][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce0 >> 8);
550
+ extseed[1][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce1 >> 8);
551
+ extseed[2][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce2 >> 8);
552
+ extseed[3][MLDSA_CRHBYTES + 1] = (uint8_t)(nonce3 >> 8);
553
+
554
+ mld_xof256_x4_init(&state);
555
+ mld_xof256_x4_absorb(&state, extseed, MLDSA_CRHBYTES + 2);
556
+ mld_xof256_x4_squeezeblocks(buf, MLD_POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
557
+
558
+ mld_polyz_unpack(r0, buf[0]);
559
+ mld_polyz_unpack(r1, buf[1]);
560
+ mld_polyz_unpack(r2, buf[2]);
561
+ mld_polyz_unpack(r3, buf[3]);
562
+ mld_xof256_x4_release(&state);
563
+
564
+ mld_assert_bound(r0->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
565
+ mld_assert_bound(r1->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
566
+ mld_assert_bound(r2->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
567
+ mld_assert_bound(r3->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
568
+
569
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
570
+ mld_zeroize(buf, sizeof(buf));
571
+ mld_zeroize(extseed, sizeof(extseed));
572
+ }
573
+ #endif /* !MLD_CONFIG_SERIAL_FIPS202_ONLY */
574
+
575
+ MLD_INTERNAL_API
576
+ void mld_poly_challenge(mld_poly *c, const uint8_t seed[MLDSA_CTILDEBYTES])
577
+ {
578
+ unsigned int i, j, pos;
579
+ uint64_t signs;
580
+ uint64_t offset;
581
+ MLD_ALIGN uint8_t buf[SHAKE256_RATE];
582
+ mld_shake256ctx state;
583
+
584
+ mld_shake256_init(&state);
585
+ mld_shake256_absorb(&state, seed, MLDSA_CTILDEBYTES);
586
+ mld_shake256_finalize(&state);
587
+ mld_shake256_squeeze(buf, SHAKE256_RATE, &state);
588
+
589
+ /* Convert the first 8 bytes of buf[] into an unsigned 64-bit value. */
590
+ /* Each bit of that dictates the sign of the resulting challenge value */
591
+ signs = 0;
592
+ for (i = 0; i < 8; ++i)
593
+ __loop__(
594
+ assigns(i, signs)
595
+ invariant(i <= 8)
596
+ decreases(8 - i)
597
+ )
598
+ {
599
+ signs |= (uint64_t)buf[i] << 8 * i;
600
+ }
601
+ pos = 8;
602
+
603
+ mld_memset(c, 0, sizeof(mld_poly));
604
+
605
+ for (i = MLDSA_N - MLDSA_TAU; i < MLDSA_N; ++i)
606
+ __loop__(
607
+ assigns(i, j, object_whole(buf), state, pos, memory_slice(c, sizeof(mld_poly)), signs)
608
+ invariant(i >= MLDSA_N - MLDSA_TAU)
609
+ invariant(i <= MLDSA_N)
610
+ invariant(pos >= 1)
611
+ invariant(pos <= SHAKE256_RATE)
612
+ invariant(array_bound(c->coeffs, 0, MLDSA_N, -1, 2))
613
+ invariant(state.pos <= SHAKE256_RATE)
614
+ decreases(MLDSA_N - i)
615
+ )
616
+ {
617
+ /* This loop teminates only probabilistically, hence no decreases clause. */
618
+ do
619
+ __loop__(
620
+ assigns(j, object_whole(buf), state, pos)
621
+ invariant(state.pos <= SHAKE256_RATE)
622
+ )
623
+ {
624
+ if (pos >= SHAKE256_RATE)
625
+ {
626
+ mld_shake256_squeeze(buf, SHAKE256_RATE, &state);
627
+ pos = 0;
628
+ }
629
+ j = buf[pos++];
630
+ } while (j > i);
631
+
632
+ c->coeffs[i] = c->coeffs[j];
633
+
634
+ /* Reference: Compute coefficent value here in two steps to */
635
+ /* mixinf unsigned and signed arithmetic with implicit */
636
+ /* conversions, and so that CBMC can keep track of ranges */
637
+ /* to complete type-safety proof here. */
638
+
639
+ /* The least-significant bit of signs tells us if we want -1 or +1 */
640
+ offset = 2 * (signs & 1);
641
+
642
+ /* offset has value 0 or 2 here, so (1 - (int32_t) offset) has
643
+ * value -1 or +1 */
644
+ c->coeffs[j] = 1 - (int32_t)offset;
645
+
646
+ /* Move to the next bit of signs for next time */
647
+ signs >>= 1;
648
+ }
649
+
650
+ mld_assert_bound(c->coeffs, MLDSA_N, -1, 2);
651
+ mld_shake256_release(&state);
652
+
653
+ /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */
654
+ mld_zeroize(buf, sizeof(buf));
655
+ mld_zeroize(&signs, sizeof(signs));
656
+ }
657
+
658
+ MLD_INTERNAL_API
659
+ void mld_polyeta_pack(uint8_t r[MLDSA_POLYETA_PACKEDBYTES], const mld_poly *a)
660
+ {
661
+ unsigned int i;
662
+ uint8_t t[8];
663
+
664
+ mld_assert_abs_bound(a->coeffs, MLDSA_N, MLDSA_ETA + 1);
665
+
666
+ #if MLDSA_ETA == 2
667
+ for (i = 0; i < MLDSA_N / 8; ++i)
668
+ __loop__(
669
+ invariant(i <= MLDSA_N/8)
670
+ decreases(MLDSA_N / 8 - i))
671
+ {
672
+ /* The casts are safe since we assume that the coefficients
673
+ * of a are <= MLDSA_ETA in absolute value. */
674
+ t[0] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 0]);
675
+ t[1] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 1]);
676
+ t[2] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 2]);
677
+ t[3] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 3]);
678
+ t[4] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 4]);
679
+ t[5] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 5]);
680
+ t[6] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 6]);
681
+ t[7] = (uint8_t)(MLDSA_ETA - a->coeffs[8 * i + 7]);
682
+
683
+ r[3 * i + 0] = (uint8_t)(((t[0] >> 0) | (t[1] << 3) | (t[2] << 6)) & 0xFF);
684
+ r[3 * i + 1] =
685
+ (uint8_t)(((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7)) &
686
+ 0xFF);
687
+ r[3 * i + 2] = (uint8_t)(((t[5] >> 1) | (t[6] << 2) | (t[7] << 5)) & 0xFF);
688
+ }
689
+ #elif MLDSA_ETA == 4
690
+ for (i = 0; i < MLDSA_N / 2; ++i)
691
+ __loop__(
692
+ invariant(i <= MLDSA_N/2)
693
+ decreases(MLDSA_N / 2 - i))
694
+ {
695
+ /* The casts are safe since we assume that the coefficients
696
+ * of a are <= MLDSA_ETA in absolute value. */
697
+ t[0] = (uint8_t)(MLDSA_ETA - a->coeffs[2 * i + 0]);
698
+ t[1] = (uint8_t)(MLDSA_ETA - a->coeffs[2 * i + 1]);
699
+ r[i] = (uint8_t)(t[0] | (t[1] << 4));
700
+ }
701
+ #else /* MLDSA_ETA == 4 */
702
+ #error "Invalid value of MLDSA_ETA"
703
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
704
+ }
705
+
706
+ void mld_polyeta_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYETA_PACKEDBYTES])
707
+ {
708
+ unsigned int i;
709
+
710
+ #if MLDSA_ETA == 2
711
+ for (i = 0; i < MLDSA_N / 8; ++i)
712
+ __loop__(
713
+ invariant(i <= MLDSA_N/8)
714
+ invariant(array_bound(r->coeffs, 0, i*8, -5, MLDSA_ETA + 1))
715
+ decreases(MLDSA_N / 8 - i))
716
+ {
717
+ r->coeffs[8 * i + 0] = (a[3 * i + 0] >> 0) & 7;
718
+ r->coeffs[8 * i + 1] = (a[3 * i + 0] >> 3) & 7;
719
+ r->coeffs[8 * i + 2] = ((a[3 * i + 0] >> 6) | (a[3 * i + 1] << 2)) & 7;
720
+ r->coeffs[8 * i + 3] = (a[3 * i + 1] >> 1) & 7;
721
+ r->coeffs[8 * i + 4] = (a[3 * i + 1] >> 4) & 7;
722
+ r->coeffs[8 * i + 5] = ((a[3 * i + 1] >> 7) | (a[3 * i + 2] << 1)) & 7;
723
+ r->coeffs[8 * i + 6] = (a[3 * i + 2] >> 2) & 7;
724
+ r->coeffs[8 * i + 7] = (a[3 * i + 2] >> 5) & 7;
725
+
726
+ r->coeffs[8 * i + 0] = MLDSA_ETA - r->coeffs[8 * i + 0];
727
+ r->coeffs[8 * i + 1] = MLDSA_ETA - r->coeffs[8 * i + 1];
728
+ r->coeffs[8 * i + 2] = MLDSA_ETA - r->coeffs[8 * i + 2];
729
+ r->coeffs[8 * i + 3] = MLDSA_ETA - r->coeffs[8 * i + 3];
730
+ r->coeffs[8 * i + 4] = MLDSA_ETA - r->coeffs[8 * i + 4];
731
+ r->coeffs[8 * i + 5] = MLDSA_ETA - r->coeffs[8 * i + 5];
732
+ r->coeffs[8 * i + 6] = MLDSA_ETA - r->coeffs[8 * i + 6];
733
+ r->coeffs[8 * i + 7] = MLDSA_ETA - r->coeffs[8 * i + 7];
734
+ }
735
+ #elif MLDSA_ETA == 4
736
+ for (i = 0; i < MLDSA_N / 2; ++i)
737
+ __loop__(
738
+ invariant(i <= MLDSA_N/2)
739
+ invariant(array_bound(r->coeffs, 0, i*2, -11, MLDSA_ETA + 1))
740
+ decreases(MLDSA_N / 2 - i))
741
+ {
742
+ r->coeffs[2 * i + 0] = a[i] & 0x0F;
743
+ r->coeffs[2 * i + 1] = a[i] >> 4;
744
+ r->coeffs[2 * i + 0] = MLDSA_ETA - r->coeffs[2 * i + 0];
745
+ r->coeffs[2 * i + 1] = MLDSA_ETA - r->coeffs[2 * i + 1];
746
+ }
747
+ #else /* MLDSA_ETA == 4 */
748
+ #error "Invalid value of MLDSA_ETA"
749
+ #endif /* MLDSA_ETA != 2 && MLDSA_ETA != 4 */
750
+
751
+ mld_assert_bound(r->coeffs, MLDSA_N, MLD_POLYETA_UNPACK_LOWER_BOUND,
752
+ MLDSA_ETA + 1);
753
+ }
754
+
755
+
756
+ MLD_INTERNAL_API
757
+ void mld_polyz_pack(uint8_t r[MLDSA_POLYZ_PACKEDBYTES], const mld_poly *a)
758
+ {
759
+ unsigned int i;
760
+ uint32_t t[4];
761
+
762
+ mld_assert_bound(a->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
763
+
764
+ #if MLD_CONFIG_PARAMETER_SET == 44
765
+ for (i = 0; i < MLDSA_N / 4; ++i)
766
+ __loop__(
767
+ invariant(i <= MLDSA_N/4)
768
+ decreases(MLDSA_N / 4 - i))
769
+ {
770
+ /* Safety: a->coeffs[i] <= MLDSA_GAMMA1, hence, these casts are safe. */
771
+ t[0] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 0]);
772
+ t[1] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 1]);
773
+ t[2] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 2]);
774
+ t[3] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[4 * i + 3]);
775
+
776
+ r[9 * i + 0] = (uint8_t)((t[0]) & 0xFF);
777
+ r[9 * i + 1] = (uint8_t)((t[0] >> 8) & 0xFF);
778
+ r[9 * i + 2] = (uint8_t)((t[0] >> 16) & 0xFF);
779
+ r[9 * i + 2] |= (uint8_t)((t[1] << 2) & 0xFF);
780
+ r[9 * i + 3] = (uint8_t)((t[1] >> 6) & 0xFF);
781
+ r[9 * i + 4] = (uint8_t)((t[1] >> 14) & 0xFF);
782
+ r[9 * i + 4] |= (uint8_t)((t[2] << 4) & 0xFF);
783
+ r[9 * i + 5] = (uint8_t)((t[2] >> 4) & 0xFF);
784
+ r[9 * i + 6] = (uint8_t)((t[2] >> 12) & 0xFF);
785
+ r[9 * i + 6] |= (uint8_t)((t[3] << 6) & 0xFF);
786
+ r[9 * i + 7] = (uint8_t)((t[3] >> 2) & 0xFF);
787
+ r[9 * i + 8] = (uint8_t)((t[3] >> 10) & 0xFF);
788
+ }
789
+ #else /* MLD_CONFIG_PARAMETER_SET == 44 */
790
+ for (i = 0; i < MLDSA_N / 2; ++i)
791
+ __loop__(
792
+ invariant(i <= MLDSA_N/2)
793
+ decreases(MLDSA_N / 2 - i))
794
+ {
795
+ /* Safety: a->coeffs[i] <= MLDSA_GAMMA1, hence, these casts are safe. */
796
+ t[0] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[2 * i + 0]);
797
+ t[1] = (uint32_t)(MLDSA_GAMMA1 - a->coeffs[2 * i + 1]);
798
+
799
+ r[5 * i + 0] = (uint8_t)((t[0]) & 0xFF);
800
+ r[5 * i + 1] = (uint8_t)((t[0] >> 8) & 0xFF);
801
+ r[5 * i + 2] = (uint8_t)((t[0] >> 16) & 0xFF);
802
+ r[5 * i + 2] |= (uint8_t)((t[1] << 4) & 0xFF);
803
+ r[5 * i + 3] = (uint8_t)((t[1] >> 4) & 0xFF);
804
+ r[5 * i + 4] = (uint8_t)((t[1] >> 12) & 0xFF);
805
+ }
806
+ #endif /* MLD_CONFIG_PARAMETER_SET != 44 */
807
+ }
808
+
809
+ MLD_STATIC_TESTABLE void mld_polyz_unpack_c(
810
+ mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES])
811
+ __contract__(
812
+ requires(memory_no_alias(r, sizeof(mld_poly)))
813
+ requires(memory_no_alias(a, MLDSA_POLYZ_PACKEDBYTES))
814
+ assigns(memory_slice(r, sizeof(mld_poly)))
815
+ ensures(array_bound(r->coeffs, 0, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
816
+ )
817
+ {
818
+ unsigned int i;
819
+ #if MLD_CONFIG_PARAMETER_SET == 44
820
+ for (i = 0; i < MLDSA_N / 4; ++i)
821
+ __loop__(
822
+ invariant(i <= MLDSA_N/4)
823
+ invariant(array_bound(r->coeffs, 0, i*4, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
824
+ decreases(MLDSA_N / 4 - i))
825
+ {
826
+ r->coeffs[4 * i + 0] = a[9 * i + 0];
827
+ r->coeffs[4 * i + 0] |= (int32_t)a[9 * i + 1] << 8;
828
+ r->coeffs[4 * i + 0] |= (int32_t)a[9 * i + 2] << 16;
829
+ r->coeffs[4 * i + 0] &= 0x3FFFF;
830
+
831
+ r->coeffs[4 * i + 1] = a[9 * i + 2] >> 2;
832
+ r->coeffs[4 * i + 1] |= (int32_t)a[9 * i + 3] << 6;
833
+ r->coeffs[4 * i + 1] |= (int32_t)a[9 * i + 4] << 14;
834
+ r->coeffs[4 * i + 1] &= 0x3FFFF;
835
+
836
+ r->coeffs[4 * i + 2] = a[9 * i + 4] >> 4;
837
+ r->coeffs[4 * i + 2] |= (int32_t)a[9 * i + 5] << 4;
838
+ r->coeffs[4 * i + 2] |= (int32_t)a[9 * i + 6] << 12;
839
+ r->coeffs[4 * i + 2] &= 0x3FFFF;
840
+
841
+ r->coeffs[4 * i + 3] = a[9 * i + 6] >> 6;
842
+ r->coeffs[4 * i + 3] |= (int32_t)a[9 * i + 7] << 2;
843
+ r->coeffs[4 * i + 3] |= (int32_t)a[9 * i + 8] << 10;
844
+ r->coeffs[4 * i + 3] &= 0x3FFFF;
845
+
846
+ r->coeffs[4 * i + 0] = MLDSA_GAMMA1 - r->coeffs[4 * i + 0];
847
+ r->coeffs[4 * i + 1] = MLDSA_GAMMA1 - r->coeffs[4 * i + 1];
848
+ r->coeffs[4 * i + 2] = MLDSA_GAMMA1 - r->coeffs[4 * i + 2];
849
+ r->coeffs[4 * i + 3] = MLDSA_GAMMA1 - r->coeffs[4 * i + 3];
850
+ }
851
+ #else /* MLD_CONFIG_PARAMETER_SET == 44 */
852
+ for (i = 0; i < MLDSA_N / 2; ++i)
853
+ __loop__(
854
+ invariant(i <= MLDSA_N/2)
855
+ invariant(array_bound(r->coeffs, 0, i*2, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1))
856
+ decreases(MLDSA_N / 2 - i))
857
+ {
858
+ r->coeffs[2 * i + 0] = a[5 * i + 0];
859
+ r->coeffs[2 * i + 0] |= (int32_t)a[5 * i + 1] << 8;
860
+ r->coeffs[2 * i + 0] |= (int32_t)a[5 * i + 2] << 16;
861
+ r->coeffs[2 * i + 0] &= 0xFFFFF;
862
+
863
+ r->coeffs[2 * i + 1] = a[5 * i + 2] >> 4;
864
+ r->coeffs[2 * i + 1] |= (int32_t)a[5 * i + 3] << 4;
865
+ r->coeffs[2 * i + 1] |= (int32_t)a[5 * i + 4] << 12;
866
+ /* r->coeffs[2*i+1] &= 0xFFFFF; */ /* No effect, since we're anyway at 20
867
+ bits */
868
+
869
+ r->coeffs[2 * i + 0] = MLDSA_GAMMA1 - r->coeffs[2 * i + 0];
870
+ r->coeffs[2 * i + 1] = MLDSA_GAMMA1 - r->coeffs[2 * i + 1];
871
+ }
872
+ #endif /* MLD_CONFIG_PARAMETER_SET != 44 */
873
+ mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
874
+ }
875
+
876
+ MLD_INTERNAL_API
877
+ void mld_polyz_unpack(mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES])
878
+ {
879
+ #if defined(MLD_USE_NATIVE_POLYZ_UNPACK_17) && MLD_CONFIG_PARAMETER_SET == 44
880
+ int ret;
881
+ ret = mld_polyz_unpack_17_native(r->coeffs, a);
882
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
883
+ {
884
+ mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
885
+ return;
886
+ }
887
+ #elif defined(MLD_USE_NATIVE_POLYZ_UNPACK_19) && \
888
+ (MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
889
+ int ret;
890
+ ret = mld_polyz_unpack_19_native(r->coeffs, a);
891
+ if (ret == MLD_NATIVE_FUNC_SUCCESS)
892
+ {
893
+ mld_assert_bound(r->coeffs, MLDSA_N, -(MLDSA_GAMMA1 - 1), MLDSA_GAMMA1 + 1);
894
+ return;
895
+ }
896
+ #endif /* !(MLD_USE_NATIVE_POLYZ_UNPACK_17 && MLD_CONFIG_PARAMETER_SET == 44) \
897
+ && MLD_USE_NATIVE_POLYZ_UNPACK_19 && (MLD_CONFIG_PARAMETER_SET == 65 \
898
+ || MLD_CONFIG_PARAMETER_SET == 87) */
899
+
900
+ mld_polyz_unpack_c(r, a);
901
+ }
902
+
903
+ MLD_INTERNAL_API
904
+ void mld_polyw1_pack(uint8_t r[MLDSA_POLYW1_PACKEDBYTES], const mld_poly *a)
905
+ {
906
+ unsigned int i;
907
+
908
+ mld_assert_bound(a->coeffs, MLDSA_N, 0, (MLDSA_Q - 1) / (2 * MLDSA_GAMMA2));
909
+
910
+ #if MLD_CONFIG_PARAMETER_SET == 44
911
+ for (i = 0; i < MLDSA_N / 4; ++i)
912
+ __loop__(
913
+ invariant(i <= MLDSA_N/4)
914
+ decreases(MLDSA_N / 4 - i))
915
+ {
916
+ r[3 * i + 0] = (uint8_t)((a->coeffs[4 * i + 0]) & 0xFF);
917
+ r[3 * i + 0] |= (uint8_t)((a->coeffs[4 * i + 1] << 6) & 0xFF);
918
+ r[3 * i + 1] = (uint8_t)((a->coeffs[4 * i + 1] >> 2) & 0xFF);
919
+ r[3 * i + 1] |= (uint8_t)((a->coeffs[4 * i + 2] << 4) & 0xFF);
920
+ r[3 * i + 2] = (uint8_t)((a->coeffs[4 * i + 2] >> 4) & 0xFF);
921
+ r[3 * i + 2] |= (uint8_t)((a->coeffs[4 * i + 3] << 2) & 0xFF);
922
+ }
923
+ #else /* MLD_CONFIG_PARAMETER_SET == 44 */
924
+ for (i = 0; i < MLDSA_N / 2; ++i)
925
+ __loop__(
926
+ invariant(i <= MLDSA_N/2)
927
+ decreases(MLDSA_N / 2 - i))
928
+ {
929
+ r[i] =
930
+ (uint8_t)((a->coeffs[2 * i + 0] | (a->coeffs[2 * i + 1] << 4)) & 0xFF);
931
+ }
932
+ #endif /* MLD_CONFIG_PARAMETER_SET != 44 */
933
+ }
934
+
935
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros. */
936
+
937
+ /* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
938
+ * Don't modify by hand -- this is auto-generated by scripts/autogen. */
939
+ #undef mld_rej_eta
940
+ #undef mld_rej_eta_c
941
+ #undef mld_poly_decompose_c
942
+ #undef mld_poly_use_hint_c
943
+ #undef mld_polyz_unpack_c
944
+ #undef MLD_POLY_UNIFORM_ETA_NBLOCKS
945
+ #undef MLD_POLY_UNIFORM_ETA_NBLOCKS
946
+ #undef MLD_POLY_UNIFORM_GAMMA1_NBLOCKS