pq_crypto 0.6.5 → 0.6.7

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +233 -0
  3. data/README.md +16 -3
  4. data/SECURITY.md +46 -0
  5. data/ext/pqcrypto/extconf.rb +8 -1
  6. data/ext/pqcrypto/pq_externalmu.c +35 -0
  7. data/ext/pqcrypto/pqcrypto_native_api.h +91 -75
  8. data/ext/pqcrypto/pqcrypto_ruby_secure.c +97 -9
  9. data/ext/pqcrypto/pqcrypto_secure.c +95 -33
  10. data/ext/pqcrypto/pqcrypto_secure.h +66 -48
  11. data/ext/pqcrypto/pqcrypto_version.h +1 -1
  12. data/ext/pqcrypto/vendor/.vendored +7 -7
  13. data/ext/pqcrypto/vendor/mldsa-native/BUILDING.md +5 -2
  14. data/ext/pqcrypto/vendor/mldsa-native/LICENSE +21 -2
  15. data/ext/pqcrypto/vendor/mldsa-native/README.md +20 -7
  16. data/ext/pqcrypto/vendor/mldsa-native/RELEASE.md +160 -0
  17. data/ext/pqcrypto/vendor/mldsa-native/SECURITY.md +1 -1
  18. data/ext/pqcrypto/vendor/mldsa-native/mldsa/README.md +2 -2
  19. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +85 -59
  20. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +292 -348
  21. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +122 -76
  22. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +184 -86
  23. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +49 -4
  24. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +49 -81
  25. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/context.h +152 -0
  26. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +25 -12
  27. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.c +2 -0
  28. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +2 -0
  29. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +2 -2
  30. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +9 -11
  31. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +19 -11
  32. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +6 -4
  33. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +7 -4
  34. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +7 -4
  35. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +12 -9
  36. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +12 -9
  37. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +1 -1
  38. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +3 -2
  39. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +3 -2
  40. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +6 -1
  41. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +3 -2
  42. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +11 -11
  43. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +9 -22
  44. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +8 -5
  45. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +1 -0
  46. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/{state_extract_bytes_x4_mve.S → keccak_f1600_x4_state_extract_bytes_mve.S} +14 -14
  47. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/{state_xor_bytes_x4_mve.S → keccak_f1600_x4_state_xor_bytes_mve.S} +12 -12
  48. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +5 -4
  49. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
  50. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +1 -0
  51. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +36 -2
  52. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +62 -4
  53. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +87 -54
  54. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{intt_aarch64_asm.S → mldsa_intt_aarch64_asm.S} +39 -6
  55. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{ntt_aarch64_asm.S → mldsa_ntt_aarch64_asm.S} +39 -6
  56. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{pointwise_montgomery_aarch64_asm.S → mldsa_pointwise_montgomery_aarch64_asm.S} +25 -3
  57. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_caddq_aarch64_asm.S → mldsa_poly_caddq_aarch64_asm.S} +19 -3
  58. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_chknorm_aarch64_asm.S → mldsa_poly_chknorm_aarch64_asm.S} +24 -3
  59. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_decompose_32_aarch64_asm.S → mldsa_poly_decompose_32_aarch64_asm.S} +25 -3
  60. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_decompose_88_aarch64_asm.S → mldsa_poly_decompose_88_aarch64_asm.S} +25 -3
  61. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_use_hint_32_aarch64_asm.S → mldsa_poly_use_hint_32_aarch64_asm.S} +25 -3
  62. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_use_hint_88_aarch64_asm.S → mldsa_poly_use_hint_88_aarch64_asm.S} +25 -3
  63. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{mld_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S → mldsa_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S} +31 -3
  64. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{mld_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S → mldsa_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S} +31 -3
  65. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{mld_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S → mldsa_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S} +31 -3
  66. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{polyz_unpack_17_aarch64_asm.S → mldsa_polyz_unpack_17_aarch64_asm.S} +31 -3
  67. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{polyz_unpack_19_aarch64_asm.S → mldsa_polyz_unpack_19_aarch64_asm.S} +31 -3
  68. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{rej_uniform_aarch64_asm.S → mldsa_rej_uniform_aarch64_asm.S} +48 -15
  69. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{rej_uniform_eta2_aarch64_asm.S → mldsa_rej_uniform_eta2_aarch64_asm.S} +42 -9
  70. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{rej_uniform_eta4_aarch64_asm.S → mldsa_rej_uniform_eta4_aarch64_asm.S} +42 -9
  71. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +11 -3
  72. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/meta.h +3 -2
  73. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +28 -28
  74. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +171 -49
  75. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{intt_avx2_asm.S → mldsa_intt_avx2_asm.S} +23 -1
  76. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{ntt_avx2_asm.S → mldsa_ntt_avx2_asm.S} +23 -1
  77. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{nttunpack_avx2_asm.S → mldsa_nttunpack_avx2_asm.S} +17 -1
  78. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{pointwise_acc_l4_avx2_asm.S → mldsa_pointwise_acc_l4_avx2_asm.S} +37 -3
  79. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{pointwise_acc_l5_avx2_asm.S → mldsa_pointwise_acc_l5_avx2_asm.S} +37 -3
  80. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{pointwise_acc_l7_avx2_asm.S → mldsa_pointwise_acc_l7_avx2_asm.S} +37 -3
  81. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{pointwise_avx2_asm.S → mldsa_pointwise_avx2_asm.S} +31 -3
  82. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{poly_caddq_avx2_asm.S → mldsa_poly_caddq_avx2_asm.S} +18 -9
  83. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_chknorm_avx2_asm.S +176 -0
  84. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_32_avx2_asm.S +490 -0
  85. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_88_avx2_asm.S +489 -0
  86. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_32_avx2_asm.S +123 -0
  87. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_88_avx2_asm.S +125 -0
  88. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_17_avx2_asm.S +355 -0
  89. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_19_avx2_asm.S +355 -0
  90. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_avx2_asm.S +132 -0
  91. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta2_avx2_asm.S +205 -0
  92. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta4_avx2_asm.S +176 -0
  93. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +27 -36
  94. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +42 -8
  95. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/params.h +93 -17
  96. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +74 -15
  97. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +97 -11
  98. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +7 -38
  99. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +49 -7
  100. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +16 -17
  101. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +26 -9
  102. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +3 -0
  103. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +18 -19
  104. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +15 -3
  105. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +28 -6
  106. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +311 -246
  107. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +245 -240
  108. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sys.h +64 -5
  109. data/ext/pqcrypto/vendor/mlkem-native/BUILDING.md +5 -2
  110. data/ext/pqcrypto/vendor/mlkem-native/LICENSE +21 -3
  111. data/ext/pqcrypto/vendor/mlkem-native/README.md +2 -2
  112. data/ext/pqcrypto/vendor/mlkem-native/RELEASE.md +113 -0
  113. data/ext/pqcrypto/vendor/mlkem-native/mlkem/README.md +2 -2
  114. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.c +17 -27
  115. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.h +68 -151
  116. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_asm.S +17 -27
  117. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_config.h +46 -44
  118. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/cbmc.h +25 -0
  119. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/common.h +37 -6
  120. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/context.h +9 -0
  121. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.h +2 -2
  122. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/keccakf1600.c +8 -8
  123. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_scalar.h +1 -1
  124. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_v84a.h +3 -3
  125. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x2_v84a.h +3 -3
  126. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_scalar.h +2 -2
  127. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +3 -3
  128. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/api.h +11 -11
  129. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/mve.h +3 -3
  130. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
  131. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.h +14 -11
  132. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.c +28 -11
  133. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.h +39 -14
  134. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/meta.h +10 -10
  135. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/meta.h +20 -20
  136. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sys.h +5 -5
  137. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/verify.h +11 -10
  138. data/lib/pq_crypto/internal.rb +10 -0
  139. data/lib/pq_crypto/kem.rb +47 -5
  140. data/lib/pq_crypto/key.rb +14 -8
  141. data/lib/pq_crypto/pkcs8.rb +13 -5
  142. data/lib/pq_crypto/signature.rb +34 -9
  143. data/lib/pq_crypto/spki.rb +4 -2
  144. data/lib/pq_crypto/version.rb +1 -1
  145. data/lib/pq_crypto.rb +9 -0
  146. data/script/vendor_libs.rb +6 -6
  147. metadata +40 -38
  148. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_chknorm_avx2.c +0 -52
  149. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +0 -157
  150. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +0 -157
  151. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +0 -103
  152. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +0 -105
  153. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +0 -94
  154. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +0 -96
  155. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_avx2.c +0 -126
  156. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +0 -157
  157. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +0 -141
