Skip to main content

ML-DSA library comparison

A reference summary of which ML-DSA implementation the PQ smart-account stack uses, why, and what the realistic alternatives are.

Selected: ml-dsa (RustCrypto)

Used in the Stylus verifier (ML-DSA-65) and the off-chain Rust CLI (pq-keygen, pq-sign, pq-verify).

Propertyml-dsa (RustCrypto)Why it matters
MaintenanceActive, multi-maintainer (Tony Arcieri + Trail of Bits contributors)Reduces single-maintainer risk for a cryptographic dependency
CompatibilityCompiles to wasm32-unknown-unknown cleanlyRequired for Stylus
StandardsPasses NIST ACVP and Wycheproof test vectorsStandards conformance is the only acceptable bar
PerformanceFaster verify than the main pure-Rust alternative in benchmarksVerification gas is the dominant runtime cost on-chain
API stabilityRC stage (0.1.0-rc.7 at time of writing)Pinned; ACVP vectors re-validated on any upgrade

The RC status is the main trade-off. The crate is well-tested and on a path to stable, but is not yet 1.0. This is mitigated by pinning and treating any version bump as a re-audit on the on-chain side.

Alternatives evaluated

The full review covered ten Rust crates and two TypeScript libraries. The four that were most relevant:

LibraryTypeVerdictReasoning
ml-dsa (RustCrypto)Rust crateSelectedBest maintenance, broadest test coverage, fastest verify
fips204 (IntegrityChain)Rust crateStrong runner-upSmaller WASM (~12.7 KB) but single-maintainer and slower verify
pqcrypto-dilithiumRust crateRejectedOlder Dilithium parameters; behind FIPS 204 spec
@noble/post-quantumTypeScript / JSSelected for client-sideAudited JS implementation by Paul Miller; used in the Snap and as the wallet's reference for cross-checking

What the selection delivers

  • Bi-directional verification. A signature generated by @noble/post-quantum in TypeScript verifies in the Stylus ml-dsa crate, and vice versa. This is asserted by an explicit cross-implementation test in the verifier's test suite.
  • NIST ACVP coverage. All three parameter sets (ML-DSA-44/65/87) are exercised against NIST ACVP keygen, siggen, and sigver vectors.
  • WASM size budget headroom. Approximately 3.3 KB raw headroom over the gzipped binary inside the 24 KB Stylus compressed limit.

What would prompt a switch

  • If ml-dsa lags Stylus SDK upgrades or the spec, fips204 is the immediate fallback. The verifier's API surface is small enough that switching is a few hundred lines.
  • If a second-source Rust implementation backed by an established cryptographer becomes available and fits the size budget, deploying both with a comparison check would be desirable for defense in depth.