Comparing version 2.0.10 to 3.0.0
103
API.md
@@ -1,59 +0,58 @@ | ||
# API Reference (v2.x) | ||
# API Reference (v3.x) | ||
- [`.secretKeyVerify(Buffer secretKey)`](#secretkeyverifybuffer-secretkey---boolean) | ||
- [`.secretKeyExport(Buffer secretKey [, Boolean compressed = true])`](#secretkeyexportbuffer-secretkey--boolean-compressed--true---buffer) | ||
- [`.secretKeyImport(Buffer secretKey)`](#secretkeyimportbuffer-secretkey---buffer) | ||
- [`.secretKeyTweakAdd(Buffer secretKey, Buffer tweak)`](#secretkeytweakaddbuffer-secretkey-buffer-tweak---buffer) | ||
- [`.secretKeyTweakMul(Buffer secretKey, Buffer tweak)`](#secretkeytweakmulbuffer-secretkey-buffer-tweak---buffer) | ||
- [`.publicKeyCreate(Buffer secretKey)`](#publickeycreatebuffer-secretkey---buffer) | ||
- [`.privateKeyVerify(Buffer privateKey)`](#privatekeyverifybuffer-privatekey---boolean) | ||
- [`.privateKeyExport(Buffer privateKey [, Boolean compressed = true])`](#privatekeyexportbuffer-privatekey--boolean-compressed--true---buffer) | ||
- [`.privateKeyImport(Buffer privateKey)`](#privatekeyimportbuffer-privatekey---buffer) | ||
- [`.privateKeyTweakAdd(Buffer privateKey, Buffer tweak)`](#privatekeytweakaddbuffer-privatekey-buffer-tweak---buffer) | ||
- [`.privateKeyTweakMul(Buffer privateKey, Buffer tweak)`](#privatekeytweakmulbuffer-privatekey-buffer-tweak---buffer) | ||
- [`.publicKeyCreate(Buffer privateKey [, Boolean compressed = true])`](#publickeycreatebuffer-privatekey--boolean-compressed--true---buffer) | ||
- [`.publicKeyConvert(Buffer publicKey [, Boolean compressed = true])`](#publickeyconvertbuffer-publickey--boolean-compressed--true---buffer) | ||
- [`.publicKeyVerify(Buffer publicKey)`](#publickeyverifybuffer-publickey---boolean) | ||
- [`.publicKeyTweakAdd(Buffer publicKey, Buffer tweak)`](#publickeytweakaddbuffer-publickey-buffer-tweak---buffer) | ||
- [`.publicKeyTweakMul(Buffer publicKey, Buffer tweak)`](#publickeytweakmulbuffer-publickey-buffer-tweak---buffer) | ||
- [`.publicKeyCombine(Array<Buffer> publicKeys)`](#publickeycombinearraybuffer-publickeys---buffer) | ||
- [`.publicKeyTweakAdd(Buffer publicKey, Buffer tweak [, Boolean compressed = true])`](#publickeytweakaddbuffer-publickey-buffer-tweak--boolean-compressed--true---buffer) | ||
- [`.publicKeyTweakMul(Buffer publicKey, Buffer tweak [, Boolean compressed = true])`](#publickeytweakmulbuffer-publickey-buffer-tweak--boolean-compressed--true---buffer) | ||
- [`.publicKeyCombine(Array<Buffer> publicKeys [, Boolean compressed = true])`](#publickeycombinearraybuffer-publickeys--boolean-compressed--true---buffer) | ||
- [`.signatureNormalize(Buffer signature)`](#signaturenormalizebuffer-signature---buffer) | ||
- [`.signatureExport(Buffer signature)`](#signatureexportbuffer-signature---buffer) | ||
- [`.signatureImport(Buffer signature)`](#signatureimportbuffer-signature---buffer) | ||
- [`.sign(Buffer msg, Buffer secretKey [, Function callback])`](#signbuffer-msg-buffer-secretkey--function-callback---promisesignature-buffer-recovery-number) | ||
- [`.signSync(Buffer msg, Buffer secretKey)`](#signsyncbuffer-msg-buffer-secretkey---signature-buffer-recovery-number) | ||
- [`.verify(Buffer msg, Buffer signature, Buffer publicKey [, Function callback])`](#verifybuffer-msg-buffer-signature-buffer-publickey--function-callback---promiseboolean) | ||
- [`.verifySync(Buffer msg, Buffer signature, Buffer publicKey)`](#verifysyncbuffer-msg-buffer-signature-buffer-publickey---boolean) | ||
- [`.recover(Buffer msg, Buffer signature, Number recovery [, Function callback])`](#recoverbuffer-msg-buffer-signature-number-recovery--function-callback---promisebuffer) | ||
- [`.recoverSync(Buffer msg, Buffer signature, Number recovery)`](#recoversyncbuffer-msg-buffer-signature-number-recovery---buffer) | ||
- [`.ecdh(Buffer publicKey, Buffer secretKey [, Function callback])`](#ecdhbuffer-publickey-buffer-secretkey--function-callback---promisebuffer) | ||
- [`.ecdhSync(Buffer publicKey, Buffer secretKey)`](#ecdhsyncbuffer-publickey-buffer-secretkey---buffer) | ||
- [`.sign(Buffer message, Buffer privateKey [, Object options])`](#signbuffer-message-buffer-privatekey--object-options---signature-buffer-recovery-number) | ||
- [Option: `Function noncefn`](#option-function-noncefn) | ||
- [Option: `Buffer data`](#option-buffer-data) | ||
- [`.verify(Buffer message, Buffer signature, Buffer publicKey)`](#verifybuffer-message-buffer-signature-buffer-publickey---boolean) | ||
- [`.recover(Buffer message, Buffer signature, Number recovery [, Boolean compressed = true])`](#recoverbuffer-message-buffer-signature-number-recovery--boolean-compressed--true---buffer) | ||
- [`.ecdh(Buffer publicKey, Buffer privateKey [, Object options])`](#ecdhbuffer-publickey-buffer-privatekey--object-options---buffer) | ||
- [Option: `Function hashfn`](#option-function-hashfn) | ||
#####`.secretKeyVerify(Buffer secretKey)` -> `Boolean` | ||
#####`.privateKeyVerify(Buffer privateKey)` -> `Boolean` | ||
Verify an ECDSA *secretKey*. | ||
Verify an ECDSA *privateKey*. | ||
<hr> | ||
#####`.secretKeyExport(Buffer secretKey [, Boolean compressed = true])` -> `Buffer` | ||
#####`.privateKeyExport(Buffer privateKey [, Boolean compressed = true])` -> `Buffer` | ||
Export a *secretKey* in DER format. | ||
Export a *privateKey* in DER format. | ||
<hr> | ||
#####`.secretKeyImport(Buffer secretKey)` -> `Buffer` | ||
#####`.privateKeyImport(Buffer privateKey)` -> `Buffer` | ||
Import a *secretKey* in DER format. | ||
Import a *privateKey* in DER format. | ||
<hr> | ||
#####`.secretKeyTweakAdd(Buffer secretKey, Buffer tweak)` -> `Buffer` | ||
#####`.privateKeyTweakAdd(Buffer privateKey, Buffer tweak)` -> `Buffer` | ||
Tweak a *secretKey* by adding *tweak* to it. | ||
Tweak a *privateKey* by adding *tweak* to it. | ||
<hr> | ||
#####`.secretKeyTweakMul(Buffer secretKey, Buffer tweak)` -> `Buffer` | ||
#####`.privateKeyTweakMul(Buffer privateKey, Buffer tweak)` -> `Buffer` | ||
Tweak a *secretKey* by multiplying it by a *tweak*. | ||
Tweak a *privateKey* by multiplying it by a *tweak*. | ||
<hr> | ||
#####`.publicKeyCreate(Buffer secretKey)` -> `Buffer` | ||
#####`.publicKeyCreate(Buffer privateKey [, Boolean compressed = true])` -> `Buffer` | ||
Compute the public key for a *secretKey*. | ||
Compute the public key for a *privateKey*. | ||
@@ -74,3 +73,3 @@ <hr> | ||
#####`.publicKeyTweakAdd(Buffer publicKey, Buffer tweak)` -> `Buffer` | ||
#####`.publicKeyTweakAdd(Buffer publicKey, Buffer tweak [, Boolean compressed = true])` -> `Buffer` | ||
@@ -81,3 +80,3 @@ Tweak a *publicKey* by adding *tweak* times the generator to it. | ||
#####`.publicKeyTweakMul(Buffer publicKey, Buffer tweak)` -> `Buffer` | ||
#####`.publicKeyTweakMul(Buffer publicKey, Buffer tweak [, Boolean compressed = true])` -> `Buffer` | ||
@@ -88,3 +87,3 @@ Tweak a *publicKey* by multiplying it by a *tweak* value. | ||
#####`.publicKeyCombine(Array<Buffer> publicKeys)` -> `Buffer` | ||
#####`.publicKeyCombine(Array<Buffer> publicKeys [, Boolean compressed = true])` -> `Buffer` | ||
@@ -113,27 +112,27 @@ Add a given *publicKeys* together. | ||
#####`.sign(Buffer msg, Buffer secretKey [, Function callback])` -> `Promise<{signature: Buffer, recovery: number}>` | ||
#####`.sign(Buffer message, Buffer privateKey [, Object options])` -> `{signature: Buffer, recovery: number}` | ||
Create an ECDSA signature. | ||
Create an ECDSA signature. Always return low-S signature. | ||
<hr> | ||
######Option: `Function noncefn` | ||
#####`.signSync(Buffer msg, Buffer secretKey)` -> `{signature: Buffer, recovery: number}` | ||
Nonce generator. By default it is [rfc6979](https://tools.ietf.org/html/rfc6979). | ||
Synchronous [.sign](#signbuffer-msg-buffer-secretkey--function-callback---promisesignature-buffer-recovery-number). Returns an object `{signature: Buffer, recovery: number}`. | ||
Function signature: `noncefn(Buffer message, Buffer privateKey, ?Buffer algo, ?Buffer data, Number attempt)` -> `Buffer` | ||
######Option: `Buffer data` | ||
Additional data for [noncefn](#option-function-noncefn) (RFC 6979 3.6) (32 bytes). By default is `null`. | ||
<hr> | ||
#####`.verify(Buffer msg, Buffer signature, Buffer publicKey [, Function callback])` -> `Promise<Boolean>` | ||
#####`.verify(Buffer message, Buffer signature, Buffer publicKey)` -> `Boolean` | ||
Verify an ECDSA signature. | ||
<hr> | ||
Note: **return false for high signatures!** | ||
#####`.verifySync(Buffer msg, Buffer signature, Buffer publicKey` -> `Boolean` | ||
Synchronous [.verify](#verifybuffer-msg-buffer-signature-buffer-publickey--function-callback---promiseboolean). Returns a `Boolean`. | ||
<hr> | ||
#####`.recover(Buffer msg, Buffer signature, Number recovery [, Function callback]` -> `Promise<Buffer>` | ||
#####`.recover(Buffer message, Buffer signature, Number recovery [, Boolean compressed = true]` -> `Buffer` | ||
@@ -144,16 +143,10 @@ Recover an ECDSA public key from a signature. | ||
#####`.recoverSync(Buffer msg, Buffer signature, Number recovery)` -> `Buffer` | ||
#####`.ecdh(Buffer publicKey, Buffer privateKey [, Object options])` -> `Buffer` | ||
Synchronous [.recover](#recoverbuffer-msg-buffer-signature-number-recovery--function-callback---promisebuffer). Returns an instance of `Buffer`. | ||
<hr> | ||
#####`.ecdh(Buffer publicKey, Buffer secretKey [, Function callback])` -> `Promise<Buffer>` | ||
Compute an EC Diffie-Hellman secret. | ||
<hr> | ||
######Option: `Function hashfn` | ||
#####`.ecdhSync(Buffer publicKey, Buffer secretKey)` -> `Buffer` | ||
Hash function that is applied to a point that is result of ecdh. By default it is sha256 that applied to compressed public key. | ||
Synchronous [.ecdh](#ecdhbuffer-publickey-buffer-secretkey--function-callback---promisebuffer). Returns an instance of `Buffer`. | ||
Function signature: `hashfn(Buffer x, Buffer y)` -> `Buffer` |
@@ -1,1 +0,3 @@ | ||
module.exports = require('./lib/bindings') | ||
'use strict' | ||
module.exports = require('bindings')('secp256k1') |
@@ -1,1 +0,3 @@ | ||
module.exports = require('./lib/elliptic') | ||
'use strict' | ||
module.exports = require('./lib')(require('./lib/elliptic')) |
@@ -1,1 +0,3 @@ | ||
module.exports = require('./elliptic') | ||
'use strict' | ||
module.exports = require('./lib')(require('./lib/js')) |
@@ -1,62 +0,373 @@ | ||
var setImmediate = require('timers').setImmediate | ||
var objectAssign = require('object-assign') | ||
'use strict' | ||
exports.Promise = require('../promise') | ||
var asserts = require('../asserts') | ||
var messages = require('../messages') | ||
var BN = require('bn.js') | ||
var EC = require('elliptic').ec | ||
// | ||
objectAssign(exports, require('./secretkey')) | ||
objectAssign(exports, require('./publickey')) | ||
objectAssign(exports, require('./signature')) | ||
objectAssign(exports, require('./sign')) | ||
objectAssign(exports, require('./verify')) | ||
objectAssign(exports, require('./recover')) | ||
objectAssign(exports, require('./ecdh')) | ||
var messages = require('../messages.json') | ||
// create async functions | ||
var asyncFunctions = [{ | ||
name: 'sign', | ||
argsCount: 3 | ||
}, { | ||
name: 'verify', | ||
argsCount: 4 | ||
}, { | ||
name: 'recover', | ||
argsCount: 4 | ||
}, { | ||
name: 'ecdh', | ||
argsCount: 3 | ||
}] | ||
var ec = new EC('secp256k1') | ||
var ecparams = ec.curve | ||
asyncFunctions.forEach(function (obj) { | ||
var original = exports[obj.name + 'Sync'] | ||
var argsCount = obj.argsCount | ||
/** | ||
* @param {Buffer} publicKey | ||
* @return {?KeyPair} | ||
*/ | ||
function pairFromPublicKey (publicKey) { | ||
var x | ||
var y | ||
exports[obj.name] = function () { | ||
var callback = arguments[argsCount - 1] | ||
if (callback !== undefined) { | ||
asserts.checkTypeFunction(callback, messages.CALLBACK_TYPE_INVALID) | ||
var first = publicKey[0] | ||
if (publicKey.length === 33 && (first === 0x02 || first === 0x03)) { | ||
x = new BN(publicKey.slice(1, 33)) | ||
// overflow | ||
if (x.cmp(ecparams.p) >= 0) { | ||
return null | ||
} | ||
var args = new Array(argsCount - 1) | ||
for (var i = 0; i < args.length; ++i) { | ||
args[i] = arguments[i] | ||
x = x.toRed(ecparams.red) | ||
y = x.redSqr().redIMul(x).redIAdd(ecparams.b).redSqrt() | ||
if ((first === 0x03) !== y.isOdd()) { | ||
y = y.redNeg() | ||
} | ||
} else if (publicKey.length === 65 && (first === 0x04 || first === 0x06 || first === 0x07)) { | ||
x = new BN(publicKey.slice(1, 33)) | ||
y = new BN(publicKey.slice(33, 65)) | ||
try { | ||
var value = original.apply(null, args) | ||
if (callback !== undefined) { | ||
setImmediate(callback, null, value) | ||
} | ||
// overflow | ||
if (x.cmp(ecparams.p) >= 0 || y.cmp(ecparams.p) >= 0) { | ||
return null | ||
} | ||
return exports.Promise.resolve(value) | ||
} catch (err) { | ||
if (callback !== undefined) { | ||
setImmediate(callback, err) | ||
x = x.toRed(ecparams.red) | ||
y = y.toRed(ecparams.red) | ||
// is odd flag | ||
if ((first === 0x06 || first === 0x07) && y.isOdd() !== (first === 0x07)) { | ||
return null | ||
} | ||
// x*x*x + b = y*y | ||
var x3 = x.redSqr().redIMul(x) | ||
if (!y.redSqr().redISub(x3.redIAdd(ecparams.b)).isZero()) { | ||
return null | ||
} | ||
} else { | ||
return null | ||
} | ||
return ec.keyPair({pub: {x: x, y: y}}) | ||
} | ||
/** | ||
* @param {Buffer} privateKey | ||
* @return {boolean} | ||
*/ | ||
exports.privateKeyVerify = function (privateKey) { | ||
var bn = new BN(privateKey) | ||
return !(bn.cmp(ecparams.n) >= 0 || bn.isZero()) | ||
} | ||
/** | ||
* @param {Buffer} privateKey | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.privateKeyExport = function (privateKey, compressed) { | ||
var d = new BN(privateKey) | ||
if (d.cmp(ecparams.n) >= 0 || d.isZero()) { | ||
throw new Error(messages.EC_PRIVATE_KEY_EXPORT_DER_FAIL) | ||
} | ||
return new Buffer(ec.keyFromPrivate(privateKey).getPublic(compressed, true)) | ||
} | ||
/** | ||
* @param {Buffer} privateKey | ||
* @param {Buffer} tweak | ||
* @return {Buffer} | ||
*/ | ||
exports.privateKeyTweakAdd = function (privateKey, tweak) { | ||
var bn = new BN(tweak) | ||
if (bn.cmp(ecparams.n) >= 0) { | ||
throw new Error(messages.EC_PRIVATE_KEY_TWEAK_ADD_FAIL) | ||
} | ||
bn.iadd(new BN(privateKey)) | ||
if (bn.cmp(ecparams.n) >= 0) { | ||
bn.isub(ecparams.n) | ||
} | ||
if (bn.isZero()) { | ||
throw new Error(messages.EC_PRIVATE_KEY_TWEAK_ADD_FAIL) | ||
} | ||
return bn.toArrayLike(Buffer, null, 32) | ||
} | ||
/** | ||
* @param {Buffer} privateKey | ||
* @param {Buffer} tweak | ||
* @return {Buffer} | ||
*/ | ||
exports.privateKeyTweakMul = function (privateKey, tweak) { | ||
var bn = new BN(tweak) | ||
if (bn.cmp(ecparams.n) >= 0 || bn.isZero()) { | ||
throw new Error(messages.EC_PRIVATE_KEY_TWEAK_MUL_FAIL) | ||
} | ||
bn.imul(new BN(privateKey)) | ||
if (bn.cmp(ecparams.n)) { | ||
bn = bn.umod(ecparams.n) | ||
} | ||
return bn.toArrayLike(Buffer, null, 32) | ||
} | ||
/** | ||
* @param {Buffer} privateKey | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.publicKeyCreate = function (privateKey, compressed) { | ||
var d = new BN(privateKey) | ||
if (d.cmp(ecparams.n) >= 0 || d.isZero()) { | ||
throw new Error(messages.EC_PUBLIC_KEY_CREATE_FAIL) | ||
} | ||
return new Buffer(ec.keyFromPrivate(privateKey).getPublic(compressed, true)) | ||
} | ||
/** | ||
* @param {Buffer} publicKey | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.publicKeyConvert = function (publicKey, compressed) { | ||
var pair = pairFromPublicKey(publicKey) | ||
if (pair === null) { | ||
throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL) | ||
} | ||
return new Buffer(pair.getPublic(compressed, true)) | ||
} | ||
/** | ||
* @param {Buffer} publicKey | ||
* @return {boolean} | ||
*/ | ||
exports.publicKeyVerify = function (publicKey) { | ||
return pairFromPublicKey(publicKey) !== null | ||
} | ||
/** | ||
* @param {Buffer} publicKey | ||
* @param {Buffer} tweak | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.publicKeyTweakAdd = function (publicKey, tweak, compressed) { | ||
var pair = pairFromPublicKey(publicKey) | ||
if (pair === null) { | ||
throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL) | ||
} | ||
tweak = new BN(tweak) | ||
if (tweak.cmp(ecparams.n) >= 0) { | ||
throw new Error(messages.EC_PUBLIC_KEY_TWEAK_ADD_FAIL) | ||
} | ||
return new Buffer(ecparams.g.mul(tweak).add(pair.pub).encode(true, compressed)) | ||
} | ||
/** | ||
* @param {Buffer} publicKey | ||
* @param {Buffer} tweak | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.publicKeyTweakMul = function (publicKey, tweak, compressed) { | ||
var pair = pairFromPublicKey(publicKey) | ||
if (pair === null) { | ||
throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL) | ||
} | ||
tweak = new BN(tweak) | ||
if (tweak.cmp(ecparams.n) >= 0 || tweak.isZero()) { | ||
throw new Error(messages.EC_PUBLIC_KEY_TWEAK_MUL_FAIL) | ||
} | ||
return new Buffer(pair.pub.mul(tweak).encode(true, compressed)) | ||
} | ||
/** | ||
* @param {Buffer[]} publicKeys | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.publicKeyCombine = function (publicKeys, compressed) { | ||
var pairs = new Array(publicKeys.length) | ||
for (var i = 0; i < publicKeys.length; ++i) { | ||
pairs[i] = pairFromPublicKey(publicKeys[i]) | ||
if (pairs[i] === null) { | ||
throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL) | ||
} | ||
} | ||
var point = pairs[0].pub | ||
for (var j = 1; j < pairs.length; ++j) { | ||
point = point.add(pairs[j].pub) | ||
} | ||
if (point.isInfinity()) { | ||
throw new Error(messages.EC_PUBLIC_KEY_COMBINE_FAIL) | ||
} | ||
return new Buffer(point.encode(true, compressed)) | ||
} | ||
/** | ||
* @param {Buffer} signature | ||
* @return {Buffer} | ||
*/ | ||
exports.signatureNormalize = function (signature) { | ||
var r = new BN(signature.slice(0, 32)) | ||
var s = new BN(signature.slice(32, 64)) | ||
if (r.cmp(ecparams.n) >= 0 || s.cmp(ecparams.n) >= 0) { | ||
throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL) | ||
} | ||
var result = new Buffer(signature) | ||
if (s.cmp(ec.nh) === 1) { | ||
new Buffer(ecparams.n.sub(s).toArray(null, 32)).copy(result, 32) | ||
} | ||
return result | ||
} | ||
/** | ||
* @param {Buffer} signature | ||
* @return {{r: Buffer, s: Buffer}} | ||
*/ | ||
exports.signatureExport = function (signature) { | ||
var r = signature.slice(0, 32) | ||
var s = signature.slice(32, 64) | ||
if (new BN(r).cmp(ecparams.n) >= 0 || new BN(s).cmp(ecparams.n) >= 0) { | ||
throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL) | ||
} | ||
return {r: r, s: s} | ||
} | ||
/** | ||
* @param {{r: Buffer, s: Buffer}} sigObj | ||
* @return {Buffer} | ||
*/ | ||
exports.signatureImport = function (sigObj) { | ||
var r = new BN(sigObj.r) | ||
if (r.cmp(ecparams.n) >= 0) { | ||
r = new BN(0) | ||
} | ||
var s = new BN(sigObj.s) | ||
if (s.cmp(ecparams.n) >= 0) { | ||
s = new BN(0) | ||
} | ||
return new Buffer(r.toArray(null, 32).concat(s.toArray(null, 32))) | ||
} | ||
/** | ||
* @param {Buffer} message | ||
* @param {Buffer} privateKey | ||
* @param {?sign~noncefn} noncefn | ||
* @param {?Buffer} data | ||
* @return {{signature: Buffer, recovery: number}} | ||
*/ | ||
exports.sign = function (message, privateKey, noncefn, data) { | ||
if (typeof noncefn === 'function') { | ||
var getNonce = noncefn | ||
noncefn = function (counter) { | ||
var nonce = getNonce(message, privateKey, null, data, counter) | ||
if (!Buffer.isBuffer(nonce) || nonce.length !== 32) { | ||
throw new Error(messages.ECDSA_SIGN_FAIL) | ||
} | ||
return exports.Promise.reject(err) | ||
return new BN(nonce) | ||
} | ||
} | ||
}) | ||
var d = new BN(privateKey) | ||
if (d.cmp(ecparams.n) >= 0 || d.isZero()) { | ||
throw new Error(messages.ECDSA_SIGN_FAIL) | ||
} | ||
var result = ec.sign(message, privateKey, {canonical: true, k: noncefn, pers: data}) | ||
return { | ||
signature: new Buffer(result.r.toArray(null, 32).concat(result.s.toArray(null, 32))), | ||
recovery: result.recoveryParam | ||
} | ||
} | ||
/** | ||
* @param {Buffer} message | ||
* @param {Buffer} signature | ||
* @param {Buffer} publicKey | ||
* @return {boolean} | ||
*/ | ||
exports.verify = function (message, signature, publicKey) { | ||
var sigObj = {r: signature.slice(0, 32), s: signature.slice(32, 64)} | ||
var sigr = new BN(sigObj.r) | ||
var sigs = new BN(sigObj.s) | ||
if (sigr.cmp(ecparams.n) >= 0 || sigs.cmp(ecparams.n) >= 0) { | ||
throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL) | ||
} | ||
if (sigs.cmp(ec.nh) === 1 || sigr.isZero() || sigs.isZero()) { | ||
return false | ||
} | ||
var pair = pairFromPublicKey(publicKey) | ||
if (pair === null) { | ||
throw new Error(messages.EC_PUBLIC_KEY_PARSE_FAIL) | ||
} | ||
return ec.verify(message, sigObj, {x: pair.pub.x, y: pair.pub.y}) | ||
} | ||
/** | ||
* @param {Buffer} message | ||
* @param {Buffer} signature | ||
* @param {number} recovery | ||
* @param {boolean} compressed | ||
* @return {Buffer} | ||
*/ | ||
exports.recover = function (message, signature, recovery, compressed) { | ||
var sigObj = {r: signature.slice(0, 32), s: signature.slice(32, 64)} | ||
var sigr = new BN(sigObj.r) | ||
var sigs = new BN(sigObj.s) | ||
if (sigr.cmp(ecparams.n) >= 0 || sigs.cmp(ecparams.n) >= 0) { | ||
throw new Error(messages.ECDSA_SIGNATURE_PARSE_FAIL) | ||
} | ||
try { | ||
if (sigr.isZero() || sigs.isZero()) { | ||
throw new Error() | ||
} | ||
var point = ec.recoverPubKey(message, sigObj, recovery) | ||
return new Buffer(point.encode(true, compressed)) | ||
} catch (err) { | ||
throw new Error(messages.ECDSA_RECOVER_FAIL) | ||
} | ||
} | ||
/** | ||
* @param {Buffer} publicKey | ||
* @param {Buffer} privateKey | ||
* @return {Buffer} | ||
*/ | ||
exports.ecdh = function (publicKey, privateKey) { | ||
} |
{ | ||
"name": "secp256k1", | ||
"version": "2.0.10", | ||
"version": "3.0.0", | ||
"description": "This module provides native bindings to ecdsa secp256k1 functions", | ||
"keywords": [ | ||
"secp256k1", | ||
"ec", | ||
"ecdh", | ||
"ecdsa", | ||
"ec" | ||
"secp256k1" | ||
], | ||
@@ -14,6 +15,3 @@ "bugs": { | ||
"license": "MIT", | ||
"author": { | ||
"name": "martin becze", | ||
"email": "mjbecze@gmail.com" | ||
}, | ||
"author": "Martin Becze <mjbecze@gmail.com>", | ||
"contributors": [ | ||
@@ -29,3 +27,2 @@ "Aaron Davis (https://github.com/kumavis)", | ||
"src", | ||
"utils", | ||
"API.md", | ||
@@ -37,3 +34,5 @@ "binding.gyp", | ||
"package.json", | ||
"README.md" | ||
"LICENSE", | ||
"README.md", | ||
"utils/has_lib.sh" | ||
], | ||
@@ -48,4 +47,2 @@ "main": "./bindings.js", | ||
"clean": "node-gyp clean", | ||
"coverage": "istanbul cover _mocha", | ||
"coveralls": "npm run coverage && coveralls <coverage/lcov.info", | ||
"install": "npm run rebuild", | ||
@@ -57,18 +54,15 @@ "lint": "standard", | ||
"test:browser": "karma start karma.conf.js", | ||
"test:node": "istanbul test _mocha -- --reporter spec" | ||
"test:node": "istanbul test _mocha -- --reporter spec test/index.js" | ||
}, | ||
"dependencies": { | ||
"bindings": "^1.2.1", | ||
"bluebird": "^3.0.2", | ||
"bn.js": "^4.6.4", | ||
"elliptic": "^6.0.2", | ||
"nan": "^2.0.9", | ||
"object-assign": "^4.0.1" | ||
"bn.js": "^4.10.0", | ||
"elliptic": "^6.2.3", | ||
"nan": "^2.2.0" | ||
}, | ||
"devDependencies": { | ||
"benchmark": "^1.0.0", | ||
"benchmark": "^2.0.0", | ||
"bigi": "^1.3.0", | ||
"bignum": "^0.11.0", | ||
"chai": "^3.4.0", | ||
"chai-as-promised": "^5.1.0", | ||
"coveralls": "^2.11.4", | ||
"ecdsa": "^0.6.0", | ||
@@ -90,5 +84,8 @@ "eckey": "^0.8.0", | ||
}, | ||
"engines": { | ||
"node": ">=0.10" | ||
}, | ||
"gypfile": true, | ||
"browser": { | ||
"./bindings.js": "./js.js" | ||
"./bindings.js": "./elliptic.js" | ||
}, | ||
@@ -98,2 +95,3 @@ "standard": { | ||
"describe", | ||
"before", | ||
"it" | ||
@@ -100,0 +98,0 @@ ] |
@@ -5,3 +5,3 @@ # secp256k1-node | ||
[![Build Status](https://img.shields.io/travis/cryptocoinjs/secp256k1-node.svg?branch=master&style=flat-square)](https://travis-ci.org/cryptocoinjs/secp256k1-node) | ||
[![Coverage Status](https://img.shields.io/coveralls/cryptocoinjs/secp256k1-node.svg?style=flat-square)](https://coveralls.io/r/cryptocoinjs/secp256k1-node) | ||
[![Dependency status](https://img.shields.io/david/cryptocoinjs/secp256k1-node.svg?style=flat-square)](https://david-dm.org/cryptocoinjs/secp256k1-node#info=dependencies) | ||
@@ -13,5 +13,5 @@ [![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard) | ||
# Installation | ||
## Installation | ||
If you have gmp installed secp256k1 will use it. Otherwise it should fallback to openssl. | ||
If you have [gmp](https://gmplib.org/) installed [secp256k1](https://github.com/bitcoin/secp256k1) will use it. Otherwise it should fallback to [OpenSSL](https://www.openssl.org/). | ||
* arch `pacman -S gmp` | ||
@@ -32,5 +32,5 @@ * ubuntu `sudo apt-get install libgmp-dev` | ||
# Usage | ||
## Usage | ||
* [API Reference (v2.x)](API.md) | ||
* [API Reference (v3.x)](API.md) | ||
@@ -41,5 +41,3 @@ ```js | ||
// or require('secp256k1/js') | ||
// if you want to use pure js implementation in node (uses elliptic now) | ||
// or require('secp256k1/elliptic') | ||
// if implementation that uses elliptic package | ||
// if you want to use pure js implementation in node | ||
@@ -53,3 +51,3 @@ // generate message to sign | ||
privKey = crypto.randomBytes(32) | ||
} while (!secp256k1.secretKeyVerify(privKey)) | ||
} while (!secp256k1.privateKeyVerify(privKey)) | ||
@@ -60,10 +58,59 @@ // get the public key in a compressed format | ||
// sign the message | ||
var sigObj = secp256k1.signSync(msg, privKey) | ||
var sigObj = secp256k1.sign(msg, privKey) | ||
// verify the signature | ||
console.log(secp256k1.verifySync(msg, sigObj.signature, pubKey)) | ||
console.log(secp256k1.verify(msg, sigObj.signature, pubKey)) | ||
``` | ||
# LICENSE | ||
\* **.verify return false for high signatures** | ||
\* ECDH is not be available while [bitcoin/secp256k1#352](https://github.com/bitcoin/secp256k1/issues/352) not resolved. Right now you can use next code: | ||
```js | ||
var BN = require('secp256k1/lib/js/bn') | ||
var ECPoint = require('secp256k1/lib/js/ecpoint') | ||
var d = BN.fromBuffer(privateKey) | ||
var Q = ECPoint.fromPublicKey(publicKey) | ||
return Q.mul(d).toPublicKey(true) | ||
``` | ||
## Elliptic vs "embedded" | ||
secp256k1-node has pure JavaScript implementation secp256k1 based on [elliptic](http://github.com/indutny/elliptic), [bn.js](http://github.com/indutny/bn.js), [hash.js](http://github.com/indutny/hash.js). | ||
The main purpose of this implementation is more [high performance](#performance), [smaller size](#code-size) and simple code audit. | ||
##### Code size: | ||
| | browserifiable | + uglified | + gzipped | | ||
|:------:|:--------------:|:----------:|:---------:| | ||
|elliptic|303555 |211777 |62124 | | ||
|embedded|129498 |88958 |20188 | | ||
##### Performance: | ||
``` | ||
$ node benchmark/benchmark.js | ||
Set seed: 5120779d9d961dc818363811b3cf44ace2323ccf5e265749206d37442a0deac5 | ||
100% (1000/1000), 2.8s elapsed, eta 0.0s | ||
Create 1000 fixtures | ||
++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
Benchmarking: publicKeyCreate | ||
-------------------------------------------------- | ||
bindings x 13,945 ops/sec ±0.76% (101 runs sampled) | ||
secp256k1js x 967 ops/sec ±0.41% (100 runs sampled) | ||
elliptic x 838 ops/sec ±0.66% (99 runs sampled) | ||
================================================== | ||
Benchmarking: sign | ||
-------------------------------------------------- | ||
bindings x 8,219 ops/sec ±0.13% (102 runs sampled) | ||
secp256k1js x 773 ops/sec ±0.47% (98 runs sampled) | ||
elliptic x 615 ops/sec ±0.43% (97 runs sampled) | ||
================================================== | ||
Benchmarking: verify | ||
-------------------------------------------------- | ||
bindings x 5,350 ops/sec ±0.11% (103 runs sampled) | ||
secp256k1js x 208 ops/sec ±0.19% (91 runs sampled) | ||
elliptic x 131 ops/sec ±2.05% (87 runs sampled) | ||
================================================== | ||
``` | ||
## LICENSE | ||
This library is free and open-source software released under the MIT license. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
827741
4
19
3175
111
117
2
- Removedbluebird@^3.0.2
- Removedobject-assign@^4.0.1
- Removedbluebird@3.7.2(transitive)
- Removedobject-assign@4.1.1(transitive)
Updatedbn.js@^4.10.0
Updatedelliptic@^6.2.3
Updatednan@^2.2.0