Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
noble-curves — Auditierte & minimale JS-Implementierung der Elliptische-Kurven-Kryptographie. | Kitploit
Tools/GitHubGitHub/paulmillr/noble-curves
Verschlüsselungs-/EntschlüsselungstoolsHash-AnalyseKryptographieDienstprogramme & FrameworksLernen & Bildung
GitHubpaulmillr/noble-curves

noble-curves

Auditierte & minimale JS-Implementierung der Elliptische-Kurven-Kryptographie.

Repository anzeigen
95810115vor 7 TagenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Webseite

noble-curves

Geprüfte & minimale JS-Implementierung der Kryptographie elliptischer Kurven.

  • 🔒 Geprüft von unabhängigen Sicherheitsfirmen
  • 🪶 Minimal: 15KB (gzipped) secp256k1, ungenutzter Code wird aus deinen Builds ausgeschlossen
  • 🏎 Schnell: handoptimiert für die Eigenheiten von JS-Engines
  • 🔍 Zuverlässig: Cross-Library- / wycheproof-Tests gewährleisten Korrektheit
  • ➰ Weierstrass-, Edwards-Kurven; ECDSA-, EdDSA-, Schnorr-, BLS-Signaturen
  • ✍️ ECDH, Hash-to-Curve, OPRF, FROST, Poseidon-Hash, FFT
  • 🔖 Nichtabstreitbarkeit (SUF-CMA, SBS) & Konsensfreundlichkeit (ZIP215) in ed25519, ed448
  • 🥈 Wrapper mit identischer API über natives WebCrypto

Kurven haben 5kb-Schwesterprojekte secp256k1 & ed25519. Sie haben eine kleinere Angriffsfläche, aber weniger Funktionen.

Diese Bibliothek gehört zur noble-Kryptographie

noble cryptography — hochsichere, leicht prüfbare Sammlung überschaubarer Kryptographie-Bibliotheken und -Werkzeuge.

  • Keine oder minimale Abhängigkeiten
  • Hochgradig lesbarer TypeScript- / JS-Code
  • PGP-signierte Releases und transparente NPM-Builds
  • Alle Bibliotheken: ciphers, curves, hashes, post-quantum, 5kb secp256k1 / ed25519
  • WASM-Version: awasm-noble
  • Schau dir die Homepage an für Lektüre-Ressourcen, Dokumentation und mit noble erstellte Apps

Verwendung

npm install @noble/curves

deno add jsr:@noble/curves

Wir unterstützen alle wichtigen Plattformen und Runtimes. Für React Native benötigst du möglicherweise einen Polyfill für getRandomValues. Eine eigenständige Datei noble-curves.js ist ebenfalls verfügbar.```js // import * from '@noble/curves'; // Error: use sub-imports, to ensure small app size import { secp256k1 } from '@noble/curves/secp256k1.js'; const { secretKey, publicKey } = secp256k1.keygen(); const msg = new TextEncoder().encode('hello noble'); const sig = secp256k1.sign(msg, secretKey); const isValid = secp256k1.verify(sig, msg, publicKey);

root@kitploit:~
- [ECDSA-, EdDSA-, Schnorr-Signaturen](#ecdsa-eddsa-schnorr-signatures)
- [ECDH: Diffie-Hellman-Shared-Secrets](#ecdh-diffie-hellman-shared-secrets)
- [webcrypto: benutzerfreundlicher Wrapper](#webcrypto-friendly-wrapper)
- [BLS-Signaturen, bls12-381, bn254 aka alt\_bn128](#bls-signatures-bls12-381-bn254-aka-alt_bn128)
- [hash-to-curve: Hashing auf Kurvenpunkte](#hash-to-curve-hashing-to-curve-points)
- [OPRFs](#oprfs) | [FROST-Schwellenwert-Signaturen](#frost-threshold-signatures)
- [poseidon: Poseidon-Hash](#poseidon-poseidon-hash) | [fft: Schnelle Fourier-Transformation](#fft-fast-fourier-transform) | [utils](#utils-byte-shuffling-conversion)
- Interna: [Punktarithmetik](#elliptic-curve-point-math) | [modular](#modular-modular-arithmetics--finite-fields) | [benutzerdefinierte Kurven](#weierstrass-custom-weierstrass-curve--ecdsa)
- [Spezifikationen](#specs)
- [Sicherheit](#security) | [Geschwindigkeit](#speed) | [Upgrade](#upgrading) | [Mitwirken & Testen](#contributing--testing) | [Lizenz](#license)

### ECDSA-, EdDSA-, Schnorr-Signaturen

#### secp256k1, p256, p384, p521, ed25519, ed448, brainpool```js
import { secp256k1, schnorr } from '@noble/curves/secp256k1.js';
import { p256, p384, p521 } from '@noble/curves/nist.js';
import { ed25519 } from '@noble/curves/ed25519.js';
import { ed448 } from '@noble/curves/ed448.js';
import { brainpoolP256r1, brainpoolP384r1, brainpoolP512r1 } from '@noble/curves/misc.js';
for (const curve of [
  secp256k1, schnorr,
  p256, p384, p521,
  ed25519, ed448,
  brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
]) {
  const { secretKey, publicKey } = curve.keygen();
  const msg = new TextEncoder().encode('hello noble');
  const sig = curve.sign(msg, secretKey);
  const isValid = curve.verify(sig, msg, publicKey);
  console.log(curve, secretKey, publicKey, sig, isValid);
}

// Specific private key
import { hexToBytes } from '@noble/curves/utils.js';
const secret2 = hexToBytes('46c930bc7bb4db7f55da20798697421b98c4175a52c630294d75a84b9c126236');
const pub2 = secp256k1.getPublicKey(secret2);

Nachrichten werden immer zuerst gehasht: siehe prehashed signing. ECDSA verwendet deterministisches k, EdDSA folgt RFC 8032, Schnorr (nur secp256k1) folgt BIP 340: siehe Specs.

MuSig2-Signaturschema und BIP324 ElligatorSwift-Mapping für secp256k1 sind in einem separaten Paket verfügbar.

ristretto255, decaf448```ts

import { ristretto255, ristretto255_hasher, ristretto255_oprf } from '@noble/curves/ed25519.js'; import { decaf448, decaf448_hasher, decaf448_oprf } from '@noble/curves/ed448.js';

console.log(ristretto255.Point, decaf448.Point);

root@kitploit:~
Sieh dir [RFC 9496](https://www.rfc-editor.org/rfc/rfc9496) an für weitere Informationen zu ristretto255 & decaf448.
Sieh dir die separate Dokumentation für [Point](#elliptic-curve-point-math), [hasher](#hash-to-curve-hashing-to-curve-points) und [oprf](#oprfs) an.

#### Vorab gehashtes Signieren```js
import { secp256k1 } from '@noble/curves/secp256k1.js';
import { keccak_256 } from '@noble/hashes/sha3.js';
const { secretKey } = secp256k1.keygen();
const msg = new TextEncoder().encode('hello noble');
// prehash: true (default) - hash using secp256k1.hash (sha256)
const sig = secp256k1.sign(msg, secretKey);
// prehash: false - hash using custom hash
const sigKeccak = secp256k1.sign(keccak_256(msg), secretKey, { prehash: false });

Standardmäßig (prehash: true) wenden sign() und verify() zuerst den eingebauten Hash der Kurve auf die Nachricht an: sha256 für secp256k1, sha512 für p521. prehash: false ermöglicht die Verwendung eines benutzerdefinierten Hashs (z. B. secp256k1 + keccak_256). In noble-curves v1 war prehash: false der Standard.

Wiederherstellen öffentlicher Schlüssel aus Signaturen```js

import { secp256k1 } from '@noble/curves/secp256k1.js'; const { secretKey, publicKey } = secp256k1.keygen(); const msg = new TextEncoder().encode('hello noble'); const sigRec = secp256k1.sign(msg, secretKey, { format: 'recovered' }); const publicKey_ = secp256k1.recoverPublicKey(sigRec, msg); // == publicKey

// recovered sig is compact sig with an extra byte const sigNoRec = secp256k1.sign(msg, secretKey, { format: 'compact' }); // sigNoRec == sigRec.slice(1)

// Signature instance const sigInstance = secp256k1.Signature.fromBytes(sigRec, 'recovered');

root@kitploit:~
Public-Key-Wiederherstellung wird nur mit ECDSA unterstützt. Es ist eine einfache mathematische Operation:
es gibt keine Garantie, dass die Signierung tatsächlich durchgeführt wurde. Ein gefälschtes (r, s, h) wird in
einen zufälligen öffentlichen Schlüssel wiederhergestellt, aber es ist nicht machbar, m zu finden, das zu diesem spezifischen gefälschten h führen würde.

#### Hedged ECDSA mit Rauschen```js
import { secp256k1 } from '@noble/curves/secp256k1.js';
const { secretKey } = secp256k1.keygen();
const msg = new TextEncoder().encode('hello noble');
// extraEntropy: false - default, hedging disabled
const sigNoisy = secp256k1.sign(msg, secretKey);
// extraEntropy: true - fetch 32 random bytes from CSPRNG
const sigNoisyA = secp256k1.sign(msg, secretKey, { extraEntropy: true });
// extraEntropy: bytes - specific extra entropy
const ent = Uint8Array.from([0xca, 0xfe, 0x01, 0x23]);
const sigNoisy2 = secp256k1.sign(msg, secretKey, { extraEntropy: ent });

Standardmäßig sind ECDSA-Signaturen deterministisch (RFC 6979). Rein deterministische Signaturen sind anfällig für Fehlerangriffe, weshalb neuere Verfahren wie BIP340 Schnorr Zufälligkeit in die Signaturerzeugung einbeziehen – auch bekannt als Hedging. extraEntropy aktiviert den Hedged-Modus. Für weitere Informationen siehe Deterministic signatures are not your friends.

Konsensfreundlichkeit vs. E-Voting```js

import { ed25519 } from '@noble/curves/ed25519.js'; const { secretKey, publicKey } = ed25519.keygen(); const msg = new TextEncoder().encode('hello noble'); const sig = ed25519.sign(msg, secretKey); // zip215: true const isValid = ed25519.verify(sig, msg, publicKey); // SBS / e-voting / RFC8032 / FIPS 186-5 const isValidRfc = ed25519.verify(sig, msg, publicKey, { zip215: false });

root@kitploit:~
* `zip215: true` (Standard) verwendet die permissiveren, [konsensfreundlichen](https://hdevalence.ca/blog/2020-10-04-its-25519am) Verifikationsregeln, die in [ZIP215](https://zips.z.cash/zip-0215) definiert sind.
* `zip215: false` erzwingt strikte RFC 8032 / FIPS 186-5-Verifikation und fügt SBS-basierte
  Nichtabstreitbarkeit hinzu, was für Vertragsunterzeichnung, E-Voting und Blockchains nützlich ist.

Beide Modi verfügen über SUF-CMA (starke Unfälschbarkeit unter Angriffen mit gewählten Nachrichten);
die meisten anderen Bibliotheken haben weder SUF-CMA noch SBS.
Weitere Informationen finden Sie unter [Taming the many EdDSAs](https://eprint.iacr.org/2020/1244).

### ECDH: Diffie-Hellman shared secrets```js
import { x25519 } from '@noble/curves/ed25519.js';
const alice = x25519.keygen();
const bob = x25519.keygen();
const sharedKey = x25519.getSharedSecret(alice.secretKey, bob.publicKey);
// Same API: secp256k1, p256, p384, p521, x448

