pq_crypto 0.4.2 → 0.5.1

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 (410) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -2
  3. data/CHANGELOG.md +59 -0
  4. data/GET_STARTED.md +21 -16
  5. data/README.md +26 -0
  6. data/SECURITY.md +22 -16
  7. data/ext/pqcrypto/extconf.rb +183 -99
  8. data/ext/pqcrypto/mldsa_api.h +1 -118
  9. data/ext/pqcrypto/mlkem_api.h +1 -42
  10. data/ext/pqcrypto/pq_externalmu.c +88 -216
  11. data/ext/pqcrypto/pqcrypto_native_api.h +132 -0
  12. data/ext/pqcrypto/pqcrypto_ruby_secure.c +234 -12
  13. data/ext/pqcrypto/pqcrypto_secure.c +429 -334
  14. data/ext/pqcrypto/pqcrypto_secure.h +13 -45
  15. data/ext/pqcrypto/pqcrypto_version.h +1 -1
  16. data/ext/pqcrypto/randombytes.h +9 -0
  17. data/ext/pqcrypto/vendor/.vendored +12 -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/hybrid_kem.rb +10 -1
  250. data/lib/pq_crypto/version.rb +1 -1
  251. data/lib/pq_crypto.rb +5 -1
  252. data/script/vendor_libs.rb +228 -154
  253. metadata +236 -160
  254. data/ext/pqcrypto/vendor/pqclean/common/aes.c +0 -639
  255. data/ext/pqcrypto/vendor/pqclean/common/aes.h +0 -64
  256. data/ext/pqcrypto/vendor/pqclean/common/compat.h +0 -73
  257. data/ext/pqcrypto/vendor/pqclean/common/crypto_declassify.h +0 -7
  258. data/ext/pqcrypto/vendor/pqclean/common/fips202.c +0 -928
  259. data/ext/pqcrypto/vendor/pqclean/common/fips202.h +0 -166
  260. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/feat.S +0 -168
  261. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.c +0 -684
  262. data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.h +0 -60
  263. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SIMD256.c +0 -1028
  264. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SnP.h +0 -50
  265. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-unrolling.macros +0 -198
  266. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile +0 -8
  267. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile.Microsoft_nmake +0 -8
  268. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/SIMD256-config.h +0 -3
  269. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/align.h +0 -34
  270. data/ext/pqcrypto/vendor/pqclean/common/keccak4x/brg_endian.h +0 -142
  271. data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.c +0 -101
  272. data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.h +0 -39
  273. data/ext/pqcrypto/vendor/pqclean/common/randombytes.c +0 -355
  274. data/ext/pqcrypto/vendor/pqclean/common/randombytes.h +0 -27
  275. data/ext/pqcrypto/vendor/pqclean/common/sha2.c +0 -769
  276. data/ext/pqcrypto/vendor/pqclean/common/sha2.h +0 -173
  277. data/ext/pqcrypto/vendor/pqclean/common/sp800-185.c +0 -156
  278. data/ext/pqcrypto/vendor/pqclean/common/sp800-185.h +0 -27
  279. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/LICENSE +0 -5
  280. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile +0 -19
  281. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile.Microsoft_nmake +0 -23
  282. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/api.h +0 -18
  283. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.c +0 -83
  284. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.h +0 -11
  285. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.c +0 -327
  286. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.h +0 -22
  287. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.c +0 -164
  288. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.h +0 -23
  289. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.c +0 -146
  290. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.h +0 -14
  291. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/params.h +0 -36
  292. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.c +0 -311
  293. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.h +0 -37
  294. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.c +0 -198
  295. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.h +0 -26
  296. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.c +0 -41
  297. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.h +0 -13
  298. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric-shake.c +0 -71
  299. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric.h +0 -30
  300. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.c +0 -67
  301. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.h +0 -13
  302. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/LICENSE +0 -5
  303. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile +0 -19
  304. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile.Microsoft_nmake +0 -23
  305. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/api.h +0 -18
  306. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.c +0 -108
  307. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.h +0 -11
  308. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.c +0 -327
  309. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.h +0 -22
  310. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.c +0 -164
  311. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.h +0 -23
  312. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.c +0 -146
  313. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.h +0 -14
  314. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/params.h +0 -36
  315. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.c +0 -299
  316. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.h +0 -37
  317. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.c +0 -188
  318. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.h +0 -26
  319. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.c +0 -41
  320. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.h +0 -13
  321. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric-shake.c +0 -71
  322. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric.h +0 -30
  323. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.c +0 -67
  324. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.h +0 -13
  325. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/LICENSE +0 -5
  326. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile +0 -19
  327. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile.Microsoft_nmake +0 -23
  328. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/api.h +0 -18
  329. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.c +0 -83
  330. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.h +0 -11
  331. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.c +0 -327
  332. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.h +0 -22
  333. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.c +0 -164
  334. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.h +0 -23
  335. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.c +0 -146
  336. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.h +0 -14
  337. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/params.h +0 -36
  338. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.c +0 -299
  339. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.h +0 -37
  340. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.c +0 -188
  341. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.h +0 -26
  342. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.c +0 -41
  343. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.h +0 -13
  344. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric-shake.c +0 -71
  345. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric.h +0 -30
  346. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.c +0 -67
  347. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.h +0 -13
  348. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/LICENSE +0 -5
  349. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile +0 -19
  350. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile.Microsoft_nmake +0 -23
  351. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/api.h +0 -50
  352. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.c +0 -98
  353. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.h +0 -10
  354. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.c +0 -261
  355. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.h +0 -31
  356. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/params.h +0 -44
  357. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.c +0 -848
  358. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.h +0 -52
  359. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.c +0 -415
  360. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.h +0 -65
  361. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.c +0 -69
  362. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.h +0 -17
  363. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.c +0 -98
  364. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.h +0 -14
  365. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.c +0 -407
  366. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.h +0 -47
  367. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric-shake.c +0 -26
  368. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric.h +0 -34
  369. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/LICENSE +0 -5
  370. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile +0 -19
  371. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile.Microsoft_nmake +0 -23
  372. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/api.h +0 -50
  373. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.c +0 -98
  374. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.h +0 -10
  375. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.c +0 -261
  376. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.h +0 -31
  377. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/params.h +0 -44
  378. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.c +0 -799
  379. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.h +0 -52
  380. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.c +0 -415
  381. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.h +0 -65
  382. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.c +0 -69
  383. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.h +0 -17
  384. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.c +0 -92
  385. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.h +0 -14
  386. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.c +0 -407
  387. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.h +0 -47
  388. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric-shake.c +0 -26
  389. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric.h +0 -34
  390. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/LICENSE +0 -5
  391. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile +0 -19
  392. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile.Microsoft_nmake +0 -23
  393. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/api.h +0 -50
  394. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.c +0 -98
  395. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.h +0 -10
  396. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.c +0 -261
  397. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.h +0 -31
  398. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/params.h +0 -44
  399. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.c +0 -823
  400. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.h +0 -52
  401. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.c +0 -415
  402. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.h +0 -65
  403. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.c +0 -69
  404. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.h +0 -17
  405. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.c +0 -92
  406. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.h +0 -14
  407. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.c +0 -407
  408. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.h +0 -47
  409. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric-shake.c +0 -26
  410. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric.h +0 -34
@@ -15,19 +15,12 @@
15
15
  #include <openssl/crypto.h>
16
16
  #include <openssl/evp.h>
17
17
  #include <openssl/rand.h>
18
- #include <openssl/bio.h>
19
- #include <openssl/buffer.h>
20
18
 
21
19
  #if OPENSSL_VERSION_NUMBER < 0x30000000L
22
20
  #error "OpenSSL 3.0 or later is required for pq_crypto"
23
21
  #endif
24
22
 
25
- #ifndef HAVE_PQCLEAN
26
- #error "PQClean-backed algorithms are required. Run: bundle exec rake vendor"
27
- #endif
28
-
29
- #include "mlkem_api.h"
30
- #include "mldsa_api.h"
23
+ #include "pqcrypto_native_api.h"
31
24
 
