PQC Library Comparison Matrix

Published · Updated

Choosing the right cryptographic library for post-quantum cryptography depends on your language ecosystem, compliance requirements, performance needs, and deployment environment. This reference compares six major libraries that implement NIST’s finalized PQC standards: OpenSSL, BoringSSL, wolfSSL, liboqs, Bouncy Castle, and AWS-LC.

All comparisons reference the NIST standards finalized in August 2024: FIPS 203 (ML-KEM), FIPS 204 (ML-DSA), and FIPS 205 (SLH-DSA). This page is maintained as a living reference and was last verified on September 22, 2026.

Full Comparison Matrix

FeatureOpenSSL 3.5BoringSSLwolfSSL 5.7+liboqs 0.10+Bouncy Castle 1.79AWS-LC
ML-KEM-512YesNoYesYesYesYes
ML-KEM-768YesYesYesYesYesYes
ML-KEM-1024YesNoYesYesYesYes
ML-DSA-44YesYesYesYesYesYes
ML-DSA-65YesYesYesYesYesYes
ML-DSA-87YesYesYesYesYesYes
SLH-DSAYesNoYesYesYesNo
Hybrid TLSYesYesYesVia oqs-providerNo (not a TLS library)Yes
FIPS 140-3 (PQC)In processNo (see AWS-LC)In processNoSeparate module; PQC outside approved scopeYes, ML-KEM only (cert. #5314)
Primary languageCC++CCJava / C#C
LicenseApache 2.0ISC-styleGPLv2 + commercialMITMITApache 2.0 + ISC
Production-readyYesYes (Google internal)YesNo (research)PartialYes
Latest stable3.5.0 (Apr 2025)Rolling5.7.4 (2025)0.10.1 (2025)1.79 (2025)1.22 (2025)

OpenSSL 3.5

Overview: OpenSSL is the most widely deployed cryptographic library in the world. Version 3.5, released April 8, 2025, is the first mainline release with native PQC support, eliminating the need for the external OQS-provider that was previously required.

PQC support: Full support for ML-KEM (all three parameter sets), ML-DSA (all three parameter sets), and SLH-DSA (all parameter sets). Hybrid key exchange groups like X25519MLKEM768 are available for TLS 1.3 out of the box.

FIPS status: OpenSSL’s FIPS provider module has a long history of FIPS 140-2 validation; those FIPS 140-2 certificates are now Historical rather than Active. The FIPS 140-3 validation effort for OpenSSL 3.5 with PQC remains in process as of September 2026. The non-FIPS default provider includes the PQC algorithms, but availability does not establish an approved CMVP scope.

TLS integration: Native TLS 1.3 support with PQC key exchange groups. Supported hybrid groups include X25519MLKEM768 (matching Chrome and Cloudflare defaults). Configuration is straightforward through ssl_conf or command-line options.

Best for: Server-side deployments (Nginx, Apache, HAProxy), custom applications using the EVP API, organizations already on OpenSSL wanting a simple upgrade path.

Considerations: OpenSSL 3.x introduced a provider architecture that changed the API surface. If you are migrating from OpenSSL 1.1.1, expect API changes beyond just PQC additions. The library’s C codebase has a large attack surface, though it receives extensive security review.

Upstream lifecycle: OpenSSL 3.0 reached the end of upstream public support on September 7, 2026. OpenSSL 3.5 is an LTS branch supported upstream through April 8, 2030 and is the preferred modern baseline for the native PQC examples on this page. Distribution-maintained packages and commercial support contracts can have different dates, so record both the upstream branch and the package-provider lifecycle in a crypto inventory.

# Check PQC algorithm availability
openssl list -kem-algorithms | grep -i ml
openssl list -signature-algorithms | grep -i ml

# Generate an ML-DSA keypair
openssl genpkey -algorithm ML-DSA-65 -out ml-dsa-65-key.pem

# Test hybrid TLS key exchange
openssl s_client -groups X25519MLKEM768 -connect example.com:443

BoringSSL

Overview: BoringSSL is Google’s fork of OpenSSL, used internally in Chrome, Android, and Google Cloud services. It is not intended for external use as a standalone library (it has no stable ABI or release versioning), but it drives PQC adoption at massive scale through Chrome.

PQC support: ML-KEM-768 for key encapsulation and ML-DSA (all three parameter sets) for signatures. BoringSSL intentionally does not support ML-KEM-512 (Google considers Level 1 insufficient) or ML-KEM-1024 (deemed unnecessary overhead). SLH-DSA is not supported.

FIPS status: BoringSSL itself does not carry FIPS validation. AWS-LC, which is a fork of BoringSSL, has achieved FIPS 140-3 validation. Google has its own internal FIPS certification process for BoringCrypto.

TLS integration: BoringSSL was an early large-scale hybrid PQC deployment. Chrome used the pre-standard X25519Kyber768Draft00 group from 2023. That group is now formally obsolete under RFC 10024. The final X25519MLKEM768 hybrid has been the Chrome default since late 2024.

Best for: Indirect use via Chrome, Android, or Google Cloud. Not recommended as a standalone library for external projects due to lack of stable releases and API guarantees.

Considerations: No versioned releases, no stable ABI, no package manager distribution. The API changes without notice. Use it through higher-level Google products, not directly.

wolfSSL

Overview: wolfSSL is a lightweight, commercial-grade TLS library targeting embedded systems, IoT devices, automotive, and RTOS environments. It is written in ANSI C and optimized for small footprint and high performance.

PQC support: Full support for ML-KEM (512/768/1024), ML-DSA (44/65/87), and SLH-DSA. wolfSSL was one of the earliest commercial libraries to implement Kyber (pre-standardization) and has tracked the NIST standards closely.

FIPS status: wolfCrypt has Active FIPS 140-3 certificate #4718, but that certificate’s approved algorithm list does not include ML-KEM, ML-DSA or SLH-DSA. A separate wolfCrypt FIPS 140-3 submission remains on the CMVP Modules in Process list. Treat the existing base-module validation and the pending PQC-specific effort as separate evidence.

TLS integration: Full TLS 1.3 support with hybrid key exchange. wolfSSL documents X25519MLKEM768 and additional implementation-specific combinations. Verify whether the exact release exposes RFC 10024’s standardized SecP256r1MLKEM768 name and code point rather than assuming an older P256MLKEM768 label is equivalent.

Best for: Embedded systems, IoT, automotive, RTOS deployments, and organizations needing commercial support with an SLA. Also suitable for any C-based project needing a lightweight alternative to OpenSSL.

Considerations: Dual-licensed under GPLv2 and a commercial license. The GPL license makes it unsuitable for proprietary projects without purchasing a commercial license. Pricing is not public. The small codebase is an advantage for security auditing but means fewer features outside of TLS/crypto.

// wolfSSL ML-KEM example (simplified)
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/kyber.h>

KyberKey key;
wc_KyberKey_Init(KYBER768, &key, NULL, INVALID_DEVID);
wc_KyberKey_MakeKey(&key, rng);

byte ct[KYBER768_CIPHERTEXT_SIZE];
byte ss[KYBER_SS_SZ];
wc_KyberKey_Encapsulate(&key, ct, ss, rng);

liboqs (Open Quantum Safe)

Overview: liboqs is the reference C library from the Open Quantum Safe (OQS) project, a collaborative academic and industry effort. It provides a common API for multiple post-quantum algorithms and serves as the upstream implementation that feeds into other projects.

PQC support: The most comprehensive algorithm coverage of any library. Supports ML-KEM (all parameter sets), ML-DSA (all parameter sets), SLH-DSA (all parameter sets), plus experimental algorithms like HQC, BIKE, and Classic McEliece that NIST is still evaluating.

FIPS status: None. liboqs is explicitly positioned as a research and prototyping library, not for production use. It has not undergone FIPS validation and the project documentation states it should not be used in production security contexts.

TLS integration: Not directly. The OQS project provides separate integration points: oqs-provider (an OpenSSL 3.x provider), oqs-boringssl (a fork), and oqs-gnutls. These allow TLS testing with PQC algorithms but inherit liboqs’s research-only status.

Best for: Research, testing, prototyping, algorithm comparison, interoperability testing, and academic work. Useful for validating your migration plan before committing to a production library.

Considerations: Not production-grade. The project explicitly warns against production use. Performance is not optimized (reference implementations, not platform-tuned). However, liboqs is invaluable for testing and as a reference for correctness.

// liboqs example: ML-KEM-768
#include <oqs/oqs.h>

OQS_KEM *kem = OQS_KEM_new(OQS_KEM_alg_ml_kem_768);

uint8_t *public_key = malloc(kem->length_public_key);
uint8_t *secret_key = malloc(kem->length_secret_key);
OQS_KEM_keypair(kem, public_key, secret_key);

uint8_t *ciphertext = malloc(kem->length_ciphertext);
uint8_t *shared_secret_enc = malloc(kem->length_shared_secret);
OQS_KEM_encaps(kem, ciphertext, shared_secret_enc, public_key);

uint8_t *shared_secret_dec = malloc(kem->length_shared_secret);
OQS_KEM_decaps(kem, shared_secret_dec, ciphertext, secret_key);

Bouncy Castle

Overview: Bouncy Castle is the primary cryptographic library for the Java and C# ecosystems. It implements a vast range of algorithms and provides both a JCE/JCA provider interface and a lower-level API. Version 1.79 (2025) includes full PQC support.

PQC support: Complete support for ML-KEM (512/768/1024), ML-DSA (44/65/87), and SLH-DSA (all parameter sets). Bouncy Castle uses the pre-NIST algorithm names internally (KYBER, DILITHIUM, SPHINCS+) but implements the final FIPS 203/204/205 specifications.

FIPS status: The main Bouncy Castle library is not FIPS validated. The separate BC-FJA product has Active FIPS 140-3 validations, including Interim certificate #4943 for version 2.1.1. Its approved algorithm list does not include ML-KEM, ML-DSA or SLH-DSA. The older BC-FNA FIPS 140-2 certificate #4416 is Historical; a BC-FNA FIPS 140-3 module is in process, not yet an issued validation. Generic Bouncy Castle PQC support must not be presented as validated PQC.

TLS integration: Bouncy Castle provides its own TLS implementation (BCTLS) but it is not commonly used for production TLS termination. Most Java applications use the JDK’s built-in TLS (JSSE) which does not yet support PQC key exchange. Bouncy Castle’s PQC strength is at the application layer: signing, encryption, key encapsulation.

Best for: Java and C# applications needing PQC at the application layer. Document signing, JWT creation, data encryption at rest, custom protocols, and anywhere you need PQC but are not doing TLS termination in Java.

Considerations: Pure Java implementation means no native performance optimizations. Performance is still good for server workloads but may lag behind C libraries for high-throughput scenarios. The separate PQC provider (BouncyCastlePQCProvider) must be explicitly registered.

// Bouncy Castle ML-KEM-768 example
Security.addProvider(new BouncyCastlePQCProvider());

KeyPairGenerator kpg = KeyPairGenerator.getInstance("KYBER", "BCPQC");
kpg.initialize(KyberParameterSpec.kyber768);
KeyPair keyPair = kpg.generateKeyPair();

KEM kem = KEM.getInstance("KYBER", "BCPQC");
KEM.Encapsulated enc = kem.newEncapsulator(keyPair.getPublic()).encapsulate();
SecretKey shared = kem.newDecapsulator(keyPair.getPrivate())
    .decapsulate(enc.encapsulation());

AWS-LC (AWS Libcrypto)

Overview: AWS-LC is Amazon Web Services’ fork of BoringSSL, optimized and hardened for AWS infrastructure. It powers S2N-TLS (AWS’s TLS implementation), the AWS SDK, and AWS services like CloudFront, ELB, and KMS.

PQC support: ML-KEM (512/768/1024) and ML-DSA (44/65/87). SLH-DSA is not currently supported. AWS-LC focuses on the algorithms needed for TLS key exchange and authentication, which aligns with AWS’s priority of protecting data in transit.

FIPS status: AWS-LC 3 Cryptographic Module (static) has Active FIPS 140-3 certificate #5314, issued June 5, 2026. Its approved algorithm list includes ML-KEM key generation and encapsulation/decapsulation. It does not list ML-DSA. The December 2024 AWS announcement described AWS-LC FIPS 3.0 entering the validation process; it was not the date of an issued certificate. Do not transfer certificate #5314’s scope to AWS-LC 4 or another build without checking that module’s own record.

TLS integration: Full TLS 1.3 support with hybrid key exchange through S2N-TLS. AWS documents X25519MLKEM768 across specific service endpoints and policies. Do not infer RFC 10024 SecP256r1MLKEM768 support from older P256MLKEM768 implementation names without release-specific evidence.

Best for: AWS-hosted workloads, applications requiring FIPS 140-3 validated ML-KEM, organizations already using S2N-TLS, and projects needing a production-grade C crypto library with PQC support.

Considerations: While open-source (Apache 2.0 + ISC), AWS-LC is primarily designed for AWS’s needs. Community contributions are accepted but the roadmap follows AWS priorities. The lack of SLH-DSA support may matter for use cases requiring hash-based signatures as a conservative fallback.

// AWS-LC ML-KEM example using EVP API
#include <openssl/evp.h>

EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_KEM, NULL);
EVP_PKEY_CTX_kem_set_params(ctx, NID_MLKEM768);
EVP_PKEY_keygen_init(ctx);

