Libraries & Tools
This page lists the PQC libraries available for each major language, with maturity level, algorithm coverage, and a quick install/usage example.
Library Ecosystem
Most PQC libraries are bindings to liboqs (Open Quantum Safe), the reference C implementation. Some languages have native implementations.
flowchart TD
LIBOQS[liboqs<br/>C reference implementation] --> RUST[oqs-rs<br/>Rust bindings]
LIBOQS --> GO[liboqs-go<br/>Go bindings]
LIBOQS --> PY[liboqs-python<br/>Python bindings]
LIBOQS --> JAVA[liboqs-java<br/>Java bindings]
LIBOQS --> NODE[liboqs-node<br/>JS/TS bindings]
NATIVE1[pqcrypto<br/>Rust native] -.-> RUST
NATIVE2[circl<br/>Go native] -.-> GO
NATIVE3[Bouncy Castle<br/>Java native] -.-> JAVA
classDef ref fill:#6b8e6b,stroke:#4a6a4a,color:#2c3e50
classDef binding fill:#5a8eaa,stroke:#3a6e8a,color:#2c3e50
classDef native fill:#8e6b8e,stroke:#6e4a6e,color:#2c3e50
class LIBOQS ref
class RUST,GO,PY,JAVA,NODE binding
class NATIVE1,NATIVE2,NATIVE3 native
Comparison Table
| Language | Library | Type | ML-KEM | ML-DSA | SLH-DSA | HQC | Maturity |
|---|---|---|---|---|---|---|---|
| C/C++ | liboqs | Reference | Yes | Yes | Yes | Yes | Production |
| C/C++ | PQClean | Reference | Yes | Yes | Yes | Yes | Production |
| Rust | pqcrypto | Native | Yes | Yes | Yes | Yes | Stable |
| Rust | oqs-rs | Binding | Yes | Yes | Yes | Yes | Stable |
| Rust | aws-lc-rs | Native | Yes | Yes | No | No | Production |
| Go | circl | Native | Yes | Yes | No | No | Production |
| Go | liboqs-go | Binding | Yes | Yes | Yes | Yes | Stable |
| Python | liboqs-python | Binding | Yes | Yes | Yes | Yes | Stable |
| Python | pqcrypto | Binding | Yes | Yes | Yes | No | Beta |
| Java | Bouncy Castle | Native | Yes | Yes | Yes | Yes | Production |
| Java | liboqs-java | Binding | Yes | Yes | Yes | Yes | Stable |
| JS/TS | liboqs-node | Binding | Yes | Yes | Yes | Yes | Beta |
C/C++ — liboqs
The reference implementation. Everything else builds on this.
# Install
git clone https://github.com/open-quantum-safe/liboqs.git
cd liboqs && mkdir build && cd build
cmake -GNinja .. && ninja && ninja install
#include <oqs/oqs.h>
OQS_KEM *kem = OQS_KEM_new(OQS_KEM_alg_ml_kem_768);
uint8_t *pk = malloc(kem->length_public_key);
uint8_t *sk = malloc(kem->length_secret_key);
OQS_KEM_keypair(kem, pk, sk);
Rust
pqcrypto (native, recommended)
# Cargo.toml
[dependencies]
pqcrypto-kyber = "0.8"
pqcrypto-dilithium = "0.5"
pqcrypto-traits = "0.3"
use pqcrypto_kyber::kyber768;
use pqcrypto_traits::kem::{PublicKey, SecretKey, SharedSecret, Ciphertext};
let (pk, sk) = kyber768::keypair();
let (ss_sender, ct) = kyber768::encapsulate(&pk);
let ss_receiver = kyber768::decapsulate(&ct, &sk);
assert_eq!(ss_sender.as_bytes(), ss_receiver.as_bytes());
aws-lc-rs (for rustls/TLS integration)
[dependencies]
aws-lc-rs = "1" # ML-KEM support for rustls
Go
circl (Cloudflare, recommended)
go get github.com/cloudflare/circl
import "github.com/cloudflare/circl/kem/mlkem/mlkem768"
pk, sk, _ := mlkem768.GenerateKeyPair(rand.Reader)
ct, ss_sender, _ := mlkem768.Encapsulate(rand.Reader, pk)
ss_receiver, _ := mlkem768.Decapsulate(sk, ct)
Go 1.23+ uses ML-KEM hybrid by default in
crypto/tls. You may not need to call circl directly.
Python
liboqs-python
pip install liboqs-python
import oqs
kem = oqs.KeyEncapsulation("ML-KEM-768")
pk = kem.generate_keypair()
ct, ss_sender = kem.encap_secret(pk)
ss_receiver = kem.decap_secret(ct)
assert ss_sender == ss_receiver
Java
Bouncy Castle (recommended)
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78</version>
</dependency>
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
Security.addProvider(new BouncyCastlePQCProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM", "BCPQC");
kpg.initialize(MLKEMParameterSpec.ml_kem_768);
KeyPair kp = kpg.generateKeyPair();
JavaScript / TypeScript
liboqs-node (beta)
npm install liboqs-node
The JS/TS ecosystem for PQC is the least mature. For server-side Node.js, consider calling liboqs via FFI or using a Go/Rust service. For browsers, PQC is handled at the TLS layer (Chrome/Firefox already support it).
Choosing a Library
flowchart TD
START[What language?] --> RUST{Rust?}
RUST -->|TLS integration| AWSLC[aws-lc-rs<br/>+ rustls]
RUST -->|Direct KEM/Sig| PQCR[pqcrypto crate]
START --> GOLANG{Go?}
GOLANG -->|Yes| CIRCL[circl<br/>Cloudflare]
START --> PYTHON{Python?}
PYTHON -->|Yes| LIBOQSPY[liboqs-python]
START --> JAVAQ{Java?}
JAVAQ -->|Yes| BC[Bouncy Castle]
START --> CPPQ{C/C++?}
CPPQ -->|Yes| LIBOQS[liboqs]
classDef start fill:#6b8e6b,stroke:#4a6a4a,color:#2c3e50
classDef lang fill:#5a8eaa,stroke:#3a6e8a,color:#2c3e50
classDef lib fill:#8e6b8e,stroke:#6e4a6e,color:#2c3e50
class START start
class RUST,GOLANG,PYTHON,JAVAQ,CPPQ lang
class AWSLC,PQCR,CIRCL,LIBOQSPY,BC,LIBOQS lib
Next: Plan your migration from classical to PQC in the Migration Guide.
| Sources: liboqs | pqcrypto crate | circl | Bouncy Castle |
Last updated: 2026-02-13