Skip to content

ml-dsa: reduce matrix stack usage without public API changes - #1444

Open
qpernil wants to merge 2 commits into
RustCrypto:masterfrom
qpernil:master
Open

qpernil wants to merge 2 commits into
RustCrypto:masterfrom
qpernil:master

Conversation

@qpernil

@qpernil qpernil commented Sep 20, 2026

Copy link
Copy Markdown

Unoptimized ML-DSA-87 key construction can overflow a 512 KiB thread stack because the complete expanded matrix is assembled and moved before an enclosing key is heap-allocated.

Use a private NttMatrix in ML-DSA backed by Array<MaybeBox<NttVector<L>>, K>. Each sampled or cloned row reaches its allocation before the next row is assembled; multiplication delegates to the existing lattice vector dot product. Without alloc, the rows remain inline. There is no new unsafe code or dependency change, and the implementation uses the released module-lattice 0.2.3.

Existing public types, tuple fields, constructor signatures, and const constructors in module-lattice are unchanged. ML-DSA's public signatures are also unchanged. This supersedes RustCrypto/KEMs#382 by keeping the allocation policy inside ML-DSA's private matrix storage.

Add regressions for construction, cloning, verification-key decoding, signing, and verification for all three parameter sets on 512 KiB workers. Keys cross a thread boundary before signing, and a modified message is rejected. CI runs the regression with optimization explicitly disabled. Vectors and other intermediate values still use stack space; 512 KiB is the tested configuration, not a portable maximum or a promise of 128 KiB construction.

Validation:

  • The new unoptimized ML-DSA-87 regression overflows its 512 KiB stack on unmodified upstream 72ebaa1; all three parameter sets pass with this change, including on Rust 1.85.
  • Full all-feature suites pass unoptimized and in release, including ACVP, Wycheproof, property tests, and doctests.
  • No-default-feature release suite and alloc-only release unit tests pass.
  • WebAssembly no_std checks pass with and without alloc; Rust 1.85 all-feature library check passes.
  • Formatting, diff checks, and all-target/all-feature Clippy with -D warnings pass. Clippy reports the existing workspace's removed from_iter_instead_of_collect lint.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant