CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-noble--curves

Audited & minimal JS implementation of elliptic curve cryptography

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

curves.mddocs/

Curve Implementations

Complete implementations of popular elliptic curves with signature schemes, key exchange protocols, and specialized cryptographic operations.

Capabilities

secp256k1 Curve

Bitcoin's elliptic curve with ECDSA signatures and BIP340 Schnorr signatures.

import { secp256k1, schnorr } from "@noble/curves/secp256k1";

// Main curve object
const secp256k1: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey, opts?: ECDSASignOpts): ECDSASignature;
  verify(signature: ECDSASignature, message: Hex, publicKey: Hex, opts?: ECDSAVerifyOpts): boolean;
  Point: WeierstrassPointCons<bigint>;
  Signature: ECDSASignatureCons;
  utils: {
    randomPrivateKey(): Uint8Array;
    precompute(windowSize?: number, point?: WeierstrassPoint<bigint>): WeierstrassPoint<bigint>;
    mod(a: bigint, b?: bigint): bigint;
    invert(number: bigint, modulo?: bigint): bigint;
    hashToPrivateScalar(hash: Hex): bigint;
  };
  CURVE: {
    p: bigint;
    n: bigint;
    a: bigint;
    b: bigint;
    Gx: bigint;
    Gy: bigint;
  };
};

// Schnorr signatures (BIP340)
const schnorr: {
  sign(message: Hex, privateKey: PrivKey, auxRand?: Hex): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  getPublicKey(privateKey: PrivKey): Uint8Array;
};

// Hash-to-curve functionality
function hashToCurve(msg: Uint8Array, options?: { DST?: string }): WeierstrassPoint<bigint>;
function encodeToCurve(msg: Uint8Array, options?: { DST?: string }): WeierstrassPoint<bigint>;

Usage Examples:

import { secp256k1, schnorr } from "@noble/curves/secp256k1";

// ECDSA signing
const privKey = secp256k1.utils.randomPrivateKey();
const pubKey = secp256k1.getPublicKey(privKey);
const msg = new TextEncoder().encode("hello");

const signature = secp256k1.sign(msg, privKey);
const isValid = secp256k1.verify(signature, msg, pubKey);

// Schnorr signing (BIP340)
const schnorrSig = schnorr.sign(msg, privKey);
const schnorrValid = schnorr.verify(schnorrSig, msg, schnorr.getPublicKey(privKey));

Ed25519 Curve

High-performance Edwards curve with EdDSA signatures and X25519 key exchange.

import { ed25519, ed25519ctx, ed25519ph, x25519, RistrettoPoint } from "@noble/curves/ed25519";

// Standard Ed25519
const ed25519: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  Point: EdwardsPointCons;
  utils: {
    randomPrivateKey(): Uint8Array;
    getExtendedPublicKey(privateKey: PrivKey): { prefix: Uint8Array; scalar: bigint; point: EdwardsPoint; pointBytes: Uint8Array };
  };
};

// Ed25519 with context support
const ed25519ctx: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
};

// Ed25519 with pre-hashing
const ed25519ph: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
};

// X25519 key exchange
const x25519: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  getSharedSecret(privateKey: PrivKey, publicKey: Hex): Uint8Array;
  utils: {
    randomPrivateKey(): Uint8Array;
  };
};

// Ristretto255 group
const ristretto255: {
  Point: typeof RistrettoPoint;
  hashToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
  encodeToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
};

// Conversion utilities
function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array;
function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array;

// Hash-to-curve functionality
function hashToCurve(msg: Uint8Array, options?: { DST?: string }): EdwardsPoint;
function encodeToCurve(msg: Uint8Array, options?: { DST?: string }): EdwardsPoint;

Usage Examples:

import { ed25519, x25519 } from "@noble/curves/ed25519";

// EdDSA signing
const privKey = ed25519.utils.randomPrivateKey();
const pubKey = ed25519.getPublicKey(privKey);
const msg = new TextEncoder().encode("message");

const signature = ed25519.sign(msg, privKey);
const isValid = ed25519.verify(signature, msg, pubKey);

// X25519 key exchange
const alicePriv = x25519.utils.randomPrivateKey();
const alicePub = x25519.getPublicKey(alicePriv);
const bobPriv = x25519.utils.randomPrivateKey(); 
const bobPub = x25519.getPublicKey(bobPriv);

const sharedSecret = x25519.getSharedSecret(alicePriv, bobPub);

NIST Curves

FIPS-approved elliptic curves P-256, P-384, and P-521.

import { p256, p384, p521, secp256r1, secp384r1, secp521r1 } from "@noble/curves/nist";

// P-256 (secp256r1)
const p256: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey, opts?: ECDSASignOpts): ECDSASignature;
  verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
  Point: WeierstrassPointCons<bigint>;
  Signature: ECDSASignatureCons;
  utils: CurveUtils;
};

// P-384 (secp384r1) 
const p384: typeof p256;

// P-521 (secp521r1)
const p521: typeof p256;