@@ -173,11 +173,11 @@ typedef struct {
173
173
 
174
174
  static const pq_mldsa_profile_t MLDSA_PROFILES[] = {
175
175
  {"ml_dsa_44", MLDSA44_PUBLICKEYBYTES, MLDSA44_SECRETKEYBYTES, MLDSA44_BYTES,
176
- pqcr_mldsa44_pk_from_sk, pqcr_mldsa44_signature_extmu, pqcr_mldsa44_verify_extmu},
176
+ pqcr_mldsa44_pk_from_sk, pq_mldsa44_signature_extmu_compat, pq_mldsa44_verify_extmu_compat},
177
177
  {"ml_dsa_65", MLDSA65_PUBLICKEYBYTES, MLDSA65_SECRETKEYBYTES, MLDSA65_BYTES,
178
- pqcr_mldsa65_pk_from_sk, pqcr_mldsa65_signature_extmu, pqcr_mldsa65_verify_extmu},
178
+ pqcr_mldsa65_pk_from_sk, pq_mldsa65_signature_extmu_compat, pq_mldsa65_verify_extmu_compat},
179
179
  {"ml_dsa_87", MLDSA87_PUBLICKEYBYTES, MLDSA87_SECRETKEYBYTES, MLDSA87_BYTES,
180
- pqcr_mldsa87_pk_from_sk, pqcr_mldsa87_signature_extmu, pqcr_mldsa87_verify_extmu},
180
+ pqcr_mldsa87_pk_from_sk, pq_mldsa87_signature_extmu_compat, pq_mldsa87_verify_extmu_compat},
181
181
  };
182
182
 
