Skip to content

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

  1. Terminology Confusion
  2. Hybrid Encryption (General Concept)
  3. Composite Keys (IETF Standard)
  4. Key Differences
  5. When to Use Simple vs Composite Keys
  6. ANKASecure Implementation
  7. 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:

  1. Single key object: Composite key treated as atomic unit
  2. Security level matching: Component keys must have equivalent security levels
  3. 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_COMBINE is ANKASecure's name for the construction, not a KDF
  4. 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-768 or P-384+ML-KEM-768
  • Signatures: P-256+ML-DSA-65 or Ed25519+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:

  1. Generate composite key:

    POST /api/v3/admin/tenants/{tenantId}/keys
    {
      "kid": "my-composite-key",
      "kty": "COMPOSITE",
      "algorithm": "P-384+ML-KEM-768"
    }
    

  2. Re-encrypt data (zero plaintext exposure):

    POST /api/v3/crypto/reencrypt
    {
      "jweToken": { "protected": "...", "recipients": [ ... ], "iv": "...", "ciphertext": "...", "tag": "..." },
      "newKid": "my-composite-key"
    }
    → new-jwe-token (encrypted with composite key)
    

  3. Update references (KID mapping)

  4. 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:

  1. Generate composite key (P-256+ML-KEM-768)
  2. Re-encrypt existing data
  3. Policy: Require composite keys for new operations

Scenario 3: Gradual Rollout

Strategy:

  1. Phase 1: Allow both simple and composite keys
  2. Phase 2: Generate only composite keys for new tenants
  3. Phase 3: Migrate existing data via re-encryption APIs
  4. 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)

Foundational Concepts

Architecture

  • Composite Hybrid Keys Architecture*
  • Flavor Dispatching*

Algorithms & Compliance

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.

* restricted content — see higher-tier documentation