====== 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