// converting ed25519 keys to x25519
import { ed25519 } from '@noble/curves/ed25519.js';
const alice2 = ed25519.keygen();
const bob2 = ed25519.keygen();
const aliceSecX = ed25519.utils.toMontgomerySecret(alice2.secretKey);
const bobPubX = ed25519.utils.toMontgomery(bob2.publicKey);
const sharedKey2 = x25519.getSharedSecret(aliceSecX, bobPubX);

Wir bieten ECDH über alle Weierstraß-Kurven und über 2 Montgomery-Kurven X25519 (Curve25519) & X448 (Curve448), konform zu RFC 7748.

Bei Weierstraß-Kurven enthalten die geteilten Geheimnisse:

  • y-Paritäts-Bytes: verwende key.slice(1), um sie zu entfernen
  • Sind nicht gehasht: verwende Hashing oder KDF darüber, wie sha256(shared) oder hkdf(shared)

webcrypto: benutzerfreundlicher Wrapper```js

import { ed25519, x25519 } from '@noble/curves/webcrypto.js';

// signatures: p256, p384, p521, ed25519, ed448 const keys = await ed25519.keygen(); const msg = new TextEncoder().encode('hello noble'); const sig = await ed25519.sign(msg, keys.secretKey); const isValid = await ed25519.verify(sig, msg, keys.publicKey);

// ECDH: p256, p384, p521, x25519, x448 const alice = await x25519.keygen(); const bob = await x25519.keygen(); const shared = await x25519.getSharedSecret(alice.secretKey, bob.publicKey);

// key conversion between noble (raw) and webcrypto (pkcs8 / spki) formats import { p256 as p256n } from '@noble/curves/nist.js'; import { p256 } from '@noble/curves/webcrypto.js'; const nobleKeys = p256n.keygen(); const secretKeyPkcs8 = await p256.utils.convertSecretKey(nobleKeys.secretKey, 'raw', 'pkcs8'); const publicKeySpki = await p256.utils.convertPublicKey(nobleKeys.publicKey, 'raw', 'spki');

root@kitploit:~
Ein dünner Wrapper über das eingebaute WebCrypto, der die noble-API spiegelt. Methoden sind immer async;
die Laufzeitunterstützung variiert - prüfe mit `await curve.isSupported()`.
Sieh dir [micro-key-producer](https://github.com/paulmillr/micro-key-producer) für
reine JS-Schlüsselkonvertierungs-Utils an.

### BLS-Signaturen, bls12-381, bn254 aka alt_bn128```ts
import { bls12_381 } from '@noble/curves/bls12-381.js';

