2015-02-23 00:36:57 +01:00
|
|
|
/* global describe, it, beforeEach, afterEach */
|
|
|
|
/* eslint-disable no-new */
|
|
|
|
|
2014-03-31 05:47:47 +02:00
|
|
|
var assert = require('assert')
|
2014-07-28 05:46:34 +02:00
|
|
|
var crypto = require('crypto')
|
2014-10-15 16:25:39 +02:00
|
|
|
var ecurve = require('ecurve')
|
2014-06-03 13:43:10 +02:00
|
|
|
var networks = require('../src/networks')
|
2014-06-23 10:22:01 +02:00
|
|
|
var sinon = require('sinon')
|
|
|
|
|
2014-05-16 05:46:06 +02:00
|
|
|
var BigInteger = require('bigi')
|
2014-05-13 09:55:53 +02:00
|
|
|
var ECKey = require('../src/eckey')
|
2014-05-16 05:46:06 +02:00
|
|
|
|
2014-05-18 11:47:39 +02:00
|
|
|
var fixtures = require('./fixtures/eckey.json')
|
2014-01-11 07:57:43 +01:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
describe('ECKey', function () {
|
|
|
|
describe('constructor', function () {
|
|
|
|
it('defaults to compressed', function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
var privKey = new ECKey(BigInteger.ONE)
|
|
|
|
|
|
|
|
assert.equal(privKey.pub.compressed, true)
|
2014-03-22 08:19:56 +01:00
|
|
|
})
|
2014-02-24 17:31:18 +01:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('supports the uncompressed flag', function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
var privKey = new ECKey(BigInteger.ONE, false)
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2014-05-16 05:46:06 +02:00
|
|
|
assert.equal(privKey.pub.compressed, false)
|
2014-03-24 17:48:50 +01:00
|
|
|
})
|
2014-03-24 23:11:34 +01:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
fixtures.valid.forEach(function (f) {
|
|
|
|
it('calculates the matching pubKey for ' + f.d, function () {
|
2014-06-07 10:24:16 +02:00
|
|
|
var d = new BigInteger(f.d)
|
|
|
|
var privKey = new ECKey(d)
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2014-06-21 09:05:12 +02:00
|
|
|
assert.equal(privKey.pub.Q.toString(), f.Q)
|
2014-05-16 05:46:06 +02:00
|
|
|
})
|
2014-03-31 05:47:47 +02:00
|
|
|
})
|
2014-03-24 17:31:55 +01:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
fixtures.invalid.constructor.forEach(function (f) {
|
|
|
|
it('throws on ' + f.d, function () {
|
2014-06-07 10:24:16 +02:00
|
|
|
var d = new BigInteger(f.d)
|
2014-05-31 03:28:00 +02:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
assert.throws(function () {
|
2014-06-07 10:24:16 +02:00
|
|
|
new ECKey(d)
|
2014-05-29 08:00:27 +02:00
|
|
|
}, new RegExp(f.exception))
|
2014-05-16 05:46:06 +02:00
|
|
|
})
|
2014-03-31 05:47:47 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('uses the secp256k1 curve by default', function () {
|
2014-10-15 16:25:39 +02:00
|
|
|
var secp256k1 = ecurve.getCurveByName('secp256k1')
|
|
|
|
|
|
|
|
for (var property in secp256k1) {
|
|
|
|
// FIXME: circular structures in ecurve
|
|
|
|
if (property === 'G') continue
|
|
|
|
if (property === 'infinity') continue
|
|
|
|
|
|
|
|
var actual = ECKey.curve[property]
|
|
|
|
var expected = secp256k1[property]
|
|
|
|
|
|
|
|
assert.deepEqual(actual, expected)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
describe('fromWIF', function () {
|
|
|
|
fixtures.valid.forEach(function (f) {
|
|
|
|
f.WIFs.forEach(function (wif) {
|
|
|
|
it('imports ' + wif.string + ' correctly', function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
var privKey = ECKey.fromWIF(wif.string)
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2014-06-07 10:24:16 +02:00
|
|
|
assert.equal(privKey.d.toString(), f.d)
|
2014-05-16 05:46:06 +02:00
|
|
|
assert.equal(privKey.pub.compressed, wif.compressed)
|
|
|
|
})
|
|
|
|
})
|
2014-03-31 05:47:47 +02:00
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
fixtures.invalid.WIF.forEach(function (f) {
|
|
|
|
it('throws on ' + f.string, function () {
|
|
|
|
assert.throws(function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
ECKey.fromWIF(f.string)
|
2014-05-29 08:00:27 +02:00
|
|
|
}, new RegExp(f.exception))
|
2014-05-16 05:46:06 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
describe('toWIF', function () {
|
|
|
|
fixtures.valid.forEach(function (f) {
|
|
|
|
f.WIFs.forEach(function (wif) {
|
|
|
|
it('exports ' + wif.string + ' correctly', function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
var privKey = ECKey.fromWIF(wif.string)
|
2014-06-03 13:43:10 +02:00
|
|
|
var network = networks[wif.network]
|
|
|
|
var result = privKey.toWIF(network)
|
2014-05-16 05:46:06 +02:00
|
|
|
|
|
|
|
assert.equal(result, wif.string)
|
|
|
|
})
|
|
|
|
})
|
2014-03-31 05:47:47 +02:00
|
|
|
})
|
2014-05-16 05:46:06 +02:00
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
describe('makeRandom', function () {
|
2014-06-23 10:22:01 +02:00
|
|
|
var exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv'
|
|
|
|
var exPrivKey = ECKey.fromWIF(exWIF)
|
|
|
|
var exBuffer = exPrivKey.d.toBuffer(32)
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
describe('uses default crypto RNG', function () {
|
|
|
|
beforeEach(function () {
|
2014-07-28 05:46:34 +02:00
|
|
|
sinon.stub(crypto, 'randomBytes').returns(exBuffer)
|
2014-06-23 10:22:01 +02:00
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
afterEach(function () {
|
2014-07-28 05:46:34 +02:00
|
|
|
crypto.randomBytes.restore()
|
2014-06-23 10:22:01 +02:00
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('generates a ECKey', function () {
|
2014-06-23 10:22:01 +02:00
|
|
|
var privKey = ECKey.makeRandom()
|
|
|
|
|
|
|
|
assert.equal(privKey.toWIF(), exWIF)
|
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('supports compression', function () {
|
2014-06-23 10:22:01 +02:00
|
|
|
assert.equal(ECKey.makeRandom(true).pub.compressed, true)
|
|
|
|
assert.equal(ECKey.makeRandom(false).pub.compressed, false)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('allows a custom RNG to be used', function () {
|
|
|
|
function rng (size) {
|
2014-06-23 10:22:01 +02:00
|
|
|
return exBuffer.slice(0, size)
|
|
|
|
}
|
|
|
|
|
|
|
|
var privKey = ECKey.makeRandom(undefined, rng)
|
|
|
|
assert.equal(privKey.toWIF(), exWIF)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
describe('signing', function () {
|
2014-07-28 17:01:11 +02:00
|
|
|
var hash = crypto.randomBytes(32)
|
2014-05-16 05:46:06 +02:00
|
|
|
var priv = ECKey.makeRandom()
|
|
|
|
var signature = priv.sign(hash)
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('should verify against the public key', function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
assert(priv.pub.verify(hash, signature))
|
|
|
|
})
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2015-02-23 00:36:57 +01:00
|
|
|
it('should not verify against the wrong public key', function () {
|
2014-05-16 05:46:06 +02:00
|
|
|
var priv2 = ECKey.makeRandom()
|
2014-03-31 05:47:47 +02:00
|
|
|
|
2014-04-23 23:45:28 +02:00
|
|
|
assert(!priv2.pub.verify(hash, signature))
|
2014-03-31 05:47:47 +02:00
|
|
|
})
|
|
|
|
})
|
2014-01-11 07:57:43 +01:00
|
|
|
})
|