pq_crypto 0.6.4 → 0.6.6

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 (213) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +180 -0
  3. data/README.md +7 -0
  4. data/ext/pqcrypto/extconf.rb +4 -1
  5. data/ext/pqcrypto/pq_externalmu.c +35 -0
  6. data/ext/pqcrypto/pqcrypto_native_api.h +85 -75
  7. data/ext/pqcrypto/pqcrypto_ruby_secure.c +16 -9
  8. data/ext/pqcrypto/pqcrypto_secure.c +43 -33
  9. data/ext/pqcrypto/pqcrypto_secure.h +52 -47
  10. data/ext/pqcrypto/pqcrypto_version.h +1 -1
  11. data/ext/pqcrypto/vendor/.vendored +7 -7
  12. data/ext/pqcrypto/vendor/mldsa-native/BUILDING.md +5 -2
  13. data/ext/pqcrypto/vendor/mldsa-native/LICENSE +21 -2
  14. data/ext/pqcrypto/vendor/mldsa-native/README.md +20 -7
  15. data/ext/pqcrypto/vendor/mldsa-native/RELEASE.md +160 -0
  16. data/ext/pqcrypto/vendor/mldsa-native/SECURITY.md +1 -1
  17. data/ext/pqcrypto/vendor/mldsa-native/mldsa/README.md +2 -2
  18. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +85 -59
  19. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +292 -348
  20. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +122 -76
  21. data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +184 -86
  22. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +49 -4
  23. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +49 -81
  24. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/context.h +152 -0
  25. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +25 -12
  26. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.c +2 -0
  27. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +2 -0
  28. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +2 -2
  29. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +9 -11
  30. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +19 -11
  31. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +6 -4
  32. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +7 -4
  33. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +7 -4
  34. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +12 -9
  35. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +12 -9
  36. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +1 -1
  37. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +3 -2
  38. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +3 -2
  39. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +6 -1
  40. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +3 -2
  41. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +11 -11
  42. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +9 -22
  43. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +8 -5
  44. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +1 -0
  45. 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
  46. 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
  47. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +5 -4
  48. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
  49. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +1 -0
  50. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +36 -2
  51. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +62 -4
  52. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +87 -54
  53. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{intt_aarch64_asm.S → mldsa_intt_aarch64_asm.S} +39 -6
  54. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{ntt_aarch64_asm.S → mldsa_ntt_aarch64_asm.S} +39 -6
  55. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{pointwise_montgomery_aarch64_asm.S → mldsa_pointwise_montgomery_aarch64_asm.S} +25 -3
  56. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_caddq_aarch64_asm.S → mldsa_poly_caddq_aarch64_asm.S} +19 -3
  57. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_chknorm_aarch64_asm.S → mldsa_poly_chknorm_aarch64_asm.S} +24 -3
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. 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
  65. 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
  66. 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
  67. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{rej_uniform_aarch64_asm.S → mldsa_rej_uniform_aarch64_asm.S} +48 -15
  68. 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
  69. 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
  70. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +11 -3
  71. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/meta.h +3 -2
  72. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +28 -28
  73. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +171 -49
  74. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{intt_avx2_asm.S → mldsa_intt_avx2_asm.S} +23 -1
  75. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{ntt_avx2_asm.S → mldsa_ntt_avx2_asm.S} +23 -1
  76. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{nttunpack_avx2_asm.S → mldsa_nttunpack_avx2_asm.S} +17 -1
  77. 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
  78. 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
  79. 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
  80. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{pointwise_avx2_asm.S → mldsa_pointwise_avx2_asm.S} +31 -3
  81. 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
  82. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_chknorm_avx2_asm.S +176 -0
  83. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_32_avx2_asm.S +490 -0
  84. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_88_avx2_asm.S +489 -0
  85. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_32_avx2_asm.S +123 -0
  86. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_88_avx2_asm.S +125 -0
  87. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_17_avx2_asm.S +355 -0
  88. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_19_avx2_asm.S +355 -0
  89. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_avx2_asm.S +132 -0
  90. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta2_avx2_asm.S +205 -0
  91. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta4_avx2_asm.S +176 -0
  92. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +27 -36
  93. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +42 -8
  94. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/params.h +93 -17
  95. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +74 -15
  96. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +97 -11
  97. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +7 -38
  98. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +49 -7
  99. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +16 -17
  100. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +26 -9
  101. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +3 -0
  102. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +18 -19
  103. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +15 -3
  104. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +28 -6
  105. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +311 -246
  106. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +245 -240
  107. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sys.h +64 -5
  108. data/ext/pqcrypto/vendor/mlkem-native/BUILDING.md +5 -2
  109. data/ext/pqcrypto/vendor/mlkem-native/LICENSE +21 -3
  110. data/ext/pqcrypto/vendor/mlkem-native/README.md +4 -6
  111. data/ext/pqcrypto/vendor/mlkem-native/RELEASE.md +211 -0
  112. data/ext/pqcrypto/vendor/mlkem-native/mlkem/README.md +2 -2
  113. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.c +25 -34
  114. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.h +79 -142
  115. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_asm.S +62 -71
  116. data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_config.h +77 -39
  117. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/cbmc.h +25 -0
  118. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/common.h +48 -34
  119. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/compress.c +25 -5
  120. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/compress.h +14 -0
  121. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/context.h +51 -0
  122. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.h +2 -2
  123. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/keccakf1600.c +8 -8
  124. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/auto.h +20 -12
  125. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +5 -3
  126. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +5 -2
  127. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +5 -2
  128. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +10 -7
  129. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +10 -7
  130. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_scalar.h +1 -1
  131. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_v84a.h +3 -2
  132. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x2_v84a.h +3 -2
  133. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_scalar.h +6 -1
  134. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +3 -2
  135. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/api.h +11 -11
  136. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/mve.h +8 -22
  137. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +8 -5
  138. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/{state_extract_bytes_x4_mve.S → keccak_f1600_x4_state_extract_bytes_mve.S} +14 -14
  139. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/src/{state_xor_bytes_x4_mve.S → keccak_f1600_x4_state_xor_bytes_mve.S} +12 -12
  140. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
  141. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +36 -2
  142. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.c +22 -0
  143. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.h +20 -11
  144. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.c +39 -11
  145. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.h +64 -15
  146. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/meta.h +44 -2
  147. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/aarch64_zetas.c +2 -0
  148. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/arith_native_aarch64.h +11 -10
  149. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{intt_aarch64_asm.S → mlkem_intt_aarch64_asm.S} +16 -9
  150. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{ntt_aarch64_asm.S → mlkem_ntt_aarch64_asm.S} +10 -7
  151. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_mulcache_compute_aarch64_asm.S → mlkem_poly_mulcache_compute_aarch64_asm.S} +6 -3
  152. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_reduce_aarch64_asm.S → mlkem_poly_reduce_aarch64_asm.S} +6 -3
  153. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_tobytes_aarch64_asm.S → mlkem_poly_tobytes_aarch64_asm.S} +12 -5
  154. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{poly_tomont_aarch64_asm.S → mlkem_poly_tomont_aarch64_asm.S} +11 -5
  155. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{polyvec_basemul_acc_montgomery_cached_k2_aarch64_asm.S → mlkem_polyvec_basemul_acc_montgomery_cached_k2_aarch64_asm.S} +6 -3
  156. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{polyvec_basemul_acc_montgomery_cached_k3_aarch64_asm.S → mlkem_polyvec_basemul_acc_montgomery_cached_k3_aarch64_asm.S} +6 -3
  157. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{polyvec_basemul_acc_montgomery_cached_k4_aarch64_asm.S → mlkem_polyvec_basemul_acc_montgomery_cached_k4_aarch64_asm.S} +6 -3
  158. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/src/{rej_uniform_aarch64_asm.S → mlkem_rej_uniform_aarch64_asm.S} +17 -17
  159. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/api.h +21 -8
  160. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/meta.h +1 -1
  161. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/meta.h +4 -0
  162. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/{intt_ppc_asm.S → mlkem_intt_ppc_asm.S} +29 -5
  163. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/{ntt_ppc_asm.S → mlkem_ntt_ppc_asm.S} +22 -1
  164. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/{poly_tomont_ppc_asm.S → mlkem_poly_tomont_ppc_asm.S} +25 -3
  165. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/ppc64le/src/{reduce_ppc_asm.S → mlkem_reduce_ppc_asm.S} +22 -1
  166. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/meta.h +4 -0
  167. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/arith_native_riscv64.h +4 -0
  168. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/riscv64/src/rv64v_poly.c +6 -2
  169. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/meta.h +45 -25
  170. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/arith_native_x86_64.h +20 -20
  171. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/compress_consts.c +14 -3
  172. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/compress_consts.h +8 -0
  173. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{intt_avx2_asm.S → mlkem_intt_avx2_asm.S} +27 -3
  174. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{ntt_avx2_asm.S → mlkem_ntt_avx2_asm.S} +23 -1
  175. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{nttfrombytes_avx2_asm.S → mlkem_nttfrombytes_avx2_asm.S} +27 -3
  176. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{ntttobytes_avx2_asm.S → mlkem_ntttobytes_avx2_asm.S} +27 -3
  177. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{nttunpack_avx2_asm.S → mlkem_nttunpack_avx2_asm.S} +17 -1
  178. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d10_avx2_asm.S → mlkem_poly_compress_d10_avx2_asm.S} +34 -3
  179. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d11_avx2_asm.S → mlkem_poly_compress_d11_avx2_asm.S} +33 -2
  180. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d4_avx2_asm.S → mlkem_poly_compress_d4_avx2_asm.S} +34 -3
  181. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_compress_d5_avx2_asm.S → mlkem_poly_compress_d5_avx2_asm.S} +33 -2
  182. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d10_avx2_asm.S → mlkem_poly_decompress_d10_avx2_asm.S} +32 -3
  183. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d11_avx2_asm.S → mlkem_poly_decompress_d11_avx2_asm.S} +32 -2
  184. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d4_avx2_asm.S → mlkem_poly_decompress_d4_avx2_asm.S} +32 -3
  185. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_decompress_d5_avx2_asm.S → mlkem_poly_decompress_d5_avx2_asm.S} +32 -2
  186. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{poly_mulcache_compute_avx2_asm.S → mlkem_poly_mulcache_compute_avx2_asm.S} +29 -1
  187. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{polyvec_basemul_acc_montgomery_cached_k2_avx2_asm.S → mlkem_polyvec_basemul_acc_montgomery_cached_k2_avx2_asm.S} +35 -1
  188. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{polyvec_basemul_acc_montgomery_cached_k3_avx2_asm.S → mlkem_polyvec_basemul_acc_montgomery_cached_k3_avx2_asm.S} +35 -1
  189. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{polyvec_basemul_acc_montgomery_cached_k4_avx2_asm.S → mlkem_polyvec_basemul_acc_montgomery_cached_k4_avx2_asm.S} +35 -1
  190. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{reduce_avx2_asm.S → mlkem_reduce_avx2_asm.S} +17 -1
  191. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{rej_uniform_avx2_asm.S → mlkem_rej_uniform_avx2_asm.S} +40 -7
  192. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/src/{tomont_avx2_asm.S → mlkem_tomont_avx2_asm.S} +20 -3
  193. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly.c +7 -2
  194. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly.h +6 -0
  195. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly_k.c +25 -4
  196. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/poly_k.h +33 -4
  197. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sampling.c +4 -0
  198. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sampling.h +4 -0
  199. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sys.h +21 -3
  200. data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/verify.h +11 -10
  201. data/lib/pq_crypto/version.rb +1 -1
  202. data/script/vendor_libs.rb +6 -6
  203. metadata +79 -79
  204. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_chknorm_avx2.c +0 -52
  205. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +0 -157
  206. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +0 -157
  207. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +0 -103
  208. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +0 -105
  209. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +0 -94
  210. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +0 -96
  211. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_avx2.c +0 -126
  212. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +0 -157
  213. data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +0 -141
