Abstract

ML-DSA's signing algorithm differs between its deterministic and hedged variants in one line: whether a 32-byte value called rnd is drawn from a random generator or fixed to zeros. This piece analyses what that line buys against fault attacks, in which an adversary perturbs the signer's computation and learns from the faulty output. It reconstructs the differential fault attack on deterministic lattice signatures that motivated the change, explains precisely why fresh randomness breaks it, and then surveys published attacks that rnd does not stop: faults on internal counters and domain separators, faults that skip loop iterations, bit flips in the stored secret induced remotely through memory disturbance, and correction attacks on hedged signing, including faults in the public matrix. It shows why verifying a signature before releasing it helps against some of these and not others, and turns the evidence into a deployment-by-deployment signing policy for HSMs, cloud key services, edge devices and agent runtimes.

There is a line in FIPS 204 that most engineers will never notice because it does nothing visible. In the signing algorithm, a 32-byte value is drawn from a random bit generator, and a comment adds that for the optional deterministic variant it may be replaced with zeros. Verification cannot tell which choice was made. Interoperability does not depend on it. And yet the choice decides whether one of the best-documented physical attacks on lattice signatures works or fails. It also does not decide several others. If agents are going to sign their actions on shared cloud hosts and on devices that sit within reach of strangers, it matters exactly where the line between those two groups falls.

One input, three kinds of attacker

FIPS 204 Section 3.4 explains the choice. For ML-DSA to be secure, the masking value the signer commits to must never be used to sign two different messages and must not be guessable. That value can come from fresh randomness at signing time or pseudorandomly from the message and a secret seed stored in the private key. The standard's default, which it calls hedged, uses both: Algorithm 7 derives the private signing seed by hashing the stored secret seed, the 32-byte value rnd, and the 64-byte message representative together. In the deterministic variant rnd is 32 zero bytes and the seed depends only on the key and the message, so signing the same message twice produces the same signature. The section warns that the deterministic variant makes fault attacks harder to mitigate and should not be used on platforms where side-channel attacks are a concern and cannot otherwise be mitigated.

A fault attack perturbs a computation and exploits the wrong answer. The perturbation can be physical, such as a glitch on the clock or supply voltage or an electromagnetic pulse aimed at a microcontroller, or it can be induced from software, as with Rowhammer, where rapid repeated access to memory rows flips bits in neighbouring rows that belong to another process. Three attacker positions follow, and they need different defences: a physical attacker holding the device, a co-resident software attacker on shared hardware, and a remote attacker who can only request signatures but can do so at very high volume and occasionally trigger an environmental fault.

The elliptic-curve world met this problem first: Poddebniak and co-authors (2018) showed fault attacks against deterministic signature schemes such as EdDSA, and Samwel and co-authors (2018) a side-channel attack on Ed25519, both cited by FIPS 204. ML-DSA's version of the problem has its own algebra, its own published attacks and its own countermeasures, and this article stays with those. Side channels in the narrower sense, timing and power analysis of the transform and the samplers, are a separate subject and are excluded here except where the standard ties them to the rnd choice.

The differential fault on deterministic signing

The attack that made the case for hedging was published by Bruinderink and Pessl (2018). Its logic is short. In a deterministic signer, the mask depends only on the key and the message. Ask the device to sign a message once, normally, and record the signature. Ask it to sign the same message a second time while injecting a single fault somewhere that changes the challenge but not the mask, for example by corrupting a value that feeds the hash from which the challenge is derived. Both responses equal the same mask plus a challenge times the first secret vector, with two different challenges. Subtract them and the mask cancels, leaving the difference of the two challenges times the secret, and both challenges can be recomputed from the signatures. What remains is linear algebra.