// G1 pubkeys, G2 sigs
const blsl = bls12_381.longSignatures;
const { secretKey, publicKey } = blsl.keygen();
const msg = new TextEncoder().encode('hello noble');
const msgp = blsl.hash(msg); // hash to point, default DST
const msgpd = blsl.hash(msg, 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_'); // custom DST (Ethereum)
const signature = blsl.sign(msgp, secretKey);
const isValid = blsl.verify(signature, msgp, publicKey);

// G1 sigs, G2 pubkeys: identical API
const blss = bls12_381.shortSignatures;

// Aggregation
const aggregatedKey = blsl.aggregatePublicKeys([
  blsl.getPublicKey(bls12_381.utils.randomSecretKey()),
  blsl.getPublicKey(bls12_381.utils.randomSecretKey()),
]);
// const aggregatedSig = blsl.aggregateSignatures(sigs)

// Pairings: bls12_381.pairing(PointG1, PointG2)
// Fields: bls12_381.fields.Fp, Fp2, Fp12, Fr

Zur Beispielverwendung sieh dir die Implementierung der BLS-EVM-Precompiles an.

Die BN254-API entspricht bls12-381. Die Kurve hieß früher alt_bn128. Die Implementierung ist kompatibel mit EIP-196 und EIP-197: sieh dir die Implementierung der bn254-EVM-Precompiles an. bn254-Punkte implementieren toBytes nicht, weil es keinen Serialisierungsstandard gibt: Implementierungen weichen bei Endianness, Flags und der Reihenfolge des Imaginärteils von G2 voneinander ab. Initialisiere Punkte stattdessen aus bigints.

hash-to-curve: Hashing auf Kurvenpunkte```ts

import { secp256k1_hasher } from '@noble/curves/secp256k1.js';

const msg = Uint8Array.from([0xca, 0xfe, 0x01, 0x23]); const point = secp256k1_hasher.hashToCurve(msg); const pointDst = secp256k1_hasher.hashToCurve(msg, { DST: 'hello noble' }); const pointNu = secp256k1_hasher.encodeToCurve(msg); const scalar = secp256k1_hasher.hashToScalar(msg);

// Same API: p256_hasher, p384_hasher, p521_hasher (nist.js), // ed25519_hasher, ristretto255_hasher (ed25519.js), ed448_hasher, decaf448_hasher (ed448.js), // bls12_381.G1, bls12_381.G2. // ristretto255 & decaf448 also provide deriveToCurve.

// abstract methods import { expand_message_xmd, expand_message_xof, hash_to_field } from '@noble/curves/abstract/hash-to-curve.js';

root@kitploit:~
Das Modul ermöglicht das Hashen beliebiger Strings auf Punkte elliptischer Kurven. Implementiert [RFC 9380](https://www.rfc-editor.org/rfc/rfc9380).
`_hasher`-Namespaces sind für Tree-Shaking von den Kurven getrennt:
Nutzer, die kein Hash-to-Curve benötigen, haben es nicht in ihren Builds.

### OPRFs```js
import { p256_oprf, p384_oprf, p521_oprf } from '@noble/curves/nist.js';
import { ristretto255_oprf } from '@noble/curves/ed25519.js';
import { decaf448_oprf } from '@noble/curves/ed448.js';

Wir stellen OPRFs (oblivious pseudorandom functions) bereit, die RFC 9497 entsprechen.

OPRF ermöglicht die interaktive Erzeugung eines Output = PRF(Input, serverSecretKey):

  • Der Server kann Output nicht selbst berechnen: er kennt Input nicht
  • Der Client kann Output nicht selbst berechnen: er kennt serverSecretKey nicht
  • Ein Angreifer, der die Kommunikation abfängt, kann Input/Output/serverSecretKey nicht wiederherstellen und kann Input nicht mit einem Wert verknüpfen.

FROST Schwellenwert-Signaturen

FROST implementiert RFC 9591 Schwellenwert-Schnorr-Signierung. Aus Anwendungssicht ähnelt es Multisig: Jede min von max Teilnehmern kann gemeinsam eine Schnorr-Signatur unter einem geteilten öffentlichen Schlüssel erzeugen. Unterstützte Ciphersuites sind p256_FROST, ed25519_FROST, ed448_FROST, ristretto255_FROST, secp256k1_FROST und schnorr_FROST (Taproot-kompatibles secp256k1). Die Signierung erfolgt in zwei Runden: Ausgewählte Unterzeichner committen zuerst und erzeugen dann Signaturanteile.```js import { p256_FROST } from '@noble/curves/nist.js';

const signers = { min: 2, max: 3 }; const alice = p256_FROST.Identifier.derive('[email protected]'); const bob = p256_FROST.Identifier.derive('[email protected]'); const carol = p256_FROST.Identifier.derive('[email protected]'); // trusted dealer const deal = p256_FROST.trustedDealer(signers, [alice, bob, carol]); for (const id of [alice, bob, carol]) p256_FROST.validateSecret(deal.secretShares[id], deal.public);

const msg = new TextEncoder().encode('hello threshold'); // round 1: selected signers commit const aliceRound1 = p256_FROST.commit(deal.secretShares[alice]); const bobRound1 = p256_FROST.commit(deal.secretShares[bob]); const commitmentList = [aliceRound1.commitments, bobRound1.commitments]; // round 2: signers produce signature shares const sigShares = { [alice]: https://raw.githubusercontent.com/paulmillr/noble-curves/main/p256_FROST.signShare( deal.secretShares[alice], deal.public, aliceRound1.nonces, commitmentList, msg ), [bob]: https://raw.githubusercontent.com/paulmillr/noble-curves/main/p256_FROST.signShare( deal.secretShares[bob], deal.public, bobRound1.nonces, commitmentList, msg ), }; const sig = p256_FROST.aggregate(deal.public, commitmentList, msg, sigShares); const isValid = p256_FROST.verify(sig, msg, deal.public.commitments[0]);

root@kitploit:~
Die Schlüsselerzeugung kann mit einem vertrauenswürdigen Dealer (oben) oder mit DKG (distributed key generation) erfolgen.
DKG hat drei Runden: Teilnehmer verpflichten sich zur Schlüsselerzeugung, tauschen private Anteile aus,
und leiten dann die endgültigen Teilnehmerschlüssel ab - siehe `DKG.round1` / `round2` / `round3` Verwendung in
[den Tests](https://github.com/paulmillr/noble-curves/blob/main/test/rfc9591-frost.test.ts).
Die Bibliothek implementiert die kryptografischen Schritte, nicht das umgebende Anwendungsprotokoll:
Aufrufer benötigen weiterhin authentifizierte Kommunikation, Koordination, Wiederholungsversuche, Sitzungsverwaltung und Richtlinien.

### poseidon: Poseidon hash

Implementiert [Poseidon](https://www.poseidon-hash.info) ZK-freundlichen Hash:
Permutation und Sponge.

Es gibt viele Poseidon-Varianten mit unterschiedlichen Konstanten.
Wir stellen sie nicht bereit: Sie sollten sie manuell konstruieren.
Schauen Sie sich das [scure-starknet](https://github.com/paulmillr/scure-starknet) Paket für ein passendes Beispiel an.```ts
import { bn254 } from '@noble/curves/bn254.js';
import { grainGenConstants, poseidon, poseidonSponge } from '@noble/curves/abstract/poseidon.js';

const rate = 2;
const capacity = 1;
const Fp = bn254.fields.Fr;
const { mds, roundConstants } = grainGenConstants({
  Fp,
  t: rate + capacity,
  roundsFull: 8,
  roundsPartial: 31,
});
const opts = {
  Fp,
  rate,
  capacity,
  sboxPower: 17,
  mds,
  roundConstants,
  roundsFull: 8,
  roundsPartial: 31,
};
const permutation = poseidon({ ...opts, t: rate + capacity });
const sponge = poseidonSponge(opts); // use carefully, not specced

fft: Schnelle Fourier-Transformation```ts

import * as fft from '@noble/curves/abstract/fft.js'; import { bls12_381 } from '@noble/curves/bls12-381.js'; const Fr = bls12_381.fields.Fr; const roots = fft.rootsOfUnity(Fr, 7n); const fftFr = fft.FFT(roots, Fr);

root@kitploit:~
NTT / FFT (Fast Fourier Transform) über endlichen Körpern.

### utils: Byte-Shuffling, Konvertierung```ts
import { bytesToHex, concatBytes, equalBytes, hexToBytes } from '@noble/curves/utils.js';

bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23]));
hexToBytes('cafe0123');
concatBytes(Uint8Array.from([0xca, 0xfe]), Uint8Array.from([0x01, 0x23]));
equalBytes(Uint8Array.of(0xca), Uint8Array.of(0xca));

