130 Commits

Author SHA1 Message Date
Lukas Zobernig 58ce150e60 ml-dsa: fix hardcoded MlDsa44 in Wycheproof verification tests (#1382)
The mldsa_verify_test macro previously hardcoded MlDsa44 for decoding both verifying keys and signatures. Due to public key length mismatches, this caused tests for ML-DSA-65 and ML-DSA-87 to fail type conversion and be silently skipped.

Using $params ensures test vectors for all parameter sets are properly decoded and verified.
2026-06-17 08:03:34 -06:00
Thomas 57a7cd7519 feat(ml-dsa): expose c_tilde getter on Signature (#1362)
Add public accessor for the challenge hash component of ML-DSA
signatures, needed by hybrid schemes that share
the challenge across both classical and post-quantum components.
2026-06-06 07:13:05 -06:00
Tony Arcieri f75d5b8299 ml-dsa v0.1.1 (#1371) 2026-06-05 12:32:04 -06:00
Kingsley Yung c97a63150d ml-dsa: alloc feature implies module-lattice/alloc (#1365)
Enable `module-lattice/alloc` feature when the `alloc` feature is
enabled. With this change, users don't need to add an explicit entry
`module-lattice` at `Cargo.toml` to enable the `alloc` feature of the
`module-lattice` crate.

This also aligns with the behavior of the `ml-kem` crate.
2026-06-02 07:33:00 -06:00
Tony Arcieri 699547f9c3 ml-dsa v0.1.0 (#1356) 2026-05-17 09:37:36 -06:00
Tony Arcieri 4055f370fd ml-dsa: migrate from sha3 to shake (#1355)
See: RustCrypto/hashes#869
2026-05-16 12:28:18 -06:00
Tony Arcieri 59fea640a4 ml-dsa v0.1.0-rc.11 (#1351)
This should be a true "release candidate" in that there are no
additional changes intended to be made before a final release, we're
just waiting for some final feedback on recent changes.
2026-05-10 15:53:13 -06:00
Tony Arcieri 093267c91d ml-dsa: use MaybeBox from module-lattice crate (#1350)
The `MaybeBox` type was moved to `module-lattice` so it could also be
used with the `ml-kem` crate.

See RustCrypto/KEMs#309
2026-05-10 15:12:31 -06:00
Tony Arcieri fb08f196a7 ml-dsa: remove KeyGen trait (#1349)
It has been replaced by the `KeyInit` and `Generate` traits from the
`crypto-common` crate.

See also: #1342
2026-05-09 17:16:38 -06:00
Tony Arcieri 0842fa86ff ml-dsa: add SigningKey::as_seed (#1347)
Provides a way of borrowing `&Seed` instead of making a copy as with
`SigningKey::to_seed`.
2026-05-09 17:00:38 -06:00
Tony Arcieri e7f6a601f9 ml-dsa: precompute VerifyingKeys when alloc enabled (#1346)
Adds an `alloc`-gated `verifying_key` field to `SigningKey`, and when
the feature is enabled precomputes the key at the time the `SigningKey`
is initialized.

We previously used to do this but stopped to optimize stack usage (see
the changes in #1259 and #1261), however when `alloc` is enabled this
isn't an issue since we've moved the relevant data to the heap in this
case (see #1344 and #1345), so stack usage is no longer an issue.

This makes it possible to implement `signature::KeypairRef` for
`SigningKey` which still provides a blanket `signature::Keypair` impl,
so we can always depend on the latter being availble but take advantage
of the former when `alloc` is enabled.
2026-05-09 16:21:34 -06:00
Tony Arcieri c3ded0c799 ml-dsa: use MaybeBox for SigningKey (#1345)
Opportunistically stores the parts of `SigningKey` on the heap when the
`alloc` feature is enabled, similar to what #1344 did for
`VerifyingKey`.

This also addresses #1308 by adding a `Drop` (and `ZeroizeOnDrop`) impl
to `SigningKey` which clears the `Seed`.
2026-05-09 16:03:49 -06:00
Tony Arcieri 7336ca4af8 ml-dsa: use MaybeBox to store VerifyingKey (#1344)
When the `alloc` feature is enabled, uses `Box` to offload the largest
parts of `VerifyingKey` to the heap.

This also extracts an internal `PrecomputedValues` struct to store the
largest components of the key, which are all derived/precomputed values,
as a single contiguous struct in a `MaybeBox`, and extracts some of the
relevant logic to it.
2026-05-09 15:28:23 -06:00
Tony Arcieri e3f07e9ce5 ml-dsa: expand usage docs (#1343) 2026-05-09 14:53:34 -06:00
Tony Arcieri 62fa7ac438 ml-dsa: implement KeyInit, KeyExport, KeySizeUser (#1342)
Implements these traits sourced from the `crypto-common` crate.

Also implements the `Generate` trait for key generation, replacing the
previous `KeyGen` trait, which this commit deprecates in favor of using
`KeyInit` and `Generate`.

This also adds a `getrandom` feature that forwards through to
`crypto-common`, making methods available on the `Generate` trait when
enabled.
2026-05-09 14:19:30 -06:00
Tony Arcieri 20b0095bd9 ml-dsa: factor from_seed method onto SigningKey (#1341)
Extracts a `SigningKey::from_seed` that was previously defined on
`MlDsaParams` via a trait impl.

This changes it to an inherent method, and has the trait method call the
inherent method.

This makes it possible to restrict the visibility of `SigningKey`
fields, addressing a TODO.
2026-05-08 10:12:42 -06:00
Tony Arcieri f9f4c60d78 ml-dsa: rename ExpandedSigningKey field/method to expanded_key (#1340)
This is a vestige from when `SigningKey` was a keypair type.

Also marks it `#[doc(hidden)]` as it exists primarily for testing.
2026-05-08 09:34:29 -06:00
Tony Arcieri e5f9f64231 ml-dsa: extract signing and verifying modules (#1339)
Extracts code previously in `lib.rs` related to the following types into
two modules:

- `signing`: `SigningKey`, `ExpandedSigningKey`
- `verifying`: `VerifyingKey`
2026-05-08 09:04:40 -06:00
Tony Arcieri 0c7cf02d1b ml-dsa: apply and fix workspace-level lints (#1338)
Applies the workspace-level config added in #1323 to this crate and
fixes any failures.
2026-05-07 21:14:26 -06:00
xjd 4854bcfa4d ml-dsa: optimize rejection sampling in rej_(ntt|bounded)_poly (#1291)
It seems like filling matrix is a bottleneck of decoding encapsulation key.

With simple changes, it gets better performance.
2026-05-06 12:45:56 -06:00
Tony Arcieri e0d47990aa Update copyright year to 2026 (#1322) 2026-05-02 18:10:44 -06:00
Tony Arcieri 088a4fe7a4 Bump signature dependency to v3 (#1321)
Release PR: RustCrypto/traits#2400
2026-05-02 15:16:18 -06:00
Onyeka Obi 826baa3682 Implement Hash on non-secret Signature and VerifyingKey types (#1309)
Per #1229: Signature and public-key types lack `Hash`, which prevents
use in `HashMap` / `HashSet` keys and similar collections.

- ecdsa: Signature, DER Signature, SignatureWithOid
- ed25519: Signature, pkcs8::PublicKeyBytes
- ed448: Signature, pkcs8::PublicKeyBytes
- ml-dsa: Signature, VerifyingKey
- slh-dsa: Signature, VerifyingKey

Where a trivial derive works (ed25519, ed448), uses derive. Where
generic bounds or upstream gaps require it, uses a manual impl over
the canonical serialized bytes (`to_bytes` / `encode` / `as_bytes`),
which is the natural Hash domain for these types anyway.

Closes #1229
2026-05-01 16:17:15 -06:00
Tony Arcieri f3c409ee83 ml-dsa: add internal MaybeBox type (#1320)
Adds an internal type for opportunistic heap offload which uses `Box`
when the `alloc` feature is available and falls back to stack allocation
when it is not.

So far it's only used for the `z` component of `Signature` but is useful
elsewhere, e.g. for `VerifyingKey`.

It's so generally useful it should probably get extracted somewhere, to
`module-lattice` at the very least, but this is enough to get started.
2026-04-30 11:13:41 -06:00
Tony Arcieri 58bae19939 Cut new prereleases (#1319)
Releases the following, which all now depend either directly or
transitively on `pkcs8` v0.11 (which had breaking changes in the final
release)

- `dsa` v0.7.0-rc.15
- `ecdsa` v0.17.0-rc.18
- `ed25519` v3.0.0-rc.5
- `ed448` v0.5.0-rc.6
- `ml-dsa` v0.1.0-rc.9
- `slh-dsa` v0.2.0-rc.5
- `xmss` v0.1.0-pre.1
2026-04-28 10:08:48 -06:00
Tony Arcieri 2eadc3c766 ml-dsa: bump module-lattice to v0.2.2 (#1318) 2026-04-28 09:36:10 -06:00
Tony Arcieri 86c035a74f Bump pkcs8 dependency to v0.11 (#1316)
Release PR: RustCrypto/formats#2314
2026-04-28 08:32:20 -06:00
Tony Arcieri d8b1875a9f Bump pkcs8 to v0.11.0-rc.12 (#1312) 2026-04-27 13:07:45 -06:00
Tony Arcieri f93d5022da ml-dsa: fix unreachable_pub lint by making Eta pub (#1311)
This lint started failing, seemingly as of Rust 1.95. Though this may
not be the best solution, to get the lint to pass again this makes `Eta`
pub.
2026-04-27 09:15:21 -06:00
Peter Membrey ecaf35904d ml-dsa: zeroize NTT-domain derived values in ExpandedSigningKey Drop (#1300)
The existing Drop impl for ExpandedSigningKey (gated on the zeroize
feature) zeroizes rho, K, tr, s1, s2, and t0 but skips the
NTT-domain derived values s1_hat, s2_hat, and t0_hat.

The NTT is invertible, so s1_hat in memory is equivalent to having
s1. This leaves secret key material unzeroized after drop.

Add s1_hat, s2_hat, and t0_hat to the Drop impl. All three are
NttVector types which implement Zeroize via module-lattice.

A_hat (the public matrix derived from rho) is not zeroized here
because NttMatrix does not implement Zeroize in module-lattice.
A_hat is derived from public data (rho) so this is lower priority,
but a follow-up PR to module-lattice could add Zeroize for NttMatrix
for completeness.
2026-04-15 10:53:09 -06:00
Arthur Gautier d011b9a356 ml-dsa: make PartialEq for ExpandedSigningKey constant time (#1286) 2026-04-03 16:58:36 -06:00
Tony Arcieri fc8907dde0 Bump sha3 dependency to v0.11 (#1283)
Release PR: RustCrypto/hashes#816
2026-04-03 08:34:07 -06:00
Arthur Gautier 73e7128459 ml-dsa: missing derives on SigningKey (#1281)
When ExpandedSigningKey was split from SigningKey in #1261, the derive
for Clone and PartialEq got removed.
2026-04-02 22:17:29 -06:00
Tony Arcieri ecfc95ebc4 ml-dsa v0.1.0-rc.8 (#1272) 2026-03-26 14:38:29 -06:00
Tony Arcieri 4deba8ec98 ml-dsa: bump module-lattice to v0.2 (#1271)
Release PR: RustCrypto/KEMs#279
2026-03-26 13:36:24 -06:00
Scott Arciszewski 7b0ffd01c1 ml-dsa: use ctutils for constant-time selection; avoid branches (#1245) 2026-03-26 13:19:57 -06:00
Tony Arcieri cdc95068ae Bump pkcs8 to v0.11.0-rc.11 (#1270) 2026-03-26 13:17:39 -06:00
Tony Arcieri 4288c5932c ml-dsa: bump module-lattice to v0.2.0-rc.0 (#1269)
The main changes don't impact this crate (migrating from `subtle` to
`ctutils`, which is used by `ml-kem`)
2026-03-26 09:38:02 -06:00
Arthur Gautier c5989c900e ml-dsa: lower stack size of KeyGen::from_seed by up to 207kb (#1261)
This reworks the API to make KeyGen::from_seed return a
`SeededSigningKey` instead of a `KeyPair`.
The `SeededSigningKey` effectively replaces the `KeyPair`, and instead
of eagerly generating the VerifyingKey (implementing
`signature::KeypairRef`), it implements `signature::Keypair` and makes
the verifying key when requested.

This reduces the depth of the stack when calling from_seed and reduces
the size of the stack by 207kb using ML-DSA-87 in debug/tests builds
(the heaviest consumers).

This is an API break.
2026-03-25 13:32:06 -06:00
philomathic_life 71b1152625 ml-dsa: re-export pkcs8 (#1265)
Re-exports traits/types from the `pkcs8` crate under `ml_dsa::pkcs8`
2026-03-25 11:26:56 -06:00
Arthur Gautier d6e621b86b ml-dsa: lower stack usage of KeyPair::from_seed by up to 112kb (#1259)
When using the KeyGen::from_seed is used, the A Matrix is
computed (using `expand_a`).

By design, the matrix is kept on the stack, and two copies end up being
held (One in the `SigningKey` and another one in the `VerifyingKey`).
That matrix takes up to 56kB for ML-DSA-87.

Because two `SigningKey::new`/`VerifyingKey::new` code paths maybe
used without the A matrix (when decoding from an expanded key), the code
paths for both builder end up having to store two copies of the matrix
and increases the stack size.

This is all private API and does not break any of the public API.

This only affects the debug/test builds as the release builds appears to
optimize the unwrap_or_else and not use extraneous stack space.
2026-03-20 09:32:56 -06:00
Tony Arcieri 8699f8f010 dsa+ecdsa: bump digest to v0.11 (#1237)
Release PR: RustCrypto/traits#2300
2026-03-02 08:39:12 -07:00
Tony Arcieri 3db77e32fa ml-dsa: bump module-lattice dependency to v0.1 (#1213)
Initial stable release
2026-02-05 13:52:31 -07:00
Tony Arcieri 70986609af ml-dsa: bump module-lattice to v0.1.0-rc.1 (#1209)
Also cuts an `ml-dsa` v0.1.0-rc.7 release
2026-02-03 09:27:52 -07:00
Tony Arcieri b8fe5097b6 ml-dsa: use flattened module-lattice API (#1208)
Companion PR to RustCrypto/KEMs#244
2026-02-03 09:06:29 -07:00
Tony Arcieri a8fb994c39 Bump dependency requirements in Cargo.toml files (#1206)
Updates the following dependency requirements:
- `cipher` v0.5.0-rc.8
- `crypto-bigint` v0.7.0-rc.25
- `ctr` v0.10.0-rc.3
- `digest` v0.11.0-rc.11
- `getrandom` v0.4
- `hmac` v0.13.0-rc.5
- `sha1` v0.11.0-rc.5
- `sha2` v0.11.0-rc.5
- `sha3` v0.11.0-rc.7

This also does the following:
- `ecdsa`: `EncodedPoint` => `Sec1Point` (RustCrypto/traits#2264)
- `slh-dsa`: adds back to workspace with `rand` sourced from `git`

Releases the following:
- `dsa` v0.7.0-rc.12
- `ecdsa` v0.17.0-rc.16
- `ed25519` v0.3.0-rc.4
- `ed448` v0.5.0-rc.5
- `lms-signature` v0.1.0-rc.2
- `ml-dsa` v0.1.0-rc.6
- `rfc6979` v0.5.0-rc.5
- `slh-dsa` v0.2.0-rc.4
2026-02-02 13:10:39 -07:00
Tony Arcieri 72b44e49c6 Bump getrandom to v0.4 (#1205)
Release PR: rust-random/getrandom#798
2026-02-02 10:16:09 -07:00
Tony Arcieri a0473fb042 Bump rand_core to v0.10.0 (#1197)
NOTE: temporarily excludes `slh-dsa` from the workspace until `rand` is
bumped because it is the only crate that depends on it

Release notes:

https://github.com/rust-random/rand_core/releases/tag/v0.10.0

Also bumps the following:
- `chacha20` v0.10.0-rc.10
- `cipher` v0.5.0-rc.7
- `crypto-bigint` v0.7.0-rc.24
- `crypto-common` v0.2.0-rc.14
- `digest` v0.11.0-rc.10
- `elliptic-curve` v0.14.0-rc.27
- `signature` v3.0.0-rc.10
2026-02-01 21:47:05 -07:00
Tony Arcieri e5244d2abe ml-dsa: add reason to all clippy div/rem allows (#1196)
For allow instances of `allow(clippy::integer_division_remainder_used)`
adds a `reason` field which is now one of "constant" (as in bound to an
all-caps-named `const` value) or "tests".
2026-01-31 13:36:06 -07:00
Tony Arcieri 4c7a2eefd0 ml-dsa v0.1.0-rc.5 (#1195) 2026-01-31 12:48:37 -07:00