WebAssembly Bindings for libsecp256k1

2.0.0 · active · verified Tue Apr 21

secp256k1-wasm provides high-performance WebAssembly bindings for `libsecp256k1`, the highly optimized C library for secp256k1 elliptic curve cryptography. This package enables cryptographic operations such as key generation, signature signing, and verification directly within JavaScript environments like web browsers and Node.js, offering near-native performance without requiring platform-specific native add-ons. The current stable version is 2.0.0, released in November 2023. While an explicit release cadence is not defined, releases appear to be feature-driven and occur periodically. Its primary differentiator is its reliance on Emscripten to compile the robust `libsecp256k1` to WebAssembly, making it ideal for applications where cryptographic throughput is critical, such as blockchain wallets or transaction processing, by avoiding the overhead of pure JavaScript implementations.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to asynchronously load the secp256k1 WASM module, generate a private/public key pair, sign a random message hash, and then verify and recover the public key from the signature. It showcases the high-level API functions exposed by the package.

import initSecp256k1 from 'secp256k1-wasm';
import { randomBytes } from 'crypto'; // Node.js built-in for secure randomness

async function runSecp256k1Example() {
  console.log("Loading secp256k1 WASM module...");
  // Initialize the WASM module. This returns a Promise that resolves to the API object.
  const secp256k1 = await initSecp256k1();
  console.log("secp256k1 WASM module loaded successfully.");

  // 1. Generate a random 32-byte private key
  const privateKey = randomBytes(32);
  console.log(`\nPrivate Key: ${privateKey.toString('hex')}`);

  // 2. Create a public key from the private key
  // 'false' means uncompressed public key (65 bytes)
  const publicKey = secp256k1.pubkeyCreate(privateKey, false);
  console.log(`Public Key (uncompressed): ${publicKey.toString('hex')}`);

  // 3. Prepare a 32-byte message hash to sign
  const messageHash = randomBytes(32);
  console.log(`Message Hash: ${messageHash.toString('hex')}`);

  // 4. Sign the message hash with the private key
  const { signature, recid } = secp256k1.sign(messageHash, privateKey);
  console.log(`Signature: ${signature.toString('hex')}`);
  console.log(`Recovery ID (RecID): ${recid}`);

  // 5. Verify the signature using the original message hash, signature, and public key
  const isValid = secp256k1.verify(messageHash, signature, publicKey);
  console.log(`Signature valid: ${isValid}`);

  // 6. Recover the public key from the message hash, signature, and recovery ID
  const recoveredPublicKey = secp256k1.recover(messageHash, signature, recid, false);
  console.log(`Recovered Public Key: ${recoveredPublicKey.toString('hex')}`);
  console.log(`Recovery matches original public key: ${publicKey.equals(recoveredPublicKey)}`);
}

runSecp256k1Example().catch(console.error);

view raw JSON →