Skip to content

Commit

Permalink
Merge pull request #52 from fanatid/benchmark
Browse files Browse the repository at this point in the history
Add benchmark (solve #42)
  • Loading branch information
wanderer committed Nov 19, 2015
2 parents 14e5661 + fa13061 commit 6871458
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 0 deletions.
76 changes: 76 additions & 0 deletions benchmark/benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
var benchmark = require('benchmark')

var bindings = require('../bindings')
var elliptic = require('../elliptic')

var ecdsa = require('./ecdsa')
var util = require('./util')

function createSuite (suiteName, objs) {
var suite = new benchmark.Suite(suiteName, {
onStart: function () {
console.log('Benchmarking: ' + suiteName)
console.log('--------------------------------------------------')
},
onCycle: function (event) {
console.log(String(event.target))
},
onError: function (event) {
console.error(event.target.error)
},
onComplete: function () {
console.log('--------------------------------------------------')
console.log('Fastest is ' + this.filter('fastest').pluck('name'))
console.log('==================================================')
}
})

Object.keys(objs).forEach(function (fnName) {
var obj = objs[fnName]
suite.add(fnName, obj.fn, obj.options)
})

return suite
}

var message = util.getMessage()
var pair = util.generateKeyPair()
var signature = util.createSignature(message, pair.privateKey)

// sign
createSuite('sign', {
bindings: {
fn: function () {
bindings.signSync(message, pair.privateKey)
}
},
elliptic: {
fn: function () {
elliptic.signSync(message, pair.privateKey)
}
},
ecdsa: {
fn: function () {
ecdsa.signSync(message, pair.privateKey)
}
}
}).run()

// verify
createSuite('verify', {
bindings: {
fn: function () {
bindings.verifySync(message, signature, pair.publicKey)
}
},
elliptic: {
fn: function () {
elliptic.verifySync(message, signature, pair.publicKey)
}
},
ecdsa: {
fn: function () {
ecdsa.verifySync(message, signature, pair.publicKey)
}
}
}).run()
66 changes: 66 additions & 0 deletions benchmark/ecdsa.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var assert = require('assert')
var BigInteger = require('bigi')
var ecdsa = require('ecdsa')
var ecurve = require('ecurve')

var ecparams = ecurve.getCurveByName('secp256k1')
ecparams.nH = ecparams.n.shiftRight(1)

/**
* @param {Buffer} message
* @param {Buffer} privateKey
* @return {{signature: string, recovery: number}}
*/
exports.signSync = function (message, privateKey) {
var D = BigInteger.fromBuffer(privateKey)
var k = ecdsa.deterministicGenerateK(message, D)
var Q = ecparams.G.multiply(k)
var e = BigInteger.fromBuffer(message)

var r = Q.affineX.mod(ecparams.n)
assert.notEqual(r.signum(), 0, 'Invalid R value')

var s = k.modInverse(ecparams.n).multiply(e.add(D.multiply(r))).mod(ecparams.n)
assert.notEqual(s.signum(), 0, 'Invalid S value')

if (s.compareTo(ecparams.nH) > 0) {
s = ecparams.n.subtract(s)
}

return {
signature: Buffer.concat([r.toBuffer(32), s.toBuffer(32)]),
recovery: null // TODO
}
}

/**
* @param {Buffer} message
* @param {Buffer} signature
* @param {Buffer} publicKey
* @return {boolean}
*/
exports.verifySync = function (message, signature, publicKey) {
var e = BigInteger.fromBuffer(message)
var r = BigInteger.fromBuffer(signature.slice(0, 32))
var s = BigInteger.fromBuffer(signature.slice(32, 64))
var Q = ecurve.Point.decodeFrom(ecparams, publicKey)

if (r.signum() <= 0 ||
r.compareTo(ecparams.n) >= 0 ||
s.signum() <= 0 ||
s.compareTo(ecparams.n) >= 0) {
return false
}

var c = s.modInverse(ecparams.n)
var u1 = e.multiply(c).mod(ecparams.n)
var u2 = r.multiply(c).mod(ecparams.n)
var R = ecparams.G.multiplyTwo(u1, Q, u2)
var v = R.affineX.mod(ecparams.n)

if (ecparams.isInfinity(R)) {
return false
}

return v.equals(r)
}
41 changes: 41 additions & 0 deletions benchmark/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
var getRandomBytes = require('crypto').randomBytes
var BN = require('bn.js')
var ECKey = require('eckey')

var secp256k1 = require('../js')

var ZERO = new BN(0)
var N = new BN('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex')

/**
* @return {Buffer}
*/
exports.generateKeyPair = function () {
while (true) {
var privateKey = getRandomBytes(32)
var bn = new BN(privateKey)
if (bn.cmp(ZERO) !== 0 && bn.cmp(N) < 0) {
var eckey = new ECKey(privateKey)
return {
privateKey: privateKey,
publicKey: eckey.publicKey
}
}
}
}

/**
* @return {Buffer}
*/
exports.getMessage = function () {
return getRandomBytes(32)
}

/**
* @param {Buffer} message
* @param {Buffer} privateKey
* @return {Buffer}
*/
exports.createSignature = function (message, privateKey) {
return secp256k1.signSync(message, privateKey).signature
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"url": "https://github.com/cryptocoinjs/secp256k1-node.git"
},
"scripts": {
"benchmark:node": "node benchmark/benchmark.js",
"clean": "node-gyp clean",
"coverage": "istanbul cover _mocha",
"coveralls": "npm run coverage && coveralls <coverage/lcov.info",
Expand All @@ -60,6 +61,7 @@
"object-assign": "^4.0.1"
},
"devDependencies": {
"benchmark": "^1.0.0",
"bigi": "^1.3.0",
"chai": "^3.4.0",
"chai-as-promised": "^5.1.0",
Expand Down

0 comments on commit 6871458

Please sign in to comment.