GHSA-h37v-hp6w-2pp8: Ml dsa Ml-dsa's UseHint Function Has Off Vulnerability

MODERATE
CWE-682 CWE-193
Published
Advisory Summary

GHSA-h37v-hp6w-2pp8 is a MODERATE ml-dsa's usehint function has off vulnerability (CWE-682: Incorrect Calculation) affecting Ml dsa libraries in the crates.io ecosystem. The issue involves ml-dsa's usehint function has off by two error when r0 equals zero. Remediation is available by upgrading affected packages to version 0.1.0-rc.5.

GHSA-h37v-hp6w-2pp8 at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-h37v-hp6w-2pp8
Severity MODERATE
CVSS v3.1 Base Score N/A
CWE Classification CWE-682: Incorrect Calculation
Affected Product Ml dsa
Package Ecosystem crates.io
Published Date
Last Updated

How to Fix GHSA-h37v-hp6w-2pp8

To remediate this vulnerability, upgrade all affected Ml dsa dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

ml-dsa fixed: 0.1.0-rc.5
Upgrade ml-dsa to 0.1.0-rc.5
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for ml-dsa

How to Check if You Are Affected

To determine whether your application is affected by GHSA-h37v-hp6w-2pp8, inspect your project dependencies for Ml dsa:

inspect dependencies for ml-dsa

Analyze the terminal output to locate any version of Ml dsa in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.1.0-rc.5), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-682: Incorrect Calculation, where the product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management. In Ml dsa, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary There's a bug in the `use_hint` function where it adds 1 instead of subtracting 1 when the decomposed low bits `r0` equal exactly zero. FIPS 204 Algorithm 40 is pretty clear that `r0 > 0` means strictly positive, but the current code treats zero as positive. This causes valid signatures to potentially fail verification when this edge case gets hit. ### Details The issue is in `ml-dsa/src/hint.rs` in the `use_hint` function. Here's what FIPS 204 Algorithm 40 says: ``` 3: if h = 1 and r0 > 0 return (r1 + 1) mod m 4: if h = 1 and r0 <= 0 return (r1 − 1) mod m ``` Line 3 uses `r0 > 0` (strictly greater than zero), and line 4 uses `r0 <= 0` (less than or equal, which includes zero). So when `r0 = 0`, the spec says to subtract 1. But the current implementation does this: ```rust if h && r0.0 <= gamma2 { Elem::new((r1.0 + 1) % m) } else if h && r0.0 >= BaseField::Q - gamma2 { Elem::new((r1.0 + m - 1) % m) } ``` The problem is `r0.0 <= gamma2` includes zero. When `r0 = 0`, this condition is true (since `0 <= gamma2`), so it adds 1. But according to the spec, `r0 = 0` should fall into the `r0 <= 0` case and subtract 1 instead. The result is +1 when it should be -1, which is an off by two error mod m. ### PoC Take MLDSA 44 where γ2 = 95,232 and m = 44. If `use_hint(true, 0)` is called: - `Decompose(0)` gives `(r1=0, r0=0)` - The condition `r0.0 <= gamma2` is `0 <= 95232` which is true - So it returns `(0 + 1) % 44 = 1` But FIPS 204 says: - `r0 > 0` is `0 > 0` which is false - `r0 ≤ 0` is `0 ≤ 0` which is true - So it should return `(0 - 1) mod 44 = 43` The function returns 1 when it should return 43. This can happen in real signatures whenever any coefficient of the `w'` vector happens to be a multiple of 2γ2, which makes its decomposed `r0` equal zero. It's not super common but it's definitely possible, and when it hits, verification will fail for a completely valid signature. ### Impact This is a FIPS 204 compliance bug that affects signature verification. When the edge case triggers, valid signatures get rejected. Since MLDSA is supposed to be used for high security post quantum cryptography, having verification randomly fail isn't great. It's also theoretically possible that the mismatch between what signing expects and what verification does could be exploited somehow, though that would need more looking into. The fix is straightforward, just change the condition to explicitly check for positive values: ```rust if h && r0.0 > 0 && r0.0 <= gamma2 { Elem::new((r1.0 + 1) % m) } else if h { Elem::new((r1.0 + m - 1) % m) } ```

GHSA-h37v-hp6w-2pp8 Affected Ml dsa Versions

1 component(s)
Fixed Versions:
0.1.0-rc.5
Product / Package Ecosystem Affected Versions Fixed Version
ml-dsa
crates.io
< 0.1.0-rc.5
0.1.0-rc.5

References

Frequently Asked Questions