32
25
  void pq_secure_wipe(void *ptr, size_t len) {
33
26
  if (ptr == NULL) {
@@ -54,43 +47,6 @@ static int pq_is_pem_whitespace(char c) {
54
47
  return c == '\n' || c == '\r' || c == ' ' || c == '\t';
55
48
  }
56
49
 
57
- static int x25519_keypair(uint8_t *pk, uint8_t *sk) {
58
- EVP_PKEY_CTX *ctx = NULL;
59
- EVP_PKEY *pkey = NULL;
60
- size_t pklen = X25519_PUBLICKEYBYTES;
61
- size_t sklen = X25519_SECRETKEYBYTES;
62
- int ret = PQ_ERROR_KEYPAIR;
63
-
64
- ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
65
- if (!ctx)
66
- goto cleanup;
67
-
68
- if (EVP_PKEY_keygen_init(ctx) <= 0)
69
- goto cleanup;
70
-
71
- if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
72
- goto cleanup;
73
-
74
- if (EVP_PKEY_get_raw_private_key(pkey, sk, &sklen) <= 0)
75
- goto cleanup;
76
- if (sklen != X25519_SECRETKEYBYTES)
77
- goto cleanup;
78
-
79
- if (EVP_PKEY_get_raw_public_key(pkey, pk, &pklen) <= 0)
80
- goto cleanup;
81
- if (pklen != X25519_PUBLICKEYBYTES)
82
- goto cleanup;
83
-
84
- ret = PQ_SUCCESS;
85
-
86
- cleanup:
87
- if (pkey)
88
- EVP_PKEY_free(pkey);
89
- if (ctx)
90
- EVP_PKEY_CTX_free(ctx);
91
- return ret;
92
- }
93
-
94
50
  static int x25519_public_from_private(uint8_t *pk, const uint8_t *sk) {
95
51
  EVP_PKEY *pkey = NULL;
96
52
  size_t pklen = X25519_PUBLICKEYBYTES;
@@ -117,16 +73,15 @@ cleanup:
117
73
  return ret;
118
74
  }
119
75
 
120
- static int x25519_shared_secret(uint8_t *shared, const uint8_t *their_pk, const uint8_t *my_sk) {
76
+ static int x25519_shared_secret_with_pkey(uint8_t *shared, const uint8_t *their_pk, EVP_PKEY *pkey) {
121
77
  EVP_PKEY_CTX *ctx = NULL;
122
- EVP_PKEY *pkey = NULL;
123
78
  EVP_PKEY *peer_key = NULL;
124
79
  size_t shared_len = X25519_SHAREDSECRETBYTES;
125
80
  int ret = PQ_ERROR_ENCAPSULATE;
126
81
 
127
- pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, my_sk, X25519_SECRETKEYBYTES);
128
- if (!pkey)
129
- goto cleanup;
82
+ if (!shared || !their_pk || !pkey) {
83
+ return PQ_ERROR_BUFFER;
84
+ }
130
85
 
131
86
  peer_key = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL, their_pk, X25519_PUBLICKEYBYTES);
132
87
  if (!peer_key)
@@ -155,53 +110,94 @@ cleanup:
155
110
  EVP_PKEY_CTX_free(ctx);
156
111
  if (peer_key)
157
112
  EVP_PKEY_free(peer_key);
158
- if (pkey)
159
- EVP_PKEY_free(pkey);
160
113
  return ret;
161
114
  }
162
115
 
163
- static const uint8_t XWING_LABEL[6] = {0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c};
116
+ static int x25519_shared_secret(uint8_t *shared, const uint8_t *their_pk, const uint8_t *my_sk) {
117
+ EVP_PKEY *pkey = NULL;
118
+ int ret;
164
119
 
165
- static int xwing_combiner(uint8_t shared_secret[HYBRID_SHAREDSECRETBYTES],
166
- const uint8_t ss_M[MLKEM_SHAREDSECRETBYTES],
167
- const uint8_t ss_X[X25519_SHAREDSECRETBYTES],
168
- const uint8_t ct_X[X25519_PUBLICKEYBYTES],
169
- const uint8_t pk_X[X25519_PUBLICKEYBYTES]) {
170
- EVP_MD_CTX *ctx = EVP_MD_CTX_new();
171
- unsigned int out_len = 0;
172
- int ret = PQ_ERROR_OPENSSL;
120
+ if (!shared || !their_pk || !my_sk) {
121
+ return PQ_ERROR_BUFFER;
122
+ }
173
123
 
174
- if (!ctx) {
175
- return PQ_ERROR_OPENSSL;
124
+ pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, my_sk, X25519_SECRETKEYBYTES);
125
+ if (!pkey)
126
+ return PQ_ERROR_ENCAPSULATE;
127
+
128
+ ret = x25519_shared_secret_with_pkey(shared, their_pk, pkey);
129
+ EVP_PKEY_free(pkey);
130
+ return ret;
131
+ }
132
+
133
+ static int x25519_ephemeral_keypair_and_shared_secret(uint8_t *ephemeral_pk, uint8_t *shared,
134
+ const uint8_t *their_pk) {
135
+ EVP_PKEY_CTX *keygen_ctx = NULL;
136
+ EVP_PKEY *ephemeral_pkey = NULL;
137
+ size_t pklen = X25519_PUBLICKEYBYTES;
138
+ int ret = PQ_ERROR_ENCAPSULATE;
139
+
140
+ if (!ephemeral_pk || !shared || !their_pk) {
141
+ return PQ_ERROR_BUFFER;
176
142
  }
177
143
 
178
- if (EVP_DigestInit_ex(ctx, EVP_sha3_256(), NULL) != 1)
144
+ keygen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
145
+ if (!keygen_ctx)
179
146
  goto cleanup;
180
- if (EVP_DigestUpdate(ctx, ss_M, MLKEM_SHAREDSECRETBYTES) != 1)
181
- goto cleanup;
182
- if (EVP_DigestUpdate(ctx, ss_X, X25519_SHAREDSECRETBYTES) != 1)
183
- goto cleanup;
184
- if (EVP_DigestUpdate(ctx, ct_X, X25519_PUBLICKEYBYTES) != 1)
185
- goto cleanup;
186
- if (EVP_DigestUpdate(ctx, pk_X, X25519_PUBLICKEYBYTES) != 1)
147
+
148
+ if (EVP_PKEY_keygen_init(keygen_ctx) <= 0)
187
149
  goto cleanup;
188
- if (EVP_DigestUpdate(ctx, XWING_LABEL, sizeof(XWING_LABEL)) != 1)
150
+
151
+ if (EVP_PKEY_keygen(keygen_ctx, &ephemeral_pkey) <= 0)
189
152
  goto cleanup;
190
- if (EVP_DigestFinal_ex(ctx, shared_secret, &out_len) != 1)
153
+
154
+ if (EVP_PKEY_get_raw_public_key(ephemeral_pkey, ephemeral_pk, &pklen) <= 0)
191
155
  goto cleanup;
192
- if (out_len != HYBRID_SHAREDSECRETBYTES)
156
+ if (pklen != X25519_PUBLICKEYBYTES)
193
157
  goto cleanup;
194
158
 
195
- ret = PQ_SUCCESS;
159
+ ret = x25519_shared_secret_with_pkey(shared, their_pk, ephemeral_pkey);
196
160
 
197
161
  cleanup:
198
- EVP_MD_CTX_free(ctx);
162
+ if (ephemeral_pkey)
163
+ EVP_PKEY_free(ephemeral_pkey);
164
+ if (keygen_ctx)
165
+ EVP_PKEY_CTX_free(keygen_ctx);
199
166
  return ret;
200
167
  }
201
168
 
169
+ static const uint8_t XWING_LABEL[6] = {0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c};
170
+
171
+ static int xwing_combiner(uint8_t shared_secret[HYBRID_SHAREDSECRETBYTES],
172
+ const uint8_t ss_M[MLKEM_SHAREDSECRETBYTES],
173
+ const uint8_t ss_X[X25519_SHAREDSECRETBYTES],
174
+ const uint8_t ct_X[X25519_PUBLICKEYBYTES],
175
+ const uint8_t pk_X[X25519_PUBLICKEYBYTES]) {
176
+ uint8_t input[MLKEM_SHAREDSECRETBYTES + X25519_SHAREDSECRETBYTES +
177
+ X25519_PUBLICKEYBYTES + X25519_PUBLICKEYBYTES + sizeof(XWING_LABEL)];
178
+ uint8_t *cur = input;
179
+
180
+ if (!shared_secret || !ss_M || !ss_X || !ct_X || !pk_X) {
181
+ return PQ_ERROR_BUFFER;
182
+ }
183
+
184
+ memcpy(cur, ss_M, MLKEM_SHAREDSECRETBYTES);
185
+ cur += MLKEM_SHAREDSECRETBYTES;
186
+ memcpy(cur, ss_X, X25519_SHAREDSECRETBYTES);
187
+ cur += X25519_SHAREDSECRETBYTES;
188
+ memcpy(cur, ct_X, X25519_PUBLICKEYBYTES);
189
+ cur += X25519_PUBLICKEYBYTES;
190
+ memcpy(cur, pk_X, X25519_PUBLICKEYBYTES);
191
+ cur += X25519_PUBLICKEYBYTES;
192
+ memcpy(cur, XWING_LABEL, sizeof(XWING_LABEL));
193
+
194
+ pqcr_mlkem_sha3_256(shared_secret, input, sizeof(input));
195
+ pq_secure_wipe(input, sizeof(input));
196
+ return PQ_SUCCESS;
197
+ }
198
+
202
199
  static int xwing_expand_secret_key(hybrid_expanded_secret_key_t *expanded_key,
203
200
  const uint8_t seed[HYBRID_SECRETKEYBYTES]) {
204
- EVP_MD_CTX *ctx = NULL;
205
201
  uint8_t expanded[XWING_EXPANDEDBYTES];
206
202
  int ret = PQ_ERROR_OPENSSL;
207
203
 
@@ -212,19 +208,9 @@ static int xwing_expand_secret_key(hybrid_expanded_secret_key_t *expanded_key,
212
208
  memset(expanded_key, 0, sizeof(*expanded_key));
213
209
  memset(expanded, 0, sizeof(expanded));
214
210
 
215
- ctx = EVP_MD_CTX_new();
216
- if (!ctx)
217
- goto cleanup;
218
-
219
- if (EVP_DigestInit_ex(ctx, EVP_shake256(), NULL) != 1)
220
- goto cleanup;
221
- if (EVP_DigestUpdate(ctx, seed, HYBRID_SECRETKEYBYTES) != 1)
222
- goto cleanup;
223
- if (EVP_DigestFinalXOF(ctx, expanded, sizeof(expanded)) != 1)
224
- goto cleanup;
211
+ pqcr_mlkem_shake256(expanded, sizeof(expanded), seed, HYBRID_SECRETKEYBYTES);
225
212
 
226
- ret = PQCLEAN_MLKEM768_CLEAN_crypto_kem_keypair_derand(expanded_key->mlkem_pk,
227
- expanded_key->mlkem_sk, expanded);
213
+ ret = pqcr_mlkem768_keypair_derand(expanded_key->mlkem_pk, expanded_key->mlkem_sk, expanded);
228
214
  if (ret != 0) {
229
215
  ret = PQ_ERROR_KEYPAIR;
230
216
  goto cleanup;
@@ -239,8 +225,6 @@ static int xwing_expand_secret_key(hybrid_expanded_secret_key_t *expanded_key,
239
225
  ret = PQ_SUCCESS;
240
226
 
241
227
  cleanup:
242
- if (ctx)
243
- EVP_MD_CTX_free(ctx);
244
228
  pq_secure_wipe(expanded, sizeof(expanded));
245
229
  if (ret != PQ_SUCCESS && expanded_key) {
246
230
  pq_secure_wipe(expanded_key, sizeof(*expanded_key));
@@ -248,31 +232,36 @@ cleanup:
248
232
  return ret;
249
233
  }
250
234
 
251
- #define PQ_MLKEM_VARIANTS(X) \
252
- X(mlkem, MLKEM768_CLEAN) \
253
- X(mlkem512, MLKEM512_CLEAN) \
254
- X(mlkem1024, MLKEM1024_CLEAN)
255
-
256
- #define PQ_DEFINE_MLKEM_SHIMS(prefix, pqclean) \
257
- int pq_##prefix##_keypair(uint8_t *pk, uint8_t *sk) { \
258
- return PQCLEAN_##pqclean##_crypto_kem_keypair(pk, sk) == 0 ? PQ_SUCCESS \
259
- : PQ_ERROR_KEYPAIR; \
260
- } \
261
- int pq_##prefix##_keypair_from_seed(uint8_t *pk, uint8_t *sk, const uint8_t *seed64) { \
262
- if (!pk || !sk || !seed64) { \
263
- return PQ_ERROR_BUFFER; \
264
- } \
265
- return PQCLEAN_##pqclean##_crypto_kem_keypair_derand(pk, sk, seed64) == 0 \
266
- ? PQ_SUCCESS \
267
- : PQ_ERROR_KEYPAIR; \
268
- } \
269
- int pq_##prefix##_encapsulate(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { \
270
- return PQCLEAN_##pqclean##_crypto_kem_enc(ct, ss, pk) == 0 ? PQ_SUCCESS \
271
- : PQ_ERROR_ENCAPSULATE; \
272
- } \
273
- int pq_##prefix##_decapsulate(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { \
274
- return PQCLEAN_##pqclean##_crypto_kem_dec(ss, ct, sk) == 0 ? PQ_SUCCESS \
275
- : PQ_ERROR_DECAPSULATE; \
235
+ #define PQ_MLKEM_VARIANTS(X) \
236
+ X(mlkem, pqcr_mlkem768) \
237
+ X(mlkem512, pqcr_mlkem512) \
238
+ X(mlkem1024, pqcr_mlkem1024)
239
+
240
+ #define PQ_DEFINE_MLKEM_SHIMS(prefix, native) \
241
+ int pq_##prefix##_keypair(uint8_t *pk, uint8_t *sk) { \
242
+ if (!pk || !sk) { \
243
+ return PQ_ERROR_BUFFER; \
244
+ } \
245
+ return native##_keypair(pk, sk) == 0 ? PQ_SUCCESS : PQ_ERROR_KEYPAIR; \
246
+ } \
247
+ int pq_##prefix##_keypair_from_seed(uint8_t *pk, uint8_t *sk, const uint8_t *seed64) {\
248
+ if (!pk || !sk || !seed64) { \
249
+ return PQ_ERROR_BUFFER; \
250
+ } \
251
+ return native##_keypair_derand(pk, sk, seed64) == 0 ? PQ_SUCCESS \
252
+ : PQ_ERROR_KEYPAIR; \
253
+ } \
254
+ int pq_##prefix##_encapsulate(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { \
255
+ if (!ct || !ss || !pk) { \
256
+ return PQ_ERROR_BUFFER; \
257
+ } \
258
+ return native##_enc(ct, ss, pk) == 0 ? PQ_SUCCESS : PQ_ERROR_ENCAPSULATE; \
259
+ } \
260
+ int pq_##prefix##_decapsulate(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { \
261
+ if (!ss || !ct || !sk) { \
262
+ return PQ_ERROR_BUFFER; \
263
+ } \
264
+ return native##_dec(ss, ct, sk) == 0 ? PQ_SUCCESS : PQ_ERROR_DECAPSULATE; \
276
265
  }
