ML-DSA
June 6, 2026 · View on GitHub
This document explains how to apply Wycheproof test vectors to an ML-DSA implementation.
Tip
This document can double as an LLM "skill" if you ask an agent to apply it.
For each parameter set (ML-DSA-44, ML-DSA-65, ML-DSA-87), there are three test vector files:
testvectors_v1/mldsa_{KL}_sign_noseed_test.jsontestvectors_v1/mldsa_{KL}_sign_seed_test.jsontestvectors_v1/mldsa_{KL}_verify_test.json
The sign_noseed vectors are for testing implementations that support importing
semi-expanded private keys (which is not recommended and exposes the
implementation to a lot more edge cases). They can be ignored by implementations
that only support "seed" private keys.
Key generation
Key generation can be tested with the sign vectors, by providing the seed to ML-DSA.KeyGen_internal, and checking the resulting public key is correct.
Signing
ML-DSA provides two orthogonal axis over which signing interfaces can vary:
- deterministic or randomized signing; and
- (message, context) or precomputed μ signing.
To test deterministic signing interfaces, use vectors without a rnd property.
To test randomized signing interfaces, use both vectors with a rnd property,
and those without, by passing 32 zero bytes as the random value for the latter.
For testing randomized signing interfaces, you can use one of the following approaches:
- implement an internal API that accepts (message, context, random) as input; or
- implement an internal API that matches ML-DSA.Sign_internal and convert message and context to M'; or
- intercept the single randomness read from ML-DSA.Sign and feed it with the provided random value.
To test precomputed μ ("External Mu") signing interfaces, use the mu property
instead of the msg and ctx properties. To test randomized precomputed μ
signing interfaces, use strategies 1 or 3 above. If precomputed μ signing is not
supported, you can ignore the mu property.
Unfortunately, some vectors (with flag Internal) only provide mu and not
msg and ctx, so can only be used with precomputed μ signing interfaces.
These vectors were provided by NIST as M' values, without accompanying message
and context, and are particularly hard to recompute.
If you expose the ability to compute μ values, you can test it by taking message
and context from the vectors, and checking the computed μ matches the mu
property. If mu is missing, the context length is invalid, and computing μ is
expected to fail.
You should also verify all signatures after computing them.
Verification
Verification can be tested with the verify vectors, by checking that signatures verify or fail as expected.
Additional test vectors
CCTV provides two sets of "accumulated" test vectors.
The first can be used to perform 100 (suitable for interactive testing), 10 000 (suitable for CI), or 60 000 000 (suitable for one-time checks) iterations of randomized testing of key generation, signing, and verification.
The second can be used to perform exhaustive testing of low-level field operations.