183
183
  static const pq_mldsa_profile_t *pq_mldsa_profile_from_value(VALUE algorithm) {
@@ -718,6 +718,12 @@ __attribute__((noreturn)) static void pq_raise_general_error(int err) {
718
718
  case PQ_ERROR_OPENSSL:
719
719
  rb_raise(ePQCryptoError, "OpenSSL error");
720
720
  break;
721
+ case PQ_ERROR_INVALID_PUBLIC_KEY:
722
+ rb_raise(ePQCryptoError, "Invalid public key");
723
+ break;
724
+ case PQ_ERROR_INVALID_SECRET_KEY:
725
+ rb_raise(ePQCryptoError, "Invalid secret key");
726
+ break;
721
727
  default:
722
728
  rb_raise(ePQCryptoError, "Unknown error: %d", err);
723
729
  break;
@@ -765,6 +771,28 @@ static VALUE pq_run_kem_keypair_from_seed(void *(*nogvl)(void *), VALUE seed, si
765
771
  X(ml_kem_1024, MLKEM1024_PUBLICKEYBYTES, MLKEM1024_SECRETKEYBYTES, MLKEM1024_CIPHERTEXTBYTES, \
766
772
  MLKEM1024_SHAREDSECRETBYTES)
767
773
 
774
+ static VALUE pq_run_key_check(int (*check)(const uint8_t *), VALUE key, size_t expected_len) {
775
+ uint8_t *buffer;
776
+ size_t copied_len = 0;
777
+ int result;
778
+
779
+ StringValue(key);
780
+ if ((size_t)RSTRING_LEN(key) != expected_len) {
781
+ return Qfalse;
782
+ }
783
+
784
+ buffer = pq_copy_ruby_string(key, &copied_len);
785
+ result = check(buffer);
786
+ pq_secure_wipe(buffer, copied_len);
787
+ free(buffer);
788
+
789
+ if (result == PQ_ERROR_NOMEM) {
790
+ rb_raise(rb_eNoMemError, "Memory allocation failed");
791
+ }
792
+
793
+ return result == PQ_SUCCESS ? Qtrue : Qfalse;
794
+ }
795
+
768
796
  #define PQ_DEFINE_RUBY_KEM(rb_name, pk_bytes, sk_bytes, ct_bytes, ss_bytes) \
769
797
  static VALUE pqcrypto_##rb_name##_keypair(VALUE self) { \
770
798
  (void)self; \
@@ -787,6 +815,41 @@ static VALUE pq_run_kem_keypair_from_seed(void *(*nogvl)(void *), VALUE seed, si
787
815
  secret_key, sk_bytes, ss_bytes); \
788
816
  }
789
817
 
818
+ #define PQ_DEFINE_RUBY_KEM_CHECK(rb_name, c_name) \
819
+ static VALUE pqcrypto_##rb_name##_check_public_key(VALUE self, VALUE key) { \
820
+ (void)self; \
821
+ return pq_run_key_check(pq_##c_name##_check_public_key, key, \
822
+ (size_t)c_name##_PUBLICKEYBYTES_VALUE); \
823
+ } \
824
+ static VALUE pqcrypto_##rb_name##_check_secret_key(VALUE self, VALUE key) { \
825
+ (void)self; \
826
+ return pq_run_key_check(pq_##c_name##_check_secret_key, key, \
827
+ (size_t)c_name##_SECRETKEYBYTES_VALUE); \
828
+ }
829
+
830
+ #define mlkem_PUBLICKEYBYTES_VALUE PQ_MLKEM_PUBLICKEYBYTES
831
+ #define mlkem_SECRETKEYBYTES_VALUE PQ_MLKEM_SECRETKEYBYTES
832
+ #define mlkem512_PUBLICKEYBYTES_VALUE MLKEM512_PUBLICKEYBYTES
833
+ #define mlkem512_SECRETKEYBYTES_VALUE MLKEM512_SECRETKEYBYTES
834
+ #define mlkem1024_PUBLICKEYBYTES_VALUE MLKEM1024_PUBLICKEYBYTES
835
+ #define mlkem1024_SECRETKEYBYTES_VALUE MLKEM1024_SECRETKEYBYTES
836
+
837
+ PQ_KEM_KEYPAIR_NOGVL_VARIANTS(PQ_DEFINE_RUBY_KEM_CHECK)
838
+
839
+ #undef PQ_DEFINE_RUBY_KEM_CHECK
840
+
841
+ #define PQ_DEFINE_RUBY_MLDSA_CHECK_SK(rb_name, c_name, sk_bytes) \
842
+ static VALUE pqcrypto_##rb_name##_check_secret_key(VALUE self, VALUE key) { \
843
+ (void)self; \
844
+ return pq_run_key_check(pq_##c_name##_check_secret_key, key, (size_t)(sk_bytes)); \
845
+ }
846
+
847
+ PQ_DEFINE_RUBY_MLDSA_CHECK_SK(ml_dsa, mldsa, MLDSA65_SECRETKEYBYTES)
848
+ PQ_DEFINE_RUBY_MLDSA_CHECK_SK(ml_dsa_44, mldsa44, MLDSA44_SECRETKEYBYTES)
849
+ PQ_DEFINE_RUBY_MLDSA_CHECK_SK(ml_dsa_87, mldsa87, MLDSA87_SECRETKEYBYTES)
850
+
851
+ #undef PQ_DEFINE_RUBY_MLDSA_CHECK_SK
852
+
790
853
  PQ_RUBY_KEM_VARIANTS(PQ_DEFINE_RUBY_KEM)
791
854
 
792
855
  #undef PQ_DEFINE_RUBY_KEM
@@ -1306,7 +1369,8 @@ PQ_DEFINE_RUBY_MLDSA_SIGN(ml_dsa_87_sign, mldsa_87_sign, MLDSA87_SECRETKEYBYTES,
1306
1369
  #undef PQ_DEFINE_RUBY_MLDSA_SIGN
1307
1370
 
1308
1371
  static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signature, VALUE public_key,
1309
- VALUE context, size_t public_key_len_expected) {
1372
+ VALUE context, size_t public_key_len_expected,
1373
+ size_t signature_len_expected) {
1310
1374
  StringValue(signature);
1311
1375
  pq_validate_bytes_argument(public_key, public_key_len_expected, "public key");
1312
1376
  StringValue(context);
@@ -1314,6 +1378,10 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
1314
1378
  rb_raise(rb_eArgError, "ML-DSA context length must be <= 255 bytes");
1315
1379
  }
1316
1380
 
1381
+ if ((size_t)RSTRING_LEN(signature) != signature_len_expected) {
1382
+ return Qfalse;
1383
+ }
1384
+
1317
1385
  verify_call_t call = {0};
1318
1386
  size_t public_key_len = 0;
1319
1387
  size_t signature_len = 0;
@@ -1341,7 +1409,7 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
1341
1409
  pq_raise_general_error(call.result);
1342
1410
  }
1343
1411
 
1344
- #define PQ_DEFINE_RUBY_MLDSA_VERIFY(rb_name, nogvl_stem, pk_bytes) \
1412
+ #define PQ_DEFINE_RUBY_MLDSA_VERIFY(rb_name, nogvl_stem, pk_bytes, sig_bytes) \
1345
1413
  static VALUE pqcrypto_##rb_name(int argc, VALUE *argv, VALUE self) { \
1346
1414
  (void)self; \
1347
1415
  VALUE message, signature, public_key, context; \
@@ -1350,12 +1418,14 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
1350
1418
  context = rb_str_new("", 0); \
1351
1419
  } \
1352
1420
  return pq_run_verify(pq_##nogvl_stem##_nogvl, message, signature, public_key, context, \
1353
- pk_bytes); \
1421
+ pk_bytes, sig_bytes); \
1354
1422
  }
1355
1423
 
1356
- PQ_DEFINE_RUBY_MLDSA_VERIFY(verify, verify, PQ_MLDSA_PUBLICKEYBYTES)
1357
- PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_44_verify, mldsa_44_verify, MLDSA44_PUBLICKEYBYTES)
1358
- PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_87_verify, mldsa_87_verify, MLDSA87_PUBLICKEYBYTES)
1424
+ PQ_DEFINE_RUBY_MLDSA_VERIFY(verify, verify, PQ_MLDSA_PUBLICKEYBYTES, PQ_MLDSA_BYTES)
1425
+ PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_44_verify, mldsa_44_verify, MLDSA44_PUBLICKEYBYTES,
1426
+ MLDSA44_BYTES)
1427
+ PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_87_verify, mldsa_87_verify, MLDSA87_PUBLICKEYBYTES,
1428
+ MLDSA87_BYTES)
1359
1429
 
1360
1430
  #undef PQ_DEFINE_RUBY_MLDSA_VERIFY
1361
1431
 
@@ -1992,6 +2062,24 @@ void Init_pqcrypto_secure(void) {
1992
2062
  pqcrypto_ml_kem_1024_encapsulate, 1);