@@ -38,7 +38,7 @@
38
38
  #endif
39
39
 
40
40
  #if MLDSA_CRYPTO_BYTES != MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)
41
- #error Mismatch for CRYPTO_BYTES between sign.h and mldsa_native.h
41
+ #error Mismatch for BYTES between sign.h and mldsa_native.h
42
42
  #endif
43
43
 
44
44
  #endif /* MLD_CHECK_APIS */
@@ -47,25 +47,23 @@
47
47
  MLD_NAMESPACE_KL(keypair_internal) MLD_CONTEXT_PARAMETERS_3
48
48
  #define mld_sign_keypair MLD_NAMESPACE_KL(keypair) MLD_CONTEXT_PARAMETERS_2
49
49
  #define mld_sign_signature_internal \
50
- MLD_NAMESPACE_KL(signature_internal) MLD_CONTEXT_PARAMETERS_9
51
- #define mld_sign_signature MLD_NAMESPACE_KL(signature) MLD_CONTEXT_PARAMETERS_7
50
+ MLD_NAMESPACE_KL(signature_internal) MLD_CONTEXT_PARAMETERS_8
51
+ #define mld_sign_signature MLD_NAMESPACE_KL(signature) MLD_CONTEXT_PARAMETERS_6
52
52
  #define mld_sign_signature_extmu \
53
- MLD_NAMESPACE_KL(signature_extmu) MLD_CONTEXT_PARAMETERS_4
54
- #define mld_sign MLD_NAMESPACE_KL(sign) MLD_CONTEXT_PARAMETERS_7
53
+ MLD_NAMESPACE_KL(signature_extmu) MLD_CONTEXT_PARAMETERS_3
55
54
  #define mld_sign_verify_internal \
56
- MLD_NAMESPACE_KL(verify_internal) MLD_CONTEXT_PARAMETERS_8
57
- #define mld_sign_verify MLD_NAMESPACE_KL(verify) MLD_CONTEXT_PARAMETERS_7
55
+ MLD_NAMESPACE_KL(verify_internal) MLD_CONTEXT_PARAMETERS_7
56
+ #define mld_sign_verify MLD_NAMESPACE_KL(verify) MLD_CONTEXT_PARAMETERS_6
58
57
  #define mld_sign_verify_extmu \
59
- MLD_NAMESPACE_KL(verify_extmu) MLD_CONTEXT_PARAMETERS_4
60
- #define mld_sign_open MLD_NAMESPACE_KL(open) MLD_CONTEXT_PARAMETERS_7
58
+ MLD_NAMESPACE_KL(verify_extmu) MLD_CONTEXT_PARAMETERS_3
61
59
  #define mld_sign_signature_pre_hash_internal \
62
- MLD_NAMESPACE_KL(signature_pre_hash_internal) MLD_CONTEXT_PARAMETERS_9
60
+ MLD_NAMESPACE_KL(signature_pre_hash_internal) MLD_CONTEXT_PARAMETERS_8
63
61
  #define mld_sign_verify_pre_hash_internal \
64
- MLD_NAMESPACE_KL(verify_pre_hash_internal) MLD_CONTEXT_PARAMETERS_8
62
+ MLD_NAMESPACE_KL(verify_pre_hash_internal) MLD_CONTEXT_PARAMETERS_7
65
63
  #define mld_sign_signature_pre_hash_shake256 \
