1 stable release
| 2.0.0 | May 5, 2026 |
|---|---|
| 1.0.0 |
|
#68 in Network programming
1MB
2.5K
SLoC
PQTG — Post-Quantum Transport Gateway
A security gateway that replaces vulnerable classical TLS with post-quantum cryptography for QKD infrastructure, protecting against quantum computer attacks on authentication and transport.
📄 Citation: S. Cormier, "Residual Classical Vulnerabilities in Quantum Key Distribution Control Channels," Zenodo, 2026. DOI: 10.5281/zenodo.18786526.
The problem
QKD vendors (Toshiba, IDQuantique) use classical TLS for their management APIs, creating a vulnerability where TLS certificates could be compromised by quantum computers, allowing attackers to steal quantum keys. This undermines the quantum security that QKD is supposed to provide.
The solution
PQTG sits directly on the QKD machine and:
- Listens only on a quantum-safe port for external clients
- Authenticates clients via Falcon-512 + SLH-DSA-Shake128f
- Establishes session keys via ML-KEM-768 key encapsulation (FIPS 203)
- Translates inbound requests to the vendor's TLS API on
localhost - Optionally mixes a per-session QKD key into the PQC session key (hybrid)
External access is always post-quantum secure; the vendor's classical TLS is never exposed beyond the loopback interface.
Cryptographic stack
All primitives go through paraxiom-pqc (pure Rust, zero C):
| Layer | Algorithm | Standard |
|---|---|---|
| Key encapsulation | ML-KEM-768 | FIPS 203 |
| Handshake sig. | Falcon-512 | FIPS 206 (pending) |
| Audit-trail sig. | SLH-DSA-Shake128f | FIPS 205 |
| AEAD | AES-256-GCM | NIST SP 800-38D |
| Transcript / KDF | SHA3-256 | FIPS 202 |
Wire protocol (v2)
ClientHello { client_random, kem_ek, falcon_vk, slh_dsa_vk, requested_size }
ServerHello { server_random, falcon_vk, slh_dsa_vk, kem_ciphertext, transcript_sig }
transcript = SHA3("pqtg-transcript-v2" || cr || sr ||
len(ek) || ek || len(vk) || vk || len(ct) || ct)
kem_ss = ML-KEM-768.Decapsulate(client_dk, kem_ciphertext) // client
= ML-KEM-768.Encapsulate(client_ek) // server
session_key = SHA3("pqtg-session-v2" || mix_keys(qkd_key, kem_ss) || transcript)
If a QKD key is unavailable, mix_keys reduces to the PQC secret directly
(PQC-only fallback).
Installation
# On your QKD hardware (Toshiba / IDQ / similar)
git clone https://github.com/Paraxiom/pq-transport-gateway
cd pq-transport-gateway
cargo build --release
sudo ./target/release/pq-qkd-proxy --generate-keys
Configuration
Edit /etc/pq-qkd-proxy/config.toml:
[proxy]
listen = "192.168.1.100:8443"
[qkd]
vendor_api = "https://localhost:443"
vendor_cert = "/etc/qkd/vendor-cert.pem"
[security]
pq_algorithm = "falcon512"
sig_algorithm = "slh-dsa-shake128f"
authorized_keys = "/etc/pq-qkd-proxy/authorized_keys"
Authorized keys format
falcon512+slh-dsa-shake128f <base64(falcon_vk(897) || slh_dsa_vk(32))> perm=read,write client@example.com
Security properties
- No external TLS: vendor TLS stays on
127.0.0.1 - PQ-only externally: every external connection uses Falcon + ML-KEM
- Hybrid optional: QKD key, when available, mixed into PQC session key
- Authenticated key agreement: server signs the full handshake transcript
- Forward secrecy: ephemeral ML-KEM keypair per handshake
- Audit logging: every key request signed with SLH-DSA (hash-based, stateless)
Formal verification
Lean 4 parameter-conformance lemmas live under lean/. They prove
size and structural properties (byte sizes, framing limits, transcript
shape, NTT compatibility, primality of moduli) against the FIPS standards.
They do not re-derive cryptographic security from lattice arithmetic;
EUF-CMA / IND-CCA properties are inherited as assumptions from the
respective standards and the audited paraxiom-pqc crate.
cd lean
lake update
lake build
Status
This is 2.0.0. 1.0.0 (Feb 2026, on crates.io) is yanked and must
not be used — it shipped a signature-only "shared secret" function that
did not actually produce a shared secret (each side derived a different
value). 2.0.0 replaces it with real ML-KEM-768 key encapsulation and
re-grounds the handshake on paraxiom-pqc. The wire protocol bumped
v1 → v2 and is not backwards compatible.
Despite the 2.0.0 major number, this should still be considered
pre-stable: open issues track production gaps including persistence
ergonomics, mutual auth, and DoS hardening. Pin exactly (= "2.0.0")
until those land if you depend on this for anything load-bearing.
License
Dual-licensed under MIT or Apache-2.0, at your option.
Dependencies
~18–35MB
~430K SLoC