The paper reports that this works with single random faults, that a large share of the signing procedure is vulnerable, up to 65.2 percent of Dilithium's execution time for an unprofiled attack in which the fault can land almost anywhere, and that the attack was demonstrated by clock glitching an ARM Cortex-M4 microcontroller. It also describes fault-induced partial nonce reuse, in which the faulty signature remains valid, which matters later because a device that checks its own output will not notice. The attack recovers the first secret vector but not every part of the private key; the authors show that a tweaked signing algorithm can still sign any message with what is recovered. In practice, then, one well-placed glitch on a deterministic signer is a forgery capability.

Two features of the attack are worth isolating because they decide which countermeasures help. It needs the same message to be signed twice with the same mask, which is precisely what determinism guarantees. And its second, faulty signature does not have to fail verification for the attack to proceed in every variant. The first feature is what rnd removes. The second is why rnd is not the whole answer.

On a deterministic signer, one correct and one faulted signature on the same message share a mask, so their difference exposes the secret.The differential fault needs the same mask twiceAttackerDeterministic signerAnalysissign message mcorrect signaturesign m with a glitchfaulted, same masksubtract: mask cancelssecret vector recovered
On a deterministic signer, one correct and one faulted signature on the same message share a mask, so their difference exposes the secret.

What the rnd input changes

With hedged signing, the mask is derived from the stored seed, the message representative and a fresh 32-byte value. Two signing operations on the same message therefore start from different masks, and the subtraction no longer cancels anything useful: the difference of two responses mixes two unrelated masks with the secret. The differential attack loses its foundation. That is the primary purpose FIPS 204 Section 3.6.1 assigns to rnd: to facilitate countermeasures against side-channel and fault attacks on deterministic signatures, citing Bruinderink and Pessl among its references.

The design is called hedged because it keeps working if either ingredient fails. If the generator is excellent, the signature is as unpredictable as a randomized one. If the generator is weak or repeats, the stored seed and the message still enter the derivation, so the worst case is the deterministic scheme, not a broken one. The standard draws an unusual conclusion from this: rnd should ideally come from an approved generator, other methods of producing fresh values may be used, and for this purpose even a weak generator may be preferable to the fully deterministic variant. It also fixes where rnd must be produced: in the cryptographic module that runs the internal signing algorithm, even when other signing steps happen elsewhere.

Hedging closes a second, quieter leak. Because the number of rejection-sampling iterations depends on the mask, a deterministic signer takes the same number of iterations every time it signs a given message. The Dilithium 3.1 specification notes that this leaks timing information about the message, though not about the key, and FIPS 204 repeats the point in a footnote, advising hedged signatures when the signer does not want to reveal what is being signed. For an agent signing tool calls whose content is sensitive, that is a reason to prefer hedging even in the absence of any fault adversary.

Determinism keeps two legitimate uses. It makes implementations easy to test against known answers, a benefit RFC 9881 notes in its security considerations, and it is the fallback when no fresh randomness is available at all. The tightness of the quantum security proof is also slightly better for deterministic signing, a trade the standard knowingly accepted. None of these is a reason to deploy determinism on hardware an attacker can touch or share.

What each signing variant offers, from FIPS 204 Sections 3.4 and 3.6.1, the Dilithium 3.1 specification and RFC 9881.
PropertyDeterministicHedged (default)
Same message gives same signatureYesNo
Differential fault on repeated messageExposes the secretDefeated
Timing of signing reveals the messagePossibleNo
Survives a weak generatorNot applicableYes, degrades to deterministic
Easy known-answer testingYesNeeds a fixed rnd in tests
Verifiers can tell the differenceNoNo

What the rnd input does not stop

The published record contains several fault attacks whose mechanism does not depend on signing the same message twice, and those survive hedging. The first family targets internal counters and domain separators. Ravi and co-authors (IACR ePrint 2018/211) showed practical electromagnetic fault attacks on reference implementations of several lattice schemes, including Dilithium, from a benchmarking library for ARM Cortex-M4 devices. These schemes feed small nonces into their samplers so that each secret or mask component is drawn from a distinct stream; skipping the instruction that updates such a nonce makes two components come from the same stream. The authors report key recovery with fewer than ten faults for recommended parameters using an instruction-skip fault model. In ML-DSA the corresponding values are the indices that separate the secret-vector samples during key generation and the counter that separates mask polynomials during signing; that mapping is this article's reading of where the same idea applies.