66
- MLD_NAMESPACE_KL(signature_pre_hash_shake256) MLD_CONTEXT_PARAMETERS_8
64
+ MLD_NAMESPACE_KL(signature_pre_hash_shake256) MLD_CONTEXT_PARAMETERS_7
67
65
  #define mld_sign_verify_pre_hash_shake256 \
68
- MLD_NAMESPACE_KL(verify_pre_hash_shake256) MLD_CONTEXT_PARAMETERS_7
66
+ MLD_NAMESPACE_KL(verify_pre_hash_shake256) MLD_CONTEXT_PARAMETERS_6
69
67
  #define mld_prepare_domain_separation_prefix \
70
68
  MLD_NAMESPACE_KL(prepare_domain_separation_prefix)
71
69
  #define mld_sign_pk_from_sk \
@@ -93,7 +91,7 @@
93
91
  * When MLD_CONFIG_KEYGEN_PCT is set, performs a Pairwise Consistency Test
94
92
  * (PCT) as required by FIPS 140-3 IG.
95
93
  *
96
- * @spec{Implements @[FIPS204 Algorithm 6 (ML-DSA.KeyGen_internal)].}
94
+ * @spec{Implements @[FIPS204, Algorithm 6, ML-DSA.KeyGen_internal].}
97
95
  *
98
96
  * @param[out] pk Output public key.
99
97
  * @param[out] sk Output private key.
@@ -106,14 +104,19 @@
106
104
  * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
107
105
  * used and an allocation via
108
106
  * MLD_CUSTOM_ALLOC returned NULL.
109
- * @retval MLD_ERR_RNG_FAIL Random number generation failed.
110
- * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The PCT's signing step exhausted
111
- * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
112
- * iterations. Only possible when
113
- * MLD_CONFIG_KEYGEN_PCT is enabled.
114
- * @retval MLD_ERR_FAIL Other kinds of failure, including
115
- * PCT failure if
107
+ * @retval MLD_ERR_RNG_FAIL Random number generation failed
108
+ * during the PCT. Only possible when
116
109
  * MLD_CONFIG_KEYGEN_PCT is enabled.
110
+ * @retval MLD_ERR_SIGNING_PAUSED The PCT's signing step was paused by
111
+ * a MLD_CONFIG_SIGN_HOOK_ATTEMPT hook.
112
+ * This should currently never happen:
113
+ * signing hooks require
114
+ * MLD_CONFIG_NO_RANDOMIZED_API, which
115
+ * is incompatible with
116
+ * MLD_CONFIG_KEYGEN_PCT, so the two
117
+ * cannot be enabled simultaneously.
118
+ * @retval MLD_ERR_PCT_FAIL MLD_CONFIG_KEYGEN_PCT is enabled and
119
+ * the PCT check failed.
117
120
  */
118
121
  MLD_MUST_CHECK_RETURN_VALUE
119
122
  MLD_EXTERNAL_API
