Skip to content
Post-Quantum Cryptography

Post-Quantum Cryptography

Since: cryptopp-modern 2026.3.0

Post-Quantum Cryptography (PQC) provides cryptographic algorithms designed to be secure against attacks by both classical and quantum computers. cryptopp-modern implements the NIST-standardized PQC algorithms from FIPS 203, 204, and 205.

Why Post-Quantum Cryptography?

Quantum computers pose a significant threat to current cryptographic systems:

  • RSA, ECDSA, ECDH, Ed25519, X25519 - All vulnerable to Shor’s algorithm on a sufficiently powerful quantum computer
  • AES, SHA-3, BLAKE3 - Remain secure (Grover’s algorithm only halves effective security)

The “Harvest Now, Decrypt Later” Threat: Adversaries may be collecting encrypted data today, planning to decrypt it once quantum computers become available. Data with long-term confidentiality requirements (medical records, state secrets, financial data) should transition to PQC now.

Available Algorithms

Key Encapsulation (Key Exchange)

AlgorithmStandardSecurity BasisRecommended For
ML-KEMFIPS 203Module latticesPure post-quantum key exchange
X-WingIETF DraftHybrid (X25519 + ML-KEM)Defence in depth (recommended)

Digital Signatures

AlgorithmStandardSecurity BasisRecommended For
ML-DSAFIPS 204Module latticesGeneral-purpose signatures
SLH-DSAFIPS 205Hash functionsConservative security (no lattice assumptions)

Quick Comparison

Key Encapsulation Mechanisms

PropertyML-KEM-768X-WingX25519 (classical)
Public Key1184 bytes1216 bytes32 bytes
Secret Key (seed)64 bytes32 bytes32 bytes*
Ciphertext1088 bytes1120 bytes32 bytes
Shared Secret32 bytes32 bytes32 bytes
Quantum SecureYesYesNo
Classical SecureYesYesYes
Security if lattices brokenNoYes (X25519 backup)N/A

*X25519 secret key is not a seed in the ML-KEM/X-Wing sense.

Digital Signatures

PropertyML-DSA-65SLH-DSA-SHA2-128fEd25519 (classical)
Public Key1952 bytes32 bytes32 bytes
Secret Key4032 bytes64 bytes64 bytes
Signature3309 bytes17088 bytes64 bytes
Quantum SecureYesYesNo
Security BasisLatticesHash functionsElliptic curves
Signing SpeedFastSlowVery Fast
Verification SpeedFastSlowFast

Choosing the Right Algorithm

For Key Exchange / Encryption

Do you need defence against both classical AND quantum attacks today?
├── YES: Use X-Wing (hybrid X25519 + ML-KEM-768)
│        - Secure even if lattice cryptography is broken
│        - Secure even if quantum computers arrive
│        - Recommended for most applications
│
└── NO: Are you building a pure post-quantum system?
    ├── YES: Use ML-KEM-768
    │        - NIST standard (FIPS 203)
    │        - Smaller than X-Wing
    │
    └── NO: Use X25519 (classical)
            - Smallest keys/ciphertexts
            - Well-understood security

For Digital Signatures

What are your priorities?
├── Conservative security (no lattice assumptions)?
│   └── Use SLH-DSA
│       - Based only on hash function security
│       - Larger signatures but different security basis
│       - Choose 'f' variants for speed, 's' variants for smaller signatures
│
├── Balanced performance and security?
│   └── Use ML-DSA-65
│       - NIST standard (FIPS 204)
│       - Good balance of key/signature sizes and speed
│       - Based on lattice assumptions
│
└── Maximum security level?
    └── Use ML-DSA-87 or SLH-DSA-256 variants
        - 256-bit security level
        - Larger keys and signatures

Security Levels

NIST defines security levels based on the computational effort to break:

LevelComparable ToAlgorithms
1AES-128 work factorML-KEM-512, SLH-DSA-128*
2SHA-256 collisionML-DSA-44
3AES-192 work factorML-KEM-768, ML-DSA-65, SLH-DSA-192*
5AES-256 work factorML-KEM-1024, ML-DSA-87, SLH-DSA-256*

Recommendation: Level 3 (ML-KEM-768, ML-DSA-65) provides excellent security for most applications.


Quick Examples

Hybrid Key Exchange with X-Wing (Recommended)

#include <cryptopp/xwing.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/hkdf.h>
#include <cryptopp/sha3.h>

using namespace CryptoPP;

// Recipient generates key pair
AutoSeededRandomPool rng;
XWingDecapsulator recipient(rng);

// Extract public key to send to sender
SecByteBlock publicKey(recipient.GetKey().GetPublicKeySize());
recipient.GetKey().GetPublicKey(publicKey.begin());

// Sender encapsulates (creates shared secret + ciphertext)
XWingEncapsulator sender(publicKey.begin(), publicKey.size());
SecByteBlock ciphertext(sender.CiphertextLength());
SecByteBlock senderSecret(sender.SharedSecretLength());
sender.Encapsulate(rng, ciphertext.begin(), senderSecret.begin());

// Recipient decapsulates to get same shared secret
SecByteBlock recipientSecret(recipient.SharedSecretLength());
bool success = recipient.Decapsulate(ciphertext.begin(), recipientSecret.begin());
if (!success) { throw Exception(Exception::OTHER_ERROR, "Decapsulation failed"); }