277
266
 
278
267
  PQ_MLKEM_VARIANTS(PQ_DEFINE_MLKEM_SHIMS)
@@ -299,136 +288,152 @@ static int pq_testing_mlkem_encapsulate_from_seed_with(
299
288
  : PQ_ERROR_ENCAPSULATE;
300
289
  }
301
290
 
302
- #define PQ_DEFINE_MLKEM_TESTING_SHIMS(prefix, pqclean) \
303
- int pq_testing_##prefix##_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, \
304
- const uint8_t *seed, size_t seed_len) { \
305
- return pq_testing_mlkem_keypair_from_seed_with( \
306
- public_key, secret_key, seed, seed_len, \
307
- PQCLEAN_##pqclean##_crypto_kem_keypair_derand); \
308
- } \
309
- int pq_testing_##prefix##_encapsulate_from_seed(uint8_t *ciphertext, uint8_t *shared_secret, \
310
- const uint8_t *public_key, \
311
- const uint8_t *seed, size_t seed_len) { \
312
- return pq_testing_mlkem_encapsulate_from_seed_with( \
313
- ciphertext, shared_secret, public_key, seed, seed_len, \
314
- PQCLEAN_##pqclean##_crypto_kem_enc_derand); \
291
+ #define PQ_DEFINE_MLKEM_TESTING_SHIMS(prefix, native) \
292
+ int pq_testing_##prefix##_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, \
293
+ const uint8_t *seed, size_t seed_len) { \
294
+ return pq_testing_mlkem_keypair_from_seed_with(public_key, secret_key, seed, seed_len, \
295
+ native##_keypair_derand); \
296
+ } \
297
+ int pq_testing_##prefix##_encapsulate_from_seed(uint8_t *ciphertext, uint8_t *shared_secret,\
298
+ const uint8_t *public_key, \
299
+ const uint8_t *seed, size_t seed_len) { \
300
+ return pq_testing_mlkem_encapsulate_from_seed_with(ciphertext, shared_secret, public_key,\
301
+ seed, seed_len, native##_enc_derand);\
315
302
  }
316
303
 
317
304
  PQ_MLKEM_VARIANTS(PQ_DEFINE_MLKEM_TESTING_SHIMS)
318
305
 
319
306
  #undef PQ_DEFINE_MLKEM_TESTING_SHIMS
320
307
 
321
- #define PQ_DEFINE_MLDSA_SIGN_KEYPAIR(prefix, pqclean) \
322
- int pq_##prefix##_keypair(uint8_t *public_key, uint8_t *secret_key) { \
323
- return PQCLEAN_##pqclean##_crypto_sign_keypair(public_key, secret_key) == 0 \
324
- ? PQ_SUCCESS \
325
- : PQ_ERROR_KEYPAIR; \
308
+ #define PQ_DEFINE_MLDSA_SIGN_KEYPAIR(prefix, native) \
309
+ int pq_##prefix##_keypair(uint8_t *public_key, uint8_t *secret_key) { \
310
+ if (!public_key || !secret_key) { \
311
+ return PQ_ERROR_BUFFER; \
312
+ } \
313
+ return native##_keypair(public_key, secret_key) == 0 ? PQ_SUCCESS \
314
+ : PQ_ERROR_KEYPAIR; \
326
315
  }
327
316
 
328
- PQ_DEFINE_MLDSA_SIGN_KEYPAIR(sign, MLDSA65_CLEAN)
329
- PQ_DEFINE_MLDSA_SIGN_KEYPAIR(mldsa44_sign, MLDSA44_CLEAN)
330
- PQ_DEFINE_MLDSA_SIGN_KEYPAIR(mldsa87_sign, MLDSA87_CLEAN)
317
+ PQ_DEFINE_MLDSA_SIGN_KEYPAIR(sign, pqcr_mldsa65)
318
+ PQ_DEFINE_MLDSA_SIGN_KEYPAIR(mldsa44_sign, pqcr_mldsa44)
319
+ PQ_DEFINE_MLDSA_SIGN_KEYPAIR(mldsa87_sign, pqcr_mldsa87)
331
320
 
332
321
  #undef PQ_DEFINE_MLDSA_SIGN_KEYPAIR
333
322
 
334
- #define PQ_DEFINE_MLDSA_SIGN(name, pqclean) \
335
- int pq_##name(uint8_t *signature, size_t *signature_len, const uint8_t *message, \
336
- size_t message_len, const uint8_t *secret_key) { \
337
- return PQCLEAN_##pqclean##_crypto_sign_signature(signature, signature_len, message, \
338
- message_len, secret_key) == 0 \
339
- ? PQ_SUCCESS \
340
- : PQ_ERROR_SIGN; \
323
+ #define PQ_DEFINE_MLDSA_SIGN(name, native) \
324
+ int pq_##name(uint8_t *signature, size_t *signature_len, const uint8_t *message, \
325
+ size_t message_len, const uint8_t *secret_key) { \
326
+ if (!signature || !signature_len || !secret_key || (message_len > 0 && !message)) {\
327
+ return PQ_ERROR_BUFFER; \
328
+ } \
329
+ return native##_signature(signature, signature_len, message, message_len, NULL, 0,\
330
+ secret_key) == 0 \
331
+ ? PQ_SUCCESS \
332
+ : PQ_ERROR_SIGN; \
341
333
  }
