pq_crypto 0.6.5 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +134 -0
- data/README.md +5 -3
- data/ext/pqcrypto/extconf.rb +4 -1
- data/ext/pqcrypto/pq_externalmu.c +35 -0
- data/ext/pqcrypto/pqcrypto_native_api.h +85 -75
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +16 -9
- data/ext/pqcrypto/pqcrypto_secure.c +43 -33
- data/ext/pqcrypto/pqcrypto_secure.h +52 -47
- data/ext/pqcrypto/pqcrypto_version.h +1 -1
- data/ext/pqcrypto/vendor/.vendored +7 -7
- data/ext/pqcrypto/vendor/mldsa-native/BUILDING.md +5 -2
- data/ext/pqcrypto/vendor/mldsa-native/LICENSE +21 -2
- data/ext/pqcrypto/vendor/mldsa-native/README.md +20 -7
- data/ext/pqcrypto/vendor/mldsa-native/RELEASE.md +160 -0
- data/ext/pqcrypto/vendor/mldsa-native/SECURITY.md +1 -1
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/README.md +2 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.c +85 -59
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native.h +292 -348
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_asm.S +122 -76
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/mldsa_native_config.h +184 -86
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/cbmc.h +49 -4
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/common.h +49 -81
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/context.h +152 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/ct.h +25 -12
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.c +2 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/debug.h +2 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +2 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +9 -11
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +19 -11
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +6 -4
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +7 -4
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +7 -4
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +12 -9
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +12 -9
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +1 -1
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +3 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +3 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +6 -1
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +3 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/api.h +11 -11
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +9 -22
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +8 -5
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +1 -0
- 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
- 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
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +5 -4
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +1 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +36 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +62 -4
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +87 -54
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{intt_aarch64_asm.S → mldsa_intt_aarch64_asm.S} +39 -6
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{ntt_aarch64_asm.S → mldsa_ntt_aarch64_asm.S} +39 -6
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{pointwise_montgomery_aarch64_asm.S → mldsa_pointwise_montgomery_aarch64_asm.S} +25 -3
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_caddq_aarch64_asm.S → mldsa_poly_caddq_aarch64_asm.S} +19 -3
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{poly_chknorm_aarch64_asm.S → mldsa_poly_chknorm_aarch64_asm.S} +24 -3
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/aarch64/src/{rej_uniform_aarch64_asm.S → mldsa_rej_uniform_aarch64_asm.S} +48 -15
- 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
- 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
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/api.h +11 -3
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/meta.h +3 -2
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +28 -28
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +171 -49
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{intt_avx2_asm.S → mldsa_intt_avx2_asm.S} +23 -1
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{ntt_avx2_asm.S → mldsa_ntt_avx2_asm.S} +23 -1
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{nttunpack_avx2_asm.S → mldsa_nttunpack_avx2_asm.S} +17 -1
- 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
- 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
- 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
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/{pointwise_avx2_asm.S → mldsa_pointwise_avx2_asm.S} +31 -3
- 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
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_chknorm_avx2_asm.S +176 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_32_avx2_asm.S +490 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_88_avx2_asm.S +489 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_32_avx2_asm.S +123 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_88_avx2_asm.S +125 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_17_avx2_asm.S +355 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_19_avx2_asm.S +355 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_avx2_asm.S +132 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta2_avx2_asm.S +205 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta4_avx2_asm.S +176 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.c +27 -36
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/packing.h +42 -8
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/params.h +93 -17
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.c +74 -15
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly.h +97 -11
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.c +7 -38
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/poly_kl.h +49 -7
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.c +16 -17
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec.h +26 -9
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +3 -0
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +18 -19
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/reduce.h +15 -3
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/rounding.h +28 -6
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.c +311 -246
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sign.h +245 -240
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/sys.h +64 -5
- data/ext/pqcrypto/vendor/mlkem-native/BUILDING.md +5 -2
- data/ext/pqcrypto/vendor/mlkem-native/LICENSE +21 -3
- data/ext/pqcrypto/vendor/mlkem-native/README.md +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/RELEASE.md +113 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/README.md +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.c +17 -27
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native.h +68 -151
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_asm.S +17 -27
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/mlkem_native_config.h +46 -44
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/cbmc.h +25 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/common.h +37 -6
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/context.h +9 -0
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/fips202.h +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/keccakf1600.c +8 -8
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_scalar.h +1 -1
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x1_v84a.h +3 -3
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x2_v84a.h +3 -3
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_scalar.h +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +3 -3
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/api.h +11 -11
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/armv81m/mve.h +3 -3
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +2 -2
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/indcpa.h +14 -11
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.c +28 -11
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/kem.h +39 -14
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/aarch64/meta.h +10 -10
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/native/x86_64/meta.h +20 -20
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/sys.h +5 -5
- data/ext/pqcrypto/vendor/mlkem-native/mlkem/src/verify.h +11 -10
- data/lib/pq_crypto/version.rb +1 -1
- data/script/vendor_libs.rb +6 -6
- metadata +40 -38
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_chknorm_avx2.c +0 -52
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_32_avx2.c +0 -157
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_decompose_88_avx2.c +0 -157
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_32_avx2.c +0 -103
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/poly_use_hint_88_avx2.c +0 -105
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_17_avx2.c +0 -94
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/polyz_unpack_19_avx2.c +0 -96
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_avx2.c +0 -126
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta2_avx2.c +0 -157
- data/ext/pqcrypto/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_eta4_avx2.c +0 -141
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 273b83c96db2314540118b933a9f70a22c954e59a6fb38377f7c6cd1f337d698
|
|
4
|
+
data.tar.gz: 0a6f4b88a3aefde58049f41f582548aa10f2aa939e98a8b60791ff23c8a5be0e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4905490a34b75ae7548a896cbb379b135c7615dfba9dca564add76892fb6074a6e0a12220ca3158417ea3264c2dcb2dc432b0a49fa91f8429eaebeef966d895
|
|
7
|
+
data.tar.gz: 854941b5a331956cba2aa91ef1777148f9a93713eec6ce746fe01475b126b69f409ad0dbcf631a1db5c7c09d127d55053d59585850bcf06a8047f8b2ae14adec
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,139 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.6] - 2026-08-10
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- update native mlkem `v1.3.0` -> `v2.0.0` and mldsa `v1.0.0-beta2` -> `v2.0.0`
|
|
8
|
+
|
|
9
|
+
`mldsa-native` v2.0.0 is that project's first stable release; it is numbered
|
|
10
|
+
`2` only to align its API and configuration with `mlkem-native` v2. Upstream
|
|
11
|
+
now guarantees that non-experimental APIs and configuration options stay
|
|
12
|
+
stable until a `v3`.
|
|
13
|
+
|
|
14
|
+
No cryptographic output changed. All six `kat-sha256` values in the upstream
|
|
15
|
+
`META.yml` files are identical to the previously vendored versions, and the
|
|
16
|
+
vendored ML-KEM-768 keygen, ML-DSA-65 keygen and ML-DSA-65 siggen KAT vectors
|
|
17
|
+
reproduce byte-for-byte. This release is purely an API migration.
|
|
18
|
+
|
|
19
|
+
### Breaking upstream changes handled
|
|
20
|
+
|
|
21
|
+
- **`siglen` removed from the ML-DSA signing and verification APIs.** Upstream
|
|
22
|
+
signatures are always exactly `MLDSA_BYTES(level)`, so `signature`,
|
|
23
|
+
`signature_internal`, `verify`, `signature_extmu` and `verify_extmu` no longer
|
|
24
|
+
carry a length parameter. Fifteen declarations in
|
|
25
|
+
`ext/pqcrypto/pqcrypto_native_api.h` were updated accordingly.
|
|
26
|
+
|
|
27
|
+
The `pq_crypto` C API is deliberately *not* changed to match: `pq_sign`,
|
|
28
|
+
`pq_verify`, `pq_sign_mu` and `pq_verify_mu` keep their length parameters.
|
|
29
|
+
The adaptation happens at the vendor boundary instead.
|
|
30
|
+
|
|
31
|
+
- **`pq_crypto` now owns the signing output length.** Because the backend no
|
|
32
|
+
longer reports it, every signing wrapper sets `*signature_len` itself from a
|
|
33
|
+
compile-time constant and clears it to `0` when the signing operation fails,
|
|
34
|
+
reproducing the pre-v2 behaviour. This affects `pq_sign`, `pq_mldsa44_sign`,
|
|
35
|
+
`pq_mldsa87_sign`, the level-agnostic deterministic helper
|
|
36
|
+
`pq_testing_mldsa_sign_from_seed_with`, and `pq_sign_mu`.
|
|
37
|
+
|
|
38
|
+
Argument-validation failures (`PQ_ERROR_BUFFER`) still leave `*signature_len`
|
|
39
|
+
untouched, exactly as before, since the pointer itself may be the invalid one.
|
|
40
|
+
|
|
41
|
+
- **`pq_crypto` now validates signature length before verifying (security
|
|
42
|
+
relevant).** Prior to v2, `mldsa-native` rejected a wrongly sized signature
|
|
43
|
+
itself via `if (siglen != MLDSA_BYTES) return -1;`, and `pq_crypto` relied on
|
|
44
|
+
that. In v2 the verification entry points take a fixed-size array and read
|
|
45
|
+
`MLDSA_BYTES(level)` bytes unconditionally, so a short caller-supplied buffer
|
|
46
|
+
would be an out-of-bounds read. `pq_verify`, `pq_mldsa44_verify` and
|
|
47
|
+
`pq_mldsa87_verify` now enforce the exact length and return `PQ_ERROR_VERIFY`
|
|
48
|
+
otherwise; the Ruby bindings additionally reject the wrong length before
|
|
49
|
+
copying the buffer.
|
|
50
|
+
|
|
51
|
+
This was not exploitable in 0.6.5 or earlier: the previously vendored
|
|
52
|
+
`mldsa-native` performed the check. It is a latent contract dependency that a
|
|
53
|
+
naive port to v2 would have turned into a real memory-safety bug. Verified
|
|
54
|
+
with AddressSanitizer: removing this check alone reproduces a
|
|
55
|
+
`heap-buffer-overflow` read inside `pqcr_mldsa65_verify_internal`.
|
|
56
|
+
|
|
57
|
+
Observable Ruby behaviour is unchanged: a wrongly sized signature is a failed
|
|
58
|
+
verification (`false`), never an `ArgumentError`.
|
|
59
|
+
|
|
60
|
+
- **ExternalMu callbacks adapted rather than re-typed.** Six new adapters,
|
|
61
|
+
`pq_mldsa{44,65,87}_{signature,verify}_extmu_compat`, sit between the
|
|
62
|
+
pre-v2 callback contract and the fixed-size v2 API. `pq_sign_mu` and
|
|
63
|
+
`pq_verify_mu` therefore keep their existing signatures and no consumer of the
|
|
64
|
+
C interface has to change.
|
|
65
|
+
|
|
66
|
+
- **`MLK_CONFIG_NO_SUPERCOP` / `MLD_CONFIG_NO_SUPERCOP` removed upstream**
|
|
67
|
+
along with the SUPERCOP `crypto_*` aliases themselves. The define is no longer
|
|
68
|
+
passed by `extconf.rb`. Upstream has no guard against the stale macro, so it
|
|
69
|
+
would have been a silently dead `-D` rather than a build failure.
|
|
70
|
+
|
|
71
|
+
- **Legacy `MLK_CONFIG_API_*` / `MLD_CONFIG_API_*` configuration removed
|
|
72
|
+
upstream.** The extension build already used the modern `*_CONFIG_*` macros;
|
|
73
|
+
only `test/native_api_conformance` still used the legacy path and has been
|
|
74
|
+
converted.
|
|
75
|
+
|
|
76
|
+
Upstream breaking changes that do not affect this gem, checked explicitly: the
|
|
77
|
+
SUPERCOP `crypto_*` and signed-message APIs (never used), the split of
|
|
78
|
+
`*_ERR_FAIL` into specific error codes (all call sites compare against `0`), the
|
|
79
|
+
`*_SYS_CAP_*` and `*_USE_NATIVE_FIPS202_*` renames (only relevant to custom
|
|
80
|
+
backends), and the raised `MLD_CONFIG_MAX_SIGNING_ATTEMPTS` floor of 821, which
|
|
81
|
+
this build does not set. `MLD_CONFIG_KEYGEN_PCT` / `MLK_CONFIG_KEYGEN_PCT`
|
|
82
|
+
remain opt-in upstream and are not enabled here, so key generation gains no new
|
|
83
|
+
failure mode or cost.
|
|
84
|
+
|
|
85
|
+
### Testing
|
|
86
|
+
|
|
87
|
+
- `test/native_api_conformance` reworked. It previously proved size agreement
|
|
88
|
+
via `_Static_assert` and, through the double declaration of upstream and
|
|
89
|
+
gem headers, prototype agreement. It could not detect a symbol that upstream
|
|
90
|
+
removed entirely, because it only ever compiled to an object file and both a
|
|
91
|
+
plain compile and a relocatable link tolerate unresolved symbols. The harness
|
|
92
|
+
now also builds the vendored objects with the same flags `extconf.rb` uses
|
|
93
|
+
(including which level owns the shared code) and diffs `nm -u` on the probe
|
|
94
|
+
object against the symbols the vendored build actually defines.
|
|
95
|
+
|
|
96
|
+
- Conformance now covers `pqcr_mlkem_shake256` and `pqcr_mlkem_sha3_256`, the
|
|
97
|
+
extension's only dependency on a non-public part of `mlkem-native` (they back
|
|
98
|
+
the X-Wing key expansion and combiner). They were absent from `probes[]`
|
|
99
|
+
entirely, and because they are not declared in `mlkem_native.h` the
|
|
100
|
+
double-declaration check could not reach them either. The shared-level
|
|
101
|
+
conformance unit now includes the internal `src/fips202/fips202.h` so that
|
|
102
|
+
prototype drift in these two is caught as well.
|
|
103
|
+
|
|
104
|
+
- Added `test/c_api`, direct tests for the `pq_crypto` C API, runnable under
|
|
105
|
+
AddressSanitizer via `PQCRYPTO_SANITIZE=address test/c_api/run.sh`. The Ruby
|
|
106
|
+
bindings pre-set `call.signature_len` before invoking the signing entry points
|
|
107
|
+
and read the same field back afterwards, so a wrapper that stopped writing
|
|
108
|
+
`*signature_len` would leave the entire Ruby suite green. That contract, and
|
|
109
|
+
the new signature-length validation, now have coverage that does not go
|
|
110
|
+
through Ruby.
|
|
111
|
+
|
|
112
|
+
- `rake test` now runs the native API conformance and C API checks alongside the
|
|
113
|
+
Ruby suite.
|
|
114
|
+
|
|
115
|
+
- The C API tests were themselves audited by mutation testing: each contract
|
|
116
|
+
this release changes was deliberately broken in turn and the suite had to
|
|
117
|
+
fail. That found three checks which passed against broken code and have been
|
|
118
|
+
rewritten:
|
|
119
|
+
|
|
120
|
+
- The ML-DSA-44 output-length check was phrased as "signing failed OR the
|
|
121
|
+
length is right" and reused the ML-DSA-65 secret key, so a
|
|
122
|
+
`pq_mldsa44_sign` that always returned an error satisfied it. ML-DSA-44 and
|
|
123
|
+
-87 now have their own key material and unconditional assertions.
|
|
124
|
+
- The ExternalMu failure check used a stub callback that cleared `*siglen`
|
|
125
|
+
itself, so it passed even when the real adapter had stopped doing so. It now
|
|
126
|
+
drives the genuine backend error path by exhausting the thread-local test
|
|
127
|
+
seed in `pq_randombytes.c`, which makes `randombytes()` fail. The same
|
|
128
|
+
technique gives `pq_sign` real coverage of its own error path.
|
|
129
|
+
- The verify adapters' length guards were unreachable through `pq_verify_mu`,
|
|
130
|
+
which validates the length first, so they were never exercised. They are now
|
|
131
|
+
called directly.
|
|
132
|
+
|
|
133
|
+
Two further gaps were closed: `pq_sign`'s recovery after a transient RNG
|
|
134
|
+
failure is now asserted, and a poisoned `*signature_len` that was set but
|
|
135
|
+
never checked is now checked.
|
|
136
|
+
|
|
3
137
|
## [0.6.5] - 2026-08-04
|
|
4
138
|
|
|
5
139
|
### Changed
|
data/README.md
CHANGED
|
@@ -88,9 +88,11 @@ bundle exec rake compile
|
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
Upstream pins are recorded in `ext/pqcrypto/vendor/.vendored` and enforced by
|
|
91
|
-
`bundle exec rake vendor:verify`. `mlkem-native`
|
|
92
|
-
|
|
93
|
-
the
|
|
91
|
+
`bundle exec rake vendor:verify`. Both `mlkem-native` and `mldsa-native` are
|
|
92
|
+
pinned at `v2.0.0`. For `mldsa-native` this is the first stable release; it
|
|
93
|
+
carries the major version `2` only so that its API and configuration line up
|
|
94
|
+
with `mlkem-native` v2. Upstream guarantees that APIs and configuration options
|
|
95
|
+
not marked experimental stay stable until a `v3`.
|
|
94
96
|
|
|
95
97
|
The default build uses the portable native source path. Upstream native assembly
|
|
96
98
|
can be tested explicitly with:
|
data/ext/pqcrypto/extconf.rb
CHANGED
|
@@ -524,7 +524,10 @@ def native_flags(kind, level, shared:)
|
|
|
524
524
|
flags << "-D#{prefix}_CONFIG_MULTILEVEL_BUILD"
|
|
525
525
|
flags << "-D#{prefix}_CONFIG_PARAMETER_SET=#{level}"
|
|
526
526
|
flags << "-D#{prefix}_CONFIG_NAMESPACE_PREFIX=#{ns}"
|
|
527
|
-
|
|
527
|
+
# NOTE: MLK/MLD_CONFIG_NO_SUPERCOP was removed in mlkem-native v2.0.0 and
|
|
528
|
+
# mldsa-native v2.0.0 along with the SUPERCOP crypto_* aliases themselves.
|
|
529
|
+
# Upstream has no guard against the stale define, so passing it would be a
|
|
530
|
+
# silently dead -D rather than a build error. Do not reintroduce it.
|
|
528
531
|
flags << (shared ? "-D#{prefix}_CONFIG_MULTILEVEL_WITH_SHARED" : "-D#{prefix}_CONFIG_MULTILEVEL_NO_SHARED")
|
|
529
532
|
flags << "-D#{prefix}_CONFIG_USE_NATIVE_BACKEND_ARITH" if NATIVE_ARITH
|
|
530
533
|
flags << "-D#{prefix}_CONFIG_USE_NATIVE_BACKEND_FIPS202" if NATIVE_FIPS202
|
|
@@ -66,6 +66,41 @@ int pq_mldsa_compute_tr_from_public_key(uint8_t *tr_out, const uint8_t *public_k
|
|
|
66
66
|
return pq_shake256(tr_out, PQ_MLDSA_TRBYTES, public_key, public_key_len);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
#define PQ_DEFINE_SIGNATURE_EXTMU_COMPAT(level, native, sig_bytes) \
|
|
70
|
+
int pq_mldsa##level##_signature_extmu_compat(uint8_t *sig, size_t *siglen, const uint8_t *mu, \
|
|
71
|
+
const uint8_t *sk) { \
|
|
72
|
+
if (sig == NULL || siglen == NULL || mu == NULL || sk == NULL) { \
|
|
73
|
+
return -1; \
|
|
74
|
+
} \
|
|
75
|
+
if (native##_signature_extmu(sig, mu, sk) != 0) { \
|
|
76
|
+
*siglen = 0; \
|
|
77
|
+
return -1; \
|
|
78
|
+
} \
|
|
79
|
+
*siglen = (size_t)(sig_bytes); \
|
|
80
|
+
return 0; \
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
PQ_DEFINE_SIGNATURE_EXTMU_COMPAT(44, pqcr_mldsa44, MLDSA44_BYTES)
|
|
84
|
+
PQ_DEFINE_SIGNATURE_EXTMU_COMPAT(65, pqcr_mldsa65, MLDSA65_BYTES)
|
|
85
|
+
PQ_DEFINE_SIGNATURE_EXTMU_COMPAT(87, pqcr_mldsa87, MLDSA87_BYTES)
|
|
86
|
+
|
|
87
|
+
#undef PQ_DEFINE_SIGNATURE_EXTMU_COMPAT
|
|
88
|
+
|
|
89
|
+
#define PQ_DEFINE_VERIFY_EXTMU_COMPAT(level, native, sig_bytes) \
|
|
90
|
+
int pq_mldsa##level##_verify_extmu_compat(const uint8_t *sig, size_t siglen, \
|
|
91
|
+
const uint8_t *mu, const uint8_t *pk) { \
|
|
92
|
+
if (sig == NULL || mu == NULL || pk == NULL || siglen != (size_t)(sig_bytes)) { \
|
|
93
|
+
return -1; \
|
|
94
|
+
} \
|
|
95
|
+
return native##_verify_extmu(sig, mu, pk); \
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
PQ_DEFINE_VERIFY_EXTMU_COMPAT(44, pqcr_mldsa44, MLDSA44_BYTES)
|
|
99
|
+
PQ_DEFINE_VERIFY_EXTMU_COMPAT(65, pqcr_mldsa65, MLDSA65_BYTES)
|
|
100
|
+
PQ_DEFINE_VERIFY_EXTMU_COMPAT(87, pqcr_mldsa87, MLDSA87_BYTES)
|
|
101
|
+
|
|
102
|
+
#undef PQ_DEFINE_VERIFY_EXTMU_COMPAT
|
|
103
|
+
|
|
69
104
|
int pq_sign_mu(uint8_t *signature, size_t *signature_len, const uint8_t *mu,
|
|
70
105
|
const uint8_t *secret_key,
|
|
71
106
|
int (*signature_extmu)(uint8_t *, size_t *, const uint8_t *, const uint8_t *)) {
|
|
@@ -15,49 +15,62 @@
|
|
|
15
15
|
* MLD_CONFIG_NAMESPACE_PREFIX=pqcr_mldsa
|
|
16
16
|
* and MLK/MLD_CONFIG_MULTILEVEL_BUILD enabled. Do not add PQClean aliases here:
|
|
17
17
|
* we want one backend only so build/runtime failures point at the new stack.
|
|
18
|
+
*
|
|
19
|
+
* mldsa-native v2.0.0 removed the `siglen` in/out parameter from the signing
|
|
20
|
+
* and verification APIs: signatures are always exactly MLDSA_BYTES(level) and
|
|
21
|
+
* the buffer size is part of the API contract rather than a runtime value.
|
|
22
|
+
*
|
|
23
|
+
* Two consequences for every caller in this extension:
|
|
24
|
+
* 1. Signing no longer reports the produced length. Each pq_crypto wrapper
|
|
25
|
+
* sets its own *signature_len from the compile-time constant, and clears
|
|
26
|
+
* it to 0 on failure, preserving the pre-v2 pq_crypto contract.
|
|
27
|
+
* 2. Verification no longer rejects a wrongly sized signature. The caller
|
|
28
|
+
* MUST check the length itself before handing the buffer to
|
|
29
|
+
* pqcr_mldsa*_verify / pqcr_mldsa*_verify_extmu, which read
|
|
30
|
+
* MLDSA_BYTES(level) bytes unconditionally.
|
|
18
31
|
*/
|
|
19
32
|
|
|
20
|
-
#define MLKEM512_SECRETKEYBYTES
|
|
21
|
-
#define MLKEM512_PUBLICKEYBYTES
|
|
22
|
-
#define MLKEM512_CIPHERTEXTBYTES
|
|
23
|
-
#define MLKEM512_SHAREDSECRETBYTES
|
|
33
|
+
#define MLKEM512_SECRETKEYBYTES 1632
|
|
34
|
+
#define MLKEM512_PUBLICKEYBYTES 800
|
|
35
|
+
#define MLKEM512_CIPHERTEXTBYTES 768
|
|
36
|
+
#define MLKEM512_SHAREDSECRETBYTES 32
|
|
24
37
|
|
|
25
|
-
#define MLKEM768_SECRETKEYBYTES
|
|
26
|
-
#define MLKEM768_PUBLICKEYBYTES
|
|
27
|
-
#define MLKEM768_CIPHERTEXTBYTES
|
|
28
|
-
#define MLKEM768_SHAREDSECRETBYTES
|
|
38
|
+
#define MLKEM768_SECRETKEYBYTES 2400
|
|
39
|
+
#define MLKEM768_PUBLICKEYBYTES 1184
|
|
40
|
+
#define MLKEM768_CIPHERTEXTBYTES 1088
|
|
41
|
+
#define MLKEM768_SHAREDSECRETBYTES 32
|
|
29
42
|
|
|
30
43
|
#define MLKEM1024_SECRETKEYBYTES 3168
|
|
31
44
|
#define MLKEM1024_PUBLICKEYBYTES 1568
|
|
32
45
|
#define MLKEM1024_CIPHERTEXTBYTES 1568
|
|
33
46
|
#define MLKEM1024_SHAREDSECRETBYTES 32
|
|
34
47
|
|
|
35
|
-
#define MLKEM_PUBLICKEYBYTES
|
|
36
|
-
#define MLKEM_SECRETKEYBYTES
|
|
37
|
-
#define MLKEM_CIPHERTEXTBYTES
|
|
38
|
-
#define MLKEM_SHAREDSECRETBYTES
|
|
39
|
-
|
|
40
|
-
#define MLDSA44_SECRETKEYBYTES
|
|
41
|
-
#define MLDSA44_PUBLICKEYBYTES
|
|
42
|
-
#define MLDSA44_BYTES
|
|
43
|
-
|
|
44
|
-
#define MLDSA65_SECRETKEYBYTES
|
|
45
|
-
#define MLDSA65_PUBLICKEYBYTES
|
|
46
|
-
#define MLDSA65_BYTES
|
|
47
|
-
|
|
48
|
-
#define MLDSA87_SECRETKEYBYTES
|
|
49
|
-
#define MLDSA87_PUBLICKEYBYTES
|
|
50
|
-
#define MLDSA87_BYTES
|
|
51
|
-
|
|
52
|
-
#define MLDSA_PUBLICKEYBYTES
|
|
53
|
-
#define MLDSA_SECRETKEYBYTES
|
|
54
|
-
#define MLDSA_BYTES
|
|
55
|
-
#define MLDSA_SEEDBYTES
|
|
56
|
-
#define MLDSA_RNDBYTES
|
|
57
|
-
#define MLDSA_TRBYTES
|
|
58
|
-
#define MLDSA_CRHBYTES
|
|
48
|
+
#define MLKEM_PUBLICKEYBYTES MLKEM768_PUBLICKEYBYTES
|
|
49
|
+
#define MLKEM_SECRETKEYBYTES MLKEM768_SECRETKEYBYTES
|
|
50
|
+
#define MLKEM_CIPHERTEXTBYTES MLKEM768_CIPHERTEXTBYTES
|
|
51
|
+
#define MLKEM_SHAREDSECRETBYTES MLKEM768_SHAREDSECRETBYTES
|
|
52
|
+
|
|
53
|
+
#define MLDSA44_SECRETKEYBYTES 2560
|
|
54
|
+
#define MLDSA44_PUBLICKEYBYTES 1312
|
|
55
|
+
#define MLDSA44_BYTES 2420
|
|
56
|
+
|
|
57
|
+
#define MLDSA65_SECRETKEYBYTES 4032
|
|
58
|
+
#define MLDSA65_PUBLICKEYBYTES 1952
|
|
59
|
+
#define MLDSA65_BYTES 3309
|
|
60
|
+
|
|
61
|
+
#define MLDSA87_SECRETKEYBYTES 4896
|
|
62
|
+
#define MLDSA87_PUBLICKEYBYTES 2592
|
|
63
|
+
#define MLDSA87_BYTES 4627
|
|
64
|
+
|
|
65
|
+
#define MLDSA_PUBLICKEYBYTES MLDSA65_PUBLICKEYBYTES
|
|
66
|
+
#define MLDSA_SECRETKEYBYTES MLDSA65_SECRETKEYBYTES
|
|
67
|
+
#define MLDSA_BYTES MLDSA65_BYTES
|
|
68
|
+
#define MLDSA_SEEDBYTES 32
|
|
69
|
+
#define MLDSA_RNDBYTES 32
|
|
70
|
+
#define MLDSA_TRBYTES 64
|
|
71
|
+
#define MLDSA_CRHBYTES 64
|
|
59
72
|
#define MLDSA_DOMAIN_SEPARATION_MAX_BYTES (2 + 255 + 11 + 64)
|
|
60
|
-
#define MLDSA_PREHASH_NONE
|
|
73
|
+
#define MLDSA_PREHASH_NONE 0
|
|
61
74
|
|
|
62
75
|
/* mlkem-native symbols: namespace prefix pqcr_mlkem + level suffix. */
|
|
63
76
|
int pqcr_mlkem512_keypair(uint8_t *pk, uint8_t *sk);
|
|
@@ -84,58 +97,55 @@ void pqcr_mlkem_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen);
|
|
|
84
97
|
/* mldsa-native symbols: namespace prefix pqcr_mldsa + level suffix. */
|
|
85
98
|
int pqcr_mldsa44_keypair(uint8_t *pk, uint8_t *sk);
|
|
86
99
|
int pqcr_mldsa44_keypair_internal(uint8_t *pk, uint8_t *sk, const uint8_t seed[MLDSA_SEEDBYTES]);
|
|
87
|
-
int pqcr_mldsa44_signature(uint8_t *sig,
|
|
88
|
-
|
|
89
|
-
int pqcr_mldsa44_signature_internal(uint8_t *sig,
|
|
90
|
-
size_t
|
|
91
|
-
const uint8_t
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
int pqcr_mldsa44_signature_extmu(uint8_t *sig,
|
|
99
|
-
|
|
100
|
-
int pqcr_mldsa44_verify_extmu(const uint8_t *sig, size_t siglen, const uint8_t mu[MLDSA_CRHBYTES],
|
|
100
|
+
int pqcr_mldsa44_signature(uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *ctx,
|
|
101
|
+
size_t ctxlen, const uint8_t *sk);
|
|
102
|
+
int pqcr_mldsa44_signature_internal(uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *pre,
|
|
103
|
+
size_t prelen, const uint8_t rnd[MLDSA_RNDBYTES],
|
|
104
|
+
const uint8_t *sk, int externalmu);
|
|
105
|
+
int pqcr_mldsa44_verify(const uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *ctx,
|
|
106
|
+
size_t ctxlen, const uint8_t *pk);
|
|
107
|
+
size_t
|
|
108
|
+
pqcr_mldsa44_prepare_domain_separation_prefix(uint8_t prefix[MLDSA_DOMAIN_SEPARATION_MAX_BYTES],
|
|
109
|
+
const uint8_t *ph, size_t phlen, const uint8_t *ctx,
|
|
110
|
+
size_t ctxlen, int hashalg);
|
|
111
|
+
int pqcr_mldsa44_signature_extmu(uint8_t *sig, const uint8_t mu[MLDSA_CRHBYTES], const uint8_t *sk);
|
|
112
|
+
int pqcr_mldsa44_verify_extmu(const uint8_t *sig, const uint8_t mu[MLDSA_CRHBYTES],
|
|
101
113
|
const uint8_t *pk);
|
|
102
114
|
int pqcr_mldsa44_pk_from_sk(uint8_t *pk, const uint8_t *sk);
|
|
103
115
|
|
|
104
116
|
int pqcr_mldsa65_keypair(uint8_t *pk, uint8_t *sk);
|
|
105
117
|
int pqcr_mldsa65_keypair_internal(uint8_t *pk, uint8_t *sk, const uint8_t seed[MLDSA_SEEDBYTES]);
|
|
106
|
-
int pqcr_mldsa65_signature(uint8_t *sig,
|
|
107
|
-
|
|
108
|
-
int pqcr_mldsa65_signature_internal(uint8_t *sig,
|
|
109
|
-
size_t
|
|
110
|
-
const uint8_t
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
int pqcr_mldsa65_signature_extmu(uint8_t *sig,
|
|
118
|
-
|
|
119
|
-
int pqcr_mldsa65_verify_extmu(const uint8_t *sig, size_t siglen, const uint8_t mu[MLDSA_CRHBYTES],
|
|
118
|
+
int pqcr_mldsa65_signature(uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *ctx,
|
|
119
|
+
size_t ctxlen, const uint8_t *sk);
|
|
120
|
+
int pqcr_mldsa65_signature_internal(uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *pre,
|
|
121
|
+
size_t prelen, const uint8_t rnd[MLDSA_RNDBYTES],
|
|
122
|
+
const uint8_t *sk, int externalmu);
|
|
123
|
+
int pqcr_mldsa65_verify(const uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *ctx,
|
|
124
|
+
size_t ctxlen, const uint8_t *pk);
|
|
125
|
+
size_t
|
|
126
|
+
pqcr_mldsa65_prepare_domain_separation_prefix(uint8_t prefix[MLDSA_DOMAIN_SEPARATION_MAX_BYTES],
|
|
127
|
+
const uint8_t *ph, size_t phlen, const uint8_t *ctx,
|
|
128
|
+
size_t ctxlen, int hashalg);
|
|
129
|
+
int pqcr_mldsa65_signature_extmu(uint8_t *sig, const uint8_t mu[MLDSA_CRHBYTES], const uint8_t *sk);
|
|
130
|
+
int pqcr_mldsa65_verify_extmu(const uint8_t *sig, const uint8_t mu[MLDSA_CRHBYTES],
|
|
120
131
|
const uint8_t *pk);
|
|
121
132
|
int pqcr_mldsa65_pk_from_sk(uint8_t *pk, const uint8_t *sk);
|
|
122
133
|
|
|
123
134
|
int pqcr_mldsa87_keypair(uint8_t *pk, uint8_t *sk);
|
|
124
135
|
int pqcr_mldsa87_keypair_internal(uint8_t *pk, uint8_t *sk, const uint8_t seed[MLDSA_SEEDBYTES]);
|
|
125
|
-
int pqcr_mldsa87_signature(uint8_t *sig,
|
|
126
|
-
|
|
127
|
-
int pqcr_mldsa87_signature_internal(uint8_t *sig,
|
|
128
|
-
size_t
|
|
129
|
-
const uint8_t
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
int pqcr_mldsa87_signature_extmu(uint8_t *sig,
|
|
137
|
-
|
|
138
|
-
int pqcr_mldsa87_verify_extmu(const uint8_t *sig, size_t siglen, const uint8_t mu[MLDSA_CRHBYTES],
|
|
136
|
+
int pqcr_mldsa87_signature(uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *ctx,
|
|
137
|
+
size_t ctxlen, const uint8_t *sk);
|
|
138
|
+
int pqcr_mldsa87_signature_internal(uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *pre,
|
|
139
|
+
size_t prelen, const uint8_t rnd[MLDSA_RNDBYTES],
|
|
140
|
+
const uint8_t *sk, int externalmu);
|
|
141
|
+
int pqcr_mldsa87_verify(const uint8_t *sig, const uint8_t *m, size_t mlen, const uint8_t *ctx,
|
|
142
|
+
size_t ctxlen, const uint8_t *pk);
|
|
143
|
+
size_t
|
|
144
|
+
pqcr_mldsa87_prepare_domain_separation_prefix(uint8_t prefix[MLDSA_DOMAIN_SEPARATION_MAX_BYTES],
|
|
145
|
+
const uint8_t *ph, size_t phlen, const uint8_t *ctx,
|
|
146
|
+
size_t ctxlen, int hashalg);
|
|
147
|
+
int pqcr_mldsa87_signature_extmu(uint8_t *sig, const uint8_t mu[MLDSA_CRHBYTES], const uint8_t *sk);
|
|
148
|
+
int pqcr_mldsa87_verify_extmu(const uint8_t *sig, const uint8_t mu[MLDSA_CRHBYTES],
|
|
139
149
|
const uint8_t *pk);
|
|
140
150
|
int pqcr_mldsa87_pk_from_sk(uint8_t *pk, const uint8_t *sk);
|
|
141
151
|
|
|
@@ -173,11 +173,11 @@ typedef struct {
|
|
|
173
173
|
|
|
174
174
|
static const pq_mldsa_profile_t MLDSA_PROFILES[] = {
|
|
175
175
|
{"ml_dsa_44", MLDSA44_PUBLICKEYBYTES, MLDSA44_SECRETKEYBYTES, MLDSA44_BYTES,
|
|
176
|
-
pqcr_mldsa44_pk_from_sk,
|
|
176
|
+
pqcr_mldsa44_pk_from_sk, pq_mldsa44_signature_extmu_compat, pq_mldsa44_verify_extmu_compat},
|
|
177
177
|
{"ml_dsa_65", MLDSA65_PUBLICKEYBYTES, MLDSA65_SECRETKEYBYTES, MLDSA65_BYTES,
|
|
178
|
-
pqcr_mldsa65_pk_from_sk,
|
|
178
|
+
pqcr_mldsa65_pk_from_sk, pq_mldsa65_signature_extmu_compat, pq_mldsa65_verify_extmu_compat},
|
|
179
179
|
{"ml_dsa_87", MLDSA87_PUBLICKEYBYTES, MLDSA87_SECRETKEYBYTES, MLDSA87_BYTES,
|
|
180
|
-
pqcr_mldsa87_pk_from_sk,
|
|
180
|
+
pqcr_mldsa87_pk_from_sk, pq_mldsa87_signature_extmu_compat, pq_mldsa87_verify_extmu_compat},
|
|
181
181
|
};
|
|
182
182
|
|
|
183
183
|
static const pq_mldsa_profile_t *pq_mldsa_profile_from_value(VALUE algorithm) {
|
|
@@ -1306,7 +1306,8 @@ PQ_DEFINE_RUBY_MLDSA_SIGN(ml_dsa_87_sign, mldsa_87_sign, MLDSA87_SECRETKEYBYTES,
|
|
|
1306
1306
|
#undef PQ_DEFINE_RUBY_MLDSA_SIGN
|
|
1307
1307
|
|
|
1308
1308
|
static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signature, VALUE public_key,
|
|
1309
|
-
VALUE context, size_t public_key_len_expected
|
|
1309
|
+
VALUE context, size_t public_key_len_expected,
|
|
1310
|
+
size_t signature_len_expected) {
|
|
1310
1311
|
StringValue(signature);
|
|
1311
1312
|
pq_validate_bytes_argument(public_key, public_key_len_expected, "public key");
|
|
1312
1313
|
StringValue(context);
|
|
@@ -1314,6 +1315,10 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
|
|
|
1314
1315
|
rb_raise(rb_eArgError, "ML-DSA context length must be <= 255 bytes");
|
|
1315
1316
|
}
|
|
1316
1317
|
|
|
1318
|
+
if ((size_t)RSTRING_LEN(signature) != signature_len_expected) {
|
|
1319
|
+
return Qfalse;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1317
1322
|
verify_call_t call = {0};
|
|
1318
1323
|
size_t public_key_len = 0;
|
|
1319
1324
|
size_t signature_len = 0;
|
|
@@ -1341,7 +1346,7 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
|
|
|
1341
1346
|
pq_raise_general_error(call.result);
|
|
1342
1347
|
}
|
|
1343
1348
|
|
|
1344
|
-
#define PQ_DEFINE_RUBY_MLDSA_VERIFY(rb_name, nogvl_stem, pk_bytes)
|
|
1349
|
+
#define PQ_DEFINE_RUBY_MLDSA_VERIFY(rb_name, nogvl_stem, pk_bytes, sig_bytes) \
|
|
1345
1350
|
static VALUE pqcrypto_##rb_name(int argc, VALUE *argv, VALUE self) { \
|
|
1346
1351
|
(void)self; \
|
|
1347
1352
|
VALUE message, signature, public_key, context; \
|
|
@@ -1350,12 +1355,14 @@ static VALUE pq_run_verify(void *(*nogvl)(void *), VALUE message, VALUE signatur
|
|
|
1350
1355
|
context = rb_str_new("", 0); \
|
|
1351
1356
|
} \
|
|
1352
1357
|
return pq_run_verify(pq_##nogvl_stem##_nogvl, message, signature, public_key, context, \
|
|
1353
|
-
pk_bytes);
|
|
1358
|
+
pk_bytes, sig_bytes); \
|
|
1354
1359
|
}
|
|
1355
1360
|
|
|
1356
|
-
PQ_DEFINE_RUBY_MLDSA_VERIFY(verify, verify, PQ_MLDSA_PUBLICKEYBYTES)
|
|
1357
|
-
PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_44_verify, mldsa_44_verify, MLDSA44_PUBLICKEYBYTES
|
|
1358
|
-
|
|
1361
|
+
PQ_DEFINE_RUBY_MLDSA_VERIFY(verify, verify, PQ_MLDSA_PUBLICKEYBYTES, PQ_MLDSA_BYTES)
|
|
1362
|
+
PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_44_verify, mldsa_44_verify, MLDSA44_PUBLICKEYBYTES,
|
|
1363
|
+
MLDSA44_BYTES)
|
|
1364
|
+
PQ_DEFINE_RUBY_MLDSA_VERIFY(ml_dsa_87_verify, mldsa_87_verify, MLDSA87_PUBLICKEYBYTES,
|
|
1365
|
+
MLDSA87_BYTES)
|
|
1359
1366
|
|
|
1360
1367
|
#undef PQ_DEFINE_RUBY_MLDSA_VERIFY
|
|
1361
1368
|
|
|
@@ -322,27 +322,29 @@ PQ_DEFINE_MLDSA_SIGN_KEYPAIR(mldsa87_sign, pqcr_mldsa87)
|
|
|
322
322
|
|
|
323
323
|
#undef PQ_DEFINE_MLDSA_SIGN_KEYPAIR
|
|
324
324
|
|
|
325
|
-
#define PQ_DEFINE_MLDSA_SIGN(name, native)
|
|
326
|
-
int pq_##name(uint8_t *signature, size_t *signature_len, const uint8_t *message,
|
|
327
|
-
size_t message_len, const uint8_t *ctx, size_t ctx_len,
|
|
328
|
-
const uint8_t *secret_key) {
|
|
329
|
-
if (!signature || !signature_len || !secret_key || (message_len > 0 && !message) ||
|
|
330
|
-
(ctx_len > 0 && !ctx) || ctx_len > 255) {
|
|
331
|
-
return PQ_ERROR_BUFFER;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
PQ_DEFINE_MLDSA_SIGN(
|
|
325
|
+
#define PQ_DEFINE_MLDSA_SIGN(name, native, sig_bytes) \
|
|
326
|
+
int pq_##name(uint8_t *signature, size_t *signature_len, const uint8_t *message, \
|
|
327
|
+
size_t message_len, const uint8_t *ctx, size_t ctx_len, \
|
|
328
|
+
const uint8_t *secret_key) { \
|
|
329
|
+
if (!signature || !signature_len || !secret_key || (message_len > 0 && !message) || \
|
|
330
|
+
(ctx_len > 0 && !ctx) || ctx_len > 255) { \
|
|
331
|
+
return PQ_ERROR_BUFFER; \
|
|
332
|
+
} \
|
|
333
|
+
if (native##_signature(signature, message, message_len, ctx, ctx_len, secret_key) != 0) { \
|
|
334
|
+
*signature_len = 0; \
|
|
335
|
+
return PQ_ERROR_SIGN; \
|
|
336
|
+
} \
|
|
337
|
+
*signature_len = (size_t)(sig_bytes); \
|
|
338
|
+
return PQ_SUCCESS; \
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
PQ_DEFINE_MLDSA_SIGN(sign, pqcr_mldsa65, MLDSA65_BYTES)
|
|
342
|
+
PQ_DEFINE_MLDSA_SIGN(mldsa44_sign, pqcr_mldsa44, MLDSA44_BYTES)
|
|
343
|
+
PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, pqcr_mldsa87, MLDSA87_BYTES)
|
|
342
344
|
|
|
343
345
|
#undef PQ_DEFINE_MLDSA_SIGN
|
|
344
346
|
|
|
345
|
-
#define PQ_DEFINE_MLDSA_VERIFY(name, native)
|
|
347
|
+
#define PQ_DEFINE_MLDSA_VERIFY(name, native, sig_bytes) \
|
|
346
348
|
int pq_##name(const uint8_t *signature, size_t signature_len, const uint8_t *message, \
|
|
347
349
|
size_t message_len, const uint8_t *ctx, size_t ctx_len, \
|
|
348
350
|
const uint8_t *public_key) { \
|
|
@@ -350,29 +352,32 @@ PQ_DEFINE_MLDSA_SIGN(mldsa87_sign, pqcr_mldsa87)
|
|
|
350
352
|
ctx_len > 255) { \
|
|
351
353
|
return PQ_ERROR_BUFFER; \
|
|
352
354
|
} \
|
|
353
|
-
|
|
354
|
-
|
|
355
|
+
if (signature_len != (size_t)(sig_bytes)) { \
|
|
356
|
+
return PQ_ERROR_VERIFY; \
|
|
357
|
+
} \
|
|
358
|
+
return native##_verify(signature, message, message_len, ctx, ctx_len, public_key) == 0 \
|
|
355
359
|
? PQ_SUCCESS \
|
|
356
360
|
: PQ_ERROR_VERIFY; \
|
|
357
361
|
}
|
|
358
362
|
|
|
359
|
-
PQ_DEFINE_MLDSA_VERIFY(verify, pqcr_mldsa65)
|
|
360
|
-
PQ_DEFINE_MLDSA_VERIFY(mldsa44_verify, pqcr_mldsa44)
|
|
361
|
-
PQ_DEFINE_MLDSA_VERIFY(mldsa87_verify, pqcr_mldsa87)
|
|
363
|
+
PQ_DEFINE_MLDSA_VERIFY(verify, pqcr_mldsa65, MLDSA65_BYTES)
|
|
364
|
+
PQ_DEFINE_MLDSA_VERIFY(mldsa44_verify, pqcr_mldsa44, MLDSA44_BYTES)
|
|
365
|
+
PQ_DEFINE_MLDSA_VERIFY(mldsa87_verify, pqcr_mldsa87, MLDSA87_BYTES)
|
|
362
366
|
|
|
363
367
|
#undef PQ_DEFINE_MLDSA_VERIFY
|
|
364
368
|
|
|
365
369
|
static int pq_testing_mldsa_sign_from_seed_with(
|
|
366
370
|
uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len,
|
|
367
|
-
const uint8_t *secret_key, const uint8_t *seed, size_t seed_len,
|
|
368
|
-
int (*signature_internal)(uint8_t *,
|
|
371
|
+
const uint8_t *secret_key, const uint8_t *seed, size_t seed_len, size_t expected_signature_len,
|
|
372
|
+
int (*signature_internal)(uint8_t *, const uint8_t *, size_t, const uint8_t *, size_t,
|
|
369
373
|
const uint8_t *, const uint8_t *, int),
|
|
370
374
|
size_t (*prepare_prefix)(uint8_t *, const uint8_t *, size_t, const uint8_t *, size_t, int)) {
|
|
371
375
|
uint8_t pre[MLDSA_DOMAIN_SEPARATION_MAX_BYTES];
|
|
372
376
|
size_t pre_len;
|
|
373
377
|
|
|
374
378
|
if (!signature || !signature_len || !secret_key || !seed || seed_len != MLDSA_RNDBYTES ||
|
|
375
|
-
!signature_internal || !prepare_prefix ||
|
|
379
|
+
!signature_internal || !prepare_prefix || expected_signature_len == 0 ||
|
|
380
|
+
(message_len > 0 && !message)) {
|
|
376
381
|
return PQ_ERROR_BUFFER;
|
|
377
382
|
}
|
|
378
383
|
|
|
@@ -385,13 +390,18 @@ static int pq_testing_mldsa_sign_from_seed_with(
|
|
|
385
390
|
*/
|
|
386
391
|
pre_len = prepare_prefix(pre, NULL, 0, NULL, 0, MLDSA_PREHASH_NONE);
|
|
387
392
|
if (pre_len == 0) {
|
|
393
|
+
*signature_len = 0;
|
|
388
394
|
return PQ_ERROR_SIGN;
|
|
389
395
|
}
|
|
390
396
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
if (signature_internal(signature, message, message_len, pre, pre_len, seed, secret_key, 0) !=
|
|
398
|
+
0) {
|
|
399
|
+
*signature_len = 0;
|
|
400
|
+
return PQ_ERROR_SIGN;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
*signature_len = expected_signature_len;
|
|
404
|
+
return PQ_SUCCESS;
|
|
395
405
|
}
|
|
396
406
|
|
|
397
407
|
int pq_mldsa44_keypair_from_seed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed32) {
|
|
@@ -447,7 +457,7 @@ int pq_testing_mldsa_sign_from_seed(uint8_t *signature, size_t *signature_len,
|
|
|
447
457
|
const uint8_t *secret_key, const uint8_t *seed,
|
|
448
458
|
size_t seed_len) {
|
|
449
459
|
return pq_testing_mldsa_sign_from_seed_with(
|
|
450
|
-
signature, signature_len, message, message_len, secret_key, seed, seed_len,
|
|
460
|
+
signature, signature_len, message, message_len, secret_key, seed, seed_len, MLDSA65_BYTES,
|
|
451
461
|
pqcr_mldsa65_signature_internal, pqcr_mldsa65_prepare_domain_separation_prefix);
|
|
452
462
|
}
|
|
453
463
|
|
|
@@ -456,7 +466,7 @@ int pq_testing_mldsa44_sign_from_seed(uint8_t *signature, size_t *signature_len,
|
|
|
456
466
|
const uint8_t *secret_key, const uint8_t *seed,
|
|
457
467
|
size_t seed_len) {
|
|
458
468
|
return pq_testing_mldsa_sign_from_seed_with(
|
|
459
|
-
signature, signature_len, message, message_len, secret_key, seed, seed_len,
|
|
469
|
+
signature, signature_len, message, message_len, secret_key, seed, seed_len, MLDSA44_BYTES,
|
|
460
470
|
pqcr_mldsa44_signature_internal, pqcr_mldsa44_prepare_domain_separation_prefix);
|
|
461
471
|
}
|
|
462
472
|
|
|
@@ -465,7 +475,7 @@ int pq_testing_mldsa87_sign_from_seed(uint8_t *signature, size_t *signature_len,
|
|
|
465
475
|
const uint8_t *secret_key, const uint8_t *seed,
|
|
466
476
|
size_t seed_len) {
|
|
467
477
|
return pq_testing_mldsa_sign_from_seed_with(
|
|
468
|
-
signature, signature_len, message, message_len, secret_key, seed, seed_len,
|
|
478
|
+
signature, signature_len, message, message_len, secret_key, seed, seed_len, MLDSA87_BYTES,
|
|
469
479
|
pqcr_mldsa87_signature_internal, pqcr_mldsa87_prepare_domain_separation_prefix);
|
|
470
480
|
}
|
|
471
481
|
|