The second family attacks the loops themselves. Espitau, Fouque, Gerard and Tibouchi (IACR ePrint 2016/449) introduced loop-abort faults against earlier lattice Fiat-Shamir signatures, including BLISS and GLP, in which a fault ends a loop early so that the output carries far too little masking or far too much structure, and reported full key recovery from a few faulty signatures or even one. ML-DSA's rejection sampling raises a related concern by analogy, which is offered here as analysis rather than as a published result: the rejection test exists because unfiltered responses carry information about the secret, so a fault that skips that test on a chosen iteration releases exactly the kind of response the aborts are designed to suppress.

The third family needs no physical access. Islam, Mus, Singh, Schaumont and Sunar (arXiv 2203.00637) presented a signature correction attack that works against both deterministic and randomized Dilithium, including constant-time vectorized implementations. It flips single bits of the stored secret, demonstrated with Rowhammer, collects the resulting faulty signatures, and uses the public key to work out which correction would make each one valid, revealing the flipped bits. They recovered 1,851 of the 3,072 bits of the first secret vector for the security level 2 parameters of the third-round submission, reducing the lattice security estimate against quantum attackers from about two to the 128 to about two to the 81, and they note the attack could be mounted on shared cloud servers without special privileges.

The fourth family attacks hedged signing directly. Krahmer, Pessl, Land and Guneysu (IACR ePrint 2024/138) describe two key-recovery attacks on randomized Dilithium built on the same correction idea. One extends an instruction-skipping attack to the randomized setting. The other injects faults into the public matrix, which the authors point out is not sensitive to side-channel leakage and had therefore seen little fault analysis. They report key recovery with as few as 1,024 and 512 faulty signatures respectively for the security level 2 parameters, each from a single targeted fault, show that several popular countermeasures can be bypassed with moderate extra effort, and confirm the results with simulated faults and clock glitches on an ARM microcontroller.

Only the top-left attack needs a repeated message on a deterministic signer; the other three survive hedged signing.Published fault attacks by what they needFAULT HITS THE COMPUTATIONFAULT HITS STORED OR EXPANDED DATAneeds a repeated messageworks on hedged signingDifferential faultsame mask twice;defeated by rndno published exampleCounter and loop faultsskip an updateor a checkSignaturecorrectionbit flips inthe stored keyPublic-matrixfaultscorrupt theexpanded matrix
Only the top-left attack needs a repeated message on a deterministic signer; the other three survive hedged signing.

Why checking the signature before release is not enough

A standard countermeasure is to verify each signature inside the signer before releasing it, discarding any output that fails. It costs one verification, which for ML-DSA is cheaper than signing. Its value depends on whether the attack needs invalid signatures to leave the device. Correction attacks, by their nature, start from signatures that are wrong and then work out how to fix them, so a signer that refuses to release invalid outputs denies them their raw material, unless the attacker can also fault or skip the check, which multiplies the precision required. Against those attacks, verify-before-release is a strong, cheap layer.

It is weak against faults that produce valid signatures. Bruinderink and Pessl's partial nonce reuse variant yields faulty signatures that verify correctly. A skipped rejection test, under the analysis above, also yields a valid signature, because verification checks only that the response is short and consistent, not that it came from the intended distribution. Verification cannot distinguish a leaky valid signature from a healthy one. This is the structural reason fault defence for ML-DSA has to be layered rather than delegated to a single check.

