isomorphic-secp256k1
An Isomorphic / Universal JavaScript elliptic curve digital signature package for the secp256k1 curve.
Features
This package has taken the bitcoin core library libsec256k1 and compiled it to a portable stand alone web assembly (Wasm) file that can be readily consumed by JavaScript.
The repository for how to achieve this can be found here.
Motivation
The Bitcoin core library, libsec256k1, has developed strategies to mitigate various side channel attacks such as differential power analysis and timing attacks for ECC signature generation. So, making the assumption that the integrity of the library is preserved after compilation of C to Wasm, this package should relay the same security 🔒 benefits as libsec256k1.
Additional considerations
Unlike JavaScript, Wasm operations are not subjected to garbage collection 🗑️, GC ¹. This is appropriate for cryptography as GC analysis, 📈 GCA may be used to infer users private keys through homomorphic models.
Support
Note - For testing you will need the Node.js web crypto.
Setup
$ npm i isomorphic-secp256k1
Security
For an indepth security analysis of web assembly please see: Everything Old is New Again: Binary Security of WebAssembly.
API
Table of contents
function generate_key_pair
Generate a cryptographically random secp256k1
public key
and private key
pair.
Returns: key_pair — Random cryptographic key pair.
Examples
Ways to import
.
import { generate_key_pair } from 'isomorphic-secp256k1'
import generate_key_pair from 'isomorphic-secp256k1/public/generate_key_pair.js'
Ways to require
.
const { generate_key_pair } = require('isomorphic-secp256k1')
const generate_key_pair = require('isomorphic-secp256k1/public/generate_key_pair.js')
Usage generate_key_pair
.
import { generate_key_pair } from 'isomorphic-secp256k1'
generate_key_pair()
function get_public_key
Given a valid secp256k1
private key return the corresponding public key
.
Parameter | Type | Description |
---|
arg | object | Argument. |
arg.private_key | Uint8Array | secp256k1 private key . |
Returns: Uint8Array — Compressed EC public key
.
Examples
Ways to import
.
import { get_public_key } from 'isomorphic-secp256k1'
import get_public_key from 'isomorphic-secp256k1/public/get_public_key.js'
Ways to require
.
const { get_public_key } = require('isomorphic-secp256k1')
const get_public_key = require('isomorphic-secp256k1/public/get_public_key.js')
Usage get_public_key
.
import { get_public_key } from 'isomorphic-secp256k1'
const private_key = new Uint8Array(32).fill(2)
get_public_key({ private_key })
function sha256
An isomorphic sha256
message digest function.
Parameter | Type | Description |
---|
data | Uint8Array | Binary array data to digest. |
Returns: Uint8Array — The message digest.
function sign_hash
Generate a secp256k1
DER
signature.
Parameter | Type | Description |
---|
arg | object | Argument. |
arg.hex | string | sha256 hash to sign. |
arg.private_key | Uint8Array | secp256k1 private key . |
Returns: Uint8Array — DER
encoded signature.
Examples
Ways to import
.
import { sign_hash } from 'isomorphic-secp256k1'
import sign_hash from 'isomorphic-secp256k1/public/sign_hash.js'
Ways to require
.
const { sign_hash } = require('isomorphic-secp256k1')
const sign_hash = require('isomorphic-secp256k1/public/sign_hash.js')
Usage sign_hash
.
import { sign_hash } from 'isomorphic-secp256k1'
import crypto from 'crypto'
const private_key_hex =
'7df0eecb35a6dc2d1faf741ac458258be61c78f57ec29a12ffd8b2cbf73f65d2'
sign_hash({
private_key: new Uint8Array(
private_key_hex.match(/.{2}/gm).map(i => `0x${i}`)
),
hex: crypto.createHash('sha256').update('hello').digest()
}).then(console.log)
A 70 byte Uint8Array
DER
encoded signature will be logged.
function verify_signature
Verify a secp256k1
DER
ecncoded EC signature.
Parameter | Type | Description |
---|
arg | object | Argument. |
arg.hash | Uint8Array | The 32 byte message digest that was signed. |
arg.der_signature | Uint8Array | 70 byte DER encoded signature to validate. |
arg.public_key | Uint8Array | Compressed 33 byte public key . |
Returns: boolean — Will be true
& false
for valid & invalid signatures respectively.
Examples
Ways to import
.
import { verify_signature } from 'isomorphic-secp256k1'
import verify_signature from 'isomorphic-secp256k1/public/verify_signature.js'
Ways to require
.
const { verify_signature } = require('isomorphic-secp256k1')
const verify_signature = require('isomorphic-secp256k1/public/verify_signature.js')
Usage verify_signature
.
import { verify_signature } from 'isomorphic-secp256k1'
const der_hex =
'3044022017ab3c02fadd943ae25e4ce94fb9144942bd18ff9a8f6ed17593986014e302d10220044d1889af00d60db8bbe0b33bbce04bf62ff3e95c5af2861317243516b785f3'
const public_key_hex =
'02c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf'
const hash_hex =
'9595c9df90075148eb06860365df33584b75bff782a510c6cd4883a419833d50'
verify_signature({
der_signature: new Uint8Array(Buffer.from(der_hex, 'hex')),
public_key: new Uint8Array(Buffer.from(public_key_hex, 'hex')),
hash: new Uint8Array(Buffer.from(hash_hex, 'hex'))
}).then(console.log)
True
will be logged if the signature was valid.
type key_pair
An asymmetric key pair for the secp256k1
curve.
Type: object
Parameter | Type | Description |
---|
private_key | Uint8Array | 32 byte key. |
public_key | Uint8Array | 33 byte compressed key. |