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
@@ -60,7 +60,8 @@ int mlk_kem_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
60
60
 
61
61
  /* We use a constant-time memcmp here to avoid having to
62
62
  * declassify the PK before the PCT has succeeded. */
63
- ret = mlk_ct_memcmp(pk, p_reencoded, MLKEM_POLYVECBYTES) ? MLK_ERR_FAIL : 0;
63
+ ret = mlk_ct_memcmp(pk, p_reencoded, MLKEM_POLYVECBYTES) ? MLK_ERR_INVALID_PK
64
+ : 0;
64
65
 
65
66
  cleanup:
66
67
  /* Specification: Partially implements
@@ -107,7 +108,7 @@ int mlk_kem_check_sk(const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES],
107
108
  * of minimizing stdlib dependency, we use our constant-time one anyway. */
108
109
  ret = mlk_ct_memcmp(sk + MLKEM_INDCCA_SECRETKEYBYTES - 2 * MLKEM_SYMBYTES,
109
110
  test, MLKEM_SYMBYTES)
110
- ? MLK_ERR_FAIL
111
+ ? MLK_ERR_INVALID_SK
111
112
  : 0;
112
113
 
113
114
  cleanup:
@@ -126,9 +127,9 @@ static int mlk_check_pct(uint8_t const pk[MLKEM_INDCCA_PUBLICKEYBYTES],
126
127
  __contract__(
127
128
  requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
128
129
  requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
129
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
130
- return_value == MLK_ERR_OUT_OF_MEMORY ||
131
- return_value == MLK_ERR_RNG_FAIL)
130
+ ensures(return_value == 0 || return_value == MLK_ERR_OUT_OF_MEMORY ||
131
+ return_value == MLK_ERR_RNG_FAIL ||
132
+ return_value == MLK_ERR_PCT_FAIL)
132
133
  );
133
134
 
134
135
  #if defined(MLK_CONFIG_KEYGEN_PCT)
