====== std.crypto.ecc — secp256k1 ECDSA ====== ''import std.crypto.ecc;'' ECDSA (Elliptic Curve Digital Signature Algorithm) auf der Kurve secp256k1 — dieselbe Kurve wie Bitcoin/Ethereum. Alle 256-Bit-Werte als 32-Byte Little-Endian-Puffer (Byte 0 = LSB). Jacobian-Koordinaten intern, Ausgabe in affiner Form. Abhängigkeit: [[lyx_-_programmiersprache:units:crypto:rand|std.crypto.rand]] (für Schlüsselgenerierung und Signing). → [[lyx_-_programmiersprache:units:crypto|std.crypto Paket]] · [[lyx_-_programmiersprache:units:crypto:rand|std.crypto.rand]] · [[lyx_-_programmiersprache:units:crypto:sha256|std.crypto.sha256]] ---- ===== Datenformat ===== ^ Typ ^ Größe ^ Format ^ | Privater Schlüssel | 32 Bytes | Little-Endian, Byte 0 = LSB | | Öffentlicher Schlüssel X | 32 Bytes | Little-Endian | | Öffentlicher Schlüssel Y | 32 Bytes | Little-Endian | | Signatur r | 32 Bytes | Little-Endian | | Signatur s | 32 Bytes | Little-Endian | | Hash-Eingabe | 32 Bytes | Beliebig (typisch SHA-256-Digest) | > **Little-Endian-Besonderheit**: Die Standard-Darstellung für secp256k1 in anderen Bibliotheken (OpenSSL, libsecp256k1) ist Big-Endian. Beim Austausch mit externen Systemen muss byte-reversed werden. ---- ===== Funktionen ===== ^ Funktion ^ Signatur ^ Beschreibung ^ | ''ECCGenKey'' | ''(privk: int64, pubx: int64, puby: int64): void'' | Generiert zufälliges Schlüsselpaar; schreibt privaten Schlüssel und öffentlichen Schlüssel (X/Y) | | ''ECCPubFromPriv'' | ''(privk: int64, pubx: int64, puby: int64): void'' | Berechnet öffentlichen Schlüssel aus privatem; ''pubkey = privk × G'' | | ''ECDSASign'' | ''(hash: int64, privk: int64, r_out: int64, s_out: int64): int64'' | Signiert 32-Byte-Hash mit privatem Schlüssel; gibt immer 1 zurück | | ''ECDSAVerify'' | ''(hash: int64, pubx: int64, puby: int64, r: int64, s: int64): int64'' | Verifiziert Signatur; gibt 1 wenn gültig, 0 wenn ungültig | ---- ===== Verwendung ===== ==== Schlüsselpaar generieren ==== import std.crypto.ecc; import std.alloc; fn main(): int64 { var privk: int64 := alloc(32); var pubx: int64 := alloc(32); var puby: int64 := alloc(32); ECCGenKey(privk, pubx, puby); // privk: 32-Byte privater Schlüssel (geheim halten!) // pubx/puby: öffentlicher Schlüssel (teilbar) free(privk, 32); free(pubx, 32); free(puby, 32); return 0; } ==== Nachricht signieren und verifizieren ==== import std.crypto.ecc; import std.crypto.sha256; import std.alloc; fn SignAndVerify(msg: pchar, msgLen: int64): int64 { var privk: int64 := alloc(32); var pubx: int64 := alloc(32); var puby: int64 := alloc(32); var hash: int64 := alloc(32); var sig_r: int64 := alloc(32); var sig_s: int64 := alloc(32); // 1. Schlüsselpaar erzeugen ECCGenKey(privk, pubx, puby); // 2. Nachricht hashen SHA256(msg as int64, msgLen, hash); // 3. Signieren ECDSASign(hash, privk, sig_r, sig_s); // 4. Verifizieren var ok: int64 := ECDSAVerify(hash, pubx, puby, sig_r, sig_s); free(privk, 32); free(pubx, 32); free(puby, 32); free(hash, 32); free(sig_r, 32); free(sig_s, 32); return ok; // 1 = gültig } ==== Öffentlichen Schlüssel aus bekanntem privaten Schlüssel ==== import std.crypto.ecc; import std.alloc; fn RestorePubKey(privk: int64, pubx: int64, puby: int64): void { // Nützlich wenn nur der private Schlüssel gespeichert wurde ECCPubFromPriv(privk, pubx, puby); } ---- ===== Hinweise ===== * **Nonce-Sicherheit**: ''ECDSASign'' generiert den Nonce ''k'' intern zufällig via ''std.crypto.rand''. Ein wiederverwendeter Nonce legt den privaten Schlüssel vollständig offen — das ist durch die interne Implementierung verhindert, aber bei eigenem ECDSA-Code kritisch. * **Little-Endian**: Alle 32-Byte-Werte sind Little-Endian (LSB zuerst). Für Interoperabilität mit OpenSSL oder RFC-Formaten muss byte-reversed werden. * **secp256k1 (nicht secp256r1)**: Dies ist die Bitcoin/Ethereum-Kurve, **nicht** die häufiger in TLS verwendete NIST-Kurve P-256 (secp256r1). * **Keine ASN.1-Kodierung**: ''ECDSASign'' gibt r und s als rohe 32-Byte-Werte zurück, kein DER-Format. Für TLS/X.509 muss DER-Encoding selbst implementiert werden. * **Performance**: Schulmethode (schoolbook multiplication). Für produktiven Hochdurchsatz-Einsatz sollte eine optimierte ECDSA-Bibliothek per ''@extern'' eingebunden werden. ---- Letzte Aktualisierung: 2026-06-05