EVP_PKEY *key = NULL;
EVP_PKEY_keygen(ctx, &key);

Decision Matrix by Use Case

Use CaseRecommended LibraryRationale
Web server TLS (Linux)OpenSSL 3.5Widest ecosystem support, native hybrid TLS
AWS-hosted servicesAWS-LC / S2N-TLSFIPS-validated ML-KEM in AWS-LC 3, native AWS integration
Embedded / IoTwolfSSLSmall footprint, RTOS support, commercial SLA
Java application cryptoBouncy CastleOnly mature Java PQC option, JCE integration
.NET application cryptoBouncy Castle C#Only mature .NET PQC option
Research / testingliboqsMost algorithms, reference implementations
Chrome / AndroidBoringSSL (automatic)Deployed automatically via browser updates
FIPS-required ML-KEMAWS-LC 3Active FIPS 140-3 certificate #5314 includes ML-KEM
Conservative (hash-based sigs)OpenSSL 3.5 or wolfSSLSLH-DSA support for maximum algorithm diversity

Algorithm Parameter Set Coverage

ML-KEM (FIPS 203) Detail

Parameter SetSecurity LevelPublic KeyCiphertextShared SecretOpenSSLBoringSSLwolfSSLliboqsBCAWS-LC
ML-KEM-5121800 B768 B32 BYesNoYesYesYesYes
ML-KEM-76831,184 B1,088 B32 BYesYesYesYesYesYes
ML-KEM-102451,568 B1,568 B32 BYesNoYesYesYesYes

