Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
noble-curves — Audited & minimal JS implementation of elliptic curve cryptography. | Kitploit
Tools/GitHubGitHub/paulmillr/noble-curves
Encryption/Decryption ToolsHash AnalysisCryptographyUtilities & FrameworksLearning & Education
GitHubpaulmillr/noble-curves

noble-curves

Audited & minimal JS implementation of elliptic curve cryptography.

View Repository
9601036627 days agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
Website

noble-curves

Audited & minimal JS implementation of elliptic curve cryptography.

  • 🔒 Audited by independent security firms
  • 🪶 Minimal: 15KB (gzipped) secp256k1, unused code is excluded from your builds
  • 🏎 Fast: hand-optimized for caveats of JS engines
  • 🔍 Reliable: cross-library / wycheproof tests ensure correctness
  • ➰ Weierstrass, Edwards curves; ECDSA, EdDSA, Schnorr, BLS signatures
  • ✍️ ECDH, hash-to-curve, OPRF, FROST, Poseidon hash, FFT
  • 🔖 Non-repudiation (SUF-CMA, SBS) & consensus-friendliness (ZIP215) in ed25519, ed448
  • 🥈 Wrapper with identical API over native WebCrypto

Curves have 5kb sister projects secp256k1 & ed25519. They have smaller attack surface, but less features.

This library belongs to noble cryptography

noble cryptography — high-security, easily auditable set of contained cryptographic libraries and tools.

  • Zero or minimal dependencies
  • Highly readable TypeScript / JS code
  • PGP-signed releases and transparent NPM builds
  • All libraries: ciphers, curves, hashes, post-quantum, 5kb secp256k1 / ed25519
  • WASM version: awasm-noble
  • Check out the homepage for reading resources, documentation, and apps built with noble

Usage

npm install @noble/curves

deno add jsr:@noble/curves

We support all major platforms and runtimes. For React Native, you may need a polyfill for getRandomValues. A standalone file noble-curves.js is also available.

// 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);
  • ECDSA, EdDSA, Schnorr signatures
  • ECDH: Diffie-Hellman shared secrets
  • webcrypto: friendly wrapper
  • BLS signatures, bls12-381, bn254 aka alt_bn128
  • hash-to-curve: hashing to curve points
  • OPRFs | FROST threshold signatures
  • poseidon: Poseidon hash | fft: Fast Fourier Transform | utils
  • Internals: Point math | modular | custom curves
  • Specs
  • Security | Speed | Upgrading | Contributing & testing | License

ECDSA, EdDSA, Schnorr signatures

secp256k1, p256, p384, p521, ed25519, ed448, brainpool

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);

Messages are always hashed first: see prehashed signing. ECDSA uses deterministic k, EdDSA follows RFC 8032, Schnorr (secp256k1-only) follows BIP 340: see Specs.

MuSig2 signature scheme and BIP324 ElligatorSwift mapping for secp256k1 are available in a separate package.

ristretto255, decaf448

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);

Check out RFC 9496 more info on ristretto255 & decaf448. Check out separate documentation for Point, hasher and oprf.

Prehashed signing

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 });

By default (prehash: true), sign() and verify() apply the curve's built-in hash to the message first: sha256 for secp256k1, sha512 for p521. prehash: false allows using a custom hash (e.g. secp256k1 + keccak_256). In noble-curves v1, prehash: false was the default.

Recovering public keys from signatures

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');

Public key recovery is only supported with ECDSA. It is a simple math operation: there are no guarantees the signing was actually done. A forged (r, s, h) recovers into a random public key, but it's not feasible to find m which would lead to this specific forged h.

Hedged ECDSA with noise

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 });

By default, ECDSA signatures are deterministic (RFC 6979). Purely deterministic signatures are vulnerable to fault attacks, so newer schemes, such as BIP340 schnorr, incorporate randomness into sig generation - a.k.a. hedging. extraEntropy enables hedged mode. For more info, check out Deterministic signatures are not your friends.

Consensus-friendliness vs e-voting

Download Tool