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