The layers this article recommends follow from the attack families. Hedged signing defeats the repeated-message differential. Verify-before-release starves correction attacks. An integrity check on stored key material before use, for example re-deriving the key from its 32-byte seed or comparing a checksum of the expanded key, detects bit flips in the stored secret, and RFC 9881's consistency check between seed and expanded key serves the same purpose at import. Expanding the public matrix freshly from its seed, or checking it against a stored digest, defends the matrix that the 2024 attack targeted. Duplicating the rejection test and loop-counter updates, or checking loop counts at the end, addresses skip faults. Physical shielding, error-correcting memory and isolation from co-resident code address the fault mechanism itself.

function guarded_sign(key_handle, message_rep):
    seed, expanded = load_key(key_handle)
    if digest(expanded) != stored_digest(key_handle):      # stored-key bit flips
        return SIGNING_ERROR
    if digest(expand_matrix(public_seed(expanded))) != stored_matrix_digest(key_handle):
        return SIGNING_ERROR                                 # matrix faults
    rnd = fresh_random_bytes(32)                             # hedged, generated in this module
    sig = sign_internal(expanded, message_rep, rnd)         # rejection test and counters checked twice inside
    if not verify_internal(public_key(expanded), message_rep, sig):
        record_fault_indicator(key_handle)                   # starve correction attacks
        return SIGNING_ERROR                                 # constant error, no partial output
    return sig
A defensive signing wrapper; illustrative structure only, to be implemented inside a validated module.

Reading the published results with care

The attack literature is strong evidence, but it is evidence about specific targets under specific conditions, and an honest threat model reads it that way. Every result surveyed here was obtained against CRYSTALS-Dilithium as submitted to the NIST process, mostly against reference or benchmarking implementations on microcontrollers or against an optimized desktop implementation, and in laboratory conditions where the attacker controls timing and can repeat measurements. FIPS 204 changed several details after the third round, including the length of the message representative and the commitment hash, the domain separation of key generation and the default signing mode. None of those changes was designed to stop the attacks above, and their mechanisms carry over, but the exact fault counts and success rates reported for the submission should not be quoted as measurements of any particular standardized product.

The numbers also measure different things. The 65.2 percent figure for the differential attack is a share of execution time in which a random fault leads to key recovery, not a probability per signature. The signature correction result reports bits of one secret vector recovered and the resulting drop in a lattice security estimate, which is a serious weakening rather than a complete key extraction by itself. The 512 and 1,024 faulty-signature figures for hedged signing count successful single targeted faults, each of which must land in the right place. Reading them together supports a qualitative conclusion, that faults against ML-DSA are practical for an adversary with the right access and that hedging alone is not a complete defence, without supporting any claim about how often such attacks occur in deployed systems.

That qualitative conclusion is the useful one for engineering. It says the countermeasure budget should follow attacker position: a signer that no untrusted party can touch or share needs little beyond the defaults, and a signer that an untrusted party can reach physically or through shared memory needs the full set of layers regardless of which specific paper's numbers apply. Validation programmes and vendor claims should be asked which fault models were tested, on which implementation, rather than whether the product is resistant to fault attacks in general.

Choosing a signing policy by deployment

The right policy depends on which of the three attacker positions is realistic. A hardware security module in a controlled data centre faces little physical risk and no co-resident code; hedged signing with verify-before-release is ample, and the module's own physical protections do the rest. A multi-tenant cloud host is different: the signature correction attack shows that software running beside the signer can induce bit flips in its memory, so stored-key integrity checks and isolation of signing keys from untrusted tenants matter as much as hedging. An edge device, a robot controller or a sensor gateway can be picked up and glitched; there, every layer applies, together with hardware designed for fault resistance.

Determinism has a narrow, legitimate place: known-answer tests, reproducible test fixtures and devices that genuinely lack any source of fresh values. The danger is leakage of that choice from test into production, for example a configuration flag that forces zero rnd so that tests are reproducible and then ships. Because verifiers cannot tell the variants apart, nothing downstream will ever notice. Deployment reviews should therefore check the signing mode explicitly rather than infer it from successful interoperation.

