A year or two ago the question was whether any mainstream library implemented the post-quantum standards at all. In October 2026 the question is harder and more useful: which library implements the parts your code needs, in the key formats your systems exchange, inside a validated boundary if your customers require one, with an interface that will not change under you? The answers differ more than release notes suggest. One popular standard library has no Stateless Hash-Based Digital Signature Algorithm (SLH-DSA) at all; another validated module certifies key encapsulation but not signatures; a third runtime marks its signature types experimental; a well-known research library tells you plainly not to protect production data with it. This article gives a dated capability picture and, more durably, the five questions that turn it into a decision for the code you own, whether a person or an AI coding assistant writes it.

A library choice is five questions

It is tempting to ask one question, 'does it support ML-KEM?', and stop. That question hides five separate ones, and each has caught real projects out. First, operations and parameter sets: which of the three standards, which sizes, and which interfaces, such as signing with a context string, signing a pre-hashed message, or signing a pre-computed message representative, are present? Second, key formats: can the library read and write the seed form, the expanded form, or both, in the standard container formats that other systems will hand it? Third, validated scope: if a customer or regulator requires a module validated under Federal Information Processing Standard (FIPS) 140-3, is this algorithm inside this module's certificate, at this version, on this platform? Fourth, stability: is the interface marked experimental, is the package still before its 1.0 release, or does the project itself warn against production use? Fifth, platform dependence: does the library implement the algorithms itself, or delegate to the operating system, so that behaviour changes from one machine to the next?

Asking all five, in that order, turns a popularity contest into an engineering decision. The rest of this article works through each one with the facts as they stood when checked on 25 October 2026.

One library decision splits into five questions that each catch a different kind of surprise.Five questionsLibrary choice Operations and setswhich parts exist Key formatsseed, expanded, both Validated scopethis module, version Stabilityexperimental or not Platformown code or the OS
One library decision splits into five questions that each catch a different kind of surprise.

Operations and sets: who has what

Coverage of Module-Lattice-Based Key-Encapsulation Mechanism (ML-KEM) is now broad. Coverage of Module-Lattice-Based Digital Signature Algorithm (ML-DSA) is close behind. SLH-DSA is where the gaps are. OpenSSL added all three standards in version 3.5.0 in April 2025, a long-term support release maintained until April 2030, and later releases added refinements such as Leighton-Micali Signature (LMS) verification in 3.6.0 and finer control of key output formats in 4.0.0. Bouncy Castle has offered all three, including pre-hash variants, in Java since version 1.79 in October 2024 and in C# since 2.5.0 that December. .NET 10, released in November 2025, has types for all three plus a composite signature type.

Elsewhere the picture is partial. The Go standard library added ML-KEM in Go 1.24 in February 2025, but only the 768 and 1024 sizes, and added ML-DSA only in Go 1.27 in August 2026; it has no SLH-DSA package or proposal. The Java Development Kit (JDK) has ML-KEM and ML-DSA since JDK 24 in March 2025, and no SLH-DSA. AWS-LC, the Amazon Web Services fork of BoringSSL, offers ML-KEM and ML-DSA but no SLH-DSA in its public headers. BoringSSL itself offers ML-KEM, ML-DSA and two SLH-DSA sets. On Windows, the default Cryptography API: Next Generation (CNG) provider documents ML-KEM and ML-DSA, while its SLH-DSA identifier is documented as not currently implemented. Python's widely used pyca cryptography package added ML-KEM and ML-DSA during 2026 and has no SLH-DSA.

Interfaces matter as much as algorithm names. Remote signing of large artifacts depends on signing a pre-computed message representative, often called external mu, and support for it is recent: Go added a way to signal it in version 1.27, the pyca cryptography package added sign-mu and verify-mu functions in version 49.0.0 in June 2026, and OpenSSL 4.0.0 added a corresponding digest. Pre-hash signing, the HashML-DSA and HashSLH-DSA variants, is offered by Bouncy Castle and others but not everywhere. Composite signatures that pair ML-DSA with a classical algorithm appear in .NET's experimental CompositeMLDsa type and in Bouncy Castle for Java, while pyca has none. A design that relies on one of these interfaces narrows the field further than the algorithm table suggests.

The lesson is not that any of these libraries is deficient; each has made deliberate choices. The lesson is to check the exact operation and size your design needs, including interfaces such as external message representatives for remote signing, before committing to a library, and to expect SLH-DSA in particular to narrow the field.