// Aliases
const secp256r1: typeof p256;
const secp384r1: typeof p384;
const secp521r1: typeof p521;

// Hash-to-curve hashers
const p256_hasher: H2CHasher<bigint>;
const p384_hasher: H2CHasher<bigint>;
const p521_hasher: H2CHasher<bigint>;

BLS12-381 Curve

Pairing-friendly curve for BLS signatures and zero-knowledge applications.

import { bls12_381 } from "@noble/curves/bls12-381";

const bls12_381: {
  // BLS signature operations
  sign(message: Hex, privateKey: PrivKey): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  aggregatePublicKeys(publicKeys: Hex[]): Uint8Array;
  aggregateSignatures(signatures: Hex[]): Uint8Array;
  verifyBatch(signature: Hex, messages: Hex[], publicKeys: Hex[]): boolean;
  
  // Key operations
  getPublicKey(privateKey: PrivKey): Uint8Array;
  
  // Points and fields
  G1: {
    Point: G1PointCons;
    ZERO: G1Point;
    BASE: G1Point;
  };
  G2: {
    Point: G2PointCons;
    ZERO: G2Point;
    BASE: G2Point;
  };
  GT: FieldExtension;
  
  // Pairing operations
  pairing(P: G1Point, Q: G2Point): Fp12;
  millerLoop(pairs: [G1Point, G2Point][]): Fp12;
  finalExponentiate(num: Fp12): Fp12;
  
  // Hash-to-curve operations
  G1_hashToCurve(msg: Uint8Array, DST?: string): G1Point;
  G2_hashToCurve(msg: Uint8Array, DST?: string): G2Point;
  
  // Point encoding/decoding
  G1_pointToBytes(point: G1Point, isCompressed?: boolean): Uint8Array;
  G1_pointFromBytes(bytes: Uint8Array): G1Point;
  G2_pointToBytes(point: G2Point, isCompressed?: boolean): Uint8Array;
  G2_pointFromBytes(bytes: Uint8Array): G2Point;
  
  // Signature encoding/decoding
  G1_signatureToBytes(point: G1Point): Uint8Array;
  G1_signatureFromBytes(bytes: Uint8Array): G1Point;
  G2_signatureToBytes(point: G2Point): Uint8Array;
  G2_signatureFromBytes(bytes: Uint8Array): G2Point;
  
  // Utilities
  utils: {
    randomPrivateKey(): Uint8Array;
    calcPairingPrecomputes(point: G2Point): any;
    isValidPrivateKey(privateKey: PrivKey): boolean;
    normPrivateKeyToScalar(privateKey: PrivKey): bigint;
  };
};

// Scalar field
const bls12_381_Fr: IField<bigint>;

BN254 Curve

BN254 (alt_bn128) pairing-friendly curve used in Ethereum and zk-SNARKs.

import { bn254, bn254_weierstrass } from "@noble/curves/bn254";

// BLS-style interface for BN254
const bn254: {
  sign(message: Hex, privateKey: PrivKey): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  getPublicKey(privateKey: PrivKey): Uint8Array;
  
  G1: {
    Point: G1PointCons;
    ZERO: G1Point;
    BASE: G1Point;
  };
  G2: {
    Point: G2PointCons;
    ZERO: G2Point;
    BASE: G2Point;
  };
  
  // Pairing operations
  pairing(P: G1Point, Q: G2Point): any;
  utils: BLSUtils;
};

// Standard Weierstrass interface for BN254
const bn254_weierstrass: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): ECDSASignature;
  verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
  Point: WeierstrassPointCons<bigint>;
};

// Scalar field
const bn254_Fr: IField<bigint>;

Ed448 Curve

Ed448-Goldilocks curve with EdDSA signatures and X448 key exchange.

import { ed448, ed448ph, ed448ctx, x448 } from "@noble/curves/ed448";

// Standard Ed448
const ed448: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  Point: EdwardsPointCons;
  utils: {
    randomPrivateKey(): Uint8Array;
  };
};

// Ed448 with pre-hashing
const ed448ph: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
};

// Ed448 with context support
const ed448ctx: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey, context?: Hex): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex, context?: Hex): boolean;
};

// X448 key exchange
const x448: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  getSharedSecret(privateKey: PrivKey, publicKey: Hex): Uint8Array;
  utils: {
    randomPrivateKey(): Uint8Array;
  };
};

Additional Curves

Miscellaneous and ZK-Friendly Curves

The /misc export provides specialized curves for zero-knowledge proofs and other advanced cryptographic applications.

JubJub Curve

Twisted Edwards curve over the BLS12-381 scalar field, designed for zero-knowledge proof systems.

import { jubjub, jubjub_groupHash, jubjub_findGroupHash } from "@noble/curves/misc";

// JubJub curve (jubjub Fp = bls12-381 n)
const jubjub: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  Point: EdwardsPointCons;
  utils: CurveUtils;
};

// JubJub group hash functions for deterministic point generation
function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array): EdwardsPoint;
function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array): EdwardsPoint;

BabyJubJub Curve

Twisted Edwards curve over the BN254 scalar field, commonly used in zero-knowledge applications.

