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.

 
Ein ungültiger level bricht das Programm ab. Gültig sind 44, 65 und 87; jeder andere Wert meldet seit lyxc 1.0.15G ML-DSA: unbekannter Level — erlaubt sind 44, 65 und 87 (#1263).

Vorher wurde ein abweichender Wert stillschweigend als ML-DSA-87 behandelt — wer seine Puffer nach ML-DSA-44 dimensioniert und sich vertippt hatte, bekam 4595 statt 2420 Byte geschrieben, also 2175 Byte über den Puffer hinaus. Diese Klasse von Fehlern ist damit erledigt.

Den level trotzdem als Konstante führen, nicht aus Konfiguration oder Benutzereingabe übernehmen.

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


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 → 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-08-09

Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).