342
334
 
343
- PQ_DEFINE_MLDSA_SIGN(sign, MLDSA65_CLEAN)
344
- PQ_DEFINE_MLDSA_SIGN(mldsa44_sign, MLDSA44_CLEAN)
345
- PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, MLDSA87_CLEAN)
335
+ PQ_DEFINE_MLDSA_SIGN(sign, pqcr_mldsa65)
336
+ PQ_DEFINE_MLDSA_SIGN(mldsa44_sign, pqcr_mldsa44)
337
+ PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, pqcr_mldsa87)
346
338
 
347
339
  #undef PQ_DEFINE_MLDSA_SIGN
348
340
 
349
- #define PQ_DEFINE_MLDSA_VERIFY(name, pqclean) \
341
+ #define PQ_DEFINE_MLDSA_VERIFY(name, native) \
350
342
  int pq_##name(const uint8_t *signature, size_t signature_len, const uint8_t *message, \
351
- size_t message_len, const uint8_t *public_key) { \
352
- return PQCLEAN_##pqclean##_crypto_sign_verify(signature, signature_len, message, \
353
- message_len, public_key) == 0 \
343
+ size_t message_len, const uint8_t *public_key) { \
344
+ if (!signature || !public_key || (message_len > 0 && !message)) { \
345
+ return PQ_ERROR_BUFFER; \
346
+ } \
347
+ return native##_verify(signature, signature_len, message, message_len, NULL, 0, \
348
+ public_key) == 0 \
354
349
  ? PQ_SUCCESS \
355
350
  : PQ_ERROR_VERIFY; \
356
351
  }
357
352
 
358
- PQ_DEFINE_MLDSA_VERIFY(verify, MLDSA65_CLEAN)
359
- PQ_DEFINE_MLDSA_VERIFY(mldsa44_verify, MLDSA44_CLEAN)
360
- PQ_DEFINE_MLDSA_VERIFY(mldsa87_verify, MLDSA87_CLEAN)
353
+ PQ_DEFINE_MLDSA_VERIFY(verify, pqcr_mldsa65)
354
+ PQ_DEFINE_MLDSA_VERIFY(mldsa44_verify, pqcr_mldsa44)
355
+ PQ_DEFINE_MLDSA_VERIFY(mldsa87_verify, pqcr_mldsa87)
361
356
 
362
357
  #undef PQ_DEFINE_MLDSA_VERIFY
363
358
 
