Hybrid vs Composite Keys
Target Audience: Solution Architects, Developers
Reading Time: 10 minutes
Prerequisites: Understanding of public-key cryptography, post-quantum cryptography basics
Executive Summary
The terms "hybrid" and "composite" are often used interchangeably in post-quantum cryptography discussions, but they have distinct meanings. This document clarifies the terminology and explains ANKASecure's implementation of composite hybrid keys, whose construction corresponds to the IETF composite Internet-Drafts (draft-ietf-lamps-pq-composite-kem-21, draft-ietf-lamps-pq-composite-sigs-19).
Key distinction:
- Hybrid encryption = General concept (classical + post-quantum algorithms)
- Composite keys = One key object holding both components (IETF composite Internet-Drafts)
Table of Contents
- Terminology Confusion
- Hybrid Encryption (General Concept)
- Composite Keys (IETF Standard)
- Key Differences
- When to Use Simple vs Composite Keys
- ANKASecure Implementation
- Migration Strategies
Terminology Confusion
Common Misuse
In the wild, you'll hear:
- "Hybrid keys" (referring to composite keys)
- "Composite encryption" (referring to hybrid encryption)
- "Hybrid PQC" (could mean either)
Why confusion exists:
Both approaches combine classical and post-quantum algorithms for defense-in-depth, but the implementation details differ significantly.
This Document's Definitions
| Term | Definition | Standard |
|---|---|---|
| Hybrid encryption | Informal pattern: use both classical and PQC algorithms | No formal standard |
| Composite keys | Single key object containing multiple keys | IETF composite Internet-Drafts (work in progress) |
ANKASecure uses: Composite keys (structure corresponding to draft-ietf-lamps-pq-composite-kem-21).
Hybrid Encryption (General Concept)
What is Hybrid Encryption?
Goal: Protect data against both classical and quantum attacks by using two separate encryption operations.
Pattern:
Plaintext
→ Encrypt with Classical Algorithm (e.g., RSA-2048)
→ Encrypt with PQC Algorithm (e.g., ML-KEM-768)
→ Doubly-encrypted ciphertext
Decryption:
Doubly-encrypted ciphertext
→ Decrypt with PQC Algorithm (ML-KEM-768)
→ Decrypt with Classical Algorithm (RSA-2048)
→ Plaintext
Characteristics
| Aspect | Details |
|---|---|
| Key storage | Two separate keys (e.g., rsa-key-2048, mlkem-key-768) |
| Key identifiers | Two distinct KIDs |
| KDF (Key Derivation) | Implementation-specific (no standard) |
| Security level | May mismatch (e.g., 112-bit RSA + 192-bit ML-KEM) |
| Ciphertext size | Larger (double encryption overhead) |
| Performance | Slower (two encryption operations) |
Example: Ad-hoc Hybrid Encryption
Encrypt:
# Step 1: Encrypt with RSA-2048 (data is Base64)
POST /api/v3/crypto/encrypt
{
"kid": "rsa-key-2048",
"data": "c2Vuc2l0aXZlIGRhdGE="
}
→ JWE1 (RSA-OAEP + AES-GCM)
# Step 2: Encrypt JWE1 with ML-KEM-768
POST /api/v3/crypto/encrypt
{
"kid": "mlkem-key-768",
"data": "<Base64 of JWE1>"
}
→ JWE2 (ML-KEM-768 + AES-GCM)
Decrypt:
# Step 1: Decrypt with ML-KEM-768 (the key is read from the JWE header)
POST /api/v3/crypto/decrypt
{
"jweToken": <JWE2>
}
→ JWE1
# Step 2: Decrypt with RSA-2048
POST /api/v3/crypto/decrypt
{
"jweToken": <JWE1>
}
→ plaintext
Problems with Ad-hoc Hybrid
- ❌ No standard format (interoperability issues)
- ❌ Two separate keys to manage
- ❌ Security level mismatch (e.g., 112-bit + 192-bit)
- ❌ Double encryption overhead
- ❌ Application must orchestrate two operations
Composite Keys (IETF Standard)
What are Composite Keys?
Definition (IETF composite drafts): A single cryptographic key object containing multiple component keys (classical + post-quantum), with a standardized Key Derivation Function (KDF) for combining shared secrets.
Key insight: From the application's perspective, it's a single key with a single KID.
IETF Composite ML-KEM Draft
Document: draft-ietf-lamps-pq-composite-kem-21 (Internet-Draft, work in progress)
Title: "Composite ML-KEM for use in X.509 Public Key Infrastructure"
Key requirements:
- Single key object: Composite key treated as atomic unit
- Security level matching: Component keys must have equivalent security levels
- Combiner over both shared secrets: the draft defines its own; ANKASecure uses the NIST SP 800-227 §4.6.1 key combiner, instantiated by the key's
kdf(see below).COMPOSITE_KEM_COMBINEis ANKASecure's name for the construction, not a KDF - Algorithm identifier: Single identifier (e.g.,
P-384+ML-KEM-768)
How Composite Keys Work
Key generation:
1. Generate classical key pair (e.g., X25519)
2. Generate PQC key pair (e.g., ML-KEM-768)
3. Combine into single composite key object
4. Assign single KID (e.g., "my-composite-key")
5. Store composite key in keystore
Encryption (KEM-based):
1. Encapsulate with classical algorithm → shared_secret_1, ciphertext_1
2. Encapsulate with PQC algorithm → shared_secret_2, ciphertext_2
3. Combine: shared_secret = KeyCombine(shared_secret_1, shared_secret_2, ciphertext_1, ciphertext_2, pk_1, pk_2, domain)
4. Encrypt payload with shared_secret (AES-GCM)
5. Output: ciphertext_1 + ciphertext_2 + encrypted_payload
Decryption:
1. Decapsulate with classical algorithm → shared_secret_1
2. Decapsulate with PQC algorithm → shared_secret_2
3. Combine: shared_secret = KeyCombine(shared_secret_1, shared_secret_2, ciphertext_1, ciphertext_2, pk_1, pk_2, domain)
4. Decrypt payload with shared_secret (AES-GCM)
5. Output: plaintext
COMPOSITE_KEM_COMBINE key combiner
Function (NIST SP 800-227, final, September 2025, §4.6.1):
KeyCombine(K_classical, K_pqc, c_classical, c_pqc, ek_classical, ek_pqc, domain)
domain = frame("ankasecure:composite-kem", alg, kdfToken) # length-framed; the kid is bound by the AAD instead
kdfToken ∈ {HKDF-SHA256 (default), HKDF-SHA384, HKDF-SHA512, CatKDF, CasKDF}
HKDF-SHA*: HKDF-Extract over K_classical ‖ K_pqc, then HKDF-Expand with info = frame(c_classical, c_pqc, ek_classical, ek_pqc, domain)
CatKDF / CasKDF: the ETSI TS 103 744 §8.2.3 / §8.3.3 constructions over the same inputs
Purpose: derive a single shared secret from both component secrets while binding both ciphertexts, both encapsulation keys and the scheme identifier, so a substituted component ciphertext changes the result. The token is carried as anka_kdf in the protected header of every token the key produces.
Characteristics
| Aspect | Details |
|---|---|
| Key storage | Single composite key object |
| Key identifiers | Single KID (e.g., my-composite-key) |
| KDF (Key Derivation) | SP 800-227 §4.6.1 key combiner, instantiated by the key's kdf (HKDF-SHA256 by default) |
| Security level | Enforced matching (e.g., 192-bit + 192-bit → 192-bit) |
| Ciphertext size | Optimized (single encryption operation) |
| Performance | Faster than ad-hoc hybrid (single encryption round) |
| Interoperability | ⚠️ Follows the draft's model; the combiner is not the draft's byte-exact one, so a draft implementation cannot decrypt |
Key Differences
Summary Table
| Aspect | Hybrid (General) | Composite (IETF composite drafts) |
|---|---|---|
| Standard | Informal pattern | IETF composite Internet-Drafts (work in progress) |
| Key object | Two separate keys | Single key object |
| Key identifiers | Two KIDs | Single KID |
| KDF | Implementation-specific | SP 800-227 §4.6.1 key combiner, instantiated by the key's kdf |
| Security level | May mismatch | Enforced matching |
| Algorithm identifier | N/A | Single identifier (e.g., P-384+ML-KEM-768) |
| Encryption rounds | Two (double encryption) | One (parallel encapsulation) |
| Ciphertext overhead | Larger (nested JWE) | Smaller (optimized) |
| Application complexity | Must orchestrate two operations | Single operation (transparent) |
| Serialization | Two nested JWEs | One JWE General JSON (or one composite JWS) |
| ANKASecure support | ⚠️ Possible but discouraged | ✅ Native support |
Visual Comparison
Hybrid (Ad-hoc):
Application
↓ (calls encrypt twice)
Classical Encryption (KID: rsa-key)
↓ (produces JWE1)
PQC Encryption (KID: mlkem-key)
↓ (produces JWE2)
Doubly-encrypted ciphertext
Composite (IETF composite drafts):
Application
↓ (single encrypt call)
Composite Key Handler (KID: composite-key)
↓
┌───────────────────┬───────────────────┐
│ │ │
Classical KEM PQC KEM
│ │
└─────────┬─────────┘
│
KDF Combiner
↓
Single encrypted ciphertext
When to Use Simple vs Composite Keys
Decision Matrix
| Scenario | Recommendation |
|---|---|
| Legacy system, no PQC requirement | Simple key (RSA, ECDSA) |
| Performance-critical, classical security sufficient | Simple key (ECDSA-P-256, Ed25519) |
| PQC readiness, defense-in-depth | Composite key (ECDSA+ML-DSA, RSA+ML-KEM) |
| PQC transition guided by NIST (CSWP 39 §3.2.4 hybrid algorithms) | Composite key |
| NSA CNSA 2.0 parameter sets | Simple or composite key with ML-KEM-1024 / ML-DSA-87 |
| Long-term data protection (>10 years) | Composite key |
| Quantum-safe only | Simple PQC key (ML-KEM, ML-DSA) |
| Small embedded device | Simple key (FALCON-512, Ed25519) |
Risk Analysis
Simple classical key (e.g., RSA-2048):
- ✅ Mature, widely supported
- ❌ Vulnerable to quantum attacks (Shor's algorithm)
- ❌ Not future-proof beyond ~2030
Simple PQC key (e.g., ML-KEM-768):
- ✅ Quantum-resistant
- ❌ Relatively new (less battle-tested)
- ❌ Larger keys and signatures
Composite key (e.g., P-384+ML-KEM-768):
- ✅ Defense-in-depth (secure if either algorithm holds)
- ✅ Hedges against cryptanalysis breakthroughs
- ✅ IETF standard (interoperable)
- ⚠️ Slightly larger ciphertext
- ⚠️ Marginally slower (but optimized)
ANKASecure Recommendation
Default choice: Composite keys at 192-bit security level
- Encryption:
P-256+ML-KEM-768orP-384+ML-KEM-768 - Signatures:
P-256+ML-DSA-65orEd25519+ML-DSA-44 - Content encryption:
A256GCM(AES-256-GCM)
Rationale:
- ✅ NIST Level 3 security (192-bit equivalent to AES-192)
- ✅ Structure corresponding to draft-ietf-lamps-pq-composite-kem-21
- ✅ Balanced performance (faster than Level 5)
- ✅ Future-proof (quantum + classical security)
- ✅ Widely supported by ANKASecure algorithms
ANKASecure Implementation
Composite Algorithm Identifiers
Format: <Classical>+<PostQuantum>
Supported combinations (41 total):
| Classical | Post-Quantum | NIST level | Algorithm identifier |
|---|---|---|---|
| X25519 | ML-KEM-512 | L1 | X25519+ML-KEM-512 |
| X25519 | ML-KEM-768 | L1 | X25519+ML-KEM-768 |
| P-256 | ML-KEM-768 | L1 | P-256+ML-KEM-768 |
| P-384 | ML-KEM-768 | L3 | P-384+ML-KEM-768 |
| P-384 | ML-KEM-1024 | L3 | P-384+ML-KEM-1024 |
| P-521 | ML-KEM-1024 | L5 | P-521+ML-KEM-1024 |
| Ed25519 | ML-DSA-44 | L1 | Ed25519+ML-DSA-44 |
| P-256 | ML-DSA-65 | L1 | P-256+ML-DSA-65 |
| P-384 | ML-DSA-87 | L3 | P-384+ML-DSA-87 |
| brainpoolP256r1 | ML-DSA-65 | L1 | brainpoolP256r1+ML-DSA-65 |
There is no RSA composite
CompositeAlgorithmCatalogue contains zero RSA pairings. Its classical components are X25519, X448, P-256/384/521 and the three Brainpool curves; its PQC components are ML-KEM, HQC and ML-DSA. An identifier such as RSA2048+MLKEM768 is wrong twice over: the spelling carries no hyphens and the pairing does not exist. A JWE whose alg header names it is rejected: AlgorithmResolverImpl refuses any composite absent from the catalogue, and the decrypter matches the header against the catalogue identifier with an exact string comparison.
See full catalog: Composite Algorithms Catalog
Single KID for Composite Keys
Key generation:
POST /api/v3/admin/tenants/{tenantId}/keys
Request:
{
"kid": "my-hybrid-key",
"algorithm": "P-256+ML-KEM-768",
"usage": ["encrypt", "decrypt"]
}
Response:
{
"kid": "my-hybrid-key",
"algorithm": "P-256+ML-KEM-768",
"flavor": "composite",
"created": "2025-01-15T10:30:00Z"
}
Usage (transparent to application):
# Encrypt with composite key (single call)
POST /api/v3/crypto/encrypt
Request:
{
"kid": "my-hybrid-key",
"data": "c2Vuc2l0aXZlIGRhdGE="
}
Response (General JSON, one recipient per component):
{
"jweToken": {
"protected": "eyJlbmMiOiJBMjU2R0NNIiwia2lkIjoibXktaHlicmlkLWtleSJ9...",
"recipients": [
{ "header": { "alg": "X25519" }, "encrypted_key": "..." },
{ "header": { "alg": "ML-KEM-768" }, "encrypted_key": "..." }
],
"iv": "...",
"ciphertext": "...",
"tag": "..."
},
"keyRequested": "my-hybrid-key",
"algorithmUsed": "X25519+ML-KEM-768"
}
Application perspective: No difference from simple key usage.
Internal Architecture
Key storage:
/srv/anka-secure/environments/prod/volumes/keystores/tenant-a/
└── my-hybrid-key.p12 (contains both ECDH-P-256 + ML-KEM-768 keys)
Metadata (database):
SELECT * FROM crypto_keys WHERE kid = 'my-hybrid-key';
kid | algorithm | flavor | security_level
----------------|---------------------|-----------|---------------
my-hybrid-key | P-256+ML-KEM-768 | composite | 1
Runtime dispatching:
1. API receives request with kid="my-hybrid-key"
2. Lookup metadata → flavor="composite"
3. Route to CompositeCryptoService
4. Load composite key from keystore
5. Execute composite encapsulation (ECDH + ML-KEM)
6. Combine secrets with COMPOSITE_KEM_COMBINE
7. Encrypt payload with derived key
8. Return JWE
See: Flavor Dispatching*
Migration Strategies
Scenario 1: Classical to Composite (Re-encrypt)
Current state: Data encrypted with RSA-2048 simple key.
Goal: Migrate to P-384+ML-KEM-768 composite key.
Steps:
-
Generate composite key:
-
Re-encrypt data (zero plaintext exposure):
-
Update references (KID mapping)
- Deprecate old key
See: Flow 4 - Asymmetric Re-encrypt (RSA → ML-KEM)
Scenario 2: PQC-Only to Composite (Defense-in-Depth)
Current state: Data encrypted with ML-KEM-768 simple key.
Goal: Add classical algorithm for defense-in-depth.
Steps:
- Generate composite key (P-256+ML-KEM-768)
- Re-encrypt existing data
- Policy: Require composite keys for new operations
Scenario 3: Gradual Rollout
Strategy:
- Phase 1: Allow both simple and composite keys
- Phase 2: Generate only composite keys for new tenants
- Phase 3: Migrate existing data via re-encryption APIs
- Phase 4: Deprecate simple key generation (composite-only policy)
Timeline: 6-12 months for large deployments.
Quick Reference
Terminology Cheat Sheet
| Term | Meaning | Standard |
|---|---|---|
| Hybrid encryption | General concept (classical + PQC) | None (informal) |
| Composite key | Single key object | IETF composite Internet-Drafts |
| Simple key | Single algorithm (classical or PQC) | N/A |
| Defense-in-depth | Multiple security layers | General principle |
| KEM | Key Encapsulation Mechanism | NIST terminology |
When to Say What
| Context | Use this term |
|---|---|
| IETF standards discussion | Composite keys |
| General concept explanation | Hybrid encryption |
| ANKASecure implementation | Composite hybrid keys |
| Customer-facing docs | Hybrid encryption (easier to understand) |
| Technical specifications | Composite keys (precise) |
Related Documentation
Foundational Concepts
Architecture
- Composite Hybrid Keys Architecture*
- Flavor Dispatching*
Algorithms & Compliance
- Composite Algorithms Catalog (41 Total)
- IETF Composite ML-KEM and Composite Signatures — Alignment
- NIST CSWP 39 Alignment*
Key Management
- Composite Hybrid Keys Usage*
- Composite Keys Best Practices*
SDK Examples
Document Status: ✅ ACTIVE
Last Updated: January 2025
Document Location: 02-concepts/hybrid-vs-composite-keys.md
Target Audience: Solution Architects, Developers
Feedback: For corrections or additions, contact the documentation team.