====== std.crypto.ct ======
Constant-Time Utilities — timing-seitenkanal-freie Basisfunktionen für kryptographischen Code. Alle Operationen laufen in streng konstanter Zeit: keine datenbabhängigen Branches, kein datenabhängiges Memory-Access-Pattern. Intern genutzt von ML-KEM, ML-DSA und DADQ.
import std.crypto.ct;
→ [[lyx_-_programmiersprache:units:crypto|std.crypto]] · [[lyx_-_programmiersprache:units|Standard Library]]
----
===== Funktionen =====
**Auswahl und Vergleich:**
^ Funktion ^ Signatur ^ Beschreibung ^
| ''CTSelect'' | ''(a, b, mask): int64'' | Gibt ''a'' zurück wenn ''mask = 0xFFFF…FF'', sonst ''b''. Kein Branch. |
| ''CTEqual'' | ''(a, b): int64'' | Gibt ''0xFFFF…FF'' zurück wenn a == b, sonst 0. |
| ''CTIsZero'' | ''(x): int64'' | Gibt ''0xFFFF…FF'' zurück wenn x == 0, sonst 0. |
| ''CTMemEqual'' | ''(a, b, len): int64'' | Vergleicht len Bytes ohne Early-Exit. Gibt 1 zurück wenn gleich. |
**Speicher:**
^ Funktion ^ Signatur ^ Beschreibung ^
| ''SecureZero'' | ''(ptr, len)'' | Überschreibt len Bytes mit 0. Nicht vom Compiler wegoptimiert (Barrier). |
**Modulare Arithmetik:**
^ Funktion ^ Signatur ^ Beschreibung ^
| ''CTBarrettReduce'' | ''(a, q): int64'' | Barrett-Reduktion: a mod q ohne Division in konstanter Zeit. Nutzt 2³²/q-Approximation. |
| ''CTMontgomeryReduce'' | ''(a, q, qinv): int64'' | Montgomery-Reduktion: a × R⁻¹ mod q. Erfordert qinv = q⁻¹ mod 2³². |
----
===== Verwendungsbeispiele =====
**Constant-Time Vergleich (kein Early-Exit):**
import std.crypto.ct;
// Sicher: MAC-Vergleich in konstanter Zeit (keine Timing-Leaks)
var mac1: int64 := alloc(32);
var mac2: int64 := alloc(32);
// ... beide MACs berechnen ...
var equal: int64 := CTMemEqual(mac1, mac2, 32); // 1 = gleich, 0 = verschieden
free(mac1, 32); free(mac2, 32);
**CTSelect für branchlose Auswahl:**
import std.crypto.ct;
// Wähle a oder b ohne if-Branch (wichtig in krypto-kritischen Schleifen):
var mask: int64 := CTEqual(condition, 1); // 0xFFFFFFFFFFFFFFFF wenn condition==1
var result: int64 := CTSelect(a, b, mask); // a wenn mask gesetzt, sonst b
**SecureZero nach Schlüsselverwendung:**
import std.crypto.ct;
import std.alloc;
var sk: int64 := alloc(576);
// ... Schlüssel verwenden ...
SecureZero(sk, 576); // Schlüsselmaterial sicher löschen (nicht wegoptimiert)
free(sk, 576);
----
===== Warum Constant-Time? =====
Normaler Code wie ''if a == b { ... }'' läuft auf modernen CPUs unterschiedlich lang je nach Daten (Branch-Predictor, Cache). Ein Angreifer kann daraus Rückschlüsse auf geheime Daten ziehen (Timing-Angriff).
''CTMemEqual'' verwendet XOR aller Bytes und gibt das Ergebnis erst am Ende zurück — kein Early-Exit, immer gleiche Laufzeit.
''CTSelect'' nutzt bitweise Maskierung statt eines if-Branches:
CTSelect(a, b, mask) = (a & mask) | (b & ~mask)
Letzte Aktualisierung: 2026-06-08