Audited & minimal JS implementation of elliptic curve cryptography
npx @tessl/cli install tessl/npm-noble--curves@1.9.0@noble/curves is a comprehensive, audited JavaScript/TypeScript implementation of elliptic curve cryptography. It provides multiple curve implementations (secp256k1, ed25519, NIST curves, BLS curves) with ECDSA, EdDSA, and Schnorr signature schemes, hash-to-curve functionality, and modular abstract cryptographic primitives for building custom curve implementations.
npm install @noble/curvesImportant: The main index cannot be imported directly - you must import specific submodules:
// Curve implementations
import { secp256k1, schnorr } from "@noble/curves/secp256k1";
import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from "@noble/curves/ed25519";
import { p256, p384, p521 } from "@noble/curves/nist";
import { bls12_381 } from "@noble/curves/bls12-381";
import { bn254 } from "@noble/curves/bn254";
// Abstract primitives
import { Field, mod, pow, invert } from "@noble/curves/abstract/modular";
import { weierstrass, ecdsa, ecdh } from "@noble/curves/abstract/weierstrass";
import { twistedEdwards, eddsa } from "@noble/curves/abstract/edwards";
// Utilities
import { bytesToHex, hexToBytes, concatBytes, randomBytes } from "@noble/curves/utils";For CommonJS:
const { secp256k1, schnorr } = require("@noble/curves/secp256k1");
const { ed25519, x25519 } = require("@noble/curves/ed25519");
const { p256, p384, p521 } = require("@noble/curves/nist");import { secp256k1 } from "@noble/curves/secp256k1";
import { ed25519 } from "@noble/curves/ed25519";
import { randomBytes } from "@noble/curves/utils";
// ECDSA with secp256k1
const privKey = randomBytes(32);
const pubKey = secp256k1.getPublicKey(privKey);
const message = new TextEncoder().encode("hello world");
const signature = secp256k1.sign(message, privKey);
const isValid = secp256k1.verify(signature, message, pubKey);
// EdDSA with Ed25519
const ed25519PrivKey = ed25519.utils.randomPrivateKey();
const ed25519PubKey = ed25519.getPublicKey(ed25519PrivKey);
const ed25519Sig = ed25519.sign(message, ed25519PrivKey);
const ed25519Valid = ed25519.verify(ed25519Sig, message, ed25519PubKey);
// Key exchange with X25519
import { x25519 } from "@noble/curves/ed25519";
const alicePriv = x25519.utils.randomPrivateKey();
const alicePub = x25519.getPublicKey(alicePriv);
const bobPriv = x25519.utils.randomPrivateKey();
const bobPub = x25519.getPublicKey(bobPriv);
const sharedSecret1 = x25519.getSharedSecret(alicePriv, bobPub);
const sharedSecret2 = x25519.getSharedSecret(bobPriv, alicePub);
// sharedSecret1 === sharedSecret2@noble/curves is built around several key architectural components:
Complete implementations of popular elliptic curves with signature schemes and key exchange protocols. Each curve provides signing, verification, key generation, and point operations.
// Common curve interface
interface CurveFn {
getPublicKey(privateKey: PrivKey): Uint8Array;
sign(message: Hex, privateKey: PrivKey): ECDSASignature;
verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
Point: WeierstrassPointCons<bigint>;
Signature: ECDSASignatureCons;
utils: {
randomPrivateKey(): Uint8Array;
precompute(windowSize?: number, point?: WeierstrassPoint<bigint>): WeierstrassPoint<bigint>;
};
}Low-level building blocks for implementing custom elliptic curves, including field arithmetic, point operations, signature schemes, and hash-to-curve functionality.
// Core abstract functions
function weierstrass(c: CurveType): CurveFn;
function twistedEdwards(c: CurveTypeWithLength): CurveFn;
function Field(ORDER: bigint, opts?: FieldOpts): IField<bigint>;
function ecdsa(Point: WeierstrassPointCons, Hash: CHash, opts?: ECDSAOpts): ECDSA;
function eddsa(Point: EdwardsPointCons, cHash: FHash, opts?: EdDSAOpts): EdDSA;Essential utility functions for byte manipulation, number conversion, validation, and cryptographic operations used throughout the library.
// Core utility functions
function bytesToHex(bytes: Uint8Array): string;
function hexToBytes(hex: string): Uint8Array;
function concatBytes(...arrays: Uint8Array[]): Uint8Array;
function randomBytes(bytesLength?: number): Uint8Array;
function mod(a: bigint, b: bigint): bigint;
function invert(number: bigint, modulo: bigint): bigint;Native browser WebCrypto API wrappers providing hardware-accelerated elliptic curve operations with the same API as main curve implementations.
// WebCrypto curve interfaces
interface WebCryptoNIST extends WebCryptoBaseCurve, WebCryptoSigner, WebCryptoECDH;
interface WebCryptoEdDSA extends WebCryptoBaseCurve, WebCryptoSigner;
interface WebCryptoMontgomery extends WebCryptoBaseCurve, WebCryptoECDH;
// Check curve availability
function supportsWc(curve: WebCryptoBaseCurve): Promise<boolean>;type Hex = Uint8Array | string;
type PrivKey = Hex | bigint;
interface CHash {
(message: Uint8Array): Uint8Array;
blockLen: number;
outputLen: number;
create(): any;
}
interface FHash {
(message: Uint8Array | string): Uint8Array;
}interface ECDSASignature {
r: bigint;
s: bigint;
recovery?: number;
toCompactRawBytes(): Uint8Array;
toDERRawBytes(): Uint8Array;
}
interface EdDSA {
sign(message: Hex, privateKey: PrivKey): Uint8Array;
verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
getPublicKey(privateKey: PrivKey): Uint8Array;
}interface IField<T> {
ORDER: bigint;
ZERO: T;
ONE: T;
create(num: T): T;
add(a: T, b: T): T;
mul(a: T, b: T): T;
pow(a: T, b: bigint): T;
inv(a: T): T;
sqrt(a: T): T;
eql(a: T, b: T): boolean;
}
interface WeierstrassPoint<T> {
x: T;
y: T;
z: T;
add(other: WeierstrassPoint<T>): WeierstrassPoint<T>;
multiply(scalar: bigint): WeierstrassPoint<T>;
toAffine(): { x: T; y: T };
toRawBytes(isCompressed?: boolean): Uint8Array;
}
interface EdwardsPoint {
x: bigint;
y: bigint;
z: bigint;
t: bigint;
add(other: EdwardsPoint): EdwardsPoint;
multiply(scalar: bigint): EdwardsPoint;
toAffine(): { x: bigint; y: bigint };
toRawBytes(): Uint8Array;
}