1993
2063
  rb_define_module_function(mPQCrypto, "ml_kem_1024_decapsulate",
1994
2064
  pqcrypto_ml_kem_1024_decapsulate, 2);
2065
+ rb_define_module_function(mPQCrypto, "ml_kem_check_public_key",
2066
+ pqcrypto_ml_kem_check_public_key, 1);
2067
+ rb_define_module_function(mPQCrypto, "ml_kem_check_secret_key",
2068
+ pqcrypto_ml_kem_check_secret_key, 1);
2069
+ rb_define_module_function(mPQCrypto, "ml_kem_512_check_public_key",
2070
+ pqcrypto_ml_kem_512_check_public_key, 1);
2071
+ rb_define_module_function(mPQCrypto, "ml_kem_512_check_secret_key",
2072
+ pqcrypto_ml_kem_512_check_secret_key, 1);
2073
+ rb_define_module_function(mPQCrypto, "ml_kem_1024_check_public_key",
2074
+ pqcrypto_ml_kem_1024_check_public_key, 1);
2075
+ rb_define_module_function(mPQCrypto, "ml_kem_1024_check_secret_key",
2076
+ pqcrypto_ml_kem_1024_check_secret_key, 1);
2077
+ rb_define_module_function(mPQCrypto, "ml_dsa_check_secret_key",
2078
+ pqcrypto_ml_dsa_check_secret_key, 1);
2079
+ rb_define_module_function(mPQCrypto, "ml_dsa_44_check_secret_key",
2080
+ pqcrypto_ml_dsa_44_check_secret_key, 1);
2081
+ rb_define_module_function(mPQCrypto, "ml_dsa_87_check_secret_key",
2082
+ pqcrypto_ml_dsa_87_check_secret_key, 1);
1995
2083
  rb_define_module_function(mPQCrypto, "hybrid_kem_keypair", pqcrypto_hybrid_kem_keypair, 0);
1996
2084
  rb_define_module_function(mPQCrypto, "hybrid_kem_encapsulate", pqcrypto_hybrid_kem_encapsulate,
1997
2085
  1);
@@ -265,12 +265,64 @@ cleanup:
265
265
  return PQ_ERROR_BUFFER; \
266
266
  } \
267
267
  return native##_dec(ss, ct, sk) == 0 ? PQ_SUCCESS : PQ_ERROR_DECAPSULATE; \
268
+ } \
269
+ int pq_##prefix##_check_public_key(const uint8_t *pk) { \
270
+ int rc; \
271
+ if (!pk) { \
272
+ return PQ_ERROR_BUFFER; \
273
+ } \
274
+ rc = native##_check_pk(pk); \
275
+ if (rc == 0) { \
276
+ return PQ_SUCCESS; \
277
+ } \
278
+ if (rc == -2) { \
279
+ return PQ_ERROR_NOMEM; \
280
+ } \
281
+ return PQ_ERROR_INVALID_PUBLIC_KEY; \
282
+ } \
283
+ int pq_##prefix##_check_secret_key(const uint8_t *sk) { \
284
+ int rc; \
285
+ if (!sk) { \
286
+ return PQ_ERROR_BUFFER; \
287
+ } \
288
+ rc = native##_check_sk(sk); \
289
+ if (rc == 0) { \
290
+ return PQ_SUCCESS; \
291
+ } \
292
+ if (rc == -2) { \
293
+ return PQ_ERROR_NOMEM; \
294
+ } \
295
+ return PQ_ERROR_INVALID_SECRET_KEY; \
268
296
  }
269
297
 
270
298
  PQ_MLKEM_VARIANTS(PQ_DEFINE_MLKEM_SHIMS)
271
299
 
272
300
  #undef PQ_DEFINE_MLKEM_SHIMS
273
301
 
302
+ #define PQ_DEFINE_MLDSA_CHECK_SK(prefix, native, pk_bytes) \
303
+ int pq_##prefix##_check_secret_key(const uint8_t *sk) { \
304
+ uint8_t pk[(pk_bytes)]; \
305
+ int rc; \
306
+ if (!sk) { \
307
+ return PQ_ERROR_BUFFER; \
308
+ } \
309
+ rc = native##_pk_from_sk(pk, sk); \
310
+ pq_secure_wipe(pk, sizeof(pk)); \
311
+ if (rc == 0) { \
312
+ return PQ_SUCCESS; \
313
+ } \
314
+ if (rc == -2) { \
315
+ return PQ_ERROR_NOMEM; \
316
+ } \
317
+ return PQ_ERROR_INVALID_SECRET_KEY; \
318
+ }
319
+
320
+ PQ_DEFINE_MLDSA_CHECK_SK(mldsa, pqcr_mldsa65, MLDSA65_PUBLICKEYBYTES)
321
+ PQ_DEFINE_MLDSA_CHECK_SK(mldsa44, pqcr_mldsa44, MLDSA44_PUBLICKEYBYTES)
322
+ PQ_DEFINE_MLDSA_CHECK_SK(mldsa87, pqcr_mldsa87, MLDSA87_PUBLICKEYBYTES)
323
+
324
+ #undef PQ_DEFINE_MLDSA_CHECK_SK
325
+
274
326
  static int pq_testing_mlkem_keypair_from_seed_with(uint8_t *public_key, uint8_t *secret_key,
275
327
  const uint8_t *seed, size_t seed_len,
276
328
  int (*keypair_derand)(uint8_t *, uint8_t *,
@@ -322,27 +374,29 @@ PQ_DEFINE_MLDSA_SIGN_KEYPAIR(mldsa87_sign, pqcr_mldsa87)
322
374
 
323
375
  #undef PQ_DEFINE_MLDSA_SIGN_KEYPAIR
324
376
 
325
- #define PQ_DEFINE_MLDSA_SIGN(name, native) \
326
- int pq_##name(uint8_t *signature, size_t *signature_len, const uint8_t *message, \
327
- size_t message_len, const uint8_t *ctx, size_t ctx_len, \
328
- const uint8_t *secret_key) { \
329
- if (!signature || !signature_len || !secret_key || (message_len > 0 && !message) || \
330
- (ctx_len > 0 && !ctx) || ctx_len > 255) { \
331
- return PQ_ERROR_BUFFER; \
332
- } \
333
- return native##_signature(signature, signature_len, message, message_len, ctx, ctx_len, \
334
- secret_key) == 0 \
335
- ? PQ_SUCCESS \
336
- : PQ_ERROR_SIGN; \
337
- }
338
-
339
- PQ_DEFINE_MLDSA_SIGN(sign, pqcr_mldsa65)
340
- PQ_DEFINE_MLDSA_SIGN(mldsa44_sign, pqcr_mldsa44)
341
- PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, pqcr_mldsa87)
377
+ #define PQ_DEFINE_MLDSA_SIGN(name, native, sig_bytes) \
378
+ int pq_##name(uint8_t *signature, size_t *signature_len, const uint8_t *message, \
379
+ size_t message_len, const uint8_t *ctx, size_t ctx_len, \
380
+ const uint8_t *secret_key) { \
381
+ if (!signature || !signature_len || !secret_key || (message_len > 0 && !message) || \
382
+ (ctx_len > 0 && !ctx) || ctx_len > 255) { \
383
+ return PQ_ERROR_BUFFER; \
384
+ } \
385
+ if (native##_signature(signature, message, message_len, ctx, ctx_len, secret_key) != 0) { \
386
+ *signature_len = 0; \
387
+ return PQ_ERROR_SIGN; \
388
+ } \
389
+ *signature_len = (size_t)(sig_bytes); \
390
+ return PQ_SUCCESS; \
391
+ }
392
+
393
+ PQ_DEFINE_MLDSA_SIGN(sign, pqcr_mldsa65, MLDSA65_BYTES)
394
+ PQ_DEFINE_MLDSA_SIGN(mldsa44_sign, pqcr_mldsa44, MLDSA44_BYTES)
395
+ PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, pqcr_mldsa87, MLDSA87_BYTES)
342
396
 
