std.crypto.pqc.mlkem
ML-KEM (CRYSTALS-Kyber, NIST FIPS 203) ist ein Key Encapsulation Mechanism (KEM). Er ersetzt ECDH und RSA-OAEP. Die Sicherheit basiert auf dem Module Learning With Errors (MLWE)-Problem, das als quantensicher gilt.
Klassifikation: Asymmetrischer KEM — erzeugt einen gemeinsamen Schlüssel (Shared Secret), der dann als symmetrischer Schlüssel verwendet wird.
import std.crypto.pqc.mlkem;
→ std.crypto.pqc · std.crypto.pqc.pqc (High-Level API) · std.crypto
Sicherheitsstufen
ML-KEM bietet drei Stufen, die über den Parameter k gesteuert werden:
| Stufe | k | Klassische Sicherheit | Quantensicherheit | Empfehlung |
|---|---|---|---|---|
| ML-KEM-512 | 2 | AES-128-äquivalent | ~100-Bit | Eingeschränkte Ressourcen |
| ML-KEM-768 | 3 | AES-192-äquivalent | ~120-Bit | Standardwahl |
| ML-KEM-1024 | 4 | AES-256-äquivalent | ~160-Bit | Höchste Sicherheit |
Empfehlung: ML-KEM-768 (k=3) ist der NIST-Standard für die meisten Anwendungen (analog zu ECDH-P256 heute).
Konstanten
| Konstante | Wert | Bedeutung |
|---|---|---|
MLKEM512_PK | 800 | Public-Key-Größe ML-KEM-512 in Bytes |
MLKEM512_SK | 1632 | Secret-Key-Größe ML-KEM-512 in Bytes |
MLKEM512_CT | 768 | Ciphertext-Größe ML-KEM-512 in Bytes |
MLKEM768_PK | 1184 | Public-Key-Größe ML-KEM-768 in Bytes |
MLKEM768_SK | 2400 | Secret-Key-Größe ML-KEM-768 in Bytes |
MLKEM768_CT | 1088 | Ciphertext-Größe ML-KEM-768 in Bytes |
MLKEM1024_PK | 1568 | Public-Key-Größe ML-KEM-1024 in Bytes |
MLKEM1024_SK | 3168 | Secret-Key-Größe ML-KEM-1024 in Bytes |
MLKEM1024_CT | 1568 | Ciphertext-Größe ML-KEM-1024 in Bytes |
SK-Layout: dk_pke (384·k) || ek (384·k+32) || H(ek) (32) || z (32)
Funktionen
| Funktion | Beschreibung |
|---|---|
MLKEMKeyGen(seed, k, pk, sk): int64 | Erzeugt Schlüsselpaar aus 64-Byte-Seed. seed[0..31]=d, seed[32..63]=z. Gibt 0 zurück. |
MLKEMEncapsulate(pk, k, randomness, ct, sharedKey): int64 | Erzeugt ct und 32-Byte sharedKey aus Public Key und 32-Byte-Zufall. Gibt 0 zurück. |
MLKEMDecapsulate(sk, k, ct, sharedKey): int64 | Rekonstruiert sharedKey aus Secret Key und Ciphertext. Implizite Ablehnung: falscher CT → pseudozufälliger Key (kein Fehler-Code). Gibt 0 zurück. |
Alle Puffer sind caller-alloziert. Größen aus den Konstanten oben.
Wichtig — Implizite Ablehnung: MLKEMDecapsulate gibt bei manipuliertem Ciphertext einen deterministischen Pseudo-Key zurück (kein -1). Der Unterschied zu einem echten Key ist von außen nicht erkennbar (constant-time). Das ist beabsichtigt (FIPS 203 §6.4).
Verwendungsbeispiel
import std.crypto.pqc.mlkem;
import std.crypto.rand;
import std.alloc;
fn main(): int64 {
// Schlüsselpaar erzeugen (ML-KEM-768, k=3)
var seed: int64 := alloc(64);
RandBytesExact(seed, 64);
var pk: int64 := alloc(MLKEM768_PK);
var sk: int64 := alloc(MLKEM768_SK);
MLKEMKeyGen(seed, 3, pk, sk);
// Sender: kapselt Shared Secret ein
var rand: int64 := alloc(32);
RandBytesExact(rand, 32);
var ct: int64 := alloc(MLKEM768_CT);
var ss_enc: int64 := alloc(32);
MLKEMEncapsulate(pk, 3, rand, ct, ss_enc);
// Empfänger: rekonstruiert Shared Secret
var ss_dec: int64 := alloc(32);
MLKEMDecapsulate(sk, 3, ct, ss_dec);
// ss_enc == ss_dec (wenn ct unmanipuliert)
free(seed, 64); free(rand, 32);
free(pk, MLKEM768_PK); free(sk, MLKEM768_SK);
free(ct, MLKEM768_CT); free(ss_enc, 32); free(ss_dec, 32);
return 0;
}
Hinweis: Für den einfachsten Einstieg → std.crypto.pqc.pqc verwenden (High-Level API, kein manuelles k/Seedhandling).
Sicherheitseigenschaften
| Eigenschaft | Ergebnis |
|---|---|
| NIST-Standard | FIPS 203 (2024) — offiziell standardisiert |
| Quantensicherheit | IND-CCA2 im QROM; Grover-Bound je nach Stufe |
| Klassische Sicherheit | MLWE-Härte (strukturell sicherer als RSA/ECDH gegen Quantenrechner) |
| Constant-Time | Implizite Ablehnung CT-sicher via CTMemEqual/CTSelect |
| Interoperabilität | FIPS 203 kompatibel (Wire-Format identisch mit liboqs, BoringSSL) |
Letzte Aktualisierung: 2026-06-08