Interna

Elliptische-Kurven-Punkt-Arithmetik```js

import { secp256k1 } from '@noble/curves/secp256k1.js'; const { Point } = secp256k1; const { BASE, ZERO, Fp, Fn } = Point; const p = BASE.multiply(2n);

// Math const p1 = p.add(p); const p2 = p.double(); const p3 = p.subtract(p); const p4 = p.negate(); const p5 = p.multiply(451n);

// MSM (multi-scalar multiplication) import { pippenger } from '@noble/curves/abstract/curve.js'; const pa = [BASE, BASE.multiply(2n), BASE.multiply(4n), BASE.multiply(8n)]; const p6 = pippenger(Point, pa, [3n, 5n, 7n, 11n]); // == BASE.multiply(129n)

// Cofactor const pcl = p.clearCofactor(); const isTorsionFree = p.isTorsionFree();

// Conversions const bytes = p.toBytes(); const p_ = Point.fromBytes(bytes); const { x, y } = p.toAffine(); const p__ = Point.fromAffine({ x, y });

root@kitploit:~
Jede Kurve stellt ihre Point-Klasse bereit: secp256k1, schnorr, p256, p384, p521, ed25519, ed448,
ristretto255, decaf448, bls12_381.G1 / G2, bn254.G1, jubjub, babyjubjub.
Weierstrass-Punkte verwenden projektive (homogene) Koordinaten `new Point(X, Y, Z)`,
Edwards-Punkte verwenden erweiterte Koordinaten `new Point(X, Y, Z, T)`; beide mit x=X/Z, y=Y/Z.

#### modular: Modulare Arithmetik & endliche Körper```js
import { mod, invert, Field } from '@noble/curves/abstract/modular.js';

// Finite Field utils
const fp = Field(2n ** 255n - 19n); // Finite field over 2^255-19
fp.mul(591n, 932n); // multiplication
fp.pow(481n, 11024858120n); // exponentiation
fp.div(5n, 17n); // division: 5/17 mod 2^255-19 == 5 * invert(17)
fp.inv(5n); // modular inverse
fp.sqrt(4n); // square root

// Non-Field generic utils are also available
mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse

Alle Arithmetik wird mit JS-Bigints über endlichen Körpern durchgeführt, die aus dem modular-Submodul definiert werden.

Körperoperationen sind nicht konstantzeitig: siehe Sicherheit. Die Tatsache ist größtenteils irrelevant, aber die wichtige Methode, die man im Hinterkopf behalten sollte, ist pow, die Exponentenbits preisgeben kann, wenn sie naiv verwendet wird.

weierstrass: benutzerdefinierte Weierstrass-Kurve & ECDSA```js

import { weierstrass, ecdsa } from '@noble/curves/abstract/weierstrass.js'; import { sha256 } from '@noble/hashes/sha2.js'; // NIST secp192r1 aka p192. https://www.secg.org/sec2-v2.pdf const p192_CURVE = { p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn, n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n, h: 1n, a: 0xfffffffffffffffffffffffffffffffefffffffffffffffcn, b: 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n, Gx: 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n, Gy: 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n, }; const p192_Point = weierstrass(p192_CURVE); const p192 = ecdsa(p192_Point, sha256);

const keys = p192.keygen(); const msg = new TextEncoder().encode('custom curve'); const sig = p192.sign(msg, keys.secretKey); const isValid = p192.verify(sig, msg, keys.publicKey);

root@kitploit:~
Die Formel der kurzen Weierstraß-Kurve lautet `y² = x³ + ax + b`. `weierstrass`
erwartet die Argumente `a`, `b`, die Körpercharakteristik `p`, die Kurvenordnung `n`,
den Kofaktor `h` und die Koordinaten `Gx`, `Gy` des Generatorpunkts und gibt eine Point-Klasse zurück.
`ecdsa` kombiniert eine Point-Klasse mit einer Hash-Funktion zu einem Signaturschema.

#### edwards: Benutzerdefinierte Edwards-Kurve```js
import { edwards } from '@noble/curves/abstract/edwards.js';
const ed25519_CURVE = {
  p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
  n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,
  h: 8n,
  a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,
  d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,
  Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,
  Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n,
};
const ed25519_Point = edwards(ed25519_CURVE);

Die Formel der Twisted-Edwards-Kurve lautet ax² + y² = 1 + dx²y². Sie müssen a, d, die Körpercharakteristik p, die Kurvenordnung n (manchmal auch als L bezeichnet), den Kofaktor h und die Koordinaten Gx, Gy des Generatorpunkts angeben.

Spezifikationen

  • ECDSA: deterministisches k aus RFC 6979, abgesicherte Signaturen aus dem cfrg-det-sigs-with-noise-Entwurf
  • EdDSA: RFC 8032, FIPS 186-5; konsensfreundliche Verifikation: ZIP215
  • Schnorr-Signaturen: BIP 340
  • X25519, X448 ECDH: RFC 7748
  • ristretto255, decaf448: RFC 9496
  • hash-to-curve: RFC 9380
  • OPRFs: RFC 9497
  • FROST: RFC 9591
  • bn254: EIP-196, EIP-197
  • Poseidon: Website

Sicherheit

