Two halves of the post-quantum migration
Most coverage of the quantum threat starts and stops with key exchange: an adversary records encrypted traffic today and decrypts it once a cryptographically-relevant quantum computer (CRQC) exists. That "harvest now, decrypt later" (HNDL) risk is real, and our companion post on ML-KEM walks through how post-quantum key encapsulation defends against it.
But key exchange is only half the migration. The other half is digital signatures — the mechanism that proves who issued a piece of data and that it hasn't been altered. Signatures sit underneath code-signing, TLS certificates, JWTs and auth tokens, software-update verification, and tamper-evident audit logs. The classical signature schemes that secure all of those — RSA, ECDSA, EdDSA — are public-key algorithms, and public-key algorithms are exactly what Shor's algorithm breaks on a CRQC.
This post is about the signature half, and specifically about ML-DSA: what it is, how it differs from ML-KEM, the parameter sets you'll choose between, and where it actually gets used. QNSP, the flagship post-quantum cryptography platform from CUI Labs, implements ML-DSA across its KMS, auth, and audit layers — we'll show exactly where at the end.
What ML-DSA is
ML-DSA — the Module-Lattice-Based Digital Signature Algorithm — is NIST's primary post-quantum digital signature standard. It was previously known as CRYSTALS-Dilithium, and it was finalized as FIPS 204 in August 2024, alongside FIPS 203 (ML-KEM) and FIPS 205 (SLH-DSA).
Like ML-KEM, ML-DSA is lattice-based: its security rests on the hardness of the Module Learning With Errors (Module-LWE) and Module Short Integer Solution (Module-SIS) problems over polynomial rings. Signatures are produced via the Fiat-Shamir transform applied to a lattice identification protocol. The important point for a non-cryptographer is that ML-DSA's hardness assumptions are not the integer-factorization or discrete-log problems that Shor's algorithm dismantles — so a quantum computer does not give an attacker an efficient way to forge ML-DSA signatures.
Signatures vs. key encapsulation — the core difference
ML-KEM and ML-DSA are both post-quantum and both lattice-based, which leads people to treat them as interchangeable. They are not. They solve different problems.
A KEM (key encapsulation mechanism) is about confidentiality: it lets two parties agree on a fresh shared secret over an untrusted channel so that an eavesdropper — even one recording everything — cannot recover it. ML-KEM produces a ciphertext and a shared secret; only the holder of the secret key can decapsulate. That shared secret then keys a symmetric cipher (typically AES) for the actual bulk data.
A signature scheme is about authenticity and integrity: it lets a signer attach a value to a message that anyone holding the public key can verify, proving the message came from the holder of the private key and has not been modified since. ML-DSA produces a signature over a message; the verifier checks it against the signer's public key. There is no secret being exchanged and nothing being kept confidential — the message can be entirely public; what's protected is its provenance.
- ML-KEM (FIPS 203) — confidentiality. Output: ciphertext + shared secret. Question it answers: "can an eavesdropper read this?"
- ML-DSA (FIPS 204) — authenticity + integrity. Output: a signature over a message. Question it answers: "did the right party produce this, unchanged?"
- You generally need both. A quantum-safe TLS session, for example, uses a KEM to establish the session key and signatures to authenticate the certificate chain.
The parameter sets: ML-DSA-44, 65, and 87
FIPS 204 defines three parameter sets, each targeting a different NIST security category. Larger sets mean stronger security and larger keys and signatures. The sizes below are fixed by the standard, not vendor-specific.
ML-DSA-44 targets NIST security level 2, with a 1,312-byte public key and roughly 2,420-byte signatures — the smallest signature of the FIPS-finalized signature schemes, which makes it a practical default for high-volume, latency-sensitive signing like auth tokens.
ML-DSA-65 targets level 3, with a 1,952-byte public key and ~3,309-byte signatures — a balanced middle ground often chosen for audit and higher-assurance token signing.
ML-DSA-87 targets level 5, with a 2,592-byte public key and ~4,627-byte signatures — the choice for the highest-assurance and government-grade deployments, where signature size is a fair price for the strongest category.
Why the quantum threat hits signatures differently than encryption
It's worth being precise about what quantum computers do and don't break, because the threat model for signatures is not identical to the one for encryption.
Shor's algorithm efficiently solves integer factorization and discrete logarithms, which breaks RSA, Diffie-Hellman/ECDH (key exchange), and RSA/ECDSA/EdDSA (signatures) — all of which are public-key. Grover's algorithm only gives a quadratic speedup against symmetric primitives, so AES-256 retains roughly 128-bit post-quantum security and SHA-384/SHA-512 stay safe; AES-128 drops to about 64-bit effective security, which is marginal. The headline is that the quantum threat is primarily to key exchange and signatures, not to bulk AES encryption of data you've already keyed.
There's also a timing difference between the two halves of the threat. The confidentiality risk is HNDL — the attacker has to record traffic now and wait. The signature risk doesn't require recording anything in advance: once a CRQC exists, an attacker holding only a public verification key can forge a valid signature outright. That makes long-lived signing material — code-signing roots, firmware-update keys, CA hierarchies, archival audit logs you'll still need to trust years from now — a priority to migrate.
Where signatures actually matter
Signatures are easy to overlook because they're rarely the headline feature — but they underpin trust decisions across a typical stack. A few of the places where a classical-signature compromise would be most damaging:
- Code-signing and software updates — a forged signature lets an attacker ship malicious firmware or packages that pass verification. These keys are often long-lived, which makes them a top migration priority.
- TLS / X.509 certificates — certificate chains authenticate servers and clients. Quantum-safe TLS pairs a KEM for the session key with PQC signatures for the chain.
- JWTs and auth tokens — every authenticated API call typically verifies a signed token. Token volume is high, which is why a compact signature (ML-DSA-44) is attractive here.
- Audit trails and tamper-evidence — signing each audit record (or a hash-chained sequence of them) is what makes the log tamper-evident; forging signatures would let an attacker rewrite history undetected.
- Compliance evidence and attestations — signed evidence packs and attestations let a third party verify integrity without trusting the issuer's word.
SLH-DSA and Falcon: the alternatives
ML-DSA is the general-purpose default, but NIST standardized more than one signature scheme on purpose — algorithm diversity is a hedge against a future weakness in any single mathematical assumption.
SLH-DSA (FIPS 205, formerly SPHINCS+) is a stateless hash-based signature scheme. Its security rests only on the properties of hash functions rather than on lattice problems, which makes it the most conservative choice — a useful belt-and-suspenders option for roots of trust you cannot afford to re-key. The trade-off is larger signatures and slower signing than ML-DSA.
Falcon (being standardized as FN-DSA in the draft FIPS 206) is also lattice-based but produces notably more compact signatures than ML-DSA, at the cost of more delicate floating-point implementation requirements. As of this writing FN-DSA is a draft, not a finalized standard, so it should be treated as forthcoming rather than ready for unconditional production reliance.
In practice: use ML-DSA as the default; reach for SLH-DSA where you want hash-only conservatism for a long-lived root; consider Falcon/FN-DSA where signature size is the binding constraint and you're comfortable tracking draft-standard status.
How QNSP uses ML-DSA
QNSP — the flagship post-quantum cryptography platform from CUI Labs — uses ML-DSA as its primary post-quantum signature scheme across several production paths, not as a marketing claim but as wired behavior:
KMS signing supports all three ML-DSA parameter sets (44 / 65 / 87), so a tenant can match the signing key to its assurance requirement. The auth-service issues JWTs signed with ML-DSA-44 (dilithium-2) by default — the compact signature keeps per-request overhead low for the highest-volume signing path. The audit trail is signed with ML-DSA-65 (dilithium-3) by default, trading a little size for stronger long-term assurance on tamper-evident records, while QNSP's public crypto-attestation (CBOM) pipeline signs with ML-DSA-44 and the verifier checks it against a pinned public key — so that attestation is independently verifiable.
ML-DSA also maps into QNSP's crypto-policy tiers: the strict tier restricts signatures to a hardened set that includes ML-DSA-65 and ML-DSA-87, and the maximum and government tiers require ML-DSA-87, where the strongest NIST category is mandated. The full 90-algorithm catalog (27 KEMs + 63 signatures across 14 families) means a tenant is not limited to ML-DSA — but ML-DSA is the standardized default the platform leans on.
Verifiable implementation, not just claims
Every ML-DSA operation in QNSP runs through dual-provider cross-verification: the native-C liboqs library and the pure-JavaScript @noble/post-quantum implementation. On the maximum and government policy tiers, cross-verification is mandatory — a signature is exercised against two independent implementations so a bug or deviation in one provider is caught rather than silently trusted.
Conformance is published, not asserted. QNSP's public NIST ACVP conformance evidence lives at /verify/conformance: the noble provider passes 435/435 of its ACVP vectors, and liboqs passes 240/240 across the addressable ML-KEM surface. For ML-DSA specifically, the noble provider passes its full set of ACVP keyGen vectors; sign and verify correctness is exercised at runtime by the cross-verification service. The point is that the claims are checkable rather than taken on trust — consistent with CUI Labs' verifiable-evidence posture and QNSP's Singapore base under PDPA and MAS TRM alignment.
Where to start
If you've already mapped your key-exchange exposure, do the same for signatures: inventory every place you rely on RSA, ECDSA, or EdDSA — code-signing roots, certificate chains, token issuers, audit signers — and rank them by how long the signed artifact has to stay trustworthy. The long-lived ones are the migration priority.
ML-DSA is the standardized, general-purpose answer for most of those; SLH-DSA is the conservative hash-based hedge for the roots you most need to protect. QNSP can take the inventory and the signing for you — the free-forever tier (10 GB storage, 50K API calls, 20 KMS keys, 25 vault secrets) and SDKs in five languages let you wire up ML-DSA signing without committing budget first, and the CBOM crypto inventory surfaces where your classical signatures still live.
For the key-exchange side of the same migration, start with the companion post on what ML-KEM actually does.