rustsec-2025-0144
Vulnerability from osv_rustsec
Summary
A timing side-channel was discovered in the Decompose algorithm which is used during ML-DSA signing to generate hints for the signature.
Details
The analysis was performed using a constant-time analyzer that examines compiled assembly code for instructions with data-dependent timing behavior. The analyzer flags:
- UDIV/SDIV instructions: Hardware division instructions have early termination optimizations where execution time depends on operand values.
The decompose function used a hardware division instruction to compute r1.0 / TwoGamma2::U32. This function is called during signing through high_bits() and low_bits(), which process values derived from secret key components:
(&w - &cs2).low_bits()wherecs2is derived from secret key components2Hint::new()callshigh_bits()on values derived from secret key componentt0
Original Code:
fn decompose<TwoGamma2: Unsigned>(self) -> (Elem, Elem) {
// ...
let mut r1 = r_plus - r0;
r1.0 /= TwoGamma2::U32; // Variable-time division on secret-derived data
(r1, r0)
}
Impact
The dividend (r1.0) is derived from secret key material. An attacker with precise timing measurements could extract information about the signing key by observing timing variations in the division operation.
Mitigation
Integer division was replaced with a constant-time Barrett reduction.
{
"affected": [
{
"database_specific": {
"categories": [
"crypto-failure"
],
"cvss": "CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N",
"informational": null
},
"ecosystem_specific": {
"affected_functions": null,
"affects": {
"arch": [],
"functions": [],
"os": []
}
},
"package": {
"ecosystem": "crates.io",
"name": "ml-dsa",
"purl": "pkg:cargo/ml-dsa"
},
"ranges": [
{
"events": [
{
"introduced": "0.0.0-0"
},
{
"fixed": "0.1.0-rc.3"
}
],
"type": "SEMVER"
}
],
"versions": []
}
],
"aliases": [
"CVE-2026-22705",
"GHSA-hcp2-x6j4-29j7"
],
"database_specific": {
"license": "CC-BY-4.0"
},
"details": "### Summary\n\nA timing side-channel was discovered in the Decompose algorithm which is used during ML-DSA signing to generate hints for the signature.\n\n### Details\n\nThe analysis was performed using a constant-time analyzer that examines compiled assembly code for instructions with data-dependent timing behavior. The analyzer flags:\n\n- **UDIV/SDIV instructions**: Hardware division instructions have early termination optimizations where execution time depends on operand values.\n\nThe `decompose` function used a hardware division instruction to compute `r1.0 / TwoGamma2::U32`. This function is called during signing through `high_bits()` and `low_bits()`, which process values derived from secret key components:\n\n- `(\u0026w - \u0026cs2).low_bits()` where `cs2` is derived from secret key component `s2`\n- `Hint::new()` calls `high_bits()` on values derived from secret key component `t0`\n\n**Original Code**:\n```rust\nfn decompose\u003cTwoGamma2: Unsigned\u003e(self) -\u003e (Elem, Elem) {\n // ...\n let mut r1 = r_plus - r0;\n r1.0 /= TwoGamma2::U32; // Variable-time division on secret-derived data\n (r1, r0)\n}\n```\n\n### Impact\n\nThe dividend (`r1.0`) is derived from secret key material. An attacker with precise timing measurements could extract information about the signing key by observing timing variations in the division operation.\n\n### Mitigation\n\nInteger division was replaced with a constant-time Barrett reduction.",
"id": "RUSTSEC-2025-0144",
"modified": "2026-01-27T22:28:37Z",
"published": "2025-12-12T12:00:00Z",
"references": [
{
"type": "PACKAGE",
"url": "https://crates.io/crates/ml-dsa"
},
{
"type": "ADVISORY",
"url": "https://rustsec.org/advisories/RUSTSEC-2025-0144.html"
},
{
"type": "ADVISORY",
"url": "https://github.com/RustCrypto/signatures/security/advisories/GHSA-hcp2-x6j4-29j7"
}
],
"related": [],
"severity": [
{
"score": "CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Timing side-channel in ML-DSA decomposition"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.