ML-DSA (CRYSTALS-Dilithium, NIST FIPS 204) ist ein Post-Quantum-Signaturverfahren. Es ersetzt RSA-Sign und ECDSA. Die Sicherheit basiert auf dem Module Short Integer Solution (MSIS)- und MLWE-Problem.
Klassifikation: Asymmetrisches Signaturverfahren — Schlüsselpaar aus Public Key (zum Verifizieren) und Secret Key (zum Signieren).
import std.crypto.pqc.mldsa;
→ std.crypto.pqc · std.crypto.pqc.pqc (High-Level API) · std.crypto
| Stufe | k / l | η | Klassische Sicherheit | Quantensicherheit | Empfehlung |
|---|---|---|---|---|---|
| ML-DSA-44 | 4/4 | 2 | AES-128-äquivalent | ~100-Bit | Eingeschränkte Ressourcen |
| ML-DSA-65 | 6/5 | 4 | AES-192-äquivalent | ~120-Bit | Standardwahl |
| ML-DSA-87 | 8/7 | 2 | AES-256-äquivalent | ~160-Bit | Höchste Sicherheit |
Empfehlung: ML-DSA-65 ist der NIST-Standard für die meisten Anwendungen (entspricht ECDSA-P256 heute).
| Konstante | Wert | Bedeutung |
|---|---|---|
MLDSA44_PK | 1312 | Public-Key-Größe ML-DSA-44 in Bytes |
MLDSA44_SK | 2528 | Secret-Key-Größe ML-DSA-44 in Bytes |
MLDSA44_SIG | 2420 | Maximale Signaturlänge ML-DSA-44 in Bytes |
MLDSA65_PK | 1952 | Public-Key-Größe ML-DSA-65 in Bytes |
MLDSA65_SK | 4000 | Secret-Key-Größe ML-DSA-65 in Bytes |
MLDSA65_SIG | 3293 | Maximale Signaturlänge ML-DSA-65 in Bytes |
MLDSA87_PK | 2592 | Public-Key-Größe ML-DSA-87 in Bytes |
MLDSA87_SK | 4864 | Secret-Key-Größe ML-DSA-87 in Bytes |
MLDSA87_SIG | 4595 | Maximale Signaturlänge ML-DSA-87 in Bytes |
DILITH_Q | 8380417 | Modul q (23-Bit-Primzahl) |
DILITH_D | 13 | Power2Round-Parameter d |
SK-Layout: ρ(32) || K(32) || tr(32) || s₁ || s₂ || t₀ · PK-Layout: ρ(32) || t₁
| Funktion | Beschreibung |
|---|---|
MLDSAKeyGen(seed, level, pk, sk): int64 | Erzeugt Schlüsselpaar aus 32-Byte-Seed ξ. level = 44, 65 oder 87. Gibt 0 zurück. |
MLDSASign(sk, level, msg, msgLen, sig): int64 | Signiert msg (msgLen Bytes). sig: caller-alloziert mit MLDSAxx_SIG Bytes. Gibt tatsächliche Signaturlänge zurück (≤ MLDSAxx_SIG), oder 0 bei Fehler. |
MLDSAVerify(pk, level, msg, msgLen, sig, sigLen): int64 | Verifiziert Signatur. Gibt 1 bei gültiger Signatur, 0 bei ungültiger. |
Signatur-Variabilität: Die tatsächliche Signaturlänge ist durch die Rejection-Sampling-Loop variabel, aber immer ≤ MLDSAxx_SIG. Der Puffer muss immer die maximale Größe haben.
Deterministische Signatur: MLDSASign verwendet die deterministische Variante (rnd = 0^256 intern). Kein Nonce-Wiederverwendungs-Risiko.
import std.crypto.pqc.mldsa;
import std.crypto.rand;
import std.alloc;
fn main(): int64 {
// Schlüsselpaar erzeugen (ML-DSA-65)
var seed: int64 := alloc(32);
RandBytesExact(seed, 32);
var pk: int64 := alloc(MLDSA65_PK);
var sk: int64 := alloc(MLDSA65_SK);
MLDSAKeyGen(seed, 65, pk, sk);
// Signieren
var msg: pchar := "Hello, ML-DSA!"c;
var m_len: int64 := 14;
var sig: int64 := alloc(MLDSA65_SIG);
var sig_len: int64 := MLDSASign(sk, 65, msg as int64, m_len, sig);
// Verifizieren
var ok: int64 := MLDSAVerify(pk, 65, msg as int64, m_len, sig, sig_len);
// ok == 1 wenn gültig
free(seed, 32);
free(pk, MLDSA65_PK); free(sk, MLDSA65_SK);
free(sig, MLDSA65_SIG);
return 0;
}
Hinweis: Für den einfachsten Einstieg → std.crypto.pqc.pqc verwenden (High-Level API).
| Eigenschaft | Ergebnis |
|---|---|
| NIST-Standard | FIPS 204 (2024) — offiziell standardisiert |
| Quantensicherheit | EUF-CMA im QROM; MSIS/MLWE-Sicherheit |
| Determinismus | Ja — kein Nonce-Wiederverwendungs-Risiko (anders als RFC 6979 ECDSA) |
| Signatur-Overhead | 3293 Bytes (ML-DSA-65) vs. 64 Bytes ECDSA — signifikant größer |
| Interoperabilität | FIPS 204 kompatibel |
Letzte Aktualisierung: 2026-06-08