Die Bibliothek wurde auditiert:

  • in Version 2.3.0, im August 2026, von Trail of Bits, in Zusammenarbeit mit OpenAI
    • Es wurde im Rahmen der Initiative „Patch the Planet" durchgeführt
    • Umfang: alles
  • in Version 1.6.0, im September 2024, unabhängig, von Cure53
    • PDFs: Website, im Repository
    • Umfang: ed25519, ed448, deren Add-ons, bls12-381, bn254, hash-to-curve, Low-Level-Primitive bls, tower, edwards, montgomery.
    • Das Audit wurde von OpenSats finanziert
  • in Version 1.2.0, im September 2023, unabhängig, von Kudelski Security
    • PDFs: im Repository
    • Umfang: scure-starknet und dessen zugehörige abstrakte Module von noble-curves: curve, modular, poseidon, weierstrass
    • Das Audit wurde von Starkware finanziert
  • in Version 0.7.3, im Februar 2023, unabhängig, von Trail of Bits
    • PDFs: Website, im Repository

Wir haben im April 2026 mit regelmäßigen KI-gestützten Selbst-Audits begonnen.

Es wird gegen eigenschaftsbasierte, bibliotheksübergreifende und Wycheproof-Vektoren getestet und wird in der GitHub-CI gefuzzt.

Wenn Sie etwas Ungewöhnliches bemerken: untersuchen und melden Sie es.

Konstantzeitigkeit

Wir streben algorithmische konstante Zeit an. JIT-Compiler und Garbage Collector machen „konstante Zeit" in einer Skriptsprache extrem schwer zu erreichen, um Timing-Angriffe abzuwehren. Das bedeutet, dass keine andere JS-Bibliothek Konstantzeitigkeit bieten kann. Selbst statisch typisiertes Rust, eine Sprache ohne GC, macht es schwieriger, konstante Zeit zu erreichen für einige Fälle. Wenn Ihr Ziel absolute Sicherheit ist, verwenden Sie keine JS-Bibliothek — einschließlich Bindings an native Bibliotheken. Verwenden Sie Low-Level-Bibliotheken und -Sprachen.

Innerhalb dieser Grenzen bietet die Multiplikation mit geheimen Skalaren spezifische, messbare Eigenschaften:

  • Feste Operationssequenz: multiply() verwendet vorzeichenbehaftete Fixed-Window-Tabellen mit datenunabhängigen Tabellenscans — die Anzahl und Reihenfolge der Punktoperationen ist unabhängig vom Skalarwert.
  • Skalar-Blinding: geheime Skalare werden zusätzlich als s + r·n mit einem zufälligen 128-Bit-r vor der Multiplikation maskiert. Dies gilt für alle Multiplikationen auf Kofaktor-1-Kurven (p256, p384, p521, secp256k1) und für Basispunkt-Multiplikationen überall.
  • Statistische Validierung: ein dudect-artiger Welch-t-Test-Harness (benchmark/ct.ts) vergleicht das Timing über gegnerische Skalarklassen (sparse vs. dense, niedrige vs. hohe Bits, nahe der Ordnung, Bitmuster). Die Basispunkt-Multiplikation zeigt auf keiner Kurve unterscheidbares Timing, und die Multiplikation mit zufälligen Punkten zeigt keines auf den Weierstrass-Kurven (max |t| ≤ 2.8 bei 1000 Stichproben; Schwellenwert 4.5).

Bekannte Einschränkung: Auf kofaktorierten Edwards-Kurven (ed25519, ed448) wird die Multiplikation eines Nicht-Basis-Punkts mit einem geheimen Skalar nicht geblindet. Derselbe Harness erkennt dies zuverlässig. EdDSA-Signierung ist davon nicht betroffen (sie multipliziert nur den geblindeten Basispunkt), und X25519/X448 verwenden eine separate Montgomery-Ladder-Implementierung (ebenfalls nicht betroffen). Es ist relevant für Protokolle, die beliebige Edwards/Ristretto-Punkte mit langlebigen geheimen Skalaren multiplizieren; bevorzugen Sie dort Skalare, die konstruktionsbedingt vollbreit sind. Beachten Sie, dass die Erkennbarkeit in einem isolierten Harness nicht bedeutet, dass sie praktisch ausnutzbar ist: Wir haben die Skalarextraktion in einer realistischen Cross-Tenant-/In-Browser-Umgebung versucht und konnten Edwards-Skalare selbst mit 100.000 Timing-Stichproben nicht wiederherstellen.

Speicher-Dumping

Verwenden Sie Low-Level-Sprachen anstelle von JS / WASM, wenn Ihr Ziel absolute Sicherheit ist.

Die Bibliothek verwendet hauptsächlich Uint8Arrays und bigints.

  • Uint8Arrays haben .fill(0), was anweist, den Inhalt mit Nullen zu füllen, aber es gibt keine Garantien in JS
  • bigints sind unveränderlich und haben keine Methode, um ihren Inhalt zu nullen: ein Benutzer muss auf den nächsten Garbage-Collection-Zyklus warten
  • Hex-Strings sind ebenfalls unveränderlich: es gibt keine Möglichkeit, sie zu nullen
  • await fn() schreibt alle internen Variablen in den Speicher. Bei asynchronen Funktionen gibt es keine Garantien, wann der Codeabschnitt ausgeführt wird. Das bedeutet, dass ein Angreifer reichlich Zeit haben kann, Daten aus dem Speicher zu lesen.

Das bedeutet, dass einige Geheimnisse länger im Speicher bleiben könnten als erwartet. Wenn ein Angreifer jedoch den Anwendungsspeicher lesen kann, ist es ohnehin aussichtslos: Es gibt keine Möglichkeit, irgendetwas über das Nullen sensibler Daten zu garantieren, ohne eine komplexe Testsuite, die den Prozessspeicher dumpt und verifiziert, dass keine sensiblen Daten zurückbleiben. Für JS bedeutet das, alle Browser (einschließlich mobiler) zu testen. Und natürlich wäre es nutzlos, ohne dieselbe Testsuite in der tatsächlichen Anwendung zu verwenden, die die Bibliothek nutzt.