// Derive encryption key from shared secret using HKDF
HKDF<SHA3_256> hkdf;
SecByteBlock encryptionKey(32);
const byte info[] = "encryption";
hkdf.DeriveKey(encryptionKey.begin(), encryptionKey.size(),
               senderSecret.begin(), senderSecret.size(),
               nullptr, 0,  // salt (optional)
               info, sizeof(info) - 1);  // info

Post-Quantum Signatures with ML-DSA

#include <cryptopp/mldsa.h>
#include <cryptopp/osrng.h>
#include <cryptopp/secblock.h>
#include <string>

using namespace CryptoPP;

AutoSeededRandomPool rng;

// Generate key pair
MLDSASigner<MLDSA_65> signer(rng);
MLDSAVerifier<MLDSA_65> verifier(signer);

// Sign a message
std::string message = "Important document";
SecByteBlock signature(signer.SignatureLength());
size_t sigLen = signer.SignMessage(rng,
    (const byte*)message.data(), message.size(),
    signature.begin());

// Verify the signature
bool valid = verifier.VerifyMessage(
    (const byte*)message.data(), message.size(),
    signature.begin(), sigLen);

Migration Strategy

Phase 1: Hybrid Mode (Recommended Now)

Use hybrid algorithms that combine classical and post-quantum cryptography:

  • Key Exchange: X-Wing (X25519 + ML-KEM-768)
  • Signatures: Consider dual signatures (Ed25519 + ML-DSA) for critical applications

Benefits:

  • Secure against both classical and quantum attacks
  • If PQC algorithms have undiscovered weaknesses, classical algorithms provide backup
  • Gradual transition without breaking compatibility

Phase 2: Pure Post-Quantum (Future)

Once PQC algorithms are thoroughly analyzed and quantum computers become a near-term threat:

  • Key Exchange: ML-KEM-768 or ML-KEM-1024
  • Signatures: ML-DSA-65 or SLH-DSA

Timeline Considerations

ApplicationRecommended Action
Long-term secrets (25+ years)Migrate to hybrid PQC now
Financial/healthcare dataBegin hybrid migration
Real-time communicationsPlan for hybrid, classical still acceptable
Short-term sessionsClassical acceptable, plan for future

Indicative Performance

Key Generation

AlgorithmApproximate Time
X25519~40 µs
ML-KEM-768~100 µs
X-Wing~150 µs
ML-DSA-65~200 µs
SLH-DSA-SHA2-128f~5 ms
SLH-DSA-SHA2-128s~50 ms

Operations

OperationML-KEM-768X-WingML-DSA-65SLH-DSA-128f
Encaps/Sign~150 µs~200 µs~500 µs~100 ms
Decaps/Verify~100 µs~150 µs~200 µs~10 ms

Performance varies by platform and implementation; benchmark in your target environment.

Guidance:

  • ML-KEM and ML-DSA are fast enough for most applications
  • SLH-DSA is slower but provides hash-based security (no lattice assumptions)
  • X-Wing adds minimal overhead over pure ML-KEM

Thread Safety

PQC class instances are not thread-safe. Use one instance per thread:

// CORRECT: Per-thread instances
void signInThread(const MLDSAPrivateKey<MLDSA_65>& privateKey) {
    AutoSeededRandomPool rng;
    MLDSASigner<MLDSA_65> signer;
    signer.AccessPrivateKey().AssignFrom(privateKey);
    // ... sign ...
}

// INCORRECT: Shared instance
MLDSASigner<MLDSA_65> globalSigner;  // Don't do this

Algorithm Details

ML-KEM (FIPS 203)

Module-Lattice Key Encapsulation Mechanism. Successor to CRYSTALS-Kyber.

  • Three parameter sets: ML-KEM-512, ML-KEM-768, ML-KEM-1024
  • IND-CCA2 secure with implicit rejection
  • Recommended: ML-KEM-768 for most applications

ML-DSA (FIPS 204)

Module-Lattice Digital Signature Algorithm. Successor to CRYSTALS-Dilithium.

  • Three parameter sets: ML-DSA-44, ML-DSA-65, ML-DSA-87
  • EUF-CMA secure, probabilistic signing
  • Recommended: ML-DSA-65 for most applications

SLH-DSA (FIPS 205)

Stateless Hash-Based Digital Signature Algorithm. Successor to SPHINCS+.

  • 12 parameter sets (SHA2/SHAKE × 128/192/256 × fast/small)
  • Security based only on hash function properties
  • Recommended: SLH-DSA-SHA2-128f for speed, SLH-DSA-SHA2-128s for smaller signatures

X-Wing

Hybrid Key Encapsulation combining X25519 and ML-KEM-768.

  • Defence in depth: secure if either algorithm is secure
  • Proposed in IETF CFRG with active industry involvement (including Cloudflare)
  • Recommended: Default choice for new applications

Standards Compliance

AlgorithmStandardStatus
ML-KEMFIPS 203Final (13 August 2024)
ML-DSAFIPS 204Final (13 August 2024)
SLH-DSAFIPS 205Final (13 August 2024)
X-WingIETF DraftDraft

See Also