import { babyjubjub } from "@noble/curves/misc";

// BabyJubJub curve (babyjubjub Fp = bn254 n)
const babyjubjub: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): Uint8Array;
  verify(signature: Hex, message: Hex, publicKey: Hex): boolean;
  Point: EdwardsPointCons;
  utils: CurveUtils;
};

Pasta Curves (Pallas/Vesta)

Cycle of curves designed for recursive zero-knowledge proofs, where each curve's base field equals the other's scalar field.

import { pallas, vesta, pasta_p, pasta_q } from "@noble/curves/misc";

// Pallas curve (deprecated - use newer ZK-friendly alternatives)
const pallas: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): ECDSASignature;
  verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
  Point: WeierstrassPointCons<bigint>;
  utils: CurveUtils;
};

// Vesta curve (deprecated - use newer ZK-friendly alternatives)
const vesta: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): ECDSASignature;
  verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
  Point: WeierstrassPointCons<bigint>;
  utils: CurveUtils;
};

// Pasta field parameters
const pasta_p: bigint; // Pallas base field = Vesta scalar field
const pasta_q: bigint; // Vesta base field = Pallas scalar field

Note: Pasta curves are also available via separate import paths:

import { pallas, vesta } from "@noble/curves/pasta"; // Deprecated aliases

Ristretto255 Cofactor Elimination

Ristretto255 provides a prime-order group from Ed25519 by eliminating the cofactor, ensuring every element has prime order.

import { ristretto255, RistrettoPoint } from "@noble/curves/ed25519";

// Ristretto255 group operations
const ristretto255: {
  Point: typeof RistrettoPoint;
  hashToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
  encodeToCurve(msg: Uint8Array, options?: { DST?: string }): RistrettoPoint;
};

// Ristretto255 point class with prime-order group operations
class RistrettoPoint {
  static ZERO: RistrettoPoint;
  static BASE: RistrettoPoint;
  
  static fromBytes(bytes: Uint8Array): RistrettoPoint;
  static fromHex(hex: string): RistrettoPoint;
  
  add(other: RistrettoPoint): RistrettoPoint;
  subtract(other: RistrettoPoint): RistrettoPoint;
  multiply(scalar: bigint): RistrettoPoint;
  negate(): RistrettoPoint;
  double(): RistrettoPoint;
  
  equals(other: RistrettoPoint): boolean;
  toBytes(): Uint8Array;
  toHex(): string;
}

Decaf448 Cofactor Elimination

Decaf448 provides a prime-order group from Ed448 by eliminating the cofactor.

import { decaf448, DecafPoint } from "@noble/curves/ed448";

// Decaf448 group operations
const decaf448: {
  Point: typeof DecafPoint;
  hashToCurve(msg: Uint8Array, options?: { DST?: string }): DecafPoint;
  encodeToCurve(msg: Uint8Array, options?: { DST?: string }): DecafPoint;
};

// Decaf448 point class with prime-order group operations
class DecafPoint {
  static ZERO: DecafPoint;
  static BASE: DecafPoint;
  
  static fromBytes(bytes: Uint8Array): DecafPoint;
  static fromHex(hex: string): DecafPoint;
  
  add(other: DecafPoint): DecafPoint;
  subtract(other: DecafPoint): DecafPoint;
  multiply(scalar: bigint): DecafPoint;
  negate(): DecafPoint;
  double(): DecafPoint;
  
  equals(other: DecafPoint): boolean;
  toBytes(): Uint8Array;
  toHex(): string;
}

Miscellaneous Curves

Additional specialized curves for specific applications.

import { stark } from "@noble/curves/misc";

// StarkNet curve - prime-order curve used by StarkNet zero-knowledge rollup
const stark: {
  getPublicKey(privateKey: PrivKey): Uint8Array;
  sign(message: Hex, privateKey: PrivKey): ECDSASignature;
  verify(signature: ECDSASignature, message: Hex, publicKey: Hex): boolean;
  Point: WeierstrassPointCons<bigint>;
  utils: CurveUtils;
};

Common Curve Interface Types

interface CurveUtils {
  randomPrivateKey(): Uint8Array;
  precompute(windowSize?: number, point?: any): any;
  mod(a: bigint, b?: bigint): bigint;
  invert(number: bigint, modulo?: bigint): bigint;
  hashToPrivateScalar(hash: Hex): bigint;
}

interface ECDSASignOpts {
  lowS?: boolean;
  extraEntropy?: Hex | boolean;
  canonical?: boolean;
  der?: boolean;
  recovered?: boolean;
}

interface ECDSAVerifyOpts {
  lowS?: boolean;
  format?: ECDSASigFormat;
}

type ECDSASigFormat = 'compact' | 'recovered' | 'der';

interface H2CHasher<T> {
  hashToCurve(msg: Uint8Array, options?: { DST?: string }): any;
  encodeToCurve(msg: Uint8Array, options?: { DST?: string }): any;
}

docs

abstract-primitives.md

curves.md

index.md

utilities.md

webcrypto.md

tile.json