Bei P-256 vs. secp256k1 hast du selten die freie Wahl: Die Kurve kommt meist mit dem Ökosystem. Beide sind 256-Bit-Weierstraß-Kurven mit Primzahlordnung, etwa 128 Bit Sicherheit und identischen Schlüssel- und Signaturgrößen. Die beiden unterscheiden sich aber in ihrer Herkunft, in den Plattformen, die sie unterstützen, und in den Konventionen, die darauf aufbauen – und genau dort, wo Daten zwischen den beiden Welten wandern, entstehen Fehler.
Auf einen Blick
| P-256 (secp256r1, prime256v1) | secp256k1 | |
|---|---|---|
| Spezifiziert in | NIST SP 800-186 §3.2.1.3, SEC 2 §2.4.2 | SEC 2 §2.4.1; nach SP 800-186 Anhang H.2 für Blockchain-Anwendungen zugelassen |
| Gleichung | y² = x³ − 3x + b über p = 2²⁵⁶ − 2²²⁴ + 2¹⁹² + 2⁹⁶ − 1 | y² = x³ + 7 über p = 2²⁵⁶ − 2³² − 977 |
| Herkunft der Parameter | b aus einem nie erklärten SHA-1-Seed abgeleitet | Feste, minimale Koeffizienten (im Koblitz-Stil) |
| Kofaktor, Sicherheit | 1, etwa 128 Bit | 1, etwa 128 Bit |
| Schlüssel und Signaturen | Privater Schlüssel 32 Byte, öffentlicher Schlüssel 33/65 Byte, rohe Signatur 64 Byte | Identisch |
| OID | 1.2.840.10045.3.1.7 | 1.3.132.0.10 |
| JOSE / COSE | ES256 / −7 | ES256K / −47 (RFC 8812) |
| Node.js 26 (OpenSSL 3.6.5), Signieren / Prüfen pro Sekunde | etwa 68.800 / 27.200 | etwa 6.500 / 7.200 |
| @noble/curves 2.3.0, Signieren / Prüfen pro Sekunde | etwa 3.800 / 870 | etwa 3.800 / 1.180 |
| WebCrypto, TLS 1.3, WebAuthn | Ja | Nein |
| Apple Secure Enclave, PIV-Karten, die meisten HSMs | Ja | Selten (AWS KMS bietet ECC_SECG_P256K1) |
| Typischer Einsatz | TLS-Zertifikate, Passkeys, JWTs, Geräteidentität | Bitcoin, Ethereum, Nostr, die meisten EVM-Chains |
Gemessen auf einem Kern eines Apple M4 Max.
Herkunft und Vertrauen
P-256 wurde 1999 vom NIST veröffentlicht und in FIPS 186-2 (2000) standardisiert, von der SECG zudem als secp256r1. Die Primzahl von P-256 hat eine spezielle Form, die eine schnelle Reduktion ermöglicht, und der Koeffizient b wurde per SHA-1 aus einem Seed erzeugt, wie es das damalige Verfahren für „verifizierbar zufällige“ Parameter vorschrieb. Die Herkunft des Seeds wurde nie erklärt, weshalb nach den Enthüllungen zu Dual_EC_DRBG manche Entwickler kryptografischer Systeme den NIST-Kurven misstrauten. Ein Angriff auf P-256, der auf diesem Seed beruht, wurde nie gefunden, und die Kurve bleibt die am gründlichsten untersuchte Kurve im praktischen Einsatz.
secp256k1 stammt aus SEC 2 (2000). Mit a = 0 und b = 7 gibt es nichts zu verbergen, und ihre besondere Struktur bietet einen effizient berechenbaren Endomorphismus (die GLV-Methode), der die Skalarmultiplikation beschleunigt. Satoshi Nakamoto wählte sie 2009 für Bitcoin, damals eine ungewöhnliche Wahl, und Ethereum folgte. NIST SP 800-186 (2023) lässt secp256k1 ausdrücklich „für Blockchain-bezogene Anwendungen“ zu.
Beide Kurven haben Primzahlordnung, es gibt also keine Feinheiten mit dem Kofaktor, und beide fallen dem Shor-Algorithmus gleichermaßen zum Opfer.
Unterstützung durch Plattformen und Bibliotheken
Hier liegt der eigentliche Unterschied. P-256 steckt in allem, was Schlüssel für dich verwaltet: WebCrypto in jedem Browser, die TLS-Stacks aller Betriebssysteme, die Secure Enclave und CryptoKit von Apple, der Android-Keystore, TPM 2.0, PIV-Smartcards und jeder KMS-Dienst in der Cloud. Passkeys nutzen P-256 standardmäßig, und die Baseline Requirements des CA/Browser Forum lassen die Kurve für öffentlich vertrauenswürdige Zertifikate zu.
secp256k1 fehlt in WebCrypto und in TLS 1.3 (RFC 8422 hatte ihren Codepoint für TLS 1.2 schon als veraltet markiert), und allgemeine Bibliotheken behandeln sie als Nebensache. Blockchain-Software setzt deshalb auf eigene Implementierungen: das zeitkonstante libsecp256k1 von Bitcoin Core, anderswo @noble/curves, k256 in Rust und go-ethereum/crypto in Go. Hardware-Wallets unterstützen die Kurve; bei HSMs für Unternehmen ist das unterschiedlich, und AWS KMS bietet sie als Schlüsselspezifikation ECC_SECG_P256K1 nur zum Signieren an.
Leistung
Bei gleichen Größen hängt die Geschwindigkeit von der Qualität der Implementierung ab, nicht von der Kurve. OpenSSL hat handoptimierten Assembler-Code für P-256 und generischen Code für secp256k1, deshalb signiert Node.js 26.10 (OpenSSL 3.6.5) mit P-256 etwa zehnmal so schnell: etwa 68.800 gegenüber 6.500 Signaturen pro Sekunde auf einem Kern eines Apple M4 Max. In reinem JavaScript kehrt sich das Bild leicht um: @noble/curves 2.3.0 signiert auf beiden Kurven gleich schnell und prüft secp256k1 dank des Endomorphismus etwa ein Drittel schneller. libsecp256k1 ist noch schneller. Die Lehre daraus: Miss die Bibliothek, die du ausliefern wirst, nicht die Kurve.
Unterschiedliche Konventionen
Dieselbe ECDSA-Mathematik ist in jeder Welt an andere Regeln gebunden.
- Hashing. P-256 wird mit SHA-256 kombiniert (
ES256,ecdsa-with-SHA256). Bitcoin signiert doppelte SHA-256-Digests; Ethereum signiert Keccak-256-Digests, und Keccak-256 ist nicht SHA3-256. - Kodierung. X.509 und TLS verwenden DER; JOSE und WebCrypto verwenden rohes
r‖s; Ethereum hängt ein Recovery-Bytevan, insgesamt also 65 Byte, und signierte Nachrichten in Bitcoin stellen ein Header-Byte voran. - Wiederherstellung des öffentlichen Schlüssels. Ethereum überträgt nie öffentliche Schlüssel: Die Wiederherstellung (
ecrecover) berechnet den Schlüssel aus der Signatur, anschließend wird die Adresse verglichen. P-256-Protokolle übertragen oder zertifizieren stattdessen den Schlüssel. - Low-S. Jede ECDSA-Signatur
(r, s)hat einen Zwilling(r, n − s). Die Relay-Policy von Bitcoin und die Transaktionsregeln von Ethereum (EIP-2) akzeptieren nur die Low-S-Form; allgemeine P-256-Verifizierer akzeptieren beide. - Schnorr. Mit Taproot kamen in Bitcoin BIP-340-Schnorr-Signaturen mit 64 Byte und x-only-Schlüssel mit 32 Byte auf secp256k1 hinzu, die auch Nostr verwendet. Für P-256 gibt es kein standardisiertes Schnorr-Verfahren.
Die Malleability lässt sich mit Node.js und seiner auf OpenSSL gestützten Unterstützung für secp256k1 leicht vorführen:
import { generateKeyPairSync, sign, verify } from "node:crypto";
// Group order of secp256k1 (SEC 2 §2.4.1).
const n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
const { privateKey, publicKey } = generateKeyPairSync("ec", { namedCurve: "secp256k1" });
const message = Buffer.from("hello");
const raw = sign("sha256", message, { key: privateKey, dsaEncoding: "ieee-p1363" });
const r = raw.subarray(0, 32);
const s = BigInt("0x" + raw.subarray(32).toString("hex"));
const flipped = Buffer.concat([r, Buffer.from((n - s).toString(16).padStart(64, "0"), "hex")]);
const check = (sig) => verify("sha256", message, { key: publicKey, dsaEncoding: "ieee-p1363" }, sig);
console.log("(r, s) and (r, n - s) both verify:", check(raw) && check(flipped));
console.log("exactly one of them is low-S:", (s <= n / 2n) !== (n - s <= n / 2n));
(r, s) and (r, n - s) both verify: true
exactly one of them is low-S: true
OpenSSL erzeugt Low-S nicht gezielt und erzwingt es auch nicht, deshalb müssen so erstellte Signaturen normalisiert werden, bevor Bitcoin oder Ethereum sie akzeptieren. Der Ethereum-Signatur-Verifizierer markiert High-S-Werte.
Wann welche Kurve passt
- Web, TLS, Passkeys, JWTs, Mobil- und Geräteschlüssel: P-256, weil die Plattformen in Hardware nichts anderes anbieten.
- Bitcoin, Ethereum und EVM-Chains, Nostr: secp256k1, mit den Regeln der jeweiligen Chain für Hashing, Kodierung, Wiederherstellung des Schlüssels und Low-S.
- Brücken zwischen beiden Welten (zum Beispiel eine Smart-Contract-Wallet, die von einem Passkey gesteuert wird): Halte die beiden Kurven sauber getrennt. Das Fusaka-Upgrade von Ethereum (Dezember 2025) hat EIP-7951 eingeführt, ein Precompile zur Prüfung von P-256-Signaturen unter der Adresse
0x100, das 6.900 Gas kostet, und viele Rollups bieten das kompatible Precompile RIP-7212 an, sodass Contracts Passkey-Signaturen direkt prüfen können. - Neues Protokoll mit freier Wahl: keine der beiden; erwäge Ed25519 für Softwareschlüssel oder P-256 für hardwaregestützte Schlüssel.
Hinweise zur Migration
Schlüssel lassen sich nicht von einer Kurve in die andere umwandeln; ein Kurvenwechsel bedeutet neue Schlüssel und in Blockchains neue Adressen.
- Verwende Schlüsselmaterial nicht kurvenübergreifend wieder. Ein 32-Byte-Secret ist auf beiden Kurven ein gültiger privater Schlüssel, aber die daraus entstehenden öffentlichen Schlüssel haben nichts miteinander zu tun; betrachte das als Stolperfalle, nicht als Feature.
- Wenn du das Signieren mit secp256k1 in ein HSM oder KMS verlagerst, prüfe, ob es den Schlüsseltyp dort gibt, rechne mit DER-Ausgabe, konvertiere in rohes
r‖s, normalisiere auf Low-S und berechne die Recovery-ID selbst, indem du beide Paritäten ausprobierst. - Wenn du P-256-Signaturen in einem EVM-Contract prüfst, nutze eine geprüfte Bibliothek oder ein Precompile, wo die Chain eines anbietet; implementiere modulare Arithmetik in Solidity nie selbst.
- In JOSE ändern sich beim Wechsel von
ES256KzuES256die Wertealgundcrvsowie der Schlüssel; veröffentliche während der Umstellung beide Schlüssel mit unterschiedlichen Werten fürkid.
Quellen
- NIST SP 800-186, Domainparameter elliptischer Kurven (§3.2.1.3 und Anhang H.2)
- SEC 2 v2, empfohlene Domainparameter elliptischer Kurven (§2.4.1, §2.4.2)
- FIPS 186-5, Standard für digitale Signaturen
- RFC 8812, ES256K und secp256k1 in JOSE und COSE
- BIP-340, Schnorr-Signaturen für secp256k1
- BIP-146, LOW_S und EIP-2
- AWS KMS, Referenz der Schlüsselspezifikationen