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,572 @@
1
+ /*
2
+ * Copyright (c) The mlkem-native project authors
3
+ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4
+ */
5
+
6
+ /* References
7
+ * ==========
8
+ *
9
+ * - [NeonNTT]
10
+ * Neon NTT: Faster Dilithium, Kyber, and Saber on Cortex-A72 and Apple M1
11
+ * Becker, Hwang, Kannwischer, Yang, Yang
12
+ * https://eprint.iacr.org/2021/986
13
+ *
14
+ * - [REF]
15
+ * CRYSTALS-Kyber C reference implementation
16
+ * Bos, Ducas, Kiltz, Lepoint, Lyubashevsky, Schanck, Schwabe, Seiler, Stehlé
17
+ * https://github.com/pq-crystals/kyber/tree/main/ref
18
+ */
19
+
20
+ #include "common.h"
21
+ #if !defined(MLK_CONFIG_MULTILEVEL_NO_SHARED)
22
+
23
+
24
+ #include "cbmc.h"
25
+ #include "debug.h"
26
+ #include "poly.h"
27
+ #include "sampling.h"
28
+ #include "symmetric.h"
29
+ #include "verify.h"
30
+
31
+ /*************************************************
32
+ * Name: mlk_fqmul
33
+ *
34
+ * Description: Montgomery multiplication modulo MLKEM_Q
35
+ *
36
+ * Arguments: - int16_t a: first factor
37
+ * Can be any int16_t.
38
+ * - int16_t b: second factor.
39
+ * Must be signed canonical (abs value <(MLKEM_Q+1)/2)
40
+ *
41
+ * Returns 16-bit integer congruent to a*b*R^{-1} mod MLKEM_Q, and
42
+ * smaller than MLKEM_Q in absolute value.
43
+ *
44
+ **************************************************/
45
+
46
+ /* Reference: `fqmul()` in the reference implementation @[REF]. */
47
+ static MLK_INLINE int16_t mlk_fqmul(int16_t a, int16_t b)
48
+ __contract__(
49
+ requires(b > -MLKEM_Q_HALF && b < MLKEM_Q_HALF)
50
+ ensures(return_value > -MLKEM_Q && return_value < MLKEM_Q)
51
+ )
52
+ {
53
+ int16_t res;
54
+ mlk_assert_abs_bound(&b, 1, MLKEM_Q_HALF);
55
+
56
+ res = mlk_montgomery_reduce((int32_t)a * (int32_t)b);
57
+ /* Bounds:
58
+ * |res| <= ceil(|a| * |b| / 2^16) + (MLKEM_Q + 1) / 2
59
+ * <= ceil(2^15 * ((MLKEM_Q - 1)/2) / 2^16) + (MLKEM_Q + 1) / 2
60
+ * <= ceil((MLKEM_Q - 1) / 4) + (MLKEM_Q + 1) / 2
61
+ * < MLKEM_Q
62
+ */
63
+
64
+ mlk_assert_abs_bound(&res, 1, MLKEM_Q);
65
+ return res;
66
+ }
67
+
68
+ /*************************************************
69
+ * Name: mlk_barrett_reduce
70
+ *
71
+ * Description: Barrett reduction; given a 16-bit integer a, computes
72
+ * centered representative congruent to a mod q in
73
+ * {-(q-1)/2,...,(q-1)/2}
74
+ *
75
+ * Arguments: - int16_t a: input integer to be reduced
76
+ *
77
+ * Returns: integer in {-(q-1)/2,...,(q-1)/2} congruent to a modulo q.
78
+ *
79
+ **************************************************/
80
+
81
+ /* Reference: `barrett_reduce()` in the reference implementation @[REF]. */
82
+ static MLK_INLINE int16_t mlk_barrett_reduce(int16_t a)
83
+ __contract__(
84
+ ensures(return_value > -MLKEM_Q_HALF && return_value < MLKEM_Q_HALF)
85
+ )
86
+ {
87
+ /* Barrett reduction approximates
88
+ * ```
89
+ * round(a/MLKEM_Q)
90
+ * = round(a*(2^N/MLKEM_Q))/2^N)
91
+ * ~= round(a*round(2^N/MLKEM_Q)/2^N)
92
+ * ```
93
+ * Here, we pick N=26.
94
+ */
95
+ const int32_t magic = 20159; /* check-magic: 20159 == round(2^26 / MLKEM_Q) */
96
+
97
+ /*
98
+ * PORTABILITY: Right-shift on a signed integer is
99
+ * implementation-defined for negative left argument.
100
+ * Here, we assume it's sign-preserving "arithmetic" shift right.
101
+ * See (C99 6.5.7 (5))
102
+ */
103
+ const int32_t t = (magic * a + ((int32_t)1 << 25)) >> 26;
104
+
105
+ /*
106
+ * t is in -10 .. +10, so we need 32-bit math to
107
+ * evaluate t * MLKEM_Q and the subsequent subtraction
108
+ */
109
+ int16_t res = (int16_t)(a - t * MLKEM_Q);
110
+
111
+ mlk_assert_abs_bound(&res, 1, MLKEM_Q_HALF);
112
+ return res;
113
+ }
114
+
115
+ /* Reference: `poly_tomont()` in the reference implementation @[REF]. */
116
+ MLK_STATIC_TESTABLE void mlk_poly_tomont_c(mlk_poly *r)
117
+ __contract__(
118
+ requires(memory_no_alias(r, sizeof(mlk_poly)))
119
+ assigns(memory_slice(r, sizeof(mlk_poly)))
120
+ ensures(array_abs_bound(r->coeffs, 0, MLKEM_N, MLKEM_Q))
121
+ )
122
+ {
123
+ unsigned i;
124
+ const int16_t f = 1353; /* check-magic: 1353 == signed_mod(2^32, MLKEM_Q) */
125
+ for (i = 0; i < MLKEM_N; i++)
126
+ __loop__(
127
+ invariant(i <= MLKEM_N)
128
+ invariant(array_abs_bound(r->coeffs, 0, i, MLKEM_Q)))
129
+ {
130
+ r->coeffs[i] = mlk_fqmul(r->coeffs[i], f);
131
+ }
132
+
133
+ mlk_assert_abs_bound(r, MLKEM_N, MLKEM_Q);
134
+ }
135
+
136
+ MLK_INTERNAL_API
137
+ void mlk_poly_tomont(mlk_poly *r)
138
+ {
139
+ #if defined(MLK_USE_NATIVE_POLY_TOMONT)
140
+ int ret;
141
+ ret = mlk_poly_tomont_native(r->coeffs);
142
+ if (ret == MLK_NATIVE_FUNC_SUCCESS)
143
+ {
144
+ mlk_assert_abs_bound(r, MLKEM_N, MLKEM_Q);
145
+ return;
146
+ }
147
+ #endif /* MLK_USE_NATIVE_POLY_TOMONT */
148
+
149
+ mlk_poly_tomont_c(r);
150
+ }
151
+
152
+ /************************************************************
153
+ * Name: mlk_scalar_signed_to_unsigned_q
154
+ *
155
+ * Description: Constant-time conversion of signed representatives
156
+ * modulo MLKEM_Q within range (-(MLKEM_Q-1) .. (MLKEM_Q-1))
157
+ * into unsigned representatives within range (0..(MLKEM_Q-1)).
158
+ *
159
+ * Arguments: c: signed coefficient to be converted
160
+ *
161
+ ************************************************************/
162
+
163
+ /* Reference: Not present in the reference implementation @[REF].
164
+ * - Used here to implement different semantics of `poly_reduce()`;
165
+ * see below. in the reference implementation @[REF], this logic is
166
+ * part of all compression functions (see `compress.c`). */
167
+ static MLK_INLINE int16_t mlk_scalar_signed_to_unsigned_q(int16_t c)
168
+ __contract__(
169
+ requires(c > -MLKEM_Q && c < MLKEM_Q)
170
+ ensures(return_value >= 0 && return_value < MLKEM_Q)
171
+ ensures(return_value == (int32_t)c + (((int32_t)c < 0) * MLKEM_Q)))
172
+ {
173
+ mlk_assert_abs_bound(&c, 1, MLKEM_Q);
174
+
175
+ /* Add MLKEM_Q if c is negative, but in constant time.
176
+ *
177
+ * Note that c + MLKEM_Q does not overflow in int16_t,
178
+ * so the cast to uint16_t is safe. */
179
+ c = mlk_ct_sel_int16((int16_t)(c + MLKEM_Q), c, mlk_ct_cmask_neg_i16(c));
180
+
181
+ mlk_assert_bound(&c, 1, 0, MLKEM_Q);
182
+ return c;
183
+ }
184
+
185
+ /* Reference: `poly_reduce()` in the reference implementation @[REF]
186
+ * - We use _unsigned_ canonical outputs, while the reference
187
+ * implementation uses _signed_ canonical outputs.
188
+ * Accordingly, we need a conditional addition of MLKEM_Q
189
+ * here to go from signed to unsigned representatives.
190
+ * This conditional addition is then dropped from all
191
+ * polynomial compression functions instead (see `compress.c`). */
192
+ MLK_STATIC_TESTABLE void mlk_poly_reduce_c(mlk_poly *r)
193
+ __contract__(
194
+ requires(memory_no_alias(r, sizeof(mlk_poly)))
195
+ assigns(memory_slice(r, sizeof(mlk_poly)))
196
+ ensures(array_bound(r->coeffs, 0, MLKEM_N, 0, MLKEM_Q))
197
+ )
198
+ {
199
+ unsigned i;
200
+
201
+ for (i = 0; i < MLKEM_N; i++)
202
+ __loop__(
203
+ invariant(i <= MLKEM_N)
204
+ invariant(array_bound(r->coeffs, 0, i, 0, MLKEM_Q)))
205
+ {
206
+ /* Barrett reduction, giving signed canonical representative */
207
+ int16_t t = mlk_barrett_reduce(r->coeffs[i]);
208
+ /* Conditional addition to get unsigned canonical representative */
209
+ r->coeffs[i] = mlk_scalar_signed_to_unsigned_q(t);
210
+ }
211
+
212
+ mlk_assert_bound(r, MLKEM_N, 0, MLKEM_Q);
213
+ }
214
+
215
+ MLK_INTERNAL_API
216
+ void mlk_poly_reduce(mlk_poly *r)
217
+ {
218
+ #if defined(MLK_USE_NATIVE_POLY_REDUCE)
219
+ int ret;
220
+ ret = mlk_poly_reduce_native(r->coeffs);
221
+ if (ret == MLK_NATIVE_FUNC_SUCCESS)
222
+ {
223
+ mlk_assert_bound(r, MLKEM_N, 0, MLKEM_Q);
224
+ return;
225
+ }
226
+ #endif /* MLK_USE_NATIVE_POLY_REDUCE */
227
+
228
+ mlk_poly_reduce_c(r);
229
+ }
230
+
231
+ /* Reference: `poly_add()` in the reference implementation @[REF].
232
+ * - We use destructive version (output=first input) to avoid
233
+ * reasoning about aliasing in the CBMC specification */
234
+ MLK_INTERNAL_API
235
+ void mlk_poly_add(mlk_poly *r, const mlk_poly *b)
236
+ {
237
+ unsigned i;
238
+ for (i = 0; i < MLKEM_N; i++)
239
+ __loop__(
240
+ invariant(i <= MLKEM_N)
241
+ invariant(forall(k0, i, MLKEM_N, r->coeffs[k0] == loop_entry(*r).coeffs[k0]))
242
+ invariant(forall(k1, 0, i, r->coeffs[k1] == loop_entry(*r).coeffs[k1] + b->coeffs[k1])))
243
+ {
244
+ /* The preconditions imply that the addition stays within int16_t. */
245
+ r->coeffs[i] = (int16_t)(r->coeffs[i] + b->coeffs[i]);
246
+ }
247
+ }
248
+
249
+ /* Reference: `poly_sub()` in the reference implementation @[REF].
250
+ * - We use destructive version (output=first input) to avoid
251
+ * reasoning about aliasing in the CBMC specification */
252
+ MLK_INTERNAL_API
253
+ void mlk_poly_sub(mlk_poly *r, const mlk_poly *b)
254
+ {
255
+ unsigned i;
256
+ for (i = 0; i < MLKEM_N; i++)
257
+ __loop__(
258
+ invariant(i <= MLKEM_N)
259
+ invariant(forall(k0, i, MLKEM_N, r->coeffs[k0] == loop_entry(*r).coeffs[k0]))
260
+ invariant(forall(k1, 0, i, r->coeffs[k1] == loop_entry(*r).coeffs[k1] - b->coeffs[k1])))
261
+ {
262
+ /* The preconditions imply that the subtraction stays within int16_t. */
263
+ r->coeffs[i] = (int16_t)(r->coeffs[i] - b->coeffs[i]);
264
+ }
265
+ }
266
+
267
+ #include "zetas.inc"
268
+
269
+ /* Reference: Does not exist in the reference implementation @[REF].
270
+ * - The reference implementation does not use a
271
+ * multiplication cache ('mulcache'). This idea originates
272
+ * from @[NeonNTT] and is used at the C level here. */
273
+ MLK_STATIC_TESTABLE void mlk_poly_mulcache_compute_c(mlk_poly_mulcache *x,
274
+ const mlk_poly *a)
275
+ __contract__(
276
+ requires(memory_no_alias(x, sizeof(mlk_poly_mulcache)))
277
+ requires(memory_no_alias(a, sizeof(mlk_poly)))
278
+ assigns(memory_slice(x, sizeof(mlk_poly_mulcache)))
279
+ )
280
+ {
281
+ unsigned i;
282
+ for (i = 0; i < MLKEM_N / 4; i++)
283
+ __loop__(
284
+ invariant(i <= MLKEM_N / 4)
285
+ invariant(array_abs_bound(x->coeffs, 0, 2 * i, MLKEM_Q)))
286
+ {
287
+ x->coeffs[2 * i + 0] = mlk_fqmul(a->coeffs[4 * i + 1], mlk_zetas[64 + i]);
288
+ /* The values in zeta table are <= MLKEM_Q in absolute value,
289
+ * so the negation in int16_t is safe. */
290
+ x->coeffs[2 * i + 1] =
291
+ mlk_fqmul(a->coeffs[4 * i + 3], (int16_t)(-mlk_zetas[64 + i]));
292
+ }
293
+
294
+ /*
295
+ * This bound is true for the C implementation, but not needed
296
+ * in the higher level bounds reasoning. It is thus omitted
297
+ * from the spec to not unnecessarily constrain native
298
+ * implementations, but checked here nonetheless.
299
+ */
300
+ mlk_assert_abs_bound(x, MLKEM_N / 2, MLKEM_Q);
301
+ }
302
+
303
+ MLK_INTERNAL_API
304
+ void mlk_poly_mulcache_compute(mlk_poly_mulcache *x, const mlk_poly *a)
305
+ {
306
+ #if defined(MLK_USE_NATIVE_POLY_MULCACHE_COMPUTE)
307
+ int ret;
308
+ ret = mlk_poly_mulcache_compute_native(x->coeffs, a->coeffs);
309
+ if (ret == MLK_NATIVE_FUNC_SUCCESS)
310
+ {
311
+ return;
312
+ }
313
+ #endif /* MLK_USE_NATIVE_POLY_MULCACHE_COMPUTE */
314
+
315
+ mlk_poly_mulcache_compute_c(x, a);
316
+ }
317
+
318
+ /*
319
+ * Computes a block CT butterflies with a fixed twiddle factor,
320
+ * using Montgomery multiplication.
321
+ * Parameters:
322
+ * - r: Pointer to base of polynomial (_not_ the base of butterfly block)
323
+ * - root: Twiddle factor to use for the butterfly. This must be in
324
+ * Montgomery form and signed canonical.
325
+ * - start: Offset to the beginning of the butterfly block
326
+ * - len: Index difference between coefficients subject to a butterfly
327
+ * - bound: Ghost variable describing coefficient bound: Prior to `start`,
328
+ * coefficients must be bound by `bound + MLKEM_Q`. Post `start`,
329
+ * they must be bound by `bound`.
330
+ * When this function returns, output coefficients in the index range
331
+ * [start, start+2*len) have bound bumped to `bound + MLKEM_Q`.
332
+ * Example:
333
+ * - start=8, len=4
334
+ * This would compute the following four butterflies
335
+ * 8 -- 12
336
+ * 9 -- 13
337
+ * 10 -- 14
338
+ * 11 -- 15
339
+ * - start=4, len=2
340
+ * This would compute the following two butterflies
341
+ * 4 -- 6
342
+ * 5 -- 7
343
+ */
344
+
345
+ /* Reference: Embedded in `ntt()` in the reference implementation @[REF]. */
346
+ static void mlk_ntt_butterfly_block(int16_t r[MLKEM_N], int16_t zeta,
347
+ unsigned start, unsigned len,
348
+ unsigned bound)
349
+ __contract__(
350
+ requires(start < MLKEM_N)
351
+ requires(1 <= len && len <= MLKEM_N / 2 && start + 2 * len <= MLKEM_N)
352
+ requires(0 <= bound && bound < INT16_MAX - MLKEM_Q)
353
+ requires(-MLKEM_Q_HALF < zeta && zeta < MLKEM_Q_HALF)
354
+ requires(memory_no_alias(r, sizeof(int16_t) * MLKEM_N))
355
+ requires(array_abs_bound(r, 0, start, bound + MLKEM_Q))
356
+ requires(array_abs_bound(r, start, MLKEM_N, bound))
357
+ assigns(memory_slice(r, sizeof(int16_t) * MLKEM_N))
358
+ ensures(array_abs_bound(r, 0, start + 2*len, bound + MLKEM_Q))
359
+ ensures(array_abs_bound(r, start + 2 * len, MLKEM_N, bound)))
360
+ {
361
+ /* `bound` is a ghost variable only needed in the CBMC specification */
362
+ unsigned j;
363
+ ((void)bound);
364
+ for (j = start; j < start + len; j++)
365
+ __loop__(
366
+ invariant(start <= j && j <= start + len)
367
+ /*
368
+ * Coefficients are updated in strided pairs, so the bounds for the
369
+ * intermediate states alternate twice between the old and new bound
370
+ */
371
+ invariant(array_abs_bound(r, 0, j, bound + MLKEM_Q))
372
+ invariant(array_abs_bound(r, j, start + len, bound))
373
+ invariant(array_abs_bound(r, start + len, j + len, bound + MLKEM_Q))
374
+ invariant(array_abs_bound(r, j + len, MLKEM_N, bound)))
375
+ {
376
+ int16_t t;
377
+ t = mlk_fqmul(r[j + len], zeta);
378
+ /* The precondition implies that the arithmetic does not overflow. */
379
+ r[j + len] = (int16_t)(r[j] - t);
380
+ r[j] = (int16_t)(r[j] + t);
381
+ }
382
+ }
383
+
384
+ /*
385
+ * Compute one layer of forward NTT
386
+ * Parameters:
387
+ * - r: Pointer to base of polynomial
388
+ * - layer: Variable indicating which layer is being applied.
389
+ */
390
+
391
+ /* Reference: Embedded in `ntt()` in the reference implementation @[REF]. */
392
+ static void mlk_ntt_layer(int16_t r[MLKEM_N], unsigned layer)
393
+ __contract__(
394
+ requires(memory_no_alias(r, sizeof(int16_t) * MLKEM_N))
395
+ requires(1 <= layer && layer <= 7)
396
+ requires(array_abs_bound(r, 0, MLKEM_N, layer * MLKEM_Q))
397
+ assigns(memory_slice(r, sizeof(int16_t) * MLKEM_N))
398
+ ensures(array_abs_bound(r, 0, MLKEM_N, (layer + 1) * MLKEM_Q)))
399
+ {
400
+ unsigned start, k, len;
401
+ /* Twiddle factors for layer n are at indices 2^(n-1)..2^n-1. */
402
+ k = 1u << (layer - 1);
403
+ len = (unsigned)MLKEM_N >> layer;
404
+ for (start = 0; start < MLKEM_N; start += 2 * len)
405
+ __loop__(
406
+ invariant(start < MLKEM_N + 2 * len)
407
+ invariant(k <= MLKEM_N / 2 && 2 * len * k == start + MLKEM_N)
408
+ invariant(array_abs_bound(r, 0, start, layer * MLKEM_Q + MLKEM_Q))
409
+ invariant(array_abs_bound(r, start, MLKEM_N, layer * MLKEM_Q)))
410
+ {
411
+ int16_t zeta = mlk_zetas[k++];
412
+ mlk_ntt_butterfly_block(r, zeta, start, len, layer * MLKEM_Q);
413
+ }
414
+ }
415
+
416
+ /*
417
+ * Compute full forward NTT
418
+ * NOTE: This particular implementation satisfies a much tighter
419
+ * bound on the output coefficients (5*q) than the contractual one (8*q),
420
+ * but this is not needed in the calling code. Should we change the
421
+ * base multiplication strategy to require smaller NTT output bounds,
422
+ * the proof may need strengthening.
423
+ */
424
+
425
+ /* Reference: `ntt()` in the reference implementation @[REF].
426
+ * - Iterate over `layer` instead of `len` in the outer loop
427
+ * to simplify computation of zeta index. */
428
+ MLK_STATIC_TESTABLE void mlk_poly_ntt_c(mlk_poly *p)
429
+ __contract__(
430
+ requires(memory_no_alias(p, sizeof(mlk_poly)))
431
+ requires(array_abs_bound(p->coeffs, 0, MLKEM_N, MLKEM_Q))
432
+ assigns(memory_slice(p, sizeof(mlk_poly)))
433
+ ensures(array_abs_bound(p->coeffs, 0, MLKEM_N, MLK_NTT_BOUND))
434
+ )
435
+ {
436
+ unsigned layer;
437
+ int16_t *r;
438
+
439
+ mlk_assert_abs_bound(p, MLKEM_N, MLKEM_Q);
440
+
441
+ r = p->coeffs;
442
+
443
+ for (layer = 1; layer <= 7; layer++)
444
+ __loop__(
445
+ invariant(1 <= layer && layer <= 8)
446
+ invariant(array_abs_bound(r, 0, MLKEM_N, layer * MLKEM_Q)))
447
+ {
448
+ mlk_ntt_layer(r, layer);
449
+ }
450
+
451
+ /* Check the stronger bound */
452
+ mlk_assert_abs_bound(p, MLKEM_N, MLK_NTT_BOUND);
453
+ }
454
+
455
+ MLK_INTERNAL_API
456
+ void mlk_poly_ntt(mlk_poly *p)
457
+ {
458
+ #if defined(MLK_USE_NATIVE_NTT)
459
+ int ret;
460
+ mlk_assert_abs_bound(p, MLKEM_N, MLKEM_Q);
461
+ ret = mlk_ntt_native(p->coeffs);
462
+ if (ret == MLK_NATIVE_FUNC_SUCCESS)
463
+ {
464
+ mlk_assert_abs_bound(p, MLKEM_N, MLK_NTT_BOUND);
465
+ return;
466
+ }
467
+ #endif /* MLK_USE_NATIVE_NTT */
468
+
469
+ mlk_poly_ntt_c(p);
470
+ }
471
+
472
+
473
+ /* Compute one layer of inverse NTT */
474
+
475
+ /* Reference: Embedded into `invntt()` in the reference implementation @[REF] */
476
+ static void mlk_invntt_layer(int16_t *r, unsigned layer)
477
+ __contract__(
478
+ requires(memory_no_alias(r, sizeof(int16_t) * MLKEM_N))
479
+ requires(1 <= layer && layer <= 7)
480
+ requires(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q))
481
+ assigns(memory_slice(r, sizeof(int16_t) * MLKEM_N))
482
+ ensures(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q)))
483
+ {
484
+ unsigned start, k, len;
485
+ len = (unsigned)MLKEM_N >> layer;
486
+ k = (1u << layer) - 1;
487
+ for (start = 0; start < MLKEM_N; start += 2 * len)
488
+ __loop__(
489
+ invariant(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q))
490
+ invariant(start <= MLKEM_N && k <= 127)
491
+ /* Normalised form of k == MLKEM_N / len - 1 - start / (2 * len) */
492
+ invariant(2 * len * k + start == 2 * MLKEM_N - 2 * len))
493
+ {
494
+ unsigned j;
495
+ int16_t zeta = mlk_zetas[k--];
496
+ for (j = start; j < start + len; j++)
497
+ __loop__(
498
+ invariant(start <= j && j <= start + len)
499
+ invariant(start <= MLKEM_N && k <= 127)
500
+ invariant(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q)))
501
+ {
502
+ int16_t t = r[j];
503
+ /* The preconditions imply that the arithmetic does not overflow. */
504
+ r[j] = mlk_barrett_reduce((int16_t)(t + r[j + len]));
505
+ r[j + len] = (int16_t)(r[j + len] - t);
506
+ r[j + len] = mlk_fqmul(r[j + len], zeta);
507
+ }
508
+ }
509
+ }
510
+
511
+ /* Reference: `invntt()` in the reference implementation @[REF]
512
+ * - We normalize at the beginning of the inverse NTT,
513
+ * while the reference implementation normalizes at
514
+ * the end. This allows us to drop a call to `poly_reduce()`
515
+ * from the base multiplication. */
516
+ MLK_STATIC_TESTABLE void mlk_poly_invntt_tomont_c(mlk_poly *p)
517
+ __contract__(
518
+ requires(memory_no_alias(p, sizeof(mlk_poly)))
519
+ assigns(memory_slice(p, sizeof(mlk_poly)))
520
+ ensures(array_abs_bound(p->coeffs, 0, MLKEM_N, MLK_INVNTT_BOUND))
521
+ )
522
+ {
523
+ unsigned j, layer;
524
+ const int16_t f = 1441; /* check-magic: 1441 == pow(2,32 - 7,MLKEM_Q) */
525
+ int16_t *r = p->coeffs;
526
+
527
+ /*
528
+ * Scale input polynomial to account for Montgomery factor
529
+ * and NTT twist. This also brings coefficients down to
530
+ * absolute value < MLKEM_Q.
531
+ */
532
+ for (j = 0; j < MLKEM_N; j++)
533
+ __loop__(
534
+ invariant(j <= MLKEM_N)
535
+ invariant(array_abs_bound(r, 0, j, MLKEM_Q)))
536
+ {
537
+ r[j] = mlk_fqmul(r[j], f);
538
+ }
539
+
540
+ /* Run the invNTT layers */
541
+ for (layer = 7; layer > 0; layer--)
542
+ __loop__(
543
+ invariant(0 <= layer && layer < 8)
544
+ invariant(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q)))
545
+ {
546
+ mlk_invntt_layer(r, layer);
547
+ }
548
+
549
+ mlk_assert_abs_bound(p, MLKEM_N, MLK_INVNTT_BOUND);
550
+ }
551
+
552
+ MLK_INTERNAL_API
553
+ void mlk_poly_invntt_tomont(mlk_poly *p)
554
+ {
555
+ #if defined(MLK_USE_NATIVE_INTT)
556
+ int ret;
557
+ ret = mlk_intt_native(p->coeffs);
558
+ if (ret == MLK_NATIVE_FUNC_SUCCESS)
559
+ {
560
+ mlk_assert_abs_bound(p, MLKEM_N, MLK_INVNTT_BOUND);
561
+ return;
562
+ }
563
+ #endif /* MLK_USE_NATIVE_INTT */
564
+
565
+ mlk_poly_invntt_tomont_c(p);
566
+ }
567
+
568
+ #else /* !MLK_CONFIG_MULTILEVEL_NO_SHARED */
569
+
570
+ MLK_EMPTY_CU(mlk_poly)
571
+
572
+ #endif /* MLK_CONFIG_MULTILEVEL_NO_SHARED */