Start from where the signer runs; physical or co-resident exposure adds layers on top of hedged signing.Picking a signing policyFresh randomness?inside the signing moduleDeterministictests or no other choiceExposed hardware?shared host or reachable deviceHedged + verifycontrolled moduleHedged + all layersintegrity, isolation, shieldingnoyesnoyes
Start from where the signer runs; physical or co-resident exposure adds layers on top of hedged signing.
This article's recommended signing policy by deployment, derived from the published attack families above.
DeploymentRealistic fault adversaryPolicy
HSM in a controlled data centreLimitedHedged, verify before release
Cloud key service on shared hostsCo-resident software (bit flips)Hedged, verify, key and matrix integrity, tenant isolation
Edge device or robotPhysical glitching and EMHedged, all layers, fault-resistant hardware
Agent runtime in a confidential VMCo-resident and host-levelHedged, verify, integrity checks, signing outside the agent process
Known-answer test harnessNoneDeterministic, never shipped

Agents turn signers into oracles

Most fault attacks share an economic requirement: many signatures, each from a separate faulted run. The 2024 correction attacks report hundreds to about a thousand faulty signatures. A human who signs a few documents a day is a poor oracle. An agent platform that signs every tool call, every inter-agent message and every log batch is an excellent one, especially when other agents, or untrusted inputs relayed through them, can trigger signing at will. The volume that makes agents useful is the volume a fault attacker needs.

That suggests controls that sit outside the cryptographic module. Signing services for agents should apply per-caller rate limits and quotas, so that no single requester can drive thousands of signing operations against one key in a short window. They should treat verify-before-release failures and key-integrity failures as security events, not as transient errors to retry, because a burst of them is the signature of a fault campaign. Agent keys should be scoped narrowly, one key per agent and purpose, so that a recovered key authorizes as little as possible. And signing should happen outside the agent's own process, in a module that the agent can ask but cannot instruct to change its mode.

The summary is a single sentence with two halves. Hedged signing, the FIPS 204 default, is necessary because it defeats the cheapest published fault attack on ML-DSA; it is not sufficient, because the published record already contains attacks that work against hedged signing, including one that needs no physical access. Agent platforms should keep the default, add the layers, and assume that any signer reachable at machine rate is reachable by an attacker at machine rate too.

⚠️
Never ship a zero rnd. Verifiers cannot tell deterministic from hedged signatures, so a test-only deterministic flag that reaches production silently reopens the cheapest fault attack.

Key takeaways

  • Deterministic and hedged ML-DSA differ only in whether the 32-byte rnd is random or zero; verifiers cannot tell them apart.
  • The differential fault attack needs the same mask twice; on a deterministic signer one correct and one glitched signature of the same message reveal the secret vector.
  • Hedged signing defeats that attack, hides the message from abort-count timing, and degrades only to determinism if the generator fails; rnd must be produced in the signing module.
  • Published attacks survive hedging: counter and nonce faults, loop and rejection-skip faults, Rowhammer-induced corrections of stored keys, and correction faults including faults in the public matrix.
  • Verify-before-release starves correction attacks but cannot catch faults that yield valid, leaky signatures, so key integrity, matrix integrity, duplicated checks and isolation are needed too.
  • Agent platforms are high-volume signing oracles; rate limits, fault-indicator monitoring, narrow keys and out-of-process signing belong in the design.

Practitioner Toolkit

Copy-paste, strictly defensive artifacts you can use today. Nothing here attacks a real system.

✅ML-DSA signer fault-hardening reviewchecklist

Gate for any service or device that holds an ML-DSA signing key.

  • Signing mode is hedged in production, verified by configuration review rather than inferred from interoperability.
  • rnd is generated inside the module that runs the internal signing algorithm.
  • Every signature is verified before release; failures return a constant error and no partial output.
  • Stored key material is integrity-checked before each use (seed re-derivation or expanded-key digest).
  • The public matrix is expanded from its seed per operation or checked against a stored digest.
  • Rejection tests and loop counters are duplicated or checked for completion.
  • Signing keys do not share hosts or memory with untrusted tenant or agent code.
  • Verify failures and integrity failures raise security alerts and are never silently retried.