Post-quantum coverage in widely used libraries, as checked on 25 October 2026.
LibraryML-KEMML-DSASLH-DSA
OpenSSL 3.5 and laterYesYesYes
Bouncy Castle (Java, C#)YesYesYes
.NET 10YesYes, experimentalYes, experimental
Go 1.27768 and 1024 onlyYes (since 1.27)No
JDK 24 and laterYesYesNo
AWS-LCYesYesNot in public headers
pyca cryptography 49YesYesNo

Formats in and out

Keys travel between systems, so the second question matters as soon as a key generated in one place must be used in another. The Internet Engineering Task Force (IETF) documents for ML-DSA and ML-KEM keys in X.509 certificates let a private-key file carry the short seed, the large expanded key, or both, and recommend the seed. Libraries differ in what they write by default, what they accept, and whether they can export a seed at all.

Go's ML-KEM decapsulation key, for example, serialises directly to its 64-byte seed. OpenSSL exposes provider settings that decide whether seeds are retained on output and which input forms are accepted. A library that only ever writes expanded keys produces files that seed-only consumers can never read, and because a seed cannot be recomputed from an expanded key, there is no conversion tool that can fix that later.

Treat interoperability as a test you run rather than a property you read. Generate a key in one library and import it into another, in seed and in expanded form; sign with one and verify with the other, with and without a context string; encapsulate with one and decapsulate with the other. Run the same tests whenever either library is upgraded.

Validated scope: the certificate, not the brand

'We use a FIPS-validated library' is one of the most common and least precise statements in security reviews. Validation under FIPS 140-3 applies to a specific cryptographic module, at a specific version, tested on specific operating environments, for a specific list of algorithms used in an approved mode. Post-quantum algorithms make the gaps unusually visible, because validation is catching up with the code.

Some examples as of October 2026 show how precise the reading must be. The AWS-LC 3 Cryptographic Module received certificate 5298 in June 2026; its algorithm list includes ML-KEM key generation and encapsulation-decapsulation but not ML-DSA, so ML-DSA calls through that module are outside the validated scope. OpenSSL's active FIPS 140-3 certificate covers a 3.1-line provider with no post-quantum algorithms, a 3.5-line provider is in review, and OpenSSL's own documentation states that the 3.6.0 FIPS provider has not been validated. The Go Cryptographic Module has a certificate for its first version, which does not include ML-DSA; the version that adds ML-DSA was still pending review. BoringSSL's FIPS service indicator reports its SHAKE-based SLH-DSA variant as not approved while the SHA2-based one is, which shows that even within one library and one algorithm, validated status can differ by variant.

The working rule is to match four things before claiming validation: the module name, the exact version you run, an operating environment on the certificate, and your exact operation in its algorithm list. Anything less is a hope, not a claim.

Every module certificate links to a security policy, a document written by the vendor and reviewed during validation that explains which services are approved, how to configure the approved mode, and which self-tests run. It is the place to confirm that, for example, a key-generation path that starts from an imported seed is an approved service, or that a particular signing interface is offered inside the boundary. Reading it once, for the operations you actually use, is a short task that prevents a long argument with an auditor later.

A validation claim holds only when brand, version, platform and the exact operation all match the certificate.What validation actually coversLibrary brandsays little on its own Module and versionmust match the certificate Operating environmenttested platform listed Your exact operationin the algorithm list narrower, and only this is a claim
A validation claim holds only when brand, version, platform and the exact operation all match the certificate.
⚠️
Read the algorithm list. A validated module can certify ML-KEM and still leave ML-DSA outside its boundary.

Stability and maturity labels

The fourth question is whether the interface you call will still be there, unchanged, next year. Libraries are honest about this if you read their labels. In .NET 10, the MLDsa, SlhDsa and CompositeMLDsa classes carry the Experimental attribute with diagnostic SYSLIB5006, and the MLKem class is stable apart from some members; experimental here means the programming interface may change, not that the algorithm is weak. The RustCrypto ml-kem and ml-dsa crates are still before their 1.0 releases and state that they have never been independently audited.

At the far end of the scale, the Open Quantum Safe project's liboqs, version 0.16.0 in July 2026, implements ML-KEM, ML-DSA and SLH-DSA and many other algorithms, and its documentation states that the project does not currently recommend relying on it in a production environment or to protect any sensitive data. Its OpenSSL plug-in, oqs-provider, inherits that position. These projects are invaluable for prototypes, interoperability testing and algorithms that no mainstream library ships yet; they are not a shortcut to production.

Reading labels this way also explains why two teams can reasonably reach different answers. A product with a long support life may wait for a stable interface; a prototype may happily use an experimental one behind a wrapper that will absorb the change.

Libraries sit at different points between research code and a validated module, and the label tells you where.From research to validated Research librarynot for production Pre-1.0 or unauditedmay change Experimental APIinterface may move Stable APIsupported Validated modulelisted operation less assurance more assurance
Libraries sit at different points between research code and a validated module, and the label tells you where.

Platform dependence

Some libraries implement the algorithms in their own code; others are thin layers over the operating system. .NET is the clearest example of the second kind: its post-quantum types work on systems whose platform cryptography is OpenSSL 3.5 or later, or Windows CNG with post-quantum support, and applications are expected to check an IsSupported property before use. The pyca cryptography package similarly gained ML-KEM and ML-DSA on OpenSSL builds only once those builds were OpenSSL 3.5 or later.

The consequence is that the same application binary can behave differently on two machines, or in two container images built from different base images, because the system library underneath differs. That is not a defect, but it moves part of the library decision into infrastructure: the operating system image, its OpenSSL version and its update policy become part of the cryptographic bill of materials.

Container images make the dependency concrete. An image built on an older distribution may still carry OpenSSL 3.0, the previous long-term release, whose security fixes ended on 7 September 2026; such a system has neither post-quantum algorithms nor upstream support, whatever the application code says. The practical controls are to pin base images, record the platform library version in the bill of materials, and run the same post-quantum tests on every operating system and image the software ships on, rather than only on a developer workstation.

Wrap the dependency and record it

Because all five answers will change over the next few years, the most durable decision is architectural. Put a thin internal interface between application code and the library: encapsulate and decapsulate; sign and verify with an explicit parameter set, context string and signing mode; import and export keys in named forms. Application code calls only that interface. When a validated module catches up, when an experimental interface stabilises, or when a gap such as SLH-DSA is filled, the change happens in one place, behind tests that already cover interoperability.

Record what sits behind the interface in a cryptographic bill of materials (CBOM), an inventory of algorithms, libraries and modules: the library and version, the module and certificate number if any, the platform library it depends on, and the date the entry was checked. That record is what a reviewer, an auditor or an incident responder will ask for first.

Two further habits keep the wrapper honest. Version the internal interface itself, so that a change of default parameter set or signing mode is a visible event with a changelog entry rather than a silent behaviour change. And keep the interoperability tests next to the wrapper, so that swapping a provider is impossible without running them.

Application code calls a small internal interface; providers behind it can change without touching callers.A replaceable crypto boundary Application code Internal crypto APIsets, modes, formats Provider Avalidated module Provider Bfills a gap CBOM recordversion, certificate calls default SLH-DSA only recorded in Replaceable provider layer
Application code calls a small internal interface; providers behind it can change without touching callers.

When AI coding assistants pick the library

More and more of the code that touches cryptography is now drafted by AI coding assistants, and their library choices follow their training data rather than your requirements. Asked to 'add ML-DSA signing', an assistant may import a research library because its examples are plentiful, pull in an unaudited pre-1.0 package, or call an experimental .NET type and suppress the SYSLIB5006 warning to make the build pass. None of these choices fails a test; all of them are decisions a reviewer would reject.

The fix is to make the decision machine-checkable. Keep an allow-list of approved libraries and versions per language, with the five answers recorded for each; fail the build when a pull request introduces a cryptographic dependency that is not on the list or suppresses an experimental diagnostic; and give assistants the internal interface to call instead of a raw library. AI agents at run time deserve the same care: their HTTP clients, tool connectors and model clients inherit whatever library the platform image provides, so pin that image and record it.

The decisions below are the ones practitioners actually face when choosing a post-quantum library, and each should be written down with a date.

  1. List the exact operations, sizes and interfaces your design needs, including SLH-DSA and remote-signing modes.
  2. Check seed and expanded key import and export against the formats your partners use, by test.
  3. Match module, version, platform and operation to a certificate before claiming validation.
  4. Note experimental, pre-1.0 and research labels, and wrap anything unstable.
  5. Record platform dependencies such as the operating system's OpenSSL version.
  6. Enforce an allow-list so assistants and people cannot introduce unapproved libraries.

Key takeaways

  • Choosing a post-quantum library means answering five questions: operations and sets, key formats, validated scope, stability and platform dependence.
  • ML-KEM and ML-DSA are now widely implemented; SLH-DSA is missing from several major libraries, including Go, the JDK and AWS-LC.
  • Seed and expanded key formats differ between libraries, so interoperability must be tested, not assumed.
  • A validation claim holds only when module, version, platform and the exact operation match a certificate; one certified module covers ML-KEM but not ML-DSA.
  • Experimental, pre-1.0 and research labels mean what they say; liboqs itself advises against production use.
  • Wrap the library behind a small internal interface, record it in a CBOM, and enforce an allow-list that AI coding assistants must respect.

Glossary

Cryptographic module
A defined piece of software or hardware that implements cryptography and can be validated as a unit under FIPS 140-3.
FIPS 140-3
The United States and Canadian standard under which cryptographic modules are tested and certified.
Validated scope
The exact module, version, platforms and algorithms listed on a module's certificate.
Experimental API
A programming interface its maintainers may still change, flagged so callers opt in knowingly.
Cryptographic bill of materials (CBOM)
An inventory of the algorithms, libraries and modules a system uses, with versions and dates.
Platform cryptography
Cryptography provided by the operating system, such as OpenSSL on Linux or CNG on Windows, that higher-level libraries call.
Allow-list
A maintained list of approved dependencies against which new code is automatically checked.

Further reading

  1. OpenSSL 3.5 Final Release (OpenSSL Library)
  2. Go 1.27 Release Notes (The Go Programming Language)
  3. What's new in .NET libraries for .NET 10 (Microsoft Learn)
  4. liboqs (Open Quantum Safe)