ML-DSA (FIPS 204) Detail

Parameter SetSecurity LevelPublic KeyPrivate KeySignatureOpenSSLBoringSSLwolfSSLliboqsBCAWS-LC
ML-DSA-4421,312 B2,560 B2,420 BYesYesYesYesYesYes
ML-DSA-6531,952 B4,032 B3,309 BYesYesYesYesYesYes
ML-DSA-8752,592 B4,896 B4,627 BYesYesYesYesYesYes

SLH-DSA (FIPS 205) Detail

FeatureOpenSSLBoringSSLwolfSSLliboqsBCAWS-LC
SLH-DSA-SHA2-128sYesNoYesYesYesNo
SLH-DSA-SHA2-128fYesNoYesYesYesNo
SLH-DSA-SHA2-192sYesNoYesYesYesNo
SLH-DSA-SHA2-192fYesNoYesYesYesNo
SLH-DSA-SHA2-256sYesNoYesYesYesNo
SLH-DSA-SHA2-256fYesNoYesYesYesNo
SLH-DSA-SHAKE-128sYesNoYesYesYesNo
SLH-DSA-SHAKE-128fYesNoYesYesYesNo
SLH-DSA-SHAKE-192sYesNoYesYesYesNo
SLH-DSA-SHAKE-192fYesNoYesYesYesNo
SLH-DSA-SHAKE-256sYesNoYesYesYesNo
SLH-DSA-SHAKE-256fYesNoYesYesYesNo