343
397
  #undef PQ_DEFINE_MLDSA_SIGN
344
398
 
345
- #define PQ_DEFINE_MLDSA_VERIFY(name, native) \
399
+ #define PQ_DEFINE_MLDSA_VERIFY(name, native, sig_bytes) \
346
400
  int pq_##name(const uint8_t *signature, size_t signature_len, const uint8_t *message, \
347
401
  size_t message_len, const uint8_t *ctx, size_t ctx_len, \
348
402
  const uint8_t *public_key) { \
@@ -350,29 +404,32 @@ PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, pqcr_mldsa87)
350
404
  ctx_len > 255) { \
351
405
  return PQ_ERROR_BUFFER; \
352
406
  } \
353
- return native##_verify(signature, signature_len, message, message_len, ctx, ctx_len, \
354
- public_key) == 0 \
407
+ if (signature_len != (size_t)(sig_bytes)) { \
408
+ return PQ_ERROR_VERIFY; \
409
+ } \
410
+ return native##_verify(signature, message, message_len, ctx, ctx_len, public_key) == 0 \
355
411
  ? PQ_SUCCESS \
356
412
  : PQ_ERROR_VERIFY; \
357
413
  }
358
414
 
359
- PQ_DEFINE_MLDSA_VERIFY(verify, pqcr_mldsa65)
360
- PQ_DEFINE_MLDSA_VERIFY(mldsa44_verify, pqcr_mldsa44)
361
- PQ_DEFINE_MLDSA_VERIFY(mldsa87_verify, pqcr_mldsa87)
415
+ PQ_DEFINE_MLDSA_VERIFY(verify, pqcr_mldsa65, MLDSA65_BYTES)
416
+ PQ_DEFINE_MLDSA_VERIFY(mldsa44_verify, pqcr_mldsa44, MLDSA44_BYTES)
417
+ PQ_DEFINE_MLDSA_VERIFY(mldsa87_verify, pqcr_mldsa87, MLDSA87_BYTES)
362
418
 
363
419
  #undef PQ_DEFINE_MLDSA_VERIFY
364
420
 
