- Update stale v3.14.0 headers/footers to v3.22.0: BINDINGS.md, DIFFERENTIAL_TESTING.md, AUDIT_TRACEABILITY.md, BINDINGS_PACKAGING.md, INTERNAL_AUDIT.md, LTS_POLICY.md - Fix SECURITY_CLAIMS.md footer v3.21.0 -> v3.22.0 - Update ARCHITECTURE.md, AUDIT_GUIDE.md, CT_VERIFICATION.md, CROSS_PLATFORM_TEST_MATRIX.md, TEST_MATRIX.md, USER_GUIDE.md - Update API_REFERENCE.md: frost_verify_partial signature - Add BIP-39, ZK, Wallet, Multi-coin, ECDH to CHANGELOG [Unreleased] - Update all 12 binding READMEs + wasm/README.md with new API surface - Refresh audit reports (clang-17, gcc-13) |
||
|---|---|---|
| .. | ||
| bench_wasm.mjs | ||
| CMakeLists.txt | ||
| package.json | ||
| README.md | ||
| secp256k1_wasm.cpp | ||
| secp256k1_wasm.h | ||
| secp256k1.d.ts | ||
| secp256k1.mjs | ||
@ultrafastsecp256k1/wasm
Ultra high-performance secp256k1 for the browser and Node.js via Emscripten/WebAssembly.
Powered by UltrafastSecp256k1.
Install
npm install @ultrafastsecp256k1/wasm
Features
- ECDSA sign/verify (RFC 6979 deterministic nonce, low-S)
- Schnorr BIP-340 sign/verify
- SHA-256 hashing
- Point arithmetic (scalar mul, add)
- Public key derivation
- Self-test
- ES6 module output with TypeScript declarations
- Key tweaking -- negate, add, multiply
- Ethereum -- Keccak-256, EIP-55 addresses, EIP-155 sign, ecrecover
- BIP-39 -- mnemonic generation, validation, seed derivation
- Multi-coin wallet -- 7-coin address dispatch (BTC/LTC/DOGE/DASH/ETH/BCH/TRX)
- Batch verification -- ECDSA + Schnorr batch verify with invalid identification
- MuSig2 -- BIP-327 multi-signatures (key agg, nonce gen, partial sign, aggregate)
- FROST -- threshold signatures (keygen, sign, aggregate, verify)
- Adaptor signatures -- Schnorr + ECDSA adaptor pre-sign, adapt, extract
- Pedersen commitments -- commit, verify, sum balance, switch commitments
- ZK proofs -- knowledge proof, DLEQ proof, Bulletproof range proof
- Multi-scalar multiplication -- Shamir's trick, MSM
- Pubkey arithmetic -- add, negate, combine N keys
- SHA-512 -- full SHA-512 hash
- Message signing -- BIP-137 Bitcoin message sign/verify
Quick Start
Build
# Install Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install latest && ./emsdk activate latest
source emsdk_env.sh
# Build WASM module
cd UltrafastSecp256k1
./scripts/build_wasm.sh
Output in build/wasm/dist/:
| File | Description |
|---|---|
secp256k1_wasm.wasm |
WebAssembly binary |
secp256k1_wasm.js |
Emscripten loader (ES6) |
secp256k1.mjs |
High-level JS wrapper |
secp256k1.d.ts |
TypeScript declarations |
package.json |
npm package metadata |
Usage (Node.js)
import { Secp256k1 } from './dist/secp256k1.mjs';
const lib = await Secp256k1.create();
console.log('Version:', lib.version());
console.log('Self-test:', lib.selftest() ? 'PASS' : 'FAIL');
// Generate public key from private key
const privkey = new Uint8Array(32);
privkey[31] = 1; // scalar = 1 (generator point)
const { x, y } = lib.pubkeyCreate(privkey);
console.log('G.x:', Buffer.from(x).toString('hex'));
// ECDSA sign
const msgHash = lib.sha256(new TextEncoder().encode('Hello secp256k1'));
const sig = lib.ecdsaSign(msgHash, privkey);
console.log('Signature:', Buffer.from(sig).toString('hex'));
// ECDSA verify
const valid = lib.ecdsaVerify(msgHash, x, y, sig);
console.log('Valid:', valid); // true
Usage (Browser)
<script type="module">
import { Secp256k1 } from './dist/secp256k1.mjs';
const lib = await Secp256k1.create();
console.log('secp256k1 WASM loaded, version:', lib.version());
// ... use lib.ecdsaSign(), lib.schnorrSign(), etc.
</script>
API Reference
Secp256k1.create(options?): Promise<Secp256k1>
Initialize the WASM module.
selftest(): boolean
Run built-in self-test.
version(): string
Library version (e.g. "3.0.0").
pubkeyCreate(seckey: Uint8Array): { x, y }
Derive public key from 32-byte private key.
pointMul(pointX, pointY, scalar): { x, y }
Scalar x Point multiplication.
pointAdd(px, py, qx, qy): { x, y }
Point addition.
ecdsaSign(msgHash, seckey): Uint8Array
ECDSA sign (64-byte compact: r ‖ s).
ecdsaVerify(msgHash, pubX, pubY, sig): boolean
ECDSA verify.
schnorrSign(seckey, msg, auxRand?): Uint8Array
Schnorr BIP-340 sign (64-byte: R.x ‖ s).
schnorrVerify(pubkeyX, msg, sig): boolean
Schnorr BIP-340 verify.
schnorrPubkey(seckey): Uint8Array
Derive x-only public key for BIP-340.
sha256(data): Uint8Array
SHA-256 hash.
C API (Low-level)
For direct use from C/C++ or custom WASM bindings, see secp256k1_wasm.h.
Build Options
# Debug build (assertions, safe heap, stack overflow checks)
./scripts/build_wasm.sh debug
# Or manually:
emcmake cmake -S wasm -B build/wasm -DCMAKE_BUILD_TYPE=Debug
cmake --build build/wasm -j
GLV Window Width
WASM defaults to GLV window w=4 (smaller tables for constrained environments). Override with:
emcmake cmake -S wasm -B build/wasm -DSECP256K1_GLV_WINDOW_WIDTH=5
| Window | Tradeoff |
|---|---|
| w=4 | Default for WASM -- smaller tables, more point additions |
| w=5 | Fewer additions, beneficial if cache permits |
See docs/PERFORMANCE_GUIDE.md for detailed benchmarks.
License
MIT