Sicherheit der Lieferkette

  • Commits sind mit PGP-Schlüsseln signiert, um Fälschung zu verhindern. Vergewissern Sie sich, die Commit-Signaturen zu verifizieren
  • Releases werden transparent über tokenlose GitHub-CI und Trusted Publishing erstellt. Vergewissern Sie sich, die Provenienz-Logs auf Authentizität zu prüfen.
  • Seltene Releases werden praktiziert, um den Bedarf an erneuten Audits durch Endbenutzer zu minimieren.
  • Abhängigkeiten werden minimiert und strikt gepinnt, um das Risiko in der Lieferkette zu reduzieren.
    • Wir verwenden so wenige Abhängigkeiten wie möglich.
    • Versionsbereiche sind gesperrt, und Änderungen werden mit npm-diff geprüft.
  • Dev-Abhängigkeiten sind von Endbenutzer-Installationen ausgeschlossen; sie werden nur für Entwicklungs- und Build-Schritte verwendet.

Für dieses Paket gibt es 1 Abhängigkeit; und einige Dev-Abhängigkeiten:

  • noble-hashes bietet kryptografische Hashing-Funktionalität
  • jsbt wird für Benchmarking / Tests / Build-Tooling verwendet und vom selben Autor entwickelt
  • prettier, fast-check und typescript werden für Codequalität / Testgenerierung / TS-Kompilierung verwendet

Zufälligkeit

Wir verlassen uns auf das eingebaute crypto.getRandomValues, das als kryptografisch sicherer PRNG gilt.

Browser hatten in der Vergangenheit Schwächen — und könnten sie wieder haben — aber einen Userspace-CSPRNG zu implementieren ist noch schlimmer, da es keine zuverlässige Userspace-Quelle für hochwertige Entropie gibt.

Quantencomputer

Ein kryptografisch relevanter Quantencomputer, falls gebaut, wird es ermöglichen, Elliptische-Kurven-Kryptografie (sowohl ECDSA / EdDSA als auch ECDH) mithilfe des Shor-Algorithmus zu brechen.

Erwägen Sie den Wechsel zu neueren / hybriden Algorithmen wie SPHINCS+. Sie sind verfügbar in noble-post-quantum.

NIST verbietet klassische Kryptografie (RSA, DSA, ECDSA, ECDH) nach 2035. Das australische ASD verbietet sie nach 2030.

Geschwindigkeit```sh

npm run benchmark

root@kitploit:~
noble-curves benötigt über 10 ms, um mehr als 20 MB an Basispunkt-Vorberechnungen zu generieren.
Dies geschieht **einmalig** pro Kurve.

Die Generierung wird verzögert, bis eine beliebige Methode (pubkey, sign, verify) aufgerufen wird.
Der Benutzer kann die Vorberechnungsgenerierung erzwingen, indem er manuell `Point.BASE.precompute(windowSize, false)` aufruft.
Sieh dir den Quellcode an.

Benchmark-Ergebnisse auf Apple M4:```
# algorithm=getPublicKey
ed25519                    7,299 ops/sec · 137 μs/op
secp256k1                  4,872 ops/sec · 205 μs/op · -1.5x
p256                       4,724 ops/sec · 212 μs/op · -1.5x
bls12_381 (long, G2 sig)   3,466 ops/sec · 288 μs/op · -2.1x
ed448                      3,224 ops/sec · 310 μs/op · -2.3x
p384                       2,185 ops/sec · 458 μs/op · -3.3x
p521                       1,221 ops/sec · 819 μs/op · -6x
bls12_381 (short, G1 sig)  1,070 ops/sec · 934 μs/op · -6.8x

# algorithm=sign
secp256k1                  4,217 ops/sec · 237 μs/op
p256                       4,116 ops/sec · 243 μs/op · ≈
ed25519                    3,536 ops/sec · 283 μs/op · -1.2x
p384                       1,992 ops/sec · 502 μs/op · -2.1x
ed448                      1,577 ops/sec · 634 μs/op · -2.7x
p521                       1,131 ops/sec · 884 μs/op · -3.7x
bls12_381 (short, G1 sig)  417 ops/sec · 2.39 ms/op · -10x
bls12_381 (long, G2 sig)   112 ops/sec · 8.88 ms/op · -37x

# algorithm=verify
ed25519                    1,504 ops/sec · 665 μs/op
secp256k1                  1,352 ops/sec · 739 μs/op · -1.1x
p256                       917 ops/sec · 1.09 ms/op · -1.6x
ed448                      546 ops/sec · 1.83 ms/op · -2.8x
p384                       381 ops/sec · 2.62 ms/op · -3.9x
p521                       187 ops/sec · 5.34 ms/op · -8x
bls12_381 (short, G1 sig)  100 ops/sec · 9.98 ms/op · -15x
bls12_381 (long, G2 sig)   77 ops/sec · 12.9 ms/op · -19x

# algorithm=getSharedSecret
ed25519                    1,695 ops/sec · 590 μs/op
secp256k1                  763 ops/sec · 1.31 ms/op · -2.2x
p256                       737 ops/sec · 1.36 ms/op · -2.3x
ed448                      599 ops/sec · 1.67 ms/op · -2.8x
p384                       326 ops/sec · 3.06 ms/op · -5.2x
p521                       176 ops/sec · 5.68 ms/op · -9.6x

Aktualisierung

Unterstützte node.js-Versionen:

  • v2 (2025-08): v20.19+ (nur ESM)
  • v1 (2023-04): v14.21+ (ESM & CJS)

v1 auf v2

v2 vereinfacht die Interna massiv, verbessert die Sicherheit, reduziert die Bundle-Größe und ebnet den Weg für die Zukunft. Wir haben versucht, v2 so weit wie möglich abwärtskompatibel zu halten.

Upgrade-Pfad: Zuerst auf curves v1.9.x aktualisieren. Die Deprecation-Warnungen beheben, dann auf v2 umsteigen.