What is GHSA-h37v-hp6w-2pp8?
GHSA-h37v-hp6w-2pp8 is a security vulnerability in Ml dsa involving ml-dsa's UseHint function has off by two error when r0 equals zero under CWE-682: Incorrect Calculation.
Which Ml dsa versions are affected?
Affected versions include releases prior to 0.1.0-rc.5 across affected packages: ml-dsa.
What version fixes GHSA-h37v-hp6w-2pp8?
Upgrading to 0.1.0-rc.5 (or the latest patched release for your respective branch) resolves the vulnerability.
Is ml-dsa affected?
Yes, ml-dsa is affected in releases prior to 0.1.0-rc.5. Upgrade your dependency to 0.1.0-rc.5 or later.
What CWE is associated with GHSA-h37v-hp6w-2pp8?
GHSA-h37v-hp6w-2pp8 is classified under CWE-682: Incorrect Calculation (The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management.).
How can I check crates.io dependencies for GHSA-h37v-hp6w-2pp8?
Run the dependency tree command: 'inspect dependencies for ml-dsa'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-h37v-hp6w-2pp8",
  "modified" : "2026-02-02T20:33:08Z",
  "published" : "2026-02-02T20:33:08Z",
  "aliases" : [ ],
  "summary" : "ml-dsa's UseHint function has off by two error when r0 equals zero",
  "details" : "### Summary\n\nThere's a bug in the `use_hint` function where it adds 1 instead of subtracting 1 when the decomposed low bits `r0` equal exactly zero. FIPS 204 Algorithm 40 is pretty clear that `r0 > 0` means strictly positive, but the current code treats zero as positive. This causes valid signatures to potentially fail verification when this edge case gets hit.\n\n### Details\n\nThe issue is in `ml-dsa/src/hint.rs` in the `use_hint` function. Here's what FIPS 204 Algorithm 40 says:\n\n```\n3: if h = 1 and r0 > 0  return (r1 + 1) mod m\n4: if h = 1 and r0 <= 0  return (r1 − 1) mod m\n```\n\nLine 3 uses `r0 > 0` (strictly greater than zero), and line 4 uses `r0 <= 0` (less than or equal, which includes zero). So when `r0 = 0`, the spec says to subtract 1.\n\nBut the current implementation does this:\n\n```rust\nif h && r0.0 <= gamma2 {\n    Elem::new((r1.0 + 1) % m)\n} else if h && r0.0 >= BaseField::Q - gamma2 {\n    Elem::new((r1.0 + m - 1) % m)\n}\n```\n\nThe problem is `r0.0 <= gamma2` includes zero. When `r0 = 0`, this condition is true (since `0 <= gamma2`), so it adds 1. But according to the spec, `r0 = 0` should fall into the `r0 <= 0` case and subtract 1 instead.\n\nThe result is +1 when it should be -1, which is an off by two error mod m.\n\n### PoC\n\nTake MLDSA 44 where γ2 = 95,232 and m = 44.\n\nIf `use_hint(true, 0)` is called:\n- `Decompose(0)` gives `(r1=0, r0=0)`\n- The condition `r0.0 <= gamma2` is `0 <= 95232` which is true\n- So it returns `(0 + 1) % 44 = 1`\n\nBut FIPS 204 says:\n- `r0 > 0` is `0 > 0` which is false\n- `r0 ≤ 0` is `0 ≤ 0` which is true\n- So it should return `(0 - 1) mod 44 = 43`\n\nThe function returns 1 when it should return 43.\n\nThis can happen in real signatures whenever any coefficient of the `w'` vector happens to be a multiple of 2γ2, which makes its decomposed `r0` equal zero. It's not super common but it's definitely possible, and when it hits, verification will fail for a completely valid signature.\n\n### Impact\n\nThis is a FIPS 204 compliance bug that affects signature verification. When the edge case triggers, valid signatures get rejected. Since MLDSA is supposed to be used for high security post quantum cryptography, having verification randomly fail isn't great. It's also theoretically possible that the mismatch between what signing expects and what verification does could be exploited somehow, though that would need more looking into.\n\nThe fix is straightforward, just change the condition to explicitly check for positive values:\n\n```rust\nif h && r0.0 > 0 && r0.0 <= gamma2 {\n    Elem::new((r1.0 + 1) % m)\n} else if h {\n    Elem::new((r1.0 + m - 1) % m)\n}\n```",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "crates.io",
      "name" : "ml-dsa"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.1.0-rc.5"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 0.1.0-rc.4"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/RustCrypto/signatures/security/advisories/GHSA-h37v-hp6w-2pp8"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/RustCrypto/signatures/commit/10f4ff04cb43ef2b789ee06e885f11cd054b1335"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/RustCrypto/signatures"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-193", "CWE-682" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-02-02T20:33:08Z",
    "nvd_published_at" : null
  }
}