365
421
  static int pq_testing_mldsa_sign_from_seed_with(
366
422
  uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len,
367
- const uint8_t *secret_key, const uint8_t *seed, size_t seed_len,
368
- int (*signature_internal)(uint8_t *, size_t *, const uint8_t *, size_t, const uint8_t *, size_t,
423
+ const uint8_t *secret_key, const uint8_t *seed, size_t seed_len, size_t expected_signature_len,
424
+ int (*signature_internal)(uint8_t *, const uint8_t *, size_t, const uint8_t *, size_t,
369
425
  const uint8_t *, const uint8_t *, int),
370
426
  size_t (*prepare_prefix)(uint8_t *, const uint8_t *, size_t, const uint8_t *, size_t, int)) {
371
427
  uint8_t pre[MLDSA_DOMAIN_SEPARATION_MAX_BYTES];
372
428
  size_t pre_len;
373
429
 
374
430
  if (!signature || !signature_len || !secret_key || !seed || seed_len != MLDSA_RNDBYTES ||
375
- !signature_internal || !prepare_prefix || (message_len > 0 && !message)) {
431
+ !signature_internal || !prepare_prefix || expected_signature_len == 0 ||
432
+ (message_len > 0 && !message)) {
376
433
  return PQ_ERROR_BUFFER;
377
434
  }
378
435
 
@@ -385,13 +442,18 @@ static int pq_testing_mldsa_sign_from_seed_with(
385
442
  */
386
443
  pre_len = prepare_prefix(pre, NULL, 0, NULL, 0, MLDSA_PREHASH_NONE);
387
444
  if (pre_len == 0) {
445
+ *signature_len = 0;
388
446
  return PQ_ERROR_SIGN;
389
447
  }
390
448
 
391
- return signature_internal(signature, signature_len, message, message_len, pre, pre_len, seed,
392
- secret_key, 0) == 0
393
- ? PQ_SUCCESS
394
- : PQ_ERROR_SIGN;
449
+ if (signature_internal(signature, message, message_len, pre, pre_len, seed, secret_key, 0) !=
450
+ 0) {
451
+ *signature_len = 0;
452
+ return PQ_ERROR_SIGN;
453
+ }
454
+
455
+ *signature_len = expected_signature_len;
456
+ return PQ_SUCCESS;
395
457
  }
396
458
 
397
459
  int pq_mldsa44_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32) {
@@ -447,7 +509,7 @@ int pq_testing_mldsa_sign_from_seed(uint8_t *signature, size_t *signature_len,
447
509
  const uint8_t *secret_key, const uint8_t *seed,
448
510
  size_t seed_len) {
449
511
  return pq_testing_mldsa_sign_from_seed_with(
450
- signature, signature_len, message, message_len, secret_key, seed, seed_len,
512
+ signature, signature_len, message, message_len, secret_key, seed, seed_len, MLDSA65_BYTES,
451
513
  pqcr_mldsa65_signature_internal, pqcr_mldsa65_prepare_domain_separation_prefix);
452
514
  }
453
515
 
@@ -456,7 +518,7 @@ int pq_testing_mldsa44_sign_from_seed(uint8_t *signature, size_t *signature_len,
456
518
  const uint8_t *secret_key, const uint8_t *seed,
457
519
  size_t seed_len) {
458
520
  return pq_testing_mldsa_sign_from_seed_with(
459
- signature, signature_len, message, message_len, secret_key, seed, seed_len,
521
+ signature, signature_len, message, message_len, secret_key, seed, seed_len, MLDSA44_BYTES,
460
522
  pqcr_mldsa44_signature_internal, pqcr_mldsa44_prepare_domain_separation_prefix);
461
523
  }
462
524
 
@@ -465,7 +527,7 @@ int pq_testing_mldsa87_sign_from_seed(uint8_t *signature, size_t *signature_len,
465
527
  const uint8_t *secret_key, const uint8_t *seed,
466
528
  size_t seed_len) {
467
529
  return pq_testing_mldsa_sign_from_seed_with(
468
- signature, signature_len, message, message_len, secret_key, seed, seed_len,
530
+ signature, signature_len, message, message_len, secret_key, seed, seed_len, MLDSA87_BYTES,
469
531
  pqcr_mldsa87_signature_internal, pqcr_mldsa87_prepare_domain_separation_prefix);
470
532
  }
471
533
 
@@ -29,7 +29,9 @@ typedef enum {
29
29
  PQ_ERROR_RANDOM = -7,
30
30
  PQ_ERROR_BUFFER = -8,
31
31
  PQ_ERROR_NOMEM = -9,
32
- PQ_ERROR_OPENSSL = -10
32
+ PQ_ERROR_OPENSSL = -10,
33
+ PQ_ERROR_INVALID_PUBLIC_KEY = -11,
34
+ PQ_ERROR_INVALID_SECRET_KEY = -12
33
35
  } pq_error_t;
34
36
 
35
37
  typedef struct {
@@ -69,15 +71,13 @@ void pq_secure_wipe(void *ptr, size_t len);
69
71
  int pq_mlkem_keypair(uint8_t *public_key, uint8_t *secret_key);
70
72
  int pq_mlkem512_keypair(uint8_t *public_key, uint8_t *secret_key);
71
73
  int pq_mlkem1024_keypair(uint8_t *public_key, uint8_t *secret_key);
72
- int pq_mlkem_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
73
- const uint8_t *seed64);
74
- int pq_mlkem512_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
75
- const uint8_t *seed64);
76
- int pq_mlkem1024_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
77
- const uint8_t *seed64);
74
+ int pq_mlkem_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed64);
75
+ int pq_mlkem512_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed64);
76
+ int pq_mlkem1024_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed64);
78
77
  int pq_mlkem_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);
79
78
  int pq_mlkem512_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);
80
- int pq_mlkem1024_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);
79
+ int pq_mlkem1024_encapsulate(uint8_t *ciphertext, uint8_t *shared_secret,
80
+ const uint8_t *public_key);
81
81
  int pq_mlkem_decapsulate(uint8_t *shared_secret, const uint8_t *ciphertext,
82
82
  const uint8_t *secret_key);
83
83
  int pq_mlkem512_decapsulate(uint8_t *shared_secret, const uint8_t *ciphertext,
@@ -85,56 +85,63 @@ int pq_mlkem512_decapsulate(uint8_t *shared_secret, const uint8_t *ciphertext,
85
85
  int pq_mlkem1024_decapsulate(uint8_t *shared_secret, const uint8_t *ciphertext,
86
86
  const uint8_t *secret_key);
87
87
 
88
+ int pq_mlkem_check_public_key(const uint8_t *public_key);
89
+ int pq_mlkem_check_secret_key(const uint8_t *secret_key);
90
+ int pq_mlkem512_check_public_key(const uint8_t *public_key);
91
+ int pq_mlkem512_check_secret_key(const uint8_t *secret_key);
92
+ int pq_mlkem1024_check_public_key(const uint8_t *public_key);
93
+ int pq_mlkem1024_check_secret_key(const uint8_t *secret_key);
94
+
95
+ int pq_mldsa_check_secret_key(const uint8_t *secret_key);
96
+ int pq_mldsa44_check_secret_key(const uint8_t *secret_key);
97
+ int pq_mldsa87_check_secret_key(const uint8_t *secret_key);
98
+
88
99
  int pq_sign_keypair(uint8_t *public_key, uint8_t *secret_key);
89
100
  int pq_mldsa44_sign_keypair(uint8_t *public_key, uint8_t *secret_key);
90
101
  int pq_mldsa87_sign_keypair(uint8_t *public_key, uint8_t *secret_key);
91
- int pq_mldsa44_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
92
- const uint8_t *seed32);
93
- int pq_mldsa_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
94
- const uint8_t *seed32);
95
- int pq_mldsa87_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key,
96
- const uint8_t *seed32);
102
+ int pq_mldsa44_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32);
103
+ int pq_mldsa_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32);
104
+ int pq_mldsa87_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32);
97
105
  int pq_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len,
98
106
  const uint8_t *ctx, size_t ctx_len, const uint8_t *secret_key);
99
- int pq_mldsa44_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len,
100
- const uint8_t *ctx, size_t ctx_len, const uint8_t *secret_key);
101
- int pq_mldsa87_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len,
102
- const uint8_t *ctx, size_t ctx_len, const uint8_t *secret_key);
107
+ int pq_mldsa44_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message,
108
+ size_t message_len, const uint8_t *ctx, size_t ctx_len,
109
+ const uint8_t *secret_key);
110
+ int pq_mldsa87_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message,
111
+ size_t message_len, const uint8_t *ctx, size_t ctx_len,
112
+ const uint8_t *secret_key);
103
113
  int pq_verify(const uint8_t *signature, size_t signature_len, const uint8_t *message,
104
114
  size_t message_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *public_key);
