~~NOTOC~~
====== Scenario 7.2: Key Encapsulation (ML-KEM) ======
**Category:** [[.:start|Encryption]] \\
**Complexity:** *** (Medium) \\
**Prerequisites:** ML-KEM key pair \\
**Estimated Time:** 15-20 minutes
----
===== Description =====
This scenario describes **Key Encapsulation** with ML-KEM (Module-Lattice-based Key Encapsulation Mechanism, NIST FIPS 203). ML-KEM is a Post-Quantum Key Encapsulation Mechanism (KEM) that is secure against quantum computer attacks.
**KEM vs. Key Exchange:**
^ Aspect ^ Key Exchange (DH) ^ Key Encapsulation (KEM) ^
| Interactivity | Both parties active | Only sender active |
| Key generation | Jointly computed | Randomly generated |
| Application | TLS handshake | Encryption, hybrid TLS |
----
===== ML-KEM Parameter Sets =====
^ Parameter ^ Security ^ Public Key ^ Ciphertext ^ Shared Secret ^
| **ML-KEM-512** | 128-bit | 800 bytes | 768 bytes | 32 bytes |
| **ML-KEM-768** | 192-bit | 1,184 bytes | 1,088 bytes | 32 bytes |
| **ML-KEM-1024** | 256-bit | 1,568 bytes | 1,568 bytes | 32 bytes |
**Recommendation:** ML-KEM-768 for most applications (BSI recommends at least 192-bit).
----
===== Workflow =====
flowchart LR
subgraph Recipient
GEN[KeyGen] --> PK[Public Key]
GEN --> SK[Secret Key]
end
subgraph Sender
PK --> ENC[Encapsulate]
ENC --> CT[Ciphertext]
ENC --> SS1[Shared Secret]
end
subgraph Recipient2[Recipient]
CT --> DEC[Decapsulate]
SK --> DEC
DEC --> SS2[Shared Secret]
end
SS1 -.->|equal| SS2
style SS1 fill:#e8f5e9
style SS2 fill:#e8f5e9
----
===== Code Example: Generate Key Pair =====
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using var ctx = PqCryptoContext.Initialize();
// Generate ML-KEM-768 key pair
using var mlKemKeyPair = ctx.GenerateKeyPair(PqAlgorithm.MlKem768);
// Export public key (for sender)
var publicKeyPem = mlKemKeyPair.PublicKey.ToPem();
File.WriteAllText("recipient-mlkem.pub.pem", publicKeyPem);
// Save private key encrypted
mlKemKeyPair.ToEncryptedPemFile("recipient-mlkem.key.pem", "SecurePassword!");
Console.WriteLine("ML-KEM-768 key pair generated:");
Console.WriteLine($" Public Key: {mlKemKeyPair.PublicKey.GetRawData().Length} bytes");
Console.WriteLine($" Algorithm OID: {mlKemKeyPair.PublicKey.Oid.Value}");
----
===== Code Example: Encapsulation (Sender) =====
using var ctx = PqCryptoContext.Initialize();
// Load recipient public key
var recipientPublicKey = ctx.LoadPublicKey("recipient-mlkem.pub.pem");
// Perform key encapsulation
var (ciphertext, sharedSecret) = ctx.Encapsulate(recipientPublicKey);
Console.WriteLine($"Encapsulation completed:");
Console.WriteLine($" Ciphertext: {ciphertext.Length} bytes");
Console.WriteLine($" Shared Secret: {sharedSecret.Length} bytes");
Console.WriteLine($" Shared Secret (hex): {Convert.ToHexString(sharedSecret)}");
// Send ciphertext to recipient
File.WriteAllBytes("ciphertext.bin", ciphertext);
// Use shared secret for encryption
var encryptionKey = ctx.DeriveKey(
sharedSecret,
outputLength: 32,
info: Encoding.UTF8.GetBytes("aes-encryption-key")
);
----
===== Code Example: Decapsulation (Recipient) =====
using var ctx = PqCryptoContext.Initialize();
// Load private key
var privateKey = ctx.LoadPrivateKey("recipient-mlkem.key.pem", "SecurePassword!");
// Receive ciphertext
var ciphertext = File.ReadAllBytes("ciphertext.bin");
// Perform decapsulation
var sharedSecret = ctx.Decapsulate(privateKey, ciphertext);
Console.WriteLine($"Decapsulation completed:");
Console.WriteLine($" Shared Secret: {sharedSecret.Length} bytes");
Console.WriteLine($" Shared Secret (hex): {Convert.ToHexString(sharedSecret)}");
// Derive same key as sender
var decryptionKey = ctx.DeriveKey(
sharedSecret,
outputLength: 32,
info: Encoding.UTF8.GetBytes("aes-encryption-key")
);
----
===== Wrapper Class for ML-KEM =====
public class MlKemService
{
private readonly PqCryptoContext _ctx;
public MlKemService()
{
_ctx = PqCryptoContext.Initialize();
}
public (byte[] PublicKey, byte[] PrivateKey) GenerateKeyPair(MlKemParameterSet paramSet = MlKemParameterSet.MlKem768)
{
var algorithm = paramSet switch
{
MlKemParameterSet.MlKem512 => PqAlgorithm.MlKem512,
MlKemParameterSet.MlKem768 => PqAlgorithm.MlKem768,
MlKemParameterSet.MlKem1024 => PqAlgorithm.MlKem1024,
_ => throw new ArgumentException("Invalid parameter set")
};
using var keyPair = _ctx.GenerateKeyPair(algorithm);
return (
keyPair.PublicKey.GetRawData(),
keyPair.PrivateKey.GetRawData()
);
}
public (byte[] Ciphertext, byte[] SharedSecret) Encapsulate(byte[] publicKey)
{
using var pubKey = _ctx.ImportPublicKey(publicKey);
return _ctx.Encapsulate(pubKey);
}
public byte[] Decapsulate(byte[] privateKey, byte[] ciphertext)
{
using var privKey = _ctx.ImportPrivateKey(privateKey);
return _ctx.Decapsulate(privKey, ciphertext);
}
}
public enum MlKemParameterSet
{
MlKem512,
MlKem768,
MlKem1024
}
----
===== Error Handling =====
try
{
var sharedSecret = ctx.Decapsulate(privateKey, ciphertext);
}
catch (CryptographicException ex) when (ex.Message.Contains("decapsulation"))
{
// Decapsulation failed - ciphertext tampered or wrong key
Console.WriteLine("Decapsulation failed: Ciphertext invalid");
throw new SecurityException("Integrity check failed", ex);
}
catch (ArgumentException ex)
{
// Wrong format
Console.WriteLine($"Format error: {ex.Message}");
throw;
}
**Security Note:** ML-KEM is IND-CCA2 secure. On decapsulation failures, a deterministic but unpredictable value is returned (implicit rejection). This prevents chosen-ciphertext attacks.
----
===== Industry-Specific Parameters =====
^ Industry ^ Recommended Parameter ^ Rationale ^
| **Standard IT** | ML-KEM-768 | Good balance |
| **Financial Sector** | ML-KEM-768/1024 | Regulatory requirements |
| **Healthcare** | ML-KEM-768 | Long-term data protection |
| **Government** | ML-KEM-1024 | Highest security |
| **IoT/Embedded** | ML-KEM-512 | Resource-constrained |
----
===== Related Scenarios =====
^ Relationship ^ Scenario ^ Description ^
| **Application** | [[.:hybrid_encryption|7.1 Hybrid Encryption]] | Combination with classical |
| **Application** | [[.:file_encryption|7.3 File Encryption]] | Practical usage |
| **Related** | [[en:int:pqcrypt:szenarien:schluessel:generierung|11.1 Key Generation]] | Key generation |
| **Related** | [[en:int:pqcrypt:szenarien:tls:hybrid_tls|10.4 Hybrid TLS]] | TLS with ML-KEM |
----
<< [[.:hybrid_encryption|<- 7.1 Hybrid Encryption]] | [[.:start|^ Encryption Overview]] | [[.:file_encryption|7.3 File Encryption ->]] >>
{{tag>scenario encryption ml-kem kem post-quantum fips203}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//