====== std.crypto.pqc.mldsa ======
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;
→ [[lyx_-_programmiersprache:units:crypto:pqc|std.crypto.pqc]] · [[lyx_-_programmiersprache:units:crypto:pqc:pqc|std.crypto.pqc.pqc (High-Level API)]] · [[lyx_-_programmiersprache:units:crypto|std.crypto]]
----
===== Sicherheitsstufen =====
^ 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).
----
===== Konstanten =====
^ 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₁
----
===== Funktionen =====
^ 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.
----
===== Verwendungsbeispiel =====
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 → [[lyx_-_programmiersprache:units:crypto:pqc:pqc|std.crypto.pqc.pqc]] verwenden (High-Level API).
----
===== Sicherheitseigenschaften =====
^ 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