- Notifications
You must be signed in to change notification settings - Fork507
Dylan Sharhon edited this pageApr 10, 2020 ·2 revisions
There are some quirks and important undocumented APIs that people keep stumbling on. Examples usehexadecimal string i/o and the Bitcoin-compatible secp256k1 curve (others are similar...but different)
Instantiation shortcut
ec = elliptic.ec('secp256k1')
Calculate a private key's 33-byte compressed public key
compressed = truepub = ec.keyFromPrivate(pri, 'hex').getPublic(compressed, 'hex')
Hash a UTF-8 string or hex using thehash.js library
// utf8 inputmsg = hash.sha256().update(string).digest('hex')// hex inputmsg = hash.sha256().update(hex, 'hex').digest('hex')
Generate a Bitcoin-compatible DER-encoded signature with canonical (aka normalized) S values
canonical = { canonical: true }der = ec.sign(msg, pri, 'hex', canonical).toDER('hex')
Verify a DER-encoded signature
bool = ec.verify(msg, der, pub, 'hex')
Generate a recoverable signature in libsecp256k1 65-byte { R | S | index } format
canonical = { canonical: true }array = elliptic.utils.toArray(msg, 'hex') // HASHED MSG MUST BE BYTE ARRAYsig_obj = ec.sign(array, pri, 'hex', canonical)r = sig_obj.r.toString('hex', 32) // MUST SPECIFY 32 BYTES TO KEEP LEADING ZEROSs = sig_obj.s.toString('hex', 32)i = sig_obj.recoveryParam.toString(16).padStart(2, '0')sig = r + s + i
Recover the compressed public key from a 65-byte recoverable signature
compressed = truesig_obj = { r: sig.slice(0, 64), s: sig.slice(64, 128) }recoveryParam = parseInt(sig.slice(128, 130), 16)array = elliptic.utils.toArray(msg, 'hex') // HASHED MSG MUST BE BYTE ARRAYpub = ec.recoverPubKey(array, sig_obj, recoveryParam, 'hex').encode('hex', compressed)