364
- static int pq_testing_mldsa_keypair_from_seed_with(uint8_t *public_key, uint8_t *secret_key,
365
- const uint8_t *seed, size_t seed_len,
366
- int (*keypair)(uint8_t *, uint8_t *)) {
367
- int rc;
368
- if (!public_key || !secret_key || !seed || seed_len != 32 || !keypair) {
369
- return PQ_ERROR_BUFFER;
370
- }
371
-
372
- pq_testing_set_seed(seed, seed_len);
373
- rc = keypair(public_key, secret_key);
374
- pq_testing_clear_seed();
375
- return rc == 0 ? PQ_SUCCESS : PQ_ERROR_KEYPAIR;
376
- }
377
-
378
359
  static int pq_testing_mldsa_sign_from_seed_with(
379
360
  uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len,
380
361
  const uint8_t *secret_key, const uint8_t *seed, size_t seed_len,
381
- int (*sign)(uint8_t *, size_t *, const uint8_t *, size_t, const uint8_t *)) {
382
- int rc;
383
- if (!signature || !signature_len || !secret_key || !seed || seed_len != 32 || !sign) {
362
+ int (*signature_internal)(uint8_t *, size_t *, const uint8_t *, size_t, const uint8_t *, size_t,
363
+ const uint8_t *, const uint8_t *, int),
364
+ size_t (*prepare_prefix)(uint8_t *, const uint8_t *, size_t, const uint8_t *, size_t, int)) {
365
+ uint8_t pre[MLDSA_DOMAIN_SEPARATION_MAX_BYTES];
366
+ size_t pre_len;
367
+
368
+ if (!signature || !signature_len || !secret_key || !seed || seed_len != MLDSA_RNDBYTES ||
369
+ !signature_internal || !prepare_prefix || (message_len > 0 && !message)) {
384
370
  return PQ_ERROR_BUFFER;
385
371
  }
386
372
 
387
- pq_testing_set_seed(seed, seed_len);
388
- rc = sign(signature, signature_len, message, message_len, secret_key);
389
- pq_testing_clear_seed();
390
- return rc == 0 ? PQ_SUCCESS : PQ_ERROR_SIGN;
373
+ /*
374
+ * mldsa-native's signature_internal is lower-level than the public pure
375
+ * ML-DSA signing API. It expects the FIPS 204 domain-separation prefix explicitly. Passing
376
+ * NULL/0 signs CRH(tr, message) instead of CRH(tr, 0x00 || ctxlen || ctx || message),
377
+ * which produces signatures that do not verify through the public pure-ML-DSA API
378
+ * and do not match ACVP/KAT sigGen vectors.
379
+ */
380
+ pre_len = prepare_prefix(pre, NULL, 0, NULL, 0, MLDSA_PREHASH_NONE);
381
+ if (pre_len == 0) {
382
+ return PQ_ERROR_SIGN;
383
+ }
384
+
385
+ return signature_internal(signature, signature_len, message, message_len, pre, pre_len, seed,
386
+ secret_key, 0) == 0
387
+ ? PQ_SUCCESS
388
+ : PQ_ERROR_SIGN;
391
389
  }
392
390
 
393
- /*
394
- * Production ML-DSA seed expansion for RFC 9881 seed-format PKCS#8 imports.
395
- *
396
- * PQClean does not expose a public crypto_sign_keypair_derand entrypoint for
397
- * ML-DSA. This deliberately reuses pq_crypto's thread-local seed-replay
398
- * randombytes() path, the same path covered by Patch 8 KATs, and is surfaced
399
- * only through the Ruby PKCS#8 opt-in gate.
400
- */
401
391
  int pq_mldsa44_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32) {
402
- return pq_testing_mldsa_keypair_from_seed_with(public_key, secret_key, seed32, 32,
403
- PQCLEAN_MLDSA44_CLEAN_crypto_sign_keypair);
392
+ if (!public_key || !secret_key || !seed32) {
393
+ return PQ_ERROR_BUFFER;
394
+ }
395
+ return pqcr_mldsa44_keypair_internal(public_key, secret_key, seed32) == 0 ? PQ_SUCCESS
396
+ : PQ_ERROR_KEYPAIR;
404
397
  }
405
398
 
406
399
  int pq_mldsa_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32) {
407
- return pq_testing_mldsa_keypair_from_seed_with(public_key, secret_key, seed32, 32,
408
- PQCLEAN_MLDSA65_CLEAN_crypto_sign_keypair);
400
+ if (!public_key || !secret_key || !seed32) {
401
+ return PQ_ERROR_BUFFER;
402
+ }
403
+ return pqcr_mldsa65_keypair_internal(public_key, secret_key, seed32) == 0 ? PQ_SUCCESS
404
+ : PQ_ERROR_KEYPAIR;
409
405
  }
410
406
 
411
407
  int pq_mldsa87_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32) {
412
- return pq_testing_mldsa_keypair_from_seed_with(public_key, secret_key, seed32, 32,
413
- PQCLEAN_MLDSA87_CLEAN_crypto_sign_keypair);
408
+ if (!public_key || !secret_key || !seed32) {
409
+ return PQ_ERROR_BUFFER;
410
+ }
411
+ return pqcr_mldsa87_keypair_internal(public_key, secret_key, seed32) == 0 ? PQ_SUCCESS
412
+ : PQ_ERROR_KEYPAIR;
414
413
  }
415
414
 
416
415
  int pq_testing_mldsa_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
417
416
  const uint8_t *seed, size_t seed_len) {
418
- return pq_testing_mldsa_keypair_from_seed_with(public_key, secret_key, seed, seed_len,
419
- PQCLEAN_MLDSA65_CLEAN_crypto_sign_keypair);
417
+ if (seed_len != MLDSA_SEEDBYTES) {
418
+ return PQ_ERROR_BUFFER;
419
+ }
420
+ return pq_mldsa_keypair_from_seed(public_key, secret_key, seed);
420
421
  }
421
422
 
422
423
  int pq_testing_mldsa44_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
423
424
  const uint8_t *seed, size_t seed_len) {
424
- return pq_testing_mldsa_keypair_from_seed_with(public_key, secret_key, seed, seed_len,
425
- PQCLEAN_MLDSA44_CLEAN_crypto_sign_keypair);
425
+ if (seed_len != MLDSA_SEEDBYTES) {
426
+ return PQ_ERROR_BUFFER;
427
+ }
428
+ return pq_mldsa44_keypair_from_seed(public_key, secret_key, seed);
426
429
  }
427
430
 
428
431
  int pq_testing_mldsa87_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
429
432
  const uint8_t *seed, size_t seed_len) {
430
- return pq_testing_mldsa_keypair_from_seed_with(public_key, secret_key, seed, seed_len,
431
- PQCLEAN_MLDSA87_CLEAN_crypto_sign_keypair);
433
+ if (seed_len != MLDSA_SEEDBYTES) {
434
+ return PQ_ERROR_BUFFER;
435
+ }
436
+ return pq_mldsa87_keypair_from_seed(public_key, secret_key, seed);
432
437
  }
433
438
 
434
439
  int pq_testing_mldsa_sign_from_seed(uint8_t *signature, size_t *signature_len,
@@ -437,7 +442,8 @@ int pq_testing_mldsa_sign_from_seed(uint8_t *signature, size_t *signature_len,
437
442
  size_t seed_len) {
438
443
  return pq_testing_mldsa_sign_from_seed_with(signature, signature_len, message, message_len,
439
444
  secret_key, seed, seed_len,
440
- PQCLEAN_MLDSA65_CLEAN_crypto_sign_signature);
445
+ pqcr_mldsa65_signature_internal,
446
+ pqcr_mldsa65_prepare_domain_separation_prefix);
441
447
  }
442
448
 
443
449
  int pq_testing_mldsa44_sign_from_seed(uint8_t *signature, size_t *signature_len,
@@ -446,7 +452,8 @@ int pq_testing_mldsa44_sign_from_seed(uint8_t *signature, size_t *signature_len,
446
452
  size_t seed_len) {
447
453
  return pq_testing_mldsa_sign_from_seed_with(signature, signature_len, message, message_len,
448
454
  secret_key, seed, seed_len,
449
- PQCLEAN_MLDSA44_CLEAN_crypto_sign_signature);
455
+ pqcr_mldsa44_signature_internal,
456
+ pqcr_mldsa44_prepare_domain_separation_prefix);
450
457
  }
451
458
 
452
459
  int pq_testing_mldsa87_sign_from_seed(uint8_t *signature, size_t *signature_len,
@@ -455,7 +462,8 @@ int pq_testing_mldsa87_sign_from_seed(uint8_t *signature, size_t *signature_len,
455
462
  size_t seed_len) {
456
463
  return pq_testing_mldsa_sign_from_seed_with(signature, signature_len, message, message_len,
457
464
  secret_key, seed, seed_len,
458
- PQCLEAN_MLDSA87_CLEAN_crypto_sign_signature);
465
+ pqcr_mldsa87_signature_internal,
466
+ pqcr_mldsa87_prepare_domain_separation_prefix);
459
467
  }