105
115
  int pq_mldsa44_verify(const uint8_t *signature, size_t signature_len, const uint8_t *message,
106
- size_t message_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *public_key);
116
+ size_t message_len, const uint8_t *ctx, size_t ctx_len,
117
+ const uint8_t *public_key);
107
118
  int pq_mldsa87_verify(const uint8_t *signature, size_t signature_len, const uint8_t *message,
108
- size_t message_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *public_key);
119
+ size_t message_len, const uint8_t *ctx, size_t ctx_len,
120
+ const uint8_t *public_key);
109
121
 
110
122
  int pq_public_key_to_pqc_container_der(uint8_t **output, size_t *output_len,
111
- const uint8_t *public_key,
112
- size_t public_key_len, const char *algorithm);
113
- int pq_public_key_to_pqc_container_pem(char **output, size_t *output_len,
114
- const uint8_t *public_key,
123
+ const uint8_t *public_key, size_t public_key_len,
124
+ const char *algorithm);
125
+ int pq_public_key_to_pqc_container_pem(char **output, size_t *output_len, const uint8_t *public_key,
115
126
  size_t public_key_len, const char *algorithm);
116
127
  int pq_secret_key_to_pqc_container_der(uint8_t **output, size_t *output_len,
117
- const uint8_t *secret_key,
118
- size_t secret_key_len, const char *algorithm);
119
- int pq_secret_key_to_pqc_container_pem(char **output, size_t *output_len,
120
- const uint8_t *secret_key,
121
- size_t secret_key_len, const char *algorithm);
128
+ const uint8_t *secret_key, size_t secret_key_len,
129
+ const char *algorithm);
130
+ int pq_secret_key_to_pqc_container_pem(char **output, size_t *output_len, const uint8_t *secret_key,
131
+ size_t secret_key_len, const char *algorithm);
122
132
  int pq_public_key_from_pqc_container_der(char **algorithm_out, uint8_t **key_out,
123
133
  size_t *key_len_out, const uint8_t *input,
124
134
  size_t input_len);
125
135
  int pq_public_key_from_pqc_container_pem(char **algorithm_out, uint8_t **key_out,
126
- size_t *key_len_out, const char *input,
127
- size_t input_len);
136
+ size_t *key_len_out, const char *input, size_t input_len);
128
137
  int pq_secret_key_from_pqc_container_der(char **algorithm_out, uint8_t **key_out,
129
- size_t *key_len_out, const uint8_t *input,
130
- size_t input_len);
138
+ size_t *key_len_out, const uint8_t *input,
139
+ size_t input_len);
131
140
  int pq_secret_key_from_pqc_container_pem(char **algorithm_out, uint8_t **key_out,
132
- size_t *key_len_out, const char *input,
133
- size_t input_len);
141
+ size_t *key_len_out, const char *input, size_t input_len);
134
142
 
135
- int pq_pkcs8_private_key_info_to_der(uint8_t **output, size_t *output_len,
136
- const char *oid_text, const uint8_t *private_key,
137
- size_t private_key_len);
143
+ int pq_pkcs8_private_key_info_to_der(uint8_t **output, size_t *output_len, const char *oid_text,
144
+ const uint8_t *private_key, size_t private_key_len);
138
145
  int pq_pkcs8_private_key_info_from_der(char **oid_text_out, uint8_t **private_key_out,
139
146
  size_t *private_key_len_out, const uint8_t *input,
140
147
  size_t input_len);
@@ -143,9 +150,8 @@ int pq_pkcs8_encrypt_private_key_info_der(uint8_t **output, size_t *output_len,
143
150
  const char *passphrase, size_t passphrase_len,
144
151
  int iterations);
145
152
  int pq_pkcs8_decrypt_private_key_info_der(uint8_t **output, size_t *output_len,
146
- const uint8_t *encrypted_der,
147
- size_t encrypted_der_len, const char *passphrase,
148
- size_t passphrase_len);
153
+ const uint8_t *encrypted_der, size_t encrypted_der_len,
154
+ const char *passphrase, size_t passphrase_len);
149
155
  int pq_pkcs8_der_is_encrypted_private_key_info(const uint8_t *input, size_t input_len);
150
156
  int pq_pkcs8_der_to_pem(char **output, size_t *output_len, const uint8_t *der, size_t der_len,
151
157
  int encrypted);
@@ -197,7 +203,7 @@ const char *pq_version(void);
197
203
  #define PQ_MLKEM_CIPHERTEXTBYTES MLKEM_CIPHERTEXTBYTES
198
204
  #define PQ_MLKEM_SHAREDSECRETBYTES MLKEM_SHAREDSECRETBYTES
199
205
 
200
- #define PQ_HYBRID_PUBLICKEYBYTES HYBRID_PUBLICKEYBYTES
206
+ #define PQ_HYBRID_PUBLICKEYBYTES HYBRID_PUBLICKEYBYTES
201
207
  #define PQ_HYBRID_SECRETKEYBYTES HYBRID_SECRETKEYBYTES
202
208
  #define PQ_HYBRID_EXPANDED_SECRETKEYBYTES HYBRID_EXPANDED_SECRETKEYBYTES
203
209
  #define PQ_HYBRID_CIPHERTEXTBYTES HYBRID_CIPHERTEXTBYTES