@@ -127,17 +130,26 @@ __contract__(
127
130
  requires(memory_no_alias(seed, MLDSA_SEEDBYTES))
128
131
  assigns(object_whole(pk))
129
132
  assigns(object_whole(sk))
130
- ensures(return_value == 0 || MLD_ANY_ERROR(return_value))
133
+ ensures(return_value == 0 || return_value == MLD_ERR_OUT_OF_MEMORY ||
134
+ return_value == MLD_ERR_RNG_FAIL ||
135
+ return_value == MLD_ERR_SIGNING_PAUSED ||
136
+ return_value == MLD_ERR_PCT_FAIL)
137
+ /* Output buffers on error, per API-CONVENTIONS.md */
138
+ ensures(return_value != 0 ==>
139
+ array_unchanged_or_zeroized_u8(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
140
+ ensures(return_value != 0 ==>
141
+ array_unchanged_or_zeroized_u8(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
131
142
  );
132
143
 
133
144
  #if !defined(MLD_CONFIG_CORE_API_ONLY)
145
+ #if !defined(MLD_CONFIG_NO_RANDOMIZED_API)
134
146
  /**
135
147
  * Generate a public-private key pair.
136
148
  *
137
149
  * When MLD_CONFIG_KEYGEN_PCT is set, performs a Pairwise Consistency Test
138
150
  * (PCT) as required by FIPS 140-3 IG.
139
151
  *
140
- * @spec{Implements @[FIPS204 Algorithm 1 (ML-DSA.KeyGen)].}
152
+ * @spec{Implements @[FIPS204, Algorithm 1, ML-DSA.KeyGen].}
141
153
  *
142
154
  * @param[out] pk Output public key.
143
155
  * @param[out] sk Output private key.
@@ -150,13 +162,16 @@ __contract__(
150
162
  * used and an allocation via
151
163
  * MLD_CUSTOM_ALLOC returned NULL.
152
164
  * @retval MLD_ERR_RNG_FAIL Random number generation failed.
153
- * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The PCT's signing step exhausted
154
- * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
155
- * iterations. Only possible when
156
- * MLD_CONFIG_KEYGEN_PCT is enabled.
157
- * @retval MLD_ERR_FAIL Other kinds of failure, including
158
- * PCT failure if
159
- * MLD_CONFIG_KEYGEN_PCT is enabled.
165
+ * @retval MLD_ERR_SIGNING_PAUSED The PCT's signing step was paused by
166
+ * a MLD_CONFIG_SIGN_HOOK_ATTEMPT hook.
167
+ * This should currently never happen:
168
+ * signing hooks require
169
+ * MLD_CONFIG_NO_RANDOMIZED_API, which
170
+ * is incompatible with
171
+ * MLD_CONFIG_KEYGEN_PCT, so the two
172
+ * cannot be enabled simultaneously.
173
+ * @retval MLD_ERR_PCT_FAIL MLD_CONFIG_KEYGEN_PCT is enabled and
174
+ * the PCT check failed.
160
175
  */
161
176
  MLD_MUST_CHECK_RETURN_VALUE
162
177
  MLD_EXTERNAL_API
@@ -168,20 +183,34 @@ __contract__(
168
183
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
169
184
  assigns(object_whole(pk))
170
185
  assigns(object_whole(sk))
171
- ensures(return_value == 0 || MLD_ANY_ERROR(return_value))
186
+ ensures(return_value == 0 || return_value == MLD_ERR_OUT_OF_MEMORY ||
187
+ return_value == MLD_ERR_RNG_FAIL ||
188
+ return_value == MLD_ERR_SIGNING_PAUSED ||
189
+ return_value == MLD_ERR_PCT_FAIL)
190
+ /* Output buffers on error, per API-CONVENTIONS.md */
191
+ ensures(return_value != 0 ==>
192
+ array_unchanged_or_zeroized_u8(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
193
+ ensures(return_value != 0 ==>
194
+ array_unchanged_or_zeroized_u8(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
172
195
  );
196
+ #endif /* !MLD_CONFIG_NO_RANDOMIZED_API */
173
197
  #endif /* !MLD_CONFIG_CORE_API_ONLY */
174
198
  #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
175
199
 
176
200
  #if !defined(MLD_CONFIG_NO_SIGN_API)
177
201
  /**
178
- * Compute signature using internal randomness.
202
+ * Compute signature using a caller-supplied random seed and prefix.
179
203
  *
180
- * If the returned value is non-zero, then the values of *sig and *siglen
181
- * should not be referenced.
204
+ * On error (non-zero return value), the signature buffer sig is zeroized.
182
205
  *
183
- * @param[out] sig Output signature.
184
- * @param[out] siglen Pointer to output length of signature.
206
+ * @spec{Implements @[FIPS204, Algorithm 7, ML-DSA.Sign_internal].}
207
+ *
208
+ * @warning This function does not perform secret key validation.
209
+ * Callers importing serialized keys can use mld_sign_pk_from_sk
210
+ * to validate them before signing.
211
+ *
212
+ * @param[out] sig Pointer to buffer to hold the generated signature of
213
+ * MLDSA_CRYPTO_BYTES bytes.
185
214
  * @param[in] m Pointer to message to be signed (when
186
215
  * externalmu == 0), or to a precomputed
187
216
  * message representative mu (when externalmu != 0).
@@ -192,7 +221,7 @@ __contract__(
192
221
  * @param prelen Length of prefix string. Ignored when
193
222
  * externalmu != 0.
194
223
  * @param[in] rnd Random seed.
195
- * @param[in] sk Bit-packed secret key.
224
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
196
225
  * @param externalmu 0: m/mlen is the raw message; mu = H(tr, pre, m) is
197
226
  * computed internally.
198
227
  * non-zero: m points to a precomputed mu of
@@ -208,11 +237,12 @@ __contract__(
208
237
  * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
209
238
  * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
210
239
  * iterations.
211
- * @retval MLD_ERR_FAIL Other kinds of failure.
240
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
241
+ * paused signing; re-invoke to resume.
212
242
  */
213
243
  MLD_MUST_CHECK_RETURN_VALUE
214
244
  MLD_EXTERNAL_API
215
- int mld_sign_signature_internal(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen,
245
+ int mld_sign_signature_internal(uint8_t sig[MLDSA_CRYPTO_BYTES],
216
246
  const uint8_t *m, size_t mlen,
217
247
  const uint8_t *pre, size_t prelen,
218
248
  const uint8_t rnd[MLDSA_RNDBYTES],
@@ -223,36 +253,39 @@ __contract__(
223
253
  requires(mlen <= MLD_MAX_BUFFER_SIZE)
224
254
  requires(prelen <= MLD_MAX_BUFFER_SIZE)
225
255
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
226
- requires(memory_no_alias(siglen, sizeof(size_t)))
227
256
  requires(memory_no_alias(m, mlen))
228
257
  requires(memory_no_alias(rnd, MLDSA_RNDBYTES))
229
258
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
230
259
  requires((externalmu == 0) ==> ((prelen == 0) || memory_no_alias(pre, prelen)))
231
260
  requires((externalmu != 0) ==> (mlen == MLDSA_CRHBYTES))
232
261
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
233
- assigns(object_whole(siglen))
234
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL ||
262
+ ensures(return_value == 0 ||
235
263
  return_value == MLD_ERR_OUT_OF_MEMORY ||
236
- return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED)
237
- ensures(return_value == 0 ==> *siglen == MLDSA_CRYPTO_BYTES)
238
- ensures(return_value != 0 ==> *siglen == 0)
239
- );
264
+ return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED ||
265
+ return_value == MLD_ERR_SIGNING_PAUSED)
266
+ /* Output buffers on error, per API-CONVENTIONS.md */
267
+ ensures(return_value != 0 ==>
268
+ array_unchanged_or_zeroized_u8(sig, MLDSA_CRYPTO_BYTES)));
240
269
 
241
270
  #if !defined(MLD_CONFIG_CORE_API_ONLY)
271
+ #if !defined(MLD_CONFIG_NO_RANDOMIZED_API)
242
272
  /**
243
273
  * Compute signature. This function implements the randomized variant of
244
274
  * ML-DSA. If you require the deterministic variant, use
245
275
  * mld_sign_signature_internal directly.
246
276
  *
247
- * @spec{Implements @[FIPS204 Algorithm 2 (ML-DSA.Sign)].}
277
+ * @spec{Implements @[FIPS204, Algorithm 2, ML-DSA.Sign].}
278
+ *
279
+ * @warning This function does not perform secret key validation.
280
+ * Callers importing serialized keys can use mld_sign_pk_from_sk
281
+ * to validate them before signing.
248
282
  *
249
283
  * @param[out] sig Output signature.
250
- * @param[out] siglen Pointer to output length of signature.
251
284
  * @param[in] m Pointer to message to be signed.
252
285
  * @param mlen Length of message.
253
286
  * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
254
287
  * @param ctxlen Length of context string. Should be <= 255.
255
- * @param[in] sk Bit-packed secret key.
288
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
256
289
  * @param context Application context. Only present when
257
290
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
258
291
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
@@ -265,27 +298,34 @@ __contract__(
265
298
  * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
266
299
  * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
267
300
  * iterations.
268
- * @retval MLD_ERR_FAIL Other kinds of failure.
301
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
302
+ * paused signing; re-invoke to resume.
303
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255
304
+ * bytes.
269
305
  */
270
306
  MLD_MUST_CHECK_RETURN_VALUE
271
307
  MLD_EXTERNAL_API
272
- int mld_sign_signature(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen,
273
- const uint8_t *m, size_t mlen, const uint8_t *ctx,
274
- size_t ctxlen,
308
+ int mld_sign_signature(uint8_t sig[MLDSA_CRYPTO_BYTES], const uint8_t *m,
309
+ size_t mlen, const uint8_t *ctx, size_t ctxlen,
275
310
  const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
276
311
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
277
312
  __contract__(
278
313
  requires(mlen <= MLD_MAX_BUFFER_SIZE)
279
314
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
280
- requires(memory_no_alias(siglen, sizeof(size_t)))
281
315
  requires(memory_no_alias(m, mlen))
282
316
  requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
283
317
  requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
284
318
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
285
319
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
286
- assigns(object_whole(siglen))
287
- ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
288
- (MLD_ANY_ERROR(return_value) && *siglen == 0))
320
+ ensures(return_value == 0 || return_value == MLD_ERR_OUT_OF_MEMORY ||
321
+ return_value == MLD_ERR_RNG_FAIL ||
322
+ return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED ||
323
+ return_value == MLD_ERR_SIGNING_PAUSED ||
324
+ return_value == MLD_ERR_INVALID_ARG)
325
+ ensures((return_value == MLD_ERR_INVALID_ARG) ==> (ctxlen > 255))
326
+ /* Output buffers on error, per API-CONVENTIONS.md */
327
+ ensures(return_value != 0 ==>
328
+ array_unchanged_or_zeroized_u8(sig, MLDSA_CRYPTO_BYTES))
289
329
  );
290
330
 
291
331
  /**
@@ -296,12 +336,15 @@ __contract__(
296
336
  * variant; for the deterministic variant, use mld_sign_signature_internal
297
337
  * directly with externalmu set to non-zero and an all-zero rnd.
298
338
  *
299
- * @spec{Implements @[FIPS204 Algorithm 2 (ML-DSA.Sign external mu variant)].}
339
+ * @spec{Implements @[FIPS204, Algorithm 2, ML-DSA.Sign external mu variant].}
340
+ *
341
+ * @warning This function does not perform secret key validation.
342
+ * Callers importing serialized keys can use mld_sign_pk_from_sk
343
+ * to validate them before signing.
300
344
  *
301
345
  * @param[out] sig Output signature.
302
- * @param[out] siglen Pointer to output length of signature.
303
346
  * @param[in] mu Precomputed message representative.
304
- * @param[in] sk Bit-packed secret key.
347
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
305
348
  * @param context Application context. Only present when
306
349
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
307
350
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
@@ -314,68 +357,30 @@ __contract__(
314
357
  * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
315
358
  * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
316
359
  * iterations.
317
- * @retval MLD_ERR_FAIL Other kinds of failure.
360
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
361
+ * paused signing; re-invoke to resume.
318
362
  */
319
363
  MLD_MUST_CHECK_RETURN_VALUE
320
364
  MLD_EXTERNAL_API
321
- int mld_sign_signature_extmu(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen,
365
+ int mld_sign_signature_extmu(uint8_t sig[MLDSA_CRYPTO_BYTES],
322
366
  const uint8_t mu[MLDSA_CRHBYTES],
323
367
  const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
324
368
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
325
369
  __contract__(
326
370
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
327
- requires(memory_no_alias(siglen, sizeof(size_t)))
328
371
  requires(memory_no_alias(mu, MLDSA_CRHBYTES))
329
372
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
330
373
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
331
- assigns(object_whole(siglen))
332
- ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
333
- (MLD_ANY_ERROR(return_value) && *siglen == 0))
374
+ ensures(return_value == 0 || return_value == MLD_ERR_OUT_OF_MEMORY ||
375
+ return_value == MLD_ERR_RNG_FAIL ||
376
+ return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED ||
377
+ return_value == MLD_ERR_SIGNING_PAUSED)
378
+ /* Output buffers on error, per API-CONVENTIONS.md */
379
+ ensures(return_value != 0 ==>
380
+ array_unchanged_or_zeroized_u8(sig, MLDSA_CRYPTO_BYTES))
334
381
  );
335
382
 
336
- /**
337
- * Compute signed message.
338
- *
339
- * @param[out] sm Pointer to output signed message (allocated array with
340
- * MLDSA_CRYPTO_BYTES + mlen bytes); can be equal to m.
341
- * @param[out] smlen Pointer to output length of signed message.
342
- * @param[in] m Pointer to message to be signed.
343
- * @param mlen Length of message.
344
- * @param[in] ctx Pointer to context string.
345
- * @param ctxlen Length of context string.
346
- * @param[in] sk Bit-packed secret key.
347
- * @param context Application context. Only present when
348
- * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
349
- * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
350
- *
351
- * @retval 0 Success.
352
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
353
- * used and an allocation via
354
- * MLD_CUSTOM_ALLOC returned NULL.
355
- * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
356
- * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
357
- * iterations.
358
- * @retval MLD_ERR_FAIL Other kinds of failure.
359
- */
360
- MLD_MUST_CHECK_RETURN_VALUE
361
- MLD_EXTERNAL_API
362
- int mld_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen,
363
- const uint8_t *ctx, size_t ctxlen,
364
- const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
365
- MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
366
- __contract__(
367
- requires(mlen <= MLD_MAX_BUFFER_SIZE)
368
- requires(memory_no_alias(sm, MLDSA_CRYPTO_BYTES + mlen))
369
- requires(memory_no_alias(smlen, sizeof(size_t)))
370
- requires(m == sm || memory_no_alias(m, mlen))
371
- requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
372
- requires(memory_no_alias(ctx, ctxlen))
373
- requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
374
- assigns(memory_slice(sm, MLDSA_CRYPTO_BYTES + mlen))
375
- assigns(object_whole(smlen))
376
- ensures((return_value == 0 && *smlen == MLDSA_CRYPTO_BYTES + mlen) ||
377
- (MLD_ANY_ERROR(return_value) && *smlen == 0))
378
- );
383
+ #endif /* !MLD_CONFIG_NO_RANDOMIZED_API */
379
384
  #endif /* !MLD_CONFIG_CORE_API_ONLY */
380
385
  #endif /* !MLD_CONFIG_NO_SIGN_API */
381
386
 
@@ -383,10 +388,10 @@ __contract__(
383
388
  /**
384
389
  * Verify signature.
385
390
  *
386
- * @spec{Implements @[FIPS204 Algorithm 8 (ML-DSA.Verify_internal)].}
391
+ * @spec{Implements @[FIPS204, Algorithm 8, ML-DSA.Verify_internal].}
387
392
  *
388
- * @param[in] sig Pointer to input signature.
389
- * @param siglen Length of signature.
393
+ * @param[in] sig Pointer to input signature of
394
+ * MLDSA_CRYPTO_BYTES bytes.
390
395
  * @param[in] m Pointer to message (when externalmu == 0), or to a
391
396
  * precomputed message representative mu (when
392
397
  * externalmu != 0).
@@ -403,14 +408,15 @@ __contract__(
403
408
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
404
409
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
405
410
  *
406
- * @retval 0 Success.
407
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
408
- * allocation via MLD_CUSTOM_ALLOC returned NULL.
409
- * @retval MLD_ERR_FAIL Signature verification failed.
411
+ * @retval 0 Success.
412
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
413
+ * used and an allocation via
414
+ * MLD_CUSTOM_ALLOC returned NULL.
415
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
410
416
  */
411
417
  MLD_MUST_CHECK_RETURN_VALUE
412
418
  MLD_EXTERNAL_API
413
- int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
419
+ int mld_sign_verify_internal(const uint8_t sig[MLDSA_CRYPTO_BYTES],
414
420
  const uint8_t *m, size_t mlen, const uint8_t *pre,
415
421
  size_t prelen,
416
422
  const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
@@ -419,23 +425,21 @@ int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
419
425
  __contract__(
420
426
  requires(prelen <= MLD_MAX_BUFFER_SIZE)
421
427
  requires(mlen <= MLD_MAX_BUFFER_SIZE)
422
- requires(siglen <= MLD_MAX_BUFFER_SIZE)
423
- requires(memory_no_alias(sig, siglen))
428
+ requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
424
429
  requires(memory_no_alias(m, mlen))
425
430
  requires((externalmu == 0) ==> ((prelen == 0) || memory_no_alias(pre, prelen)))
426
431
  requires((externalmu != 0) ==> (mlen == MLDSA_CRHBYTES))
427
432
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
428
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
433
+ ensures(return_value == 0 || return_value == MLD_ERR_INVALID_SIGNATURE || return_value == MLD_ERR_OUT_OF_MEMORY)
429
434
  );
430
435
 
431
436
  #if !defined(MLD_CONFIG_CORE_API_ONLY)
432
437
  /**
433
438
  * Verify signature.
434
439
  *
435
- * @spec{Implements @[FIPS204 Algorithm 3 (ML-DSA.Verify)].}
440
+ * @spec{Implements @[FIPS204, Algorithm 3, ML-DSA.Verify].}
436
441
  *
437
442
  * @param[in] sig Pointer to input signature.
438
- * @param siglen Length of signature.
439
443
  * @param[in] m Pointer to message.
440
444
  * @param mlen Length of message.
441
445
  * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
@@ -445,26 +449,28 @@ __contract__(
445
449
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
446
450
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
447
451
  *
448
- * @retval 0 Success.
449
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
450
- * allocation via MLD_CUSTOM_ALLOC returned NULL.
451
- * @retval MLD_ERR_FAIL Signature verification failed.
452
+ * @retval 0 Success.
453
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
454
+ * used and an allocation via
455
+ * MLD_CUSTOM_ALLOC returned NULL.
456
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
457
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255 bytes.
452
458
  */
453
459
  MLD_MUST_CHECK_RETURN_VALUE
454
460
  MLD_EXTERNAL_API
455
- int mld_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m,
461
+ int mld_sign_verify(const uint8_t sig[MLDSA_CRYPTO_BYTES], const uint8_t *m,
456
462
  size_t mlen, const uint8_t *ctx, size_t ctxlen,
457
463
  const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
458
464
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
459
465
  __contract__(
460
466
  requires(mlen <= MLD_MAX_BUFFER_SIZE)
461
- requires(siglen <= MLD_MAX_BUFFER_SIZE)
462
467
  requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
463
- requires(memory_no_alias(sig, siglen))
468
+ requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
464
469
  requires(memory_no_alias(m, mlen))
465
470
  requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
466
471
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
467
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
472
+ ensures(return_value == 0 || return_value == MLD_ERR_INVALID_SIGNATURE || return_value == MLD_ERR_INVALID_ARG || return_value == MLD_ERR_OUT_OF_MEMORY)
473
+ ensures((return_value == MLD_ERR_INVALID_ARG) ==> (ctxlen > 255))
468
474
  );
469
475
 
470
476
  /**
@@ -474,81 +480,42 @@ __contract__(
474
480
  * 0x00 || ctxlen || ctx || msg for pure ML-DSA). The same mu must have been
475
481
  * used at signing time.
476
482
  *
477
- * @spec{Implements @[FIPS204 Algorithm 3 (ML-DSA.Verify external mu variant)].}
483
+ * @spec{Implements @[FIPS204, Algorithm 3, ML-DSA.Verify external mu variant].}
478
484
  *
479
485
  * @param[in] sig Pointer to input signature.
480
- * @param siglen Length of signature.
481
486
  * @param[in] mu Precomputed message representative.
482
487
  * @param[in] pk Bit-packed public key.
483
488
  * @param context Application context. Only present when
484
489
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
485
490
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
486
491
  *
487
- * @retval 0 Success.
488
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
489
- * allocation via MLD_CUSTOM_ALLOC returned NULL.
490
- * @retval MLD_ERR_FAIL Signature verification failed.
492
+ * @retval 0 Success.
493
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
494
+ * used and an allocation via
495
+ * MLD_CUSTOM_ALLOC returned NULL.
496
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
491
497
  */
492
498
  MLD_MUST_CHECK_RETURN_VALUE
493
499
  MLD_EXTERNAL_API
494
- int mld_sign_verify_extmu(const uint8_t *sig, size_t siglen,
500
+ int mld_sign_verify_extmu(const uint8_t sig[MLDSA_CRYPTO_BYTES],
495
501
  const uint8_t mu[MLDSA_CRHBYTES],
496
502
  const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
497
503
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
498
- __contract__(
499
- requires(siglen <= MLD_MAX_BUFFER_SIZE)
500
- requires(memory_no_alias(sig, siglen))
504
+ __contract__( requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
501
505
  requires(memory_no_alias(mu, MLDSA_CRHBYTES))
502
506
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
503
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
507
+ ensures(return_value == 0 || return_value == MLD_ERR_INVALID_SIGNATURE || return_value == MLD_ERR_OUT_OF_MEMORY)
504
508
  );
505
509
 
506
- /**
507
- * Verify signed message.
508
- *
509
- * @param[out] m Pointer to output message (allocated array with smlen
510
- * bytes); can be equal to sm.
511
- * @param[out] mlen Pointer to output length of message.
512
- * @param[in] sm Pointer to signed message.
513
- * @param smlen Length of signed message.
514
- * @param[in] ctx Pointer to context string.
515
- * @param ctxlen Length of context string.
516
- * @param[in] pk Bit-packed public key.
517
- * @param context Application context. Only present when
518
- * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
519
- * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
520
- *
521
- * @retval 0 Success.
522
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
523
- * allocation via MLD_CUSTOM_ALLOC returned NULL.
524
- * @retval MLD_ERR_FAIL Signature verification failed.
525
- */
526
- MLD_MUST_CHECK_RETURN_VALUE
527
- MLD_EXTERNAL_API
528
- int mld_sign_open(uint8_t *m, size_t *mlen, const uint8_t *sm, size_t smlen,
529
- const uint8_t *ctx, size_t ctxlen,
530
- const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
531
- MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
532
- __contract__(
533
- requires(smlen <= MLD_MAX_BUFFER_SIZE)
534
- requires(memory_no_alias(m, smlen))
535
- requires(memory_no_alias(mlen, sizeof(size_t)))
536
- requires(m == sm || memory_no_alias(sm, smlen))
537
- requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
538
- requires(memory_no_alias(ctx, ctxlen))
539
- requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
540
- assigns(memory_slice(m, smlen))
541
- assigns(memory_slice(mlen, sizeof(size_t)))
542
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
543
- );
544
510
  #endif /* !MLD_CONFIG_CORE_API_ONLY */
545
511
  #endif /* !MLD_CONFIG_NO_VERIFY_API */
546
512
 
547
513
  #if !defined(MLD_CONFIG_CORE_API_ONLY)
548
514
  #if !defined(MLD_CONFIG_NO_SIGN_API)
549
515
  /**
550
- * FIPS 204: Algorithm 4 HashML-DSA.Sign. Compute signature with pre-hashed
551
- * message.
516
+ * Compute signature with pre-hashed message.
517
+ *
518
+ * @spec{Implements @[FIPS204, Algorithm 4, HashML-DSA.Sign].}
552
519
  *
553
520
  * Supported hash algorithm constants:
554
521
  * MLD_PREHASH_SHA2_224, MLD_PREHASH_SHA2_256, MLD_PREHASH_SHA2_384,
@@ -556,17 +523,25 @@ __contract__(
556
523
  * MLD_PREHASH_SHA3_224, MLD_PREHASH_SHA3_256, MLD_PREHASH_SHA3_384,
557
524
  * MLD_PREHASH_SHA3_512, MLD_PREHASH_SHAKE_128, MLD_PREHASH_SHAKE_256.
558
525
  *
526
+ * MLD_PREHASH_NONE is rejected by this API.
527
+ *
559
528
  * @warning This is an unstable API that may change in the future. If you need
560
529
  * a stable API use mld_sign_signature_pre_hash_shake256.
561
530
  *
531
+ * @warning This function does not perform secret key validation.
532
+ * Callers importing serialized keys can use mld_sign_pk_from_sk
533
+ * to validate them before signing.
534
+ *
562
535
  * @param[out] sig Output signature.
563
- * @param[out] siglen Pointer to output length of signature.
564
536
  * @param[in] ph Pointer to pre-hashed message.
565
- * @param phlen Length of pre-hashed message.
566
- * @param[in] ctx Pointer to context string.
537
+ * @param phlen Length of pre-hashed message. Must match the output
538
+ * length of hashalg (the digest size for SHA-2/SHA-3,
539
+ * 32 bytes for MLD_PREHASH_SHAKE_128, 64 bytes for
540
+ * MLD_PREHASH_SHAKE_256).
541
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
567
542
  * @param ctxlen Length of context string.
568
543
  * @param[in] rnd Random seed.
569
- * @param[in] sk Bit-packed secret key.
544
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
570
545
  * @param hashalg Hash algorithm constant (one of MLD_PREHASH_*).
571
546
  * @param context Application context. Only present when
572
547
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
@@ -579,36 +554,42 @@ __contract__(
579
554
  * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
580
555
  * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
581
556
  * iterations.
582
- * @retval MLD_ERR_FAIL Other kinds of failure.
557
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
558
+ * paused signing; re-invoke to resume.
559
+ * @retval MLD_ERR_INVALID_ARG The pre-hash algorithm was
560
+ * MLD_PREHASH_NONE or unsupported,
561
+ * phlen did not match the output
562
+ * length of hashalg, or the context
563
+ * string exceeded 255 bytes.
583
564
  */
584
565
  MLD_MUST_CHECK_RETURN_VALUE
585
566
  MLD_EXTERNAL_API
586
567
  int mld_sign_signature_pre_hash_internal(
587
- uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, const uint8_t *ph,
588
- size_t phlen, const uint8_t *ctx, size_t ctxlen,
589
- const uint8_t rnd[MLDSA_RNDBYTES],
568
+ uint8_t sig[MLDSA_CRYPTO_BYTES], const uint8_t *ph, size_t phlen,
569
+ const uint8_t *ctx, size_t ctxlen, const uint8_t rnd[MLDSA_RNDBYTES],
590
570
  const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES], int hashalg,
591
571
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
592
572
  __contract__(
593
573
  requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
594
574
  requires(phlen <= MLD_MAX_BUFFER_SIZE)
595
575
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
596
- requires(memory_no_alias(siglen, sizeof(size_t)))
597
576
  requires(memory_no_alias(ph, phlen))
598
577
  requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
599
578
  requires(memory_no_alias(rnd, MLDSA_RNDBYTES))
600
579
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
601
580
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
602
- assigns(object_whole(siglen))
603
- ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
604
- ((return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY || return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED) && *siglen == 0))
581
+ ensures(return_value == 0 || return_value == MLD_ERR_OUT_OF_MEMORY || return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED || return_value == MLD_ERR_SIGNING_PAUSED || return_value == MLD_ERR_INVALID_ARG)
582
+ /* Output buffers on error, per API-CONVENTIONS.md */
583
+ ensures(return_value != 0 ==>
584
+ array_unchanged_or_zeroized_u8(sig, MLDSA_CRYPTO_BYTES))
605
585
  );
606
586
  #endif /* !MLD_CONFIG_NO_SIGN_API */
607
587
 
608
588
  #if !defined(MLD_CONFIG_NO_VERIFY_API)
609
589
  /**
610
- * FIPS 204: Algorithm 5 HashML-DSA.Verify. Verify signature with pre-hashed
611
- * message.
590
+ * Verify signature with pre-hashed message.
591
+ *
592
+ * @spec{Implements @[FIPS204, Algorithm 5, HashML-DSA.Verify].}
612
593
  *
613
594
  * Supported hash algorithm constants:
614
595
  * MLD_PREHASH_SHA2_224, MLD_PREHASH_SHA2_256, MLD_PREHASH_SHA2_384,
@@ -616,14 +597,18 @@ __contract__(
616
597
  * MLD_PREHASH_SHA3_224, MLD_PREHASH_SHA3_256, MLD_PREHASH_SHA3_384,
617
598
  * MLD_PREHASH_SHA3_512, MLD_PREHASH_SHAKE_128, MLD_PREHASH_SHAKE_256.
618
599
  *
600
+ * MLD_PREHASH_NONE is rejected by this API.
601
+ *
619
602
  * @warning This is an unstable API that may change in the future. If you need
620
603
  * a stable API use mld_sign_verify_pre_hash_shake256.
621
604
  *
622
605
  * @param[in] sig Pointer to input signature.
623
- * @param siglen Length of signature.
624
606
  * @param[in] ph Pointer to pre-hashed message.
625
- * @param phlen Length of pre-hashed message.
626
- * @param[in] ctx Pointer to context string.
607
+ * @param phlen Length of pre-hashed message. Must match the output
608
+ * length of hashalg (the digest size for SHA-2/SHA-3,
609
+ * 32 bytes for MLD_PREHASH_SHAKE_128, 64 bytes for
610
+ * MLD_PREHASH_SHAKE_256).
611
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
627
612
  * @param ctxlen Length of context string.
628
613
  * @param[in] pk Bit-packed public key.
629
614
  * @param hashalg Hash algorithm constant (one of MLD_PREHASH_*).
@@ -631,45 +616,54 @@ __contract__(
631
616
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
632
617
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
633
618
  *
634
- * @retval 0 Success.
635
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
636
- * allocation via MLD_CUSTOM_ALLOC returned NULL.
637
- * @retval MLD_ERR_FAIL Signature verification failed.
619
+ * @retval 0 Success.
620
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
621
+ * used and an allocation via
622
+ * MLD_CUSTOM_ALLOC returned NULL.
623
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
624
+ * @retval MLD_ERR_INVALID_ARG The pre-hash algorithm was
625
+ * MLD_PREHASH_NONE or unsupported, phlen
626
+ * did not match the output length of
627
+ * hashalg, or the context string exceeded
628
+ * 255 bytes.
638
629
  */
639
630
  MLD_MUST_CHECK_RETURN_VALUE
640
631
  MLD_EXTERNAL_API
641
632
  int mld_sign_verify_pre_hash_internal(
642
- const uint8_t *sig, size_t siglen, const uint8_t *ph, size_t phlen,
633
+ const uint8_t sig[MLDSA_CRYPTO_BYTES], const uint8_t *ph, size_t phlen,
643
634
  const uint8_t *ctx, size_t ctxlen,
644
635
  const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES], int hashalg,
645
636
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
646
637
  __contract__(
647
638
  requires(phlen <= MLD_MAX_BUFFER_SIZE)
648
639
  requires(ctxlen <= MLD_MAX_BUFFER_SIZE - 77)
649
- requires(siglen <= MLD_MAX_BUFFER_SIZE)
650
- requires(memory_no_alias(sig, siglen))
640
+ requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
651
641
  requires(memory_no_alias(ph, phlen))
652
642
  requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
653
643
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
654
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
644
+ ensures(return_value == 0 || return_value == MLD_ERR_INVALID_SIGNATURE || return_value == MLD_ERR_INVALID_ARG || return_value == MLD_ERR_OUT_OF_MEMORY)
655
645
  );
656
646
  #endif /* !MLD_CONFIG_NO_VERIFY_API */
657
647
 
658
648
  #if !defined(MLD_CONFIG_NO_SIGN_API)
659
649
  /**
660
- * FIPS 204: Algorithm 4 HashML-DSA.Sign with SHAKE256.
661
- *
662
650
  * Compute signature with pre-hashed message using SHAKE256. This function
663
651
  * computes the SHAKE256 hash of the message internally.
664
652
  *
653
+ * @spec{Implements @[FIPS204, Algorithm 4, HashML-DSA.Sign] with SHAKE256 as
654
+ * the pre-hash.}
655
+ *
656
+ * @warning This function does not perform secret key validation.
657
+ * Callers importing serialized keys can use mld_sign_pk_from_sk
658
+ * to validate them before signing.
659
+ *
665
660
  * @param[out] sig Output signature.
666
- * @param[out] siglen Pointer to output length of signature.
667
661
  * @param[in] m Pointer to message to be hashed and signed.
668
662
  * @param mlen Length of message.
669
- * @param[in] ctx Pointer to context string.
663
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
670
664
  * @param ctxlen Length of context string.
671
665
  * @param[in] rnd Random seed.
672
- * @param[in] sk Bit-packed secret key.
666
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
673
667
  * @param context Application context. Only present when
674
668
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
675
669
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
@@ -681,71 +675,74 @@ __contract__(
681
675
  * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
682
676
  * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
683
677
  * iterations.
684
- * @retval MLD_ERR_FAIL Other kinds of failure.
678
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
679
+ * paused signing; re-invoke to resume.
680
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255
681
+ * bytes.
685
682
  */
686
683
  MLD_MUST_CHECK_RETURN_VALUE
687
684
  MLD_EXTERNAL_API
688
685
  int mld_sign_signature_pre_hash_shake256(
689
- uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, const uint8_t *m,
690
- size_t mlen, const uint8_t *ctx, size_t ctxlen,
691
- const uint8_t rnd[MLDSA_RNDBYTES],
686
+ uint8_t sig[MLDSA_CRYPTO_BYTES], const uint8_t *m, size_t mlen,
687
+ const uint8_t *ctx, size_t ctxlen, const uint8_t rnd[MLDSA_RNDBYTES],
692
688
  const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
693
689
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
694
690
  __contract__(
695
691
  requires(mlen <= MLD_MAX_BUFFER_SIZE)
696
692
  requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
697
693
  requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
698
- requires(memory_no_alias(siglen, sizeof(size_t)))
699
694
  requires(memory_no_alias(m, mlen))
700
695
  requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
701
696
  requires(memory_no_alias(rnd, MLDSA_RNDBYTES))
702
697
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
703
698
  assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
704
- assigns(object_whole(siglen))
705
- ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
706
- ((return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY || return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED) && *siglen == 0))
699
+ ensures(return_value == 0 || return_value == MLD_ERR_OUT_OF_MEMORY || return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED || return_value == MLD_ERR_SIGNING_PAUSED || return_value == MLD_ERR_INVALID_ARG)
700
+ /* Output buffers on error, per API-CONVENTIONS.md */
701
+ ensures(return_value != 0 ==>
702
+ array_unchanged_or_zeroized_u8(sig, MLDSA_CRYPTO_BYTES))
707
703
  );
708
704
  #endif /* !MLD_CONFIG_NO_SIGN_API */
709
705
 
710
706
  #if !defined(MLD_CONFIG_NO_VERIFY_API)
711
707
  /**
712
- * FIPS 204: Algorithm 5 HashML-DSA.Verify with SHAKE256.
713
- *
714
708
  * Verify signature with pre-hashed message using SHAKE256. This function
715
709
  * computes the SHAKE256 hash of the message internally.
716
710
  *
711
+ * @spec{Implements @[FIPS204, Algorithm 5, HashML-DSA.Verify] with SHAKE256 as
712
+ * the pre-hash.}
713
+ *
717
714
  * @param[in] sig Pointer to input signature.
718
- * @param siglen Length of signature.
719
715
  * @param[in] m Pointer to message to be hashed and verified.
720
716
  * @param mlen Length of message.
721
- * @param[in] ctx Pointer to context string.
717
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
722
718
  * @param ctxlen Length of context string.
723
719
  * @param[in] pk Bit-packed public key.
724
720
  * @param context Application context. Only present when
725
721
  * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
726
722
  * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
727
723
  *
728
- * @retval 0 Success.
729
- * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
730
- * allocation via MLD_CUSTOM_ALLOC returned NULL.
731
- * @retval MLD_ERR_FAIL Signature verification failed.
724
+ * @retval 0 Success.
725
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
726
+ * used and an allocation via
727
+ * MLD_CUSTOM_ALLOC returned NULL.
728
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
729
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255 bytes.
732
730
  */
733
731
  MLD_MUST_CHECK_RETURN_VALUE
734
732
  MLD_EXTERNAL_API
735
733
  int mld_sign_verify_pre_hash_shake256(
736
- const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
734
+ const uint8_t sig[MLDSA_CRYPTO_BYTES], const uint8_t *m, size_t mlen,
737
735
  const uint8_t *ctx, size_t ctxlen,
738
736
  const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
739
737
  MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
740
738
  __contract__(
741
739
  requires(mlen <= MLD_MAX_BUFFER_SIZE)
742
740
  requires(ctxlen <= MLD_MAX_BUFFER_SIZE - 77)
743
- requires(siglen <= MLD_MAX_BUFFER_SIZE)
744
- requires(memory_no_alias(sig, siglen))
741
+ requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
745
742
  requires(memory_no_alias(m, mlen))
746
743
  requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
747
744
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
748
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
745
+ ensures(return_value == 0 || return_value == MLD_ERR_INVALID_SIGNATURE || return_value == MLD_ERR_INVALID_ARG || return_value == MLD_ERR_OUT_OF_MEMORY)
749
746
  );
750
747
  #endif /* !MLD_CONFIG_NO_VERIFY_API */
751
748
 
@@ -767,26 +764,31 @@ __contract__(
767
764
  * This function is useful for building incremental signing APIs.
768
765
  *
769
766
  * @spec{For HashML-DSA (hashalg != MLD_PREHASH_NONE), implements
770
- * @[FIPS204, Algorithm 4, L23]. For Pure ML-DSA (hashalg == MLD_PREHASH_NONE),
771
- * implements
767
+ * @[FIPS204, Algorithm 4, line 23]. For Pure ML-DSA
768
+ * (hashalg == MLD_PREHASH_NONE), implements
772
769
  * ```
773
770
  * M' <- BytesToBits(IntegerToBytes(0, 1)
774
771
  * || IntegerToBytes(|ctx|, 1)
775
772
  * || ctx
776
773
  * ```
777
- * which is part of @[FIPS204, Algorithm 2 (ML-DSA.Sign), L10] and
778
- * @[FIPS204, Algorithm 3 (ML-DSA.Verify), L5].}
774
+ * which is part of @[FIPS204, Algorithm 2, ML-DSA.Sign, line 10] and
775
+ * @[FIPS204, Algorithm 3, ML-DSA.Verify, line 5].}
779
776
  *
780
777
  * @param[out] prefix Output domain separation prefix buffer.
781
778
  * @param[in] ph Pointer to pre-hashed message (ignored for pure
782
779
  * ML-DSA).
783
- * @param phlen Length of pre-hashed message (ignored for pure ML-DSA).
784
- * @param[in] ctx Pointer to context string (may be NULL).
780
+ * @param phlen Length of pre-hashed message; must match the output
781
+ * length of hashalg (ignored for pure ML-DSA).
782
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
785
783
  * @param ctxlen Length of context string.
786
784
  * @param hashalg Hash algorithm constant (MLD_PREHASH_NONE for pure
787
785
  * ML-DSA, or MLD_PREHASH_* for HashML-DSA).
788
786
  *
789
787
  * @return The total length of the formatted prefix, or 0 on error.
788
+ * Errors are:
789
+ * - The context string exceeded 255 bytes.
790
+ * - For HashML-DSA: hashalg was unsupported, ph was NULL, or phlen
791
+ * did not match the output length of hashalg.
790
792
  */
791
793
  MLD_MUST_CHECK_RETURN_VALUE
792
794
  MLD_EXTERNAL_API
@@ -809,7 +811,7 @@ __contract__(
809
811
  * Perform basic validity checks on secret key, and derive public key.
810
812
  *
811
813
  * Referring to the decoding of the secret key `sk=(rho, K, tr, s1, s2, t0)`
812
- * (cf. @[FIPS204, Algorithm 25 skDecode]), the following checks are
814
+ * (cf. @[FIPS204, Algorithm 25, skDecode]), the following checks are
813
815
  * performed:
814
816
  * - Check that s1 and s2 have coefficients in [-MLDSA_ETA, MLDSA_ETA].
815
817
  * - Check that t0 and tr stored in sk match recomputed values.
@@ -826,7 +828,7 @@ __contract__(
826
828
  * @retval 0 Success.
827
829
  * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
828
830
  * allocation via MLD_CUSTOM_ALLOC returned NULL.
829
- * @retval MLD_ERR_FAIL Secret key validation failed.
831
+ * @retval MLD_ERR_INVALID_KEY Secret key validation failed.
830
832
  */
831
833
  MLD_MUST_CHECK_RETURN_VALUE
832
834
  MLD_EXTERNAL_API
@@ -837,7 +839,10 @@ __contract__(
837
839
  requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
838
840
  requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
839
841
  assigns(memory_slice(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
840
- ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
842
+ ensures(return_value == 0 || return_value == MLD_ERR_INVALID_KEY || return_value == MLD_ERR_OUT_OF_MEMORY)
843
+ /* Output buffers on error, per API-CONVENTIONS.md */
844
+ ensures(return_value != 0 ==>
845
+ array_unchanged_or_zeroized_u8(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
841
846
  );
842
847
  #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
843
848
  #endif /* !MLD_CONFIG_CORE_API_ONLY */