Module:

  • Das Paket ist jetzt nur noch ESM. ESM kann endlich von common.js auf node v20.19+ geladen werden
  • Die .js-Erweiterung ist jetzt erforderlich: @noble/curves/ed25519 => @noble/curves/ed25519.js. Dies ermöglicht die native Nutzung im Browser, ohne Transpiler
  • p256, p384, p521 wurden nach nist verschoben; jubjub wurde nach misc verschoben
  • Die Kurven pasta und bn254_weierstrass (NICHT das pairing-basierte bn254) wurden entfernt

Neue Funktionen:

  • webcrypto: benutzerfreundlicher, noble-ähnlicher Wrapper über das eingebaute WebCrypto
  • oprf: RFC 9497 OPRFs (oblivious pseudorandom functions) für p256, p384, p521, ristretto255 und decaf448
  • weierstrass, edwards: neue Methoden isValidSecretKey, isValidPublicKey
  • misc: Brainpool-Kurven brainpoolP256r1, brainpoolP384r1, brainpoolP512r1
  • Massiv verbesserte, aussagekräftigere Fehlermeldungen

Breaking Changes:

  • Die meisten Methoden akzeptieren jetzt nur noch Uint8Array; String-Hex-Eingaben sind nicht mehr erlaubt. Dies vereinfacht die Argumentation, verbessert die Sicherheit und reduziert die Malleabilität. Point.fromHex akzeptiert jetzt nur noch Strings: Verwenden Sie Point.fromBytes für Uint8Array
  • ECDSA (secp256k1, p256, p384...) sign & verify:
    • Prehashed messages: Methoden erwarten jetzt die ungehashte Nachricht anstelle von messageHash. Altes Verhalten: {prehash: false}
    • lowS-Signaturen standardmäßig. secp256k1 ist nicht betroffen: Es verwendet lowS seit Beginn an. Altes Verhalten: {lowS: false}
    • Uint8Array-Signaturen (Format: 'compact') standardmäßig
    • verify: das der-Format muss explizit angegeben werden in {format: 'der'}. Dies reduziert die Malleabilität
    • verify: Signature-Instanzen sind nicht erlaubt: Rufen Sie zuerst signature.toBytes() auf
  • BLS-Signaturen (bls12-381, bn254):
    • getPublicKey, sign, verify, signShortSignature usw. wurden in zwei neue Namespaces verschoben: longSignatures (G1-Pubkeys, G2-Sigs) und shortSignatures (G1-Sigs, G2-Pubkeys)
    • verifyBatch erwartet jetzt ein Array von Eingaben {message: ..., publicKey: ...}[]

Umbenennungen (curves v1.9 markiert alte Namen als veraltet):

  • Points
    • ExtendedPoint, ProjectivePoint => Point
    • Point-Koordinaten px/ex, py/ey, pz/ez, et => X, Y, Z, T
    • toRawBytes, fromRawBytes => toBytes, fromBytes
    • Point.normalizeZ, Point.msm => separate Methoden im Submodul abstract/curve.js
    • Point.fromPrivateKey(key) => Point.BASE.multiply(Point.Fn.fromBytes(key))
    • CURVE-Eigenschaft mit allerlei zufälligem Zeug => Point.CURVE(), die nur Kurvenparameter bereitstellt
    • RistrettoPoint => ristretto255.Point, DecafPoint => decaf448.Point
  • ECDSA-Signaturen
    • toCompactRawBytes, toDERRawBytes => toBytes('compact'), toBytes('der')
    • toCompactHex, toDERHex => toHex('compact'), toHex('der')
    • fromCompact, fromDER => fromBytes(bytes, format), fromHex(hex, format)
  • utils
    • randomPrivateKey => randomSecretKey
    • normPrivateKeyToScalar => Point.Fn.fromBytes
    • utils.precompute, Point#_setWindowSize => Point#precompute
    • edwardsToMontgomery, edwardsToMontgomeryPriv => utils.toMontgomery, utils.toMontgomerySecret
  • Kurvenspezifische hash-to-curve-Methoden => *curve*_hasher. Beispiel: secp256k1.hashToCurve => secp256k1_hasher.hashToCurve()
  • Massives Umbenennen und Verbessern von Typen

Entfernte Funktionen: Point#multiplyAndAddUnsafe, Point#hasEvenY, Field.MASK

Mitwirken & Testen

npm install && npm run build && npm test baut den Code und führt Tests aus.

Es gibt zusätzliche Test-Suites: langsame Large-Scalar-/Large-Curve-Tests npm run test:slow, und das Constant-Timeness-Harness npm run benchmark:ct.

Siehe paulmillr.com/noble für nützliche Ressourcen, Artikel, Dokumentation und Demos zur Bibliothek.

Lizenz

The MIT License (MIT)

Copyright (c) 2022 Paul Miller (https://paulmillr.com)

Siehe LICENSE-Datei.

Tool herunterladen
  • Umfang: abstrakte Module curve, hash-to-curve, modular, poseidon, utils, weierstrass und Top-Level-Module _shortw_utils und secp256k1
  • Das Audit wurde von Ryan Shea finanziert
  • Benutzerdefinierte Kurven:
    • Die Kurvenerstellung wurde massiv vereinfacht und in Punkterstellung & Sig-Generator-Erstellung aufgeteilt: weierstrass() + ecdsa() / edwards() + eddsa(). weierstrass / edwards erwarten vereinfachte Kurvenparameter (Fp wurde zu p); ecdsa / eddsa erwarten die Point-Klasse und einen Hash
    • pippenger: unnötiges Fn-Argument entfernt
    • Field#fromBytes() validiert jetzt Elemente im Bereich 0..order-1