@@ -215,15 +221,27 @@ int pq_mldsa_extract_tr_from_secret_key(uint8_t *tr_out, const uint8_t *secret_k
215
221
  int pq_mldsa_compute_tr_from_public_key(uint8_t *tr_out, const uint8_t *public_key,
216
222
  size_t public_key_len);
217
223
 
218
- int pq_sign_mu(uint8_t *signature, size_t *signature_len,
219
- const uint8_t *mu, const uint8_t *secret_key,
224
+ int pq_mldsa44_signature_extmu_compat(uint8_t *sig, size_t *siglen, const uint8_t *mu,
225
+ const uint8_t *sk);
226
+ int pq_mldsa65_signature_extmu_compat(uint8_t *sig, size_t *siglen, const uint8_t *mu,
227
+ const uint8_t *sk);
228
+ int pq_mldsa87_signature_extmu_compat(uint8_t *sig, size_t *siglen, const uint8_t *mu,
229
+ const uint8_t *sk);
230
+ int pq_mldsa44_verify_extmu_compat(const uint8_t *sig, size_t siglen, const uint8_t *mu,
231
+ const uint8_t *pk);
232
+ int pq_mldsa65_verify_extmu_compat(const uint8_t *sig, size_t siglen, const uint8_t *mu,
233
+ const uint8_t *pk);
234
+ int pq_mldsa87_verify_extmu_compat(const uint8_t *sig, size_t siglen, const uint8_t *mu,
235
+ const uint8_t *pk);
236
+
237
+ int pq_sign_mu(uint8_t *signature, size_t *signature_len, const uint8_t *mu,
238
+ const uint8_t *secret_key,
220
239
  int (*signature_extmu)(uint8_t *, size_t *, const uint8_t *, const uint8_t *));
221
- int pq_verify_mu(const uint8_t *signature, size_t signature_len,
222
- const uint8_t *mu, const uint8_t *public_key, size_t expected_signature_len,
240
+ int pq_verify_mu(const uint8_t *signature, size_t signature_len, const uint8_t *mu,
241
+ const uint8_t *public_key, size_t expected_signature_len,
223
242
  int (*verify_extmu)(const uint8_t *, size_t, const uint8_t *, const uint8_t *));
224
243
  void *pq_mu_builder_new(void);
225
- int pq_mu_builder_init(void *state, const uint8_t *tr,
226
- const uint8_t *ctx, size_t ctxlen);
244
+ int pq_mu_builder_init(void *state, const uint8_t *tr, const uint8_t *ctx, size_t ctxlen);
227
245
  int pq_mu_builder_absorb(void *state, const uint8_t *chunk, size_t chunk_len);
228
246
  int pq_mu_builder_finalize(void *state, uint8_t *mu_out);
229
247
  void pq_mu_builder_release(void *state);
@@ -2,6 +2,6 @@
2
2
  #ifndef PQCRYPTO_VERSION_H
3
3
  #define PQCRYPTO_VERSION_H
4
4
 
5
- #define PQCRYPTO_VERSION "0.6.5"
5
+ #define PQCRYPTO_VERSION "0.6.7"
6
6
 
7
7
  #endif
@@ -2,11 +2,11 @@
2
2
  backend=PQ Code Package native only
3
3
  pqclean=removed
4
4
  mlkem_native_repo=https://github.com/pq-code-package/mlkem-native.git
5
- mlkem_native_ref=v1.3.0
6
- mlkem_native_commit=398050c877ff4353c96305c6434b63528accfc37
7
- mlkem_native_tree_sha256=3cd7af93cde256f73ce5ffde3ac3accd31e4361616e275f1bf1c39d462c2149e
5
+ mlkem_native_ref=v2.0.0
6
+ mlkem_native_commit=d1b2fe782888bdb761a50336012923180be7f502
7
+ mlkem_native_tree_sha256=18bfa9ea4e2232bdf56f8ec374b62d10e50b99a30cb08aafc18d0b97e00cd06f
8
8
  mldsa_native_repo=https://github.com/pq-code-package/mldsa-native.git
9
- mldsa_native_ref=v1.0.0-beta2
10
- mldsa_native_commit=9b0ee84f4cf399043eca59eca4e5f8531ca1d61b
11
- mldsa_native_tree_sha256=2887f59926c18a877e8c5a5e30727e84497c357032093d00d7135aedf53f011e
12
- manifest_sha256=6fc387662d86d42905f6cbed29c92bc83abf18e8678a21500eb27fce14a89c7d
9
+ mldsa_native_ref=v2.0.0
10
+ mldsa_native_commit=834a90d5e846ffa1e1611bd24e160bb2e9b86d35
11
+ mldsa_native_tree_sha256=25b3c3949d2ed37d1ad5d4722c8476d13deb2a0bb945f12444f463378d69375d
12
+ manifest_sha256=4bcf7cc4d0ac0d0e66ebb9612042960dc1197838f26bbedb16e3b6a3978e264c
@@ -73,11 +73,14 @@ For detailed information on how to use the script, please refer to
73
73
 
74
74
  You can also build **mldsa-native** on Windows using `nmake` and an MSVC compiler.
75
75
 
76
- To build and run the tests (only support functional testing for non-opt implementation for now), use the following `nmake` targets:
76
+ To build and run the tests, use the following `nmake` target:
77
77
  ```powershell
78
- nmke /f .\Makefile.Microsoft_nmake quickcheck
78
+ nmake /f .\Makefile.Microsoft_nmake quickcheck
79
79
  ```
80
80
 
81
+ This runs the functional, RNG-failure, allocation, ACVP, KAT and Wycheproof tests. The assembly backends are not yet
82
+ supported on Windows, so the tests are built for the C backend only.
83
+
81
84
  # Checking the proofs
82
85
 
83
86
  ## CBMC
@@ -6,14 +6,33 @@ implementation are made available under the Apache-2.0 license OR
6
6
  the ISC license OR the MIT license. These licenses are
7
7
  reproduced at the bottom of this file.
8
8
 
9
- The code in test/notrandombytes/* is derived from
9
+ Files outside the library itself may carry different terms. Every file
10
+ states its own SPDX-License-Identifier, which determines the terms that
11
+ apply to it. In particular:
12
+
13
+ The code in test/notrandombytes/*, and its copies in
14
+ examples/*/test_only_rng/* and scripts/notrandombytes, is derived from
10
15
  https://cr.yp.to/papers.html#surf and licensed under
11
16
  LicenseRef-PD-hp OR CC0-1.0 OR 0BSD OR MIT-0 OR MIT.
12
17
  It is only used for testing purposes.
13
18
 
14
- The benchmarking code in test/hal/hal.c carries the
19
+ The benchmarking code in test/hal/* carries the
15
20
  MIT license. It is only used for testing purposes.
16
21
 
22
+ The tiny_sha3 code in
23
+ examples/bring_your_own_fips202/custom_fips202/tiny_sha3/* and
24
+ examples/custom_backend/mldsa_native/src/fips202/native/custom/src/*
25
+ carries the MIT license. It is only used to demonstrate custom
26
+ FIPS-202 implementations.
27
+
28
+ The proofs in proofs/* are in part derived from Amazon Web Services
29
+ verification infrastructure and licensed under
30
+ Apache-2.0 OR ISC OR MIT-0, MIT-0, or MIT-0 AND Apache-2.0. The IACR
31
+ document class proofs/isabelle/neon_ntt/document/iacrtrans.cls is
32
+ licensed under CC0-1.0. None of this is part of the library.
33
+
34
+ Documentation is licensed under CC-BY-4.0.
35
+
17
36
  ```
18
37
  Copyright (c) The mldsa-native project authors
19
38
  Copyright (c) The mlkem-native project authors