@@ -136,7 +137,13 @@ __contract__(
136
137
  * Partially implements 'Pairwise Consistency Test' @[FIPS140_3_IG, p.87] and
137
138
  * @[FIPS203, Section 7.1, Pairwise Consistency]. */
138
139
 
139
- /* Reference: Not implemented in the reference implementation @[REF]. */
140
+ /* Reference: Not implemented in the reference implementation @[REF].
141
+ *
142
+ * @retval 0 Success.
143
+ * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
144
+ * MLK_CUSTOM_ALLOC returned NULL.
145
+ * @retval MLK_ERR_RNG_FAIL Random number generation failed.
146
+ * @retval MLK_ERR_PCT_FAIL The consistency check failed. */
140
147
  MLK_MUST_CHECK_RETURN_VALUE
141
148
  static int mlk_check_pct(uint8_t const pk[MLKEM_INDCCA_PUBLICKEYBYTES],
142
149
  uint8_t const sk[MLKEM_INDCCA_SECRETKEYBYTES],
@@ -179,7 +186,7 @@ static int mlk_check_pct(uint8_t const pk[MLKEM_INDCCA_PUBLICKEYBYTES],
179
186
 
180
187
  if (ret != 0)
181
188
  {
182
- ret = MLK_ERR_FAIL;
189
+ ret = MLK_ERR_PCT_FAIL;
183
190
  }
184
191
 
185
192
  cleanup:
@@ -189,9 +196,21 @@ cleanup:
189
196
  MLK_FREE(ss_dec, uint8_t, MLKEM_SSBYTES, context);
190
197
  MLK_FREE(ss_enc, uint8_t, MLKEM_SSBYTES, context);
191
198
  MLK_FREE(ct, uint8_t, MLKEM_INDCCA_CIPHERTEXTBYTES, context);
199
+
200
+ /* The key pair being tested was just generated by this library, so a key
201
+ * check rejecting it hints at a faulty implementation rather than at bad
202
+ * input. Report it as a PCT failure. */
203
+ if (ret == MLK_ERR_INVALID_PK || ret == MLK_ERR_INVALID_SK)
204
+ {
205
+ ret = MLK_ERR_PCT_FAIL;
206
+ }
207
+
208
+ /* Other error codes, e.g. platform failures like out of memory or
209
+ * randomness failure, are passed on unmodified. */
210
+
192
211
  return ret;
193
212
  }
194
- #else /* MLK_CONFIG_KEYGEN_PCT */
213
+ #else /* MLK_CONFIG_KEYGEN_PCT */
195
214
  MLK_MUST_CHECK_RETURN_VALUE
196
215
  static int mlk_check_pct(uint8_t const pk[MLKEM_INDCCA_PUBLICKEYBYTES],
197
216
  uint8_t const sk[MLKEM_INDCCA_SECRETKEYBYTES],
@@ -200,9 +219,7 @@ static int mlk_check_pct(uint8_t const pk[MLKEM_INDCCA_PUBLICKEYBYTES],
200
219
  /* Skip PCT */
201
220
  ((void)pk);
202
221
  ((void)sk);
203
- #if defined(MLK_CONFIG_CONTEXT_PARAMETER)
204
- ((void)context);
205
- #endif
222
+ MLK_CONTEXT_UNUSED(context);
206
223
  return 0;
207
224
  }
208
225
  #endif /* !MLK_CONFIG_KEYGEN_PCT */
@@ -80,7 +80,7 @@
80
80
  * MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
81
81
  *
82
82
  * @retval 0 Success.
83
- * @retval MLK_ERR_FAIL Modulus check failed.
83
+ * @retval MLK_ERR_INVALID_PK Modulus check failed.
84
84
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
85
85
  * MLK_CUSTOM_ALLOC returned NULL.
86
86
  */
@@ -91,7 +91,7 @@ int mlk_kem_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES],
91
91
  MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
92
92
  __contract__(
93
93
  requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
94
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
94
+ ensures(return_value == 0 || return_value == MLK_ERR_INVALID_PK ||
95
95
  return_value == MLK_ERR_OUT_OF_MEMORY)
96
96
  );
97
97
  #endif /* !MLK_CONFIG_NO_ENCAPS_API */
@@ -112,7 +112,7 @@ __contract__(
112
112
  * MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
113
113
  *
114
114
  * @retval 0 Success.
115
- * @retval MLK_ERR_FAIL Public key hash check failed.
115
+ * @retval MLK_ERR_INVALID_SK Public key hash check failed.
116
116
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
117
117
  * MLK_CUSTOM_ALLOC returned NULL.
118
118
  */
@@ -123,7 +123,7 @@ int mlk_kem_check_sk(const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES],
123
123
  MLK_CONFIG_CONTEXT_PARAMETER_TYPE context)
124
124
  __contract__(
125
125
  requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
126
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
126
+ ensures(return_value == 0 || return_value == MLK_ERR_INVALID_SK ||
127
127
  return_value == MLK_ERR_OUT_OF_MEMORY)
128
128
  );
129
129
  #endif /* !MLK_CONFIG_NO_DECAPS_API */
@@ -145,9 +145,11 @@ __contract__(
145
145
  * MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
146
146
  *
147
147
  * @retval 0 Success.
148
- * @retval MLK_ERR_FAIL MLK_CONFIG_KEYGEN_PCT enabled and PCT failed.
148
+ * @retval MLK_ERR_PCT_FAIL MLK_CONFIG_KEYGEN_PCT enabled and PCT failed.
149
149
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
150
150
  * MLK_CUSTOM_ALLOC returned NULL.
151
+ * @retval MLK_ERR_RNG_FAIL MLK_CONFIG_KEYGEN_PCT enabled and random
152
+ * number generation failed within the PCT.
151
153
  */
152
154
  MLK_EXTERNAL_API
153
155
  MLK_MUST_CHECK_RETURN_VALUE
@@ -161,9 +163,14 @@ __contract__(
161
163
  requires(memory_no_alias(coins, 2 * MLKEM_SYMBYTES))
162
164
  assigns(memory_slice(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
163
165
  assigns(memory_slice(sk, MLKEM_INDCCA_SECRETKEYBYTES))
164
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
166
+ ensures(return_value == 0 || return_value == MLK_ERR_PCT_FAIL ||
165
167
  return_value == MLK_ERR_OUT_OF_MEMORY ||
166
168
  return_value == MLK_ERR_RNG_FAIL)
169
+ /* Output buffers on error, per API-CONVENTIONS.md */
170
+ ensures(return_value != 0 ==>
171
+ array_unchanged_or_zeroized_u8(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
172
+ ensures(return_value != 0 ==>
173
+ array_unchanged_or_zeroized_u8(sk, MLKEM_INDCCA_SECRETKEYBYTES))
167
174
  );
168
175
 
169
176
  #if !defined(MLK_CONFIG_NO_RANDOMIZED_API)
@@ -184,7 +191,7 @@ __contract__(
184
191
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
185
192
  * MLK_CUSTOM_ALLOC returned NULL.
186
193
  * @retval MLK_ERR_RNG_FAIL Random number generation failed.
187
- * @retval MLK_ERR_FAIL MLK_CONFIG_KEYGEN_PCT enabled and PCT failed.
194
+ * @retval MLK_ERR_PCT_FAIL MLK_CONFIG_KEYGEN_PCT enabled and PCT failed.
188
195
  */
189
196
  MLK_EXTERNAL_API
190
197
  MLK_MUST_CHECK_RETURN_VALUE
@@ -196,9 +203,14 @@ __contract__(
196
203
  requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
197
204
  assigns(memory_slice(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
198
205
  assigns(memory_slice(sk, MLKEM_INDCCA_SECRETKEYBYTES))
199
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
206
+ ensures(return_value == 0 || return_value == MLK_ERR_PCT_FAIL ||
200
207
  return_value == MLK_ERR_OUT_OF_MEMORY ||
201
208
  return_value == MLK_ERR_RNG_FAIL)
209
+ /* Output buffers on error, per API-CONVENTIONS.md */
210
+ ensures(return_value != 0 ==>
211
+ array_unchanged_or_zeroized_u8(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
212
+ ensures(return_value != 0 ==>
213
+ array_unchanged_or_zeroized_u8(sk, MLKEM_INDCCA_SECRETKEYBYTES))
202
214
  );
203
215
  #endif /* !MLK_CONFIG_NO_RANDOMIZED_API */
204
216
  #endif /* !MLK_CONFIG_NO_KEYPAIR_API */
@@ -221,7 +233,7 @@ __contract__(
221
233
  * MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
222
234
  *
223
235
  * @retval 0 Success.
224
- * @retval MLK_ERR_FAIL The 'modulus check' @[FIPS203, Section 7.2]
236
+ * @retval MLK_ERR_INVALID_PK The 'modulus check' @[FIPS203, Section 7.2]
225
237
  * for the public key failed.
226
238
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
227
239
  * MLK_CUSTOM_ALLOC returned NULL.
@@ -241,8 +253,13 @@ __contract__(
241
253
  requires(memory_no_alias(coins, MLKEM_SYMBYTES))
242
254
  assigns(memory_slice(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
243
255
  assigns(memory_slice(ss, MLKEM_SSBYTES))
244
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
256
+ ensures(return_value == 0 || return_value == MLK_ERR_INVALID_PK ||
245
257
  return_value == MLK_ERR_OUT_OF_MEMORY)
258
+ /* Output buffers on error, per API-CONVENTIONS.md */
259
+ ensures(return_value != 0 ==>
260
+ array_unchanged_or_zeroized_u8(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
261
+ ensures(return_value != 0 ==>
262
+ array_unchanged_or_zeroized_u8(ss, MLKEM_SSBYTES))
246
263
  );
247
264
 
248
265
  #if !defined(MLK_CONFIG_NO_RANDOMIZED_API)
@@ -265,7 +282,7 @@ __contract__(
265
282
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
266
283
  * MLK_CUSTOM_ALLOC returned NULL.
267
284
  * @retval MLK_ERR_RNG_FAIL Random number generation failed.
268
- * @retval MLK_ERR_FAIL The 'modulus check' @[FIPS203, Section 7.2]
285
+ * @retval MLK_ERR_INVALID_PK The 'modulus check' @[FIPS203, Section 7.2]
269
286
  * for the public key failed.
270
287
  */
271
288
  MLK_EXTERNAL_API
@@ -280,9 +297,14 @@ __contract__(
280
297
  requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES))
281
298
  assigns(memory_slice(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
282
299
  assigns(memory_slice(ss, MLKEM_SSBYTES))
283
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
300
+ ensures(return_value == 0 || return_value == MLK_ERR_INVALID_PK ||
284
301
  return_value == MLK_ERR_OUT_OF_MEMORY ||
285
302
  return_value == MLK_ERR_RNG_FAIL)
303
+ /* Output buffers on error, per API-CONVENTIONS.md */
304
+ ensures(return_value != 0 ==>
305
+ array_unchanged_or_zeroized_u8(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
306
+ ensures(return_value != 0 ==>
307
+ array_unchanged_or_zeroized_u8(ss, MLKEM_SSBYTES))
286
308
  );
287
309
  #endif /* !MLK_CONFIG_NO_RANDOMIZED_API */
288
310
  #endif /* !MLK_CONFIG_NO_ENCAPS_API */
@@ -303,7 +325,7 @@ __contract__(
303
325
  * MLK_CONFIG_CONTEXT_PARAMETER_TYPE.
304
326
  *
305
327
  * @retval 0 Success.
306
- * @retval MLK_ERR_FAIL The 'hash check' @[FIPS203, Section 7.3]
328
+ * @retval MLK_ERR_INVALID_SK The 'hash check' @[FIPS203, Section 7.3]
307
329
  * for the secret key failed.
308
330
  * @retval MLK_ERR_OUT_OF_MEMORY MLK_CONFIG_CUSTOM_ALLOC_FREE was used and
309
331
  * MLK_CUSTOM_ALLOC returned NULL.
@@ -320,8 +342,11 @@ __contract__(
320
342
  requires(memory_no_alias(ct, MLKEM_INDCCA_CIPHERTEXTBYTES))
321
343
  requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES))
322
344
  assigns(memory_slice(ss, MLKEM_SSBYTES))
323
- ensures(return_value == 0 || return_value == MLK_ERR_FAIL ||
345
+ ensures(return_value == 0 || return_value == MLK_ERR_INVALID_SK ||
324
346
  return_value == MLK_ERR_OUT_OF_MEMORY)
347
+ /* Output buffers on error, per API-CONVENTIONS.md */
348
+ ensures(return_value != 0 ==>
349
+ array_unchanged_or_zeroized_u8(ss, MLKEM_SSBYTES))
325
350
  );
326
351
  #endif /* !MLK_CONFIG_NO_DECAPS_API */
327
352
 
@@ -28,7 +28,7 @@
28
28
  MLK_MUST_CHECK_RETURN_VALUE
29
29
  static MLK_INLINE int mlk_ntt_native(int16_t data[MLKEM_N])
30
30
  {
31
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
31
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
32
32
  {
33
33
  return MLK_NATIVE_FUNC_FALLBACK;
34
34
  }
@@ -41,7 +41,7 @@ static MLK_INLINE int mlk_ntt_native(int16_t data[MLKEM_N])
41
41
  MLK_MUST_CHECK_RETURN_VALUE
42
42
  static MLK_INLINE int mlk_intt_native(int16_t data[MLKEM_N])
43
43
  {
44
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
44
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
45
45
  {
46
46
  return MLK_NATIVE_FUNC_FALLBACK;
47
47
  }
@@ -54,7 +54,7 @@ static MLK_INLINE int mlk_intt_native(int16_t data[MLKEM_N])
54
54
  MLK_MUST_CHECK_RETURN_VALUE
55
55
  static MLK_INLINE int mlk_poly_reduce_native(int16_t data[MLKEM_N])
56
56
  {
57
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
57
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
58
58
  {
59
59
  return MLK_NATIVE_FUNC_FALLBACK;
60
60
  }
@@ -66,7 +66,7 @@ static MLK_INLINE int mlk_poly_reduce_native(int16_t data[MLKEM_N])
66
66
  MLK_MUST_CHECK_RETURN_VALUE
67
67
  static MLK_INLINE int mlk_poly_tomont_native(int16_t data[MLKEM_N])
68
68
  {
69
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
69
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
70
70
  {
71
71
  return MLK_NATIVE_FUNC_FALLBACK;
72
72
  }
@@ -79,7 +79,7 @@ MLK_MUST_CHECK_RETURN_VALUE
79
79
  static MLK_INLINE int mlk_poly_mulcache_compute_native(int16_t x[MLKEM_N / 2],
80
80
  const int16_t y[MLKEM_N])
81
81
  {
82
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
82
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
83
83
  {
84
84
  return MLK_NATIVE_FUNC_FALLBACK;
85
85
  }
@@ -95,7 +95,7 @@ static MLK_INLINE int mlk_polyvec_basemul_acc_montgomery_cached_k2_native(
95
95
  int16_t r[MLKEM_N], const int16_t a[2 * MLKEM_N],
96
96
  const int16_t b[2 * MLKEM_N], const int16_t b_cache[2 * (MLKEM_N / 2)])
97
97
  {
98
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
98
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
99
99
  {
100
100
  return MLK_NATIVE_FUNC_FALLBACK;
101
101
  }
@@ -110,7 +110,7 @@ static MLK_INLINE int mlk_polyvec_basemul_acc_montgomery_cached_k3_native(
110
110
  int16_t r[MLKEM_N], const int16_t a[3 * MLKEM_N],
111
111
  const int16_t b[3 * MLKEM_N], const int16_t b_cache[3 * (MLKEM_N / 2)])
112
112
  {
113
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
113
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
114
114
  {
115
115
  return MLK_NATIVE_FUNC_FALLBACK;
116
116
  }
@@ -125,7 +125,7 @@ static MLK_INLINE int mlk_polyvec_basemul_acc_montgomery_cached_k4_native(
125
125
  int16_t r[MLKEM_N], const int16_t a[4 * MLKEM_N],
126
126
  const int16_t b[4 * MLKEM_N], const int16_t b_cache[4 * (MLKEM_N / 2)])
127
127
  {
128
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
128
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
129
129
  {
130
130
  return MLK_NATIVE_FUNC_FALLBACK;
131
131
  }
@@ -139,7 +139,7 @@ MLK_MUST_CHECK_RETURN_VALUE
139
139
  static MLK_INLINE int mlk_poly_tobytes_native(uint8_t r[MLKEM_POLYBYTES],
140
140
  const int16_t a[MLKEM_N])
141
141
  {
142
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON))
142
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON))
143
143
  {
144
144
  return MLK_NATIVE_FUNC_FALLBACK;
145
145
  }
@@ -153,7 +153,7 @@ static MLK_INLINE int mlk_rej_uniform_native(int16_t *r, unsigned len,
153
153
  const uint8_t *buf,
154
154
  unsigned buflen)
155
155
  {
156
- if (!mlk_sys_check_capability(MLK_SYS_CAP_NEON) || len != MLKEM_N ||
156
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_AARCH64_NEON) || len != MLKEM_N ||
157
157
  buflen % 24 != 0)
158
158
  {
159
159
  return MLK_NATIVE_FUNC_FALLBACK;
@@ -37,7 +37,7 @@
37
37
 
38
38
  static MLK_INLINE void mlk_poly_permute_bitrev_to_custom(int16_t data[MLKEM_N])
39
39
  {
40
- if (mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
40
+ if (mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
41
41
  {
42
42
  mlk_nttunpack_avx2_asm(data);
43
43
  }
@@ -48,7 +48,7 @@ static MLK_INLINE int mlk_rej_uniform_native(int16_t *r, unsigned len,
48
48
  const uint8_t *buf,
49
49
  unsigned buflen)
50
50
  {
51
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2) || len != MLKEM_N ||
51
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2) || len != MLKEM_N ||
52
52
  buflen % 12 != 0)
53
53
  {
54
54
  return MLK_NATIVE_FUNC_FALLBACK;
@@ -59,7 +59,7 @@ static MLK_INLINE int mlk_rej_uniform_native(int16_t *r, unsigned len,
59
59
  MLK_MUST_CHECK_RETURN_VALUE
60
60
  static MLK_INLINE int mlk_ntt_native(int16_t data[MLKEM_N])
61
61
  {
62
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
62
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
63
63
  {
64
64
  return MLK_NATIVE_FUNC_FALLBACK;
65
65
  }
@@ -72,7 +72,7 @@ static MLK_INLINE int mlk_ntt_native(int16_t data[MLKEM_N])
72
72
  MLK_MUST_CHECK_RETURN_VALUE
73
73
  static MLK_INLINE int mlk_intt_native(int16_t data[MLKEM_N])
74
74
  {
75
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
75
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
76
76
  {
77
77
  return MLK_NATIVE_FUNC_FALLBACK;
78
78
  }
@@ -85,7 +85,7 @@ static MLK_INLINE int mlk_intt_native(int16_t data[MLKEM_N])
85
85
  MLK_MUST_CHECK_RETURN_VALUE
86
86
  static MLK_INLINE int mlk_poly_reduce_native(int16_t data[MLKEM_N])
87
87
  {
88
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
88
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
89
89
  {
90
90
  return MLK_NATIVE_FUNC_FALLBACK;
91
91
  }
@@ -98,7 +98,7 @@ static MLK_INLINE int mlk_poly_reduce_native(int16_t data[MLKEM_N])
98
98
  MLK_MUST_CHECK_RETURN_VALUE
99
99
  static MLK_INLINE int mlk_poly_tomont_native(int16_t data[MLKEM_N])
100
100
  {
101
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
101
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
102
102
  {
103
103
  return MLK_NATIVE_FUNC_FALLBACK;
104
104
  }
@@ -112,7 +112,7 @@ MLK_MUST_CHECK_RETURN_VALUE
112
112
  static MLK_INLINE int mlk_poly_mulcache_compute_native(int16_t x[MLKEM_N / 2],
113
113
  const int16_t y[MLKEM_N])
114
114
  {
115
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
115
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
116
116
  {
117
117
  return MLK_NATIVE_FUNC_FALLBACK;
118
118
  }
@@ -127,7 +127,7 @@ static MLK_INLINE int mlk_polyvec_basemul_acc_montgomery_cached_k2_native(
127
127
  int16_t r[MLKEM_N], const int16_t a[2 * MLKEM_N],
128
128
  const int16_t b[2 * MLKEM_N], const int16_t b_cache[2 * (MLKEM_N / 2)])
129
129
  {
130
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
130
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
131
131
  {
132
132
  return MLK_NATIVE_FUNC_FALLBACK;
133
133
  }
@@ -143,7 +143,7 @@ static MLK_INLINE int mlk_polyvec_basemul_acc_montgomery_cached_k3_native(
143
143
  int16_t r[MLKEM_N], const int16_t a[3 * MLKEM_N],
144
144
  const int16_t b[3 * MLKEM_N], const int16_t b_cache[3 * (MLKEM_N / 2)])
145
145
  {
146
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
146
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
147
147
  {
148
148
  return MLK_NATIVE_FUNC_FALLBACK;
149
149
  }
@@ -159,7 +159,7 @@ static MLK_INLINE int mlk_polyvec_basemul_acc_montgomery_cached_k4_native(
159
159
  int16_t r[MLKEM_N], const int16_t a[4 * MLKEM_N],
160
160
  const int16_t b[4 * MLKEM_N], const int16_t b_cache[4 * (MLKEM_N / 2)])
161
161
  {
162
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
162
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
163
163
  {
164
164
  return MLK_NATIVE_FUNC_FALLBACK;
165
165
  }
@@ -174,7 +174,7 @@ MLK_MUST_CHECK_RETURN_VALUE
174
174
  static MLK_INLINE int mlk_poly_tobytes_native(uint8_t r[MLKEM_POLYBYTES],
175
175
  const int16_t a[MLKEM_N])
176
176
  {
177
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
177
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
178
178
  {
179
179
  return MLK_NATIVE_FUNC_FALLBACK;
180
180
  }
@@ -189,7 +189,7 @@ MLK_MUST_CHECK_RETURN_VALUE
189
189
  static MLK_INLINE int mlk_poly_frombytes_native(
190
190
  int16_t r[MLKEM_N], const uint8_t a[MLKEM_POLYBYTES])
191
191
  {
192
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
192
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
193
193
  {
194
194
  return MLK_NATIVE_FUNC_FALLBACK;
195
195
  }
@@ -207,7 +207,7 @@ MLK_MUST_CHECK_RETURN_VALUE
207
207
  static MLK_INLINE int mlk_poly_compress_d4_native(
208
208
  uint8_t r[MLKEM_POLYCOMPRESSEDBYTES_D4], const int16_t a[MLKEM_N])
209
209
  {
210
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
210
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
211
211
  {
212
212
  return MLK_NATIVE_FUNC_FALLBACK;
213
213
  }
@@ -220,7 +220,7 @@ MLK_MUST_CHECK_RETURN_VALUE
220
220
  static MLK_INLINE int mlk_poly_compress_d10_native(
221
221
  uint8_t r[MLKEM_POLYCOMPRESSEDBYTES_D10], const int16_t a[MLKEM_N])
222
222
  {
223
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
223
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
224
224
  {
225
225
  return MLK_NATIVE_FUNC_FALLBACK;
226
226
  }
@@ -234,7 +234,7 @@ MLK_MUST_CHECK_RETURN_VALUE
234
234
  static MLK_INLINE int mlk_poly_decompress_d4_native(
235
235
  int16_t r[MLKEM_N], const uint8_t a[MLKEM_POLYCOMPRESSEDBYTES_D4])
236
236
  {
237
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
237
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
238
238
  {
239
239
  return MLK_NATIVE_FUNC_FALLBACK;
240
240
  }
@@ -247,7 +247,7 @@ MLK_MUST_CHECK_RETURN_VALUE
247
247
  static MLK_INLINE int mlk_poly_decompress_d10_native(
248
248
  int16_t r[MLKEM_N], const uint8_t a[MLKEM_POLYCOMPRESSEDBYTES_D10])
249
249
  {
250
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
250
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
251
251
  {
252
252
  return MLK_NATIVE_FUNC_FALLBACK;
253
253
  }
@@ -267,7 +267,7 @@ MLK_MUST_CHECK_RETURN_VALUE
267
267
  static MLK_INLINE int mlk_poly_compress_d5_native(
268
268
  uint8_t r[MLKEM_POLYCOMPRESSEDBYTES_D5], const int16_t a[MLKEM_N])
269
269
  {
270
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
270
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
271
271
  {
272
272
  return MLK_NATIVE_FUNC_FALLBACK;
273
273
  }
@@ -280,7 +280,7 @@ MLK_MUST_CHECK_RETURN_VALUE
280
280
  static MLK_INLINE int mlk_poly_compress_d11_native(
281
281
  uint8_t r[MLKEM_POLYCOMPRESSEDBYTES_D11], const int16_t a[MLKEM_N])
282
282
  {
283
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
283
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
284
284
  {
285
285
  return MLK_NATIVE_FUNC_FALLBACK;
286
286
  }
@@ -294,7 +294,7 @@ MLK_MUST_CHECK_RETURN_VALUE
294
294
  static MLK_INLINE int mlk_poly_decompress_d5_native(
295
295
  int16_t r[MLKEM_N], const uint8_t a[MLKEM_POLYCOMPRESSEDBYTES_D5])
296
296
  {
297
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
297
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
298
298
  {
299
299
  return MLK_NATIVE_FUNC_FALLBACK;
300
300
  }
@@ -307,7 +307,7 @@ MLK_MUST_CHECK_RETURN_VALUE
307
307
  static MLK_INLINE int mlk_poly_decompress_d11_native(
308
308
  int16_t r[MLKEM_N], const uint8_t a[MLKEM_POLYCOMPRESSEDBYTES_D11])
309
309
  {
310
- if (!mlk_sys_check_capability(MLK_SYS_CAP_AVX2))
310
+ if (!mlk_sys_check_capability(MLK_SYS_CAP_X86_64_AVX2))
311
311
  {
312
312
  return MLK_NATIVE_FUNC_FALLBACK;
313
313
  }
@@ -210,7 +210,7 @@
210
210
  #endif
211
211
 
212
212
 
213
- /* New X86_64 CPUs support Conflow-flow protection using the CET instructions.
213
+ /* New X86_64 CPUs support control-flow protection using the CET instructions.
214
214
  * When enabled (through -fcf-protection=), all compilation units (including
215
215
  * empty ones) need to support CET for this to work.
216
216
  * For assembly, this means that source files need to signal support for
@@ -288,12 +288,12 @@
288
288
  typedef enum
289
289
  {
290
290
  /* x86_64 */
291
- MLK_SYS_CAP_AVX2,
291
+ MLK_SYS_CAP_X86_64_AVX2,
292
292
  /* AArch64 */
293
- MLK_SYS_CAP_NEON,
294
- MLK_SYS_CAP_SHA3,
293
+ MLK_SYS_CAP_AARCH64_NEON,
294
+ MLK_SYS_CAP_AARCH64_SHA3,
295
295
  /* Armv8.1-M */
296
- MLK_SYS_CAP_MVE
296
+ MLK_SYS_CAP_ARMV81M_MVE
297
297
  } mlk_sys_cap;
298
298
 
299
299
  #if !defined(MLK_CONFIG_CUSTOM_CAPABILITY_FUNC)
@@ -419,17 +419,20 @@ __contract__(
419
419
  #if !defined(MLK_CONFIG_CUSTOM_ZEROIZE)
420
420
  #if defined(MLK_SYS_WINDOWS)
421
421
  #include <windows.h>
422
+ #elif !defined(MLK_HAVE_INLINE_ASM)
423
+ #error No plausibly-secure implementation of mlk_zeroize available. Please provide your own using MLK_CONFIG_CUSTOM_ZEROIZE.
424
+ #endif
425
+
422
426
  static MLK_INLINE void mlk_zeroize(void *ptr, size_t len)
423
427
  __contract__(
428
+ requires(len <= UINT32_MAX)
424
429
  requires(memory_no_alias(ptr, len))
425
- assigns(memory_slice(ptr, len))) { SecureZeroMemory(ptr, len); }
426
- #elif defined(MLK_HAVE_INLINE_ASM)
427
- #include <string.h>
428
- static MLK_INLINE void mlk_zeroize(void *ptr, size_t len)
429
- __contract__(
430
- requires(memory_no_alias(ptr, len))
431
- assigns(memory_slice(ptr, len)))
430
+ assigns(memory_slice(ptr, len))
431
+ ensures(array_zeroized_u8((uint8_t *)ptr, len)))
432
432
  {
433
+ #if defined(MLK_SYS_WINDOWS)
434
+ SecureZeroMemory(ptr, len);
435
+ #else
433
436
  mlk_memset(ptr, 0, len);
434
437
  /* This follows OpenSSL and seems sufficient to prevent the compiler
435
438
  * from optimizing away the memset.
@@ -437,10 +440,8 @@ __contract__(
437
440
  * If there was a reliable way to detect availability of memset_s(),
438
441
  * that would be preferred. */
439
442
  __asm__ volatile("" : : "r"(ptr) : "memory");
443
+ #endif /* !MLK_SYS_WINDOWS */
440
444
  }
441
- #else /* !MLK_SYS_WINDOWS && MLK_HAVE_INLINE_ASM */
442
- #error No plausibly-secure implementation of mlk_zeroize available. Please provide your own using MLK_CONFIG_CUSTOM_ZEROIZE.
443
- #endif /* !MLK_SYS_WINDOWS && !MLK_HAVE_INLINE_ASM */
444
445
  #endif /* !MLK_CONFIG_CUSTOM_ZEROIZE */
445
446
 
446
447
  #endif /* !MLK_VERIFY_H */
@@ -8,6 +8,16 @@ module PQCrypto
8
8
  String(value).b
9
9
  end
10
10
 
11
+ def frozen_binary_string(value)
12
+ binary_string(value).freeze
13
+ end
14
+
15
+ def strict_boolean!(value, name:)
16
+ return value if value.equal?(true) || value.equal?(false)
17
+
18
+ raise ArgumentError, "#{name} must be true or false (got #{value.inspect})"
19
+ end
20
+
11
21
  def safe_wipe(value)
12
22
  return unless value.is_a?(String) && !value.frozen?
13
23