460
468
 
461
469
  int pq_hybrid_kem_keypair(uint8_t *public_key, uint8_t *secret_key) {
@@ -499,7 +507,6 @@ int pq_hybrid_kem_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret,
499
507
  hybrid_ciphertext_t ct;
500
508
  uint8_t mlkem_ss[MLKEM_SHAREDSECRETBYTES];
501
509
  uint8_t x25519_ss[X25519_SHAREDSECRETBYTES];
502
- uint8_t x25519_ephemeral_sk[X25519_SECRETKEYBYTES];
503
510
  int ret = PQ_SUCCESS;
504
511
 
505
512
  if (!ciphertext || !shared_secret || !public_key) {
@@ -510,20 +517,14 @@ int pq_hybrid_kem_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret,
510
517
  memset(&ct, 0, sizeof(ct));
511
518
  memset(mlkem_ss, 0, sizeof(mlkem_ss));
512
519
  memset(x25519_ss, 0, sizeof(x25519_ss));
513
- memset(x25519_ephemeral_sk, 0, sizeof(x25519_ephemeral_sk));
514
520
 
515
- if (PQCLEAN_MLKEM768_CLEAN_crypto_kem_enc(ct.mlkem_ct, mlkem_ss, pk.mlkem_pk) != 0) {
521
+ if (pqcr_mlkem768_enc(ct.mlkem_ct, mlkem_ss, pk.mlkem_pk) != 0) {
516
522
  ret = PQ_ERROR_ENCAPSULATE;
517
523
  goto cleanup;
518
524
  }
519
525
 
520
- ret = x25519_keypair(ct.x25519_ephemeral, x25519_ephemeral_sk);
521
- if (ret != PQ_SUCCESS) {
522
- ret = PQ_ERROR_ENCAPSULATE;
523
- goto cleanup;
524
- }
525
-
526
- ret = x25519_shared_secret(x25519_ss, pk.x25519_pk, x25519_ephemeral_sk);
526
+ ret = x25519_ephemeral_keypair_and_shared_secret(ct.x25519_ephemeral, x25519_ss,
527
+ pk.x25519_pk);
527
528
  if (ret != PQ_SUCCESS) {
528
529
  ret = PQ_ERROR_ENCAPSULATE;
529
530
  goto cleanup;
@@ -539,51 +540,121 @@ int pq_hybrid_kem_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret,
539
540
  cleanup:
540
541
  pq_secure_wipe(mlkem_ss, sizeof(mlkem_ss));
541
542
  pq_secure_wipe(x25519_ss, sizeof(x25519_ss));
542
- pq_secure_wipe(x25519_ephemeral_sk, sizeof(x25519_ephemeral_sk));
543
543
  return ret;
544
544
  }
545
545
 
546
- int pq_hybrid_kem_decapsulate(uint8_t *shared_secret, const uint8_t *ciphertext,
547
- const uint8_t *secret_key) {
548
- hybrid_ciphertext_t ct;
546
+ int pq_hybrid_kem_expand_secret_key(uint8_t *expanded_secret_key, const uint8_t *secret_key) {
549
547
  hybrid_expanded_secret_key_t expanded;
548
+ int ret;
549
+
550
+ if (!expanded_secret_key || !secret_key) {
551
+ return PQ_ERROR_BUFFER;
552
+ }
553
+
554
+ memset(&expanded, 0, sizeof(expanded));
555
+ ret = xwing_expand_secret_key(&expanded, secret_key);
556
+ if (ret == PQ_SUCCESS) {
557
+ memcpy(expanded_secret_key, &expanded, sizeof(expanded));
558
+ }
559
+ pq_secure_wipe(&expanded, sizeof(expanded));
560
+ return ret == PQ_SUCCESS ? PQ_SUCCESS : PQ_ERROR_DECAPSULATE;
561
+ }
562
+
563
+ int pq_hybrid_kem_decapsulate_expanded(uint8_t *shared_secret, const uint8_t *ciphertext,
564
+ const uint8_t *expanded_secret_key) {
565
+ hybrid_ciphertext_t ct;
566
+ const hybrid_expanded_secret_key_t *expanded;
550
567
  uint8_t mlkem_ss[MLKEM_SHAREDSECRETBYTES];
551
568
  uint8_t x25519_ss[X25519_SHAREDSECRETBYTES];
552
569
  int ret = PQ_SUCCESS;
553
570
 
554
- if (!shared_secret || !ciphertext || !secret_key) {
571
+ if (!shared_secret || !ciphertext || !expanded_secret_key) {
555
572
  return PQ_ERROR_BUFFER;
556
573
  }
557
574
 
575
+ expanded = (const hybrid_expanded_secret_key_t *)expanded_secret_key;
558
576
  memcpy(&ct, ciphertext, HYBRID_CIPHERTEXTBYTES);
559
- memset(&expanded, 0, sizeof(expanded));
560
577
  memset(mlkem_ss, 0, sizeof(mlkem_ss));
561
578
  memset(x25519_ss, 0, sizeof(x25519_ss));
562
579
 
563
- ret = xwing_expand_secret_key(&expanded, secret_key);
580
+ if (pqcr_mlkem768_dec(mlkem_ss, ct.mlkem_ct, expanded->mlkem_sk) != 0) {
581
+ ret = PQ_ERROR_DECAPSULATE;
582
+ goto cleanup;
583
+ }
584
+
585
+ ret = x25519_shared_secret(x25519_ss, ct.x25519_ephemeral, expanded->x25519_sk);
564
586
  if (ret != PQ_SUCCESS) {
565
587
  ret = PQ_ERROR_DECAPSULATE;
566
588
  goto cleanup;
567
589
  }
568
590
 
569
- if (PQCLEAN_MLKEM768_CLEAN_crypto_kem_dec(mlkem_ss, ct.mlkem_ct, expanded.mlkem_sk) != 0) {
591
+ ret = xwing_combiner(shared_secret, mlkem_ss, x25519_ss, ct.x25519_ephemeral,
592
+ expanded->x25519_pk);
593
+
594
+ cleanup:
595
+ pq_secure_wipe(mlkem_ss, sizeof(mlkem_ss));
596
+ pq_secure_wipe(x25519_ss, sizeof(x25519_ss));
597
+ return ret;
598
+ }
599
+
600
+ int pq_hybrid_kem_decapsulate_expanded_pkey(uint8_t *shared_secret, const uint8_t *ciphertext,
601
+ const uint8_t *expanded_secret_key,
602
+ void *x25519_private_pkey) {
603
+ hybrid_ciphertext_t ct;
604
+ const hybrid_expanded_secret_key_t *expanded;
605
+ uint8_t mlkem_ss[MLKEM_SHAREDSECRETBYTES];
606
+ uint8_t x25519_ss[X25519_SHAREDSECRETBYTES];
607
+ int ret = PQ_SUCCESS;
608
+
609
+ if (!shared_secret || !ciphertext || !expanded_secret_key || !x25519_private_pkey) {
610
+ return PQ_ERROR_BUFFER;
611
+ }
612
+
613
+ expanded = (const hybrid_expanded_secret_key_t *)expanded_secret_key;
614
+ memcpy(&ct, ciphertext, HYBRID_CIPHERTEXTBYTES);
615
+ memset(mlkem_ss, 0, sizeof(mlkem_ss));
616
+ memset(x25519_ss, 0, sizeof(x25519_ss));
617
+
618
+ if (pqcr_mlkem768_dec(mlkem_ss, ct.mlkem_ct, expanded->mlkem_sk) != 0) {
570
619
  ret = PQ_ERROR_DECAPSULATE;
571
620
  goto cleanup;
572
621
  }
573
622
 
574
- ret = x25519_shared_secret(x25519_ss, ct.x25519_ephemeral, expanded.x25519_sk);
623
+ ret = x25519_shared_secret_with_pkey(x25519_ss, ct.x25519_ephemeral,
624
+ (EVP_PKEY *)x25519_private_pkey);
575
625
  if (ret != PQ_SUCCESS) {
576
626
  ret = PQ_ERROR_DECAPSULATE;
577
627
  goto cleanup;
578
628
  }
579
629
 
580
- ret =
581
- xwing_combiner(shared_secret, mlkem_ss, x25519_ss, ct.x25519_ephemeral, expanded.x25519_pk);
630
+ ret = xwing_combiner(shared_secret, mlkem_ss, x25519_ss, ct.x25519_ephemeral,
631
+ expanded->x25519_pk);
582
632
 
583
633
  cleanup:
584
634
  pq_secure_wipe(mlkem_ss, sizeof(mlkem_ss));
585
635
  pq_secure_wipe(x25519_ss, sizeof(x25519_ss));
586
- pq_secure_wipe(&expanded, sizeof(expanded));
636
+ return ret;
637
+ }
638
+
639
+ int pq_hybrid_kem_decapsulate(uint8_t *shared_secret, const uint8_t *ciphertext,
640
+ const uint8_t *secret_key) {
641
+ uint8_t expanded[HYBRID_EXPANDED_SECRETKEYBYTES];
642
+ int ret;
643
+
644
+ if (!shared_secret || !ciphertext || !secret_key) {
645
+ return PQ_ERROR_BUFFER;
646
+ }
647
+
648
+ memset(expanded, 0, sizeof(expanded));
649
+ ret = pq_hybrid_kem_expand_secret_key(expanded, secret_key);
650
+ if (ret != PQ_SUCCESS) {
651
+ goto cleanup;
652
+ }
653
+
654
+ ret = pq_hybrid_kem_decapsulate_expanded(shared_secret, ciphertext, expanded);
655
+
656
+ cleanup:
657
+ pq_secure_wipe(expanded, sizeof(expanded));
587
658
  return ret;
588
659
  }
589
660
 
@@ -787,24 +858,51 @@ static int pq_decode_serialized_key(const uint8_t *input, size_t input_len, uint
787
858
  return PQ_SUCCESS;
788
859
  }
789
860
 
861
+ static int pq_base64_char_value(unsigned char c) {
862
+ if (c >= 'A' && c <= 'Z')
863
+ return (int)(c - 'A');
864
+ if (c >= 'a' && c <= 'z')
865
+ return (int)(c - 'a' + 26);
866
+ if (c >= '0' && c <= '9')
867
+ return (int)(c - '0' + 52);
868
+ if (c == '+')
869
+ return 62;
870
+ if (c == '/')
871
+ return 63;
872
+ if (c == '=')
873
+ return 64;
874
+ return -1;
875
+ }
876
+
877
+ static const char *pq_find_pem_footer(const char *start, size_t len, const char *footer,
878
+ size_t footer_len) {
879
+ if (!start || !footer || footer_len == 0 || len < footer_len)
880
+ return NULL;
881
+
882
+ for (size_t i = 0; i <= len - footer_len; ++i) {
883
+ if (start[i] == '-' && memcmp(start + i, footer, footer_len) == 0)
884
+ return start + i;
885
+ }
886
+ return NULL;
887
+ }
888
+
790
889
  static int pq_der_to_pem(const char *label, const uint8_t *der, size_t der_len, char **output,
791
890
  size_t *output_len) {
792
- BIO *bio_mem = NULL;
793
- BIO *bio_b64 = NULL;
794
- BIO *bio_chain = NULL;
795
- BUF_MEM *bptr = NULL;
796
891
  char header[64];
797
892
  char footer[64];
798
893
  int header_len, footer_len;
799
- int ret = PQ_ERROR_OPENSSL;
800
894
  char *pem = NULL;
801
- size_t total_len = 0;
802
- size_t needed = 0;
895
+ unsigned char *encoded = NULL;
896
+ size_t encoded_len;
897
+ size_t line_count;
898
+ size_t needed;
899
+ char *cur;
803
900
 
804
901
  if (!label || !der || !output || !output_len)
805
902
  return PQ_ERROR_BUFFER;
806
903
  *output = NULL;
807
904
  *output_len = 0;
905
+
808
906
  header_len = snprintf(header, sizeof(header), "-----BEGIN %s-----", label);
809
907
  footer_len = snprintf(footer, sizeof(footer), "-----END %s-----", label);
810
908
  if (header_len <= 0 || footer_len <= 0)
@@ -812,68 +910,60 @@ static int pq_der_to_pem(const char *label, const uint8_t *der, size_t der_len,
812
910
  if (der_len > (size_t)INT_MAX)
813
911
  return PQ_ERROR_BUFFER;
814
912
 
815
- bio_b64 = BIO_new(BIO_f_base64());
816
- bio_mem = BIO_new(BIO_s_mem());
817
- if (!bio_b64 || !bio_mem) {
818
- ret = PQ_ERROR_NOMEM;
819
- goto cleanup;
913
+ encoded_len = 4 * ((der_len + 2) / 3);
914
+ if (encoded_len > (size_t)INT_MAX)
915
+ return PQ_ERROR_BUFFER;
916
+
917
+ encoded = malloc(encoded_len + 1);
918
+ if (!encoded)
919
+ return PQ_ERROR_NOMEM;
920
+
921
+ if (EVP_EncodeBlock(encoded, der, (int)der_len) != (int)encoded_len) {
922
+ pq_secure_wipe(encoded, encoded_len + 1);
923
+ free(encoded);
924
+ return PQ_ERROR_OPENSSL;
820
925
  }
821
926
 
822
- bio_chain = BIO_push(bio_b64, bio_mem);
927
+ line_count = encoded_len == 0 ? 0 : ((encoded_len + 63) / 64);
928
+ if (SIZE_MAX - (size_t)header_len < 1 || SIZE_MAX - ((size_t)header_len + 1) < encoded_len ||
929
+ SIZE_MAX - ((size_t)header_len + 1 + encoded_len) < line_count ||
930
+ SIZE_MAX - ((size_t)header_len + 1 + encoded_len + line_count) < (size_t)footer_len + 1) {
931
+ pq_secure_wipe(encoded, encoded_len + 1);
932
+ free(encoded);
933
+ return PQ_ERROR_BUFFER;
934
+ }
935
+ needed = (size_t)header_len + 1 + encoded_len + line_count + (size_t)footer_len + 1;
823
936
 
824
- if (BIO_write(bio_chain, der, (int)der_len) != (int)der_len)
825
- goto cleanup;
826
- if (BIO_flush(bio_chain) != 1)
827
- goto cleanup;
828
- BIO_get_mem_ptr(bio_chain, &bptr);
829
- if (!bptr || !bptr->data)
830
- goto cleanup;
937
+ pem = malloc(needed);
938
+ if (!pem) {
939
+ pq_secure_wipe(encoded, encoded_len + 1);
940
+ free(encoded);
941
+ return PQ_ERROR_NOMEM;
942
+ }
831
943
 
832
- {
833
- size_t body_len = bptr->length;
834
- needed = (size_t)header_len + 1 + body_len;
835
- if (body_len == 0 || bptr->data[body_len - 1] != '\n')
836
- needed += 1;
837
- needed += (size_t)footer_len + 1;
838
-
839
- pem = malloc(needed);
840
- if (!pem) {
841
- ret = PQ_ERROR_NOMEM;
842
- goto cleanup;
843
- }
844
- char *cur = pem;
845
- memcpy(cur, header, (size_t)header_len);
846
- cur += header_len;
944
+ cur = pem;
945
+ memcpy(cur, header, (size_t)header_len);
946
+ cur += header_len;
947
+ *cur++ = '\n';
948
+
949
+ for (size_t offset = 0; offset < encoded_len; offset += 64) {
950
+ size_t line_len = encoded_len - offset;
951
+ if (line_len > 64)
952
+ line_len = 64;
953
+ memcpy(cur, encoded + offset, line_len);
954
+ cur += line_len;
847
955
  *cur++ = '\n';
848
- memcpy(cur, bptr->data, body_len);
849
- cur += body_len;
850
- if (body_len == 0 || bptr->data[body_len - 1] != '\n')
851
- *cur++ = '\n';
852
- memcpy(cur, footer, (size_t)footer_len);
853
- cur += footer_len;
854
- *cur = '\0';
855
- total_len = (size_t)(cur - pem);
856
956
  }
857
957
 
858
- *output = pem;
859
- *output_len = total_len;
860
- pem = NULL;
861
- ret = PQ_SUCCESS;
958
+ memcpy(cur, footer, (size_t)footer_len);
959
+ cur += footer_len;
960
+ *cur = '\0';
862
961
 
863
- cleanup:
864
- if (bio_chain) {
865
- BIO_free_all(bio_chain);
866
- } else {
867
- if (bio_b64)
868
- BIO_free(bio_b64);
869
- if (bio_mem)
870
- BIO_free(bio_mem);
871
- }
872
- if (pem) {
873
- pq_secure_wipe(pem, needed);
874
- free(pem);
875
- }
876
- return ret;
962
+ *output = pem;
963
+ *output_len = (size_t)(cur - pem);
964
+ pq_secure_wipe(encoded, encoded_len + 1);
965
+ free(encoded);
966
+ return PQ_SUCCESS;
877
967
  }
878
968
 
879
969
  static int pq_pem_to_der(const char *label, const char *input, size_t input_len, uint8_t **der_out,
@@ -883,17 +973,19 @@ static int pq_pem_to_der(const char *label, const char *input, size_t input_len,
883
973
  const char *body_start, *footer_pos;
884
974
  const char *tail;
885
975
  uint8_t *der = NULL;
976
+ unsigned char *compact = NULL;
886
977
  size_t body_len = 0;
887
- int ret;
888
- BIO *bio_b64 = NULL;
889
- BIO *bio_mem = NULL;
890
- BIO *bio_chain = NULL;
978
+ size_t compact_len = 0;
979
+ size_t der_cap = 0;
891
980
  int decoded_len = 0;
981
+ int padding = 0;
982
+ int saw_padding = 0;
892
983
 
893
984
  if (!label || !input || !der_out || !der_len_out)
894
985
  return PQ_ERROR_BUFFER;
895
986
  *der_out = NULL;
896
987
  *der_len_out = 0;
988
+
897
989
  header_len = snprintf(header, sizeof(header), "-----BEGIN %s-----", label);
898
990
  footer_len = snprintf(footer, sizeof(footer), "-----END %s-----", label);
899
991
  if (header_len <= 0 || footer_len <= 0)
@@ -902,22 +994,13 @@ static int pq_pem_to_der(const char *label, const char *input, size_t input_len,
902
994
  return PQ_ERROR_BUFFER;
903
995
  if (strncmp(input, header, (size_t)header_len) != 0)
904
996
  return PQ_ERROR_BUFFER;
997
+
905
998
  body_start = input + header_len;
906
999
  while ((size_t)(body_start - input) < input_len && pq_is_pem_whitespace(*body_start))
907
1000
  body_start++;
908
- footer_pos = NULL;
909
- {
910
- size_t remaining = input_len - (size_t)(body_start - input);
911
- size_t footer_size = (size_t)footer_len;
912
- if (remaining < footer_size)
913
- return PQ_ERROR_BUFFER;
914
- for (size_t i = 0; i <= remaining - footer_size; ++i) {
915
- if (memcmp(body_start + i, footer, footer_size) == 0) {
916
- footer_pos = body_start + i;
917
- break;
918
- }
919
- }
920
- }
1001
+
1002
+ footer_pos = pq_find_pem_footer(body_start, input_len - (size_t)(body_start - input), footer,
1003
+ (size_t)footer_len);
921
1004
  if (!footer_pos)
922
1005
  return PQ_ERROR_BUFFER;
923
1006
 
@@ -932,53 +1015,65 @@ static int pq_pem_to_der(const char *label, const char *input, size_t input_len,
932
1015
  if (body_len > (size_t)INT_MAX)
933
1016
  return PQ_ERROR_BUFFER;
934
1017
 
935
- {
936
- size_t der_cap = (body_len * 3) / 4 + 3;
937
- der = malloc(der_cap ? der_cap : 1);
938
- if (!der)
939
- return PQ_ERROR_NOMEM;
1018
+ compact = malloc(body_len ? body_len : 1);
1019
+ if (!compact)
1020
+ return PQ_ERROR_NOMEM;
940
1021
 
941
- bio_mem = BIO_new_mem_buf(body_start, (int)body_len);
942
- bio_b64 = BIO_new(BIO_f_base64());
943
- if (!bio_mem || !bio_b64) {
944
- ret = PQ_ERROR_NOMEM;
945
- goto cleanup;
946
- }
947
- bio_chain = BIO_push(bio_b64, bio_mem);
1022
+ for (size_t i = 0; i < body_len; ++i) {
1023
+ unsigned char c = (unsigned char)body_start[i];
1024
+ int value;
1025
+ if (pq_is_pem_whitespace((char)c))
1026
+ continue;
948
1027
 
949
- decoded_len = BIO_read(bio_chain, der, (int)der_cap);
950
- if (decoded_len <= 0) {
951
- ret = PQ_ERROR_BUFFER;
952
- goto cleanup;
1028
+ value = pq_base64_char_value(c);
1029
+ if (value < 0) {
1030
+ pq_secure_wipe(compact, body_len);
1031
+ free(compact);
1032
+ return PQ_ERROR_BUFFER;
953
1033
  }
954
- {
955
- unsigned char tail_byte;
956
- int extra = BIO_read(bio_chain, &tail_byte, 1);
957
- if (extra > 0) {
958
- ret = PQ_ERROR_BUFFER;
959
- goto cleanup;
1034
+ if (c == '=') {
1035
+ saw_padding = 1;
1036
+ padding++;
1037
+ if (padding > 2) {
1038
+ pq_secure_wipe(compact, body_len);
1039
+ free(compact);
1040
+ return PQ_ERROR_BUFFER;
960
1041
  }
1042
+ } else if (saw_padding) {
1043
+ pq_secure_wipe(compact, body_len);
1044
+ free(compact);
1045
+ return PQ_ERROR_BUFFER;
961
1046
  }
1047
+ compact[compact_len++] = c;
1048
+ }
962
1049
 
963
- *der_len_out = (size_t)decoded_len;
964
- *der_out = der;
965
- der = NULL;
966
- ret = PQ_SUCCESS;
1050
+ if (compact_len == 0 || (compact_len % 4) != 0 || compact_len > (size_t)INT_MAX) {
1051
+ pq_secure_wipe(compact, body_len);
1052
+ free(compact);
1053
+ return PQ_ERROR_BUFFER;
967
1054
  }
968
1055
 
969
- cleanup:
970
- if (bio_chain) {
971
- BIO_free_all(bio_chain);
972
- } else {
973
- if (bio_b64)
974
- BIO_free(bio_b64);
975
- if (bio_mem)
976
- BIO_free(bio_mem);
1056
+ der_cap = (compact_len / 4) * 3;
1057
+ der = malloc(der_cap ? der_cap : 1);
1058
+ if (!der) {
1059
+ pq_secure_wipe(compact, body_len);
1060
+ free(compact);
1061
+ return PQ_ERROR_NOMEM;
977
1062
  }
978
- if (der) {
1063
+
1064
+ decoded_len = EVP_DecodeBlock(der, compact, (int)compact_len);
1065
+ pq_secure_wipe(compact, body_len);
1066
+ free(compact);
1067
+ compact = NULL;
1068
+ if (decoded_len <= 0 || decoded_len < padding) {
1069
+ pq_secure_wipe(der, der_cap);
979
1070
  free(der);
1071
+ return PQ_ERROR_BUFFER;
980
1072
  }
981
- return ret;
1073
+
1074
+ *der_len_out = (size_t)(decoded_len - padding);
1075
+ *der_out = der;
1076
+ return PQ_SUCCESS;
982
1077
  }
983
1078
 
984
1079
  int pq_public_key_to_pqc_container_der(uint8_t **output, size_t *output_len,