pqc-py
Post-quantum cryptography for Python via Rust.
FIPS 203/204/205 implementations (ML-KEM, ML-DSA, SLH-DSA) plus classical primitives (AES-256-GCM, HKDF, HMAC-SHA256), all backed by audited Rust crates with automatic key zeroization.
Features
| Algorithm | Standard | Purpose |
|---|---|---|
| ML-KEM (Kyber) | FIPS 203 | Post-quantum key encapsulation |
| ML-DSA (Dilithium) | FIPS 204 | Post-quantum digital signatures |
| SLH-DSA (SPHINCS+) | FIPS 205 | Stateless hash-based signatures |
| AES-256-GCM | NIST SP 800-38D | Authenticated encryption |
| HKDF-SHA256/512 | RFC 5869 | Key derivation |
| HMAC-SHA256 | RFC 2104 | Message authentication |
Security
- All secret key material is automatically zeroed on drop (
zeroize) - Constant-time comparisons where applicable (
subtle) - No
unsafecode in the Rust layer - Built on audited RustCrypto and pqcrypto libraries
Installation
From PyPI (when published)
pip install pqc-py
From source
Requires Rust 1.70+ and maturin:
git clone https://github.com/ScrappinR/pqc-py.git
cd pqc-py
pip install maturin
maturin develop --release
Usage
Post-Quantum Key Exchange (Kyber / ML-KEM)
import pqc_py
# Generate key pair (level1=128bit, level3=192bit, level5=256bit)
pk, sk = pqc_py.kyber_keygen("level3")
# Encapsulate (sender)
ciphertext, shared_secret_sender = pqc_py.kyber_encapsulate(pk)
# Decapsulate (receiver)
shared_secret_receiver = pqc_py.kyber_decapsulate(ciphertext, sk)
assert shared_secret_sender == shared_secret_receiver
Post-Quantum Signatures (Dilithium / ML-DSA)
import pqc_py
pk, sk = pqc_py.dilithium_keygen("level3")
signature = pqc_py.dilithium_sign(sk, b"message to sign")
valid = pqc_py.dilithium_verify(pk, b"message to sign", signature)
assert valid
SPHINCS+ (SLH-DSA) — Conservative Signatures
import pqc_py
# 12 variants: sha2/shake x 128/192/256 x fast/small
pk, sk = pqc_py.sphincs_keygen("sha2-192f")
signature = pqc_py.sphincs_sign(sk, b"message", variant="sha2-192f")
valid = pqc_py.sphincs_verify(pk, b"message", signature, variant="sha2-192f")
Classical Crypto
import pqc_py
# AES-256-GCM
key = pqc_py.random_key() # 32 bytes
nonce = pqc_py.random_nonce() # 12 bytes
ciphertext = pqc_py.encrypt_aes_gcm(key, nonce, b"plaintext", b"aad")
plaintext = pqc_py.decrypt_aes_gcm(key, nonce, ciphertext, b"aad")
# HKDF key derivation
derived = pqc_py.derive_key(b"secret", salt=b"salt", info=b"context", length=32)
# HMAC-SHA256
tag = pqc_py.hmac_sha256(key, b"message")
assert pqc_py.verify_hmac(key, b"message", tag)
# SHA-256
digest = pqc_py.sha256(b"data")
hex_digest = pqc_py.sha256_hex(b"data")
Building
# Rust library only
cargo build --release
# Python wheel
maturin build --release
# Development install
maturin develop --release
# Run Rust tests
cargo test
# Run benchmarks
cargo bench
Benchmarks
Run cargo bench for performance numbers. Key operations:
- Kyber keygen + encapsulate + decapsulate
- Dilithium keygen + sign + verify
- SPHINCS+ keygen + sign + verify (all 12 variants)
- AES-256-GCM encrypt/decrypt
- HKDF derivation
License
Apache 2.0
Author
Brian James Rutherford — brianrutherford.dev
Metadata
Release files for pqc-py 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pqc_py-0.1.0.tar.gz | 39.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pqc_py-0.1.0-cp313-cp313-win_amd64.whl | CPython 3.13 | CPython 3.13 | Windows x86-64 | Details |
Total release size: 300.0 kB
Release files / pqc_py-0.1.0.tar.gz
| Download URL | pqc_py-0.1.0.tar.gz |
|---|---|
| Size | 39.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0947d19042bf3ef1ddff136835b073ff4b7d9d670c5a926045a548df8afdbfaa
|
|
BLAKE2b-256 checksum How to use checksums |
925212bbed012ac0a743438911c4a754ec41e520109d98ab6b9f7ab677a97372
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|
Release files / pqc_py-0.1.0-cp313-cp313-win_amd64.whl
| Download URL | pqc_py-0.1.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 260.2 kB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
902ef0c6aeb3f3d3bf3c855e19600f70216057c0b4a459129ad0d8fe950ae6c4
|
|
BLAKE2b-256 checksum How to use checksums |
b352bf0e50589222aeccbf8d291b60828a565295cb2dff943f6d7a8d22ffbeda
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|