🔒Agent signing-service guardrailspolicy

Illustrative limits for a service that signs on behalf of agents.

agent_signing_service:
  algorithm: ML-DSA-65
  signing_mode: hedged              # deterministic forbidden outside test builds
  rnd_source: module_internal_rbg
  verify_before_release: required
  key_scope: one_key_per_agent_and_purpose
  callers:
    rate_limit_per_caller: bounded  # no single caller drives sustained bulk signing
    quota_window: rolling
  fault_indicators:
    on_verify_failure: alert_and_suspend_key
    on_integrity_failure: alert_and_suspend_key
  placement: outside_agent_process  # agents request signatures, cannot change mode
Illustrative documentation template, not a product configuration.
🚀Do these firstquickstart

Minimum viable fault defence for ML-DSA signers.

  • Confirm hedged mode is on everywhere outside test harnesses.
  • Turn on verify-before-release.
  • Add a stored-key integrity check before each signing operation.
  • Move agent signing keys off shared, multi-tenant hosts or into a dedicated module.
  • Alert on any verification or integrity failure inside the signer.

Glossary

rnd
The 32-byte value mixed into ML-DSA's private signing seed: random in the default hedged variant, all zeros in the deterministic variant.
Hedged signing
Deriving per-signature randomness from both a stored secret seed with the message and fresh random input, so security degrades gracefully if either fails.
Fault attack
An attack that perturbs a cryptographic computation, physically or through induced memory errors, and exploits the incorrect output.
Differential fault attack
A fault attack that compares a correct and a faulty output of the same computation to cancel unknown values and isolate secret data.
Rowhammer
A memory disturbance effect in which repeated access to some DRAM rows flips bits in physically adjacent rows, inducible from unprivileged software.
Signature correction attack
An attack that collects faulty signatures and uses the public key to find the correction that makes each valid, revealing the injected change to secret data.
Instruction-skip fault
A fault model in which the attacker causes a processor to skip one instruction, for example a counter update or a comparison.
Verify-before-release
A countermeasure in which the signer verifies each signature internally and outputs nothing if verification fails.

References

  1. NIST FIPS 204, Module-Lattice-Based Digital Signature Standard (2024), Sections 3.4, 3.6.1, 5.4 and Algorithm 7
  2. Bruinderink and Pessl, Differential Fault Attacks on Deterministic Lattice Signatures, IACR TCHES 2018(3)
  3. Ravi, Roy, Bhasin, Chattopadhyay and Mukhopadhyay, Number 'Not Used' Once: Practical Fault Attack on pqm4 Implementations of NIST Candidates, IACR ePrint 2018/211
  4. Espitau, Fouque, Gerard and Tibouchi, Loop-Abort Faults on Lattice-Based Fiat-Shamir and Hash-and-Sign Signatures, IACR ePrint 2016/449
  5. Islam, Mus, Singh, Schaumont and Sunar, Signature Correction Attack on Dilithium Signature Scheme, arXiv 2203.00637
  6. Krahmer, Pessl, Land and Guneysu, Correction Fault Attacks on Randomized CRYSTALS-Dilithium, IACR ePrint 2024/138
  7. Poddebniak, Somorovsky, Schinzel, Lochter and Rosler, Attacking Deterministic Signature Schemes Using Fault Attacks (IEEE EuroS&P 2018)
  8. Ducas et al., CRYSTALS-Dilithium Algorithm Specifications and Supporting Documentation, Version 3.1 (2021), Section 3.2
  9. RFC 9881, Algorithm Identifiers for ML-DSA in the Internet X.509 PKI (2025), Security Considerations