Add cap-0084 ML-DSA sig verification host functions#1946
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new draft Core Advancement Proposal (CAP-0084) describing Soroban host functions for verifying ML-DSA (FIPS 204) signatures, and registers the CAP in the core CAP index.
Changes:
- Adds a new draft CAP document (
core/cap-0084.md) specifying three ML-DSA verification host functions and associated metering/XDR updates. - Updates
core/README.mdto list CAP-0084 under Draft Proposals.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| core/README.md | Adds CAP-0084 to the Draft Proposals index table. |
| core/cap-0084.md | Introduces a new CAP draft specifying ML-DSA signature verification host functions and related cost-type additions. |
| Status: Draft | ||
| Created: 2026-06-05 | ||
| Discussion: TBD | ||
| Protocol version: TBD |
| Length errors are reported as `Object`/`UnexpectedSize`; the remaining | ||
| conditions are reported as `Crypto`/`InvalidInput`. As with the existing | ||
| signature verification host functions, a failed verification traps rather | ||
| than returning a boolean (see [Design Rationale](#design-rationale)). |
| A context string longer than 255 bytes traps with a distinct error rather | ||
| than failing verification: an over-long context is necessarily a contract | ||
| bug, and silently failing verification would misattribute it to a bad | ||
| signature. |
| { "name": "context", "type": "BytesObject" } | ||
| ], | ||
| "return": "Void", | ||
| "docs": "Verifies an ML-DSA-44 (FIPS 204) signature using the external interface ML-DSA.Verify. `public_key` must be a 1312-byte encoded verifying key, `signature` a 2420-byte encoded signature, and `context` a domain-separation string of 0-255 bytes (pass empty bytes if unused). Traps with Crypto/InvalidInput if the signature is malformed or verification fails.", |
| { "name": "context", "type": "BytesObject" } | ||
| ], | ||
| "return": "Void", | ||
| "docs": "Verifies an ML-DSA-65 (FIPS 204) signature using the external interface ML-DSA.Verify. `public_key` must be a 1952-byte encoded verifying key, `signature` a 3309-byte encoded signature, and `context` a domain-separation string of 0-255 bytes (pass empty bytes if unused). Traps with Crypto/InvalidInput if the signature is malformed or verification fails.", |
| { "name": "context", "type": "BytesObject" } | ||
| ], | ||
| "return": "Void", | ||
| "docs": "Verifies an ML-DSA-87 (FIPS 204) signature using the external interface ML-DSA.Verify. `public_key` must be a 2592-byte encoded verifying key, `signature` a 4627-byte encoded signature, and `context` a domain-separation string of 0-255 bytes (pass empty bytes if unused). Traps with Crypto/InvalidInput if the signature is malformed or verification fails.", |
anupsdf
left a comment
There was a problem hiding this comment.
Thanks for creating the CAP. I left some questions/comments.
| ML-DSA (Module-Lattice-Based Digital Signature Algorithm, | ||
| [FIPS 204]) is one of the two post-quantum signature standards finalized by NIST, and its adoption is underway across the | ||
| signing ecosystem: NSA's CNSA 2.0 suite includes ML-DSA, with software- and | ||
| firmware-signing transitions expected to prefer CNSA 2.0 algorithms by 2025 |
There was a problem hiding this comment.
Since we are in 2026, we have to rephrase this from "expected... by 2025". Maybe we could say expected adoption would happen between 2025 and 2030.
|
|
||
| ML-DSA (Module-Lattice-Based Digital Signature Algorithm, | ||
| [FIPS 204]) is one of the two post-quantum signature standards finalized by NIST, and its adoption is underway across the | ||
| signing ecosystem: NSA's CNSA 2.0 suite includes ML-DSA, with software- and |
There was a problem hiding this comment.
How about putting these examples (CNSA 2.0, X.509/PKI, libraries, runtimes etc.) in separate bulletpoints for readability?
| This CAP adds three host functions to the Soroban environment's exported | ||
| interface, `verify_sig_ml_dsa_44`, `verify_sig_ml_dsa_65` and | ||
| `verify_sig_ml_dsa_87`, implementing the FIPS 204 external verification | ||
| interface `ML-DSA.Verify` for the three standardized parameter sets. Each |
There was a problem hiding this comment.
For better maintainability, can the parameter set be an input so we can provide 1 host function instead of 3?
SDK can expose 3 if needed. wdyt?
| - **Message**: an arbitrary byte string. The full message must be provided; | ||
| see the design rationale for why a pre-hashed interface is not offered. |
There was a problem hiding this comment.
Should we provide a hazmat version that accepts pre-hashed message? To support a use case where message is very very large. Might also be good with less bandwidth over the network.
Related discussion: https://github.com/orgs/stellar/discussions/1915#discussioncomment-16898752