Performance Comparison

Performance varies significantly by platform, compiler optimizations, and whether AVX2/NEON instructions are available. These figures represent typical performance on modern x86-64 hardware:

OperationOpenSSL 3.5wolfSSLliboqsBouncy CastleAWS-LC
ML-KEM-768 keygen~0.03 ms~0.03 ms~0.05 ms~0.1 ms~0.02 ms
ML-KEM-768 encaps~0.04 ms~0.04 ms~0.05 ms~0.1 ms~0.03 ms
ML-KEM-768 decaps~0.04 ms~0.04 ms~0.05 ms~0.1 ms~0.03 ms
ML-DSA-65 keygen~0.1 ms~0.1 ms~0.15 ms~0.3 ms~0.08 ms
ML-DSA-65 sign~0.3 ms~0.3 ms~0.4 ms~0.5 ms~0.2 ms
ML-DSA-65 verify~0.1 ms~0.1 ms~0.15 ms~0.3 ms~0.08 ms

AWS-LC tends to be fastest due to aggressive platform-specific optimizations (AVX2, AVX-512). Bouncy Castle is slowest due to being pure Java, but still adequate for most server workloads. liboqs prioritizes correctness over speed.

Licensing Summary

LibraryLicenseCommercial useCopyleftNotes
OpenSSL 3.5Apache 2.0YesNoChanged from dual OpenSSL/SSLeay in 3.0
BoringSSLISC-styleYesNoNo versioned releases
wolfSSLGPLv2 + commercialRequires licenseYes (GPL)Free for open-source, paid for proprietary
liboqsMITYesNoResearch use recommended
Bouncy CastleMITYesNoJava and C# editions
AWS-LCApache 2.0 + ISCYesNoSome files ISC, most Apache 2.0

Migration Recommendations

If you are starting fresh: Use OpenSSL 3.5 for C/C++ server applications, AWS-LC for AWS-hosted workloads requiring FIPS, or Bouncy Castle for Java/C# applications.

If you are on OpenSSL 1.1.1: Upgrade to OpenSSL 3.5. The migration effort is significant (new provider API) but gives you native PQC without additional dependencies.

If you are on OpenSSL 3.0: upstream public support has ended and 3.0 has no native ML-KEM, ML-DSA, or SLH-DSA implementation. Plan and test a move to 3.5 LTS or a later compatible branch, while checking whether your operating-system or commercial provider maintains a separate package lifecycle.

The OpenSSL 3.0-to-3.5 PQC migration worksheet provides the inventory, provider/FIPS, interoperability, rollout, evidence, and rollback fields for that work.

If you need FIPS-validated ML-KEM today: AWS-LC 3 certificate #5314 includes ML-KEM in its approved algorithm list. That evidence does not extend to ML-DSA or another AWS-LC version. Verify the exact module and approved service using the FIPS 140-2 to FIPS 140-3 transition guide.

If you are testing PQC: Use liboqs for algorithm exploration and interoperability testing, then move to a production library for deployment.

If you are on embedded/IoT: wolfSSL provides the best combination of small footprint, PQC support, and commercial backing for constrained devices.

Frequently Asked Questions

Which library should I choose if I need FIPS 140-3 compliance for PQC?

AWS-LC 3 certificate #5314 includes ML-KEM, but its approved algorithm list does not include ML-DSA. OpenSSL and wolfSSL have PQC-specific validation efforts in progress. Bouncy Castle’s separate BC-FJA module has Active FIPS 140-3 validation, but its approved algorithm list does not include ML-KEM or ML-DSA. Always match the algorithm, module version, certificate and approved service rather than applying a library-wide FIPS label.

Why does BoringSSL only support ML-KEM-768 and not 512 or 1024?

Google’s position is that ML-KEM-768 (Security Level 3) provides sufficient security margin for all foreseeable threats, making ML-KEM-512 unnecessary, while ML-KEM-1024 adds overhead without meaningful security benefit over 768. This is a deliberate design choice, not a limitation.

Can I use liboqs in production?

The Open Quantum Safe project explicitly advises against production use of liboqs. It is designed for research, prototyping, and interoperability testing. The implementations may have side-channel vulnerabilities and have not undergone the same hardening as production libraries. Use liboqs for testing, then deploy with OpenSSL, AWS-LC, wolfSSL, or Bouncy Castle.

What is the difference between OpenSSL and AWS-LC?

AWS-LC is a fork of BoringSSL (not OpenSSL) that AWS maintains for its infrastructure. It has a different API surface than OpenSSL. Key differences: AWS-LC 3 has FIPS 140-3 validation including ML-KEM, a smaller attack surface (fewer legacy algorithms), and platform-specific performance optimizations. OpenSSL has broader ecosystem compatibility, more algorithms (including SLH-DSA), and is the default on most Linux distributions.

Do I need SLH-DSA support?

SLH-DSA (hash-based signatures) provides a conservative fallback that relies only on hash function security rather than lattice assumptions. If your threat model requires algorithm diversity (in case lattice-based schemes like ML-DSA are broken), include SLH-DSA capability. For most organizations, ML-DSA alone is sufficient.

How often is this comparison updated?

This page is updated whenever a library makes a significant PQC-related release or achieves new FIPS validation status. The verified date at the top of this page indicates when all information was last confirmed.

Will these libraries support the upcoming NIST HQC standard?

NIST selected HQC as an additional KEM standard in March 2025 (to complement ML-KEM). Final standardization is expected in 2027. liboqs already supports HQC. Other libraries are expected to add support once the standard is finalized.

Sources