var assert = require('assert') var crypto = require('crypto') var ecurve = require('ecurve') var networks = require('../src/networks') var sinon = require('sinon') var BigInteger = require('bigi') var ECKey = require('../src/eckey') var fixtures = require('./fixtures/eckey.json') describe('ECKey', function() { describe('constructor', function() { it('defaults to compressed', function() { var privKey = new ECKey(BigInteger.ONE) assert.equal(privKey.pub.compressed, true) }) it('supports the uncompressed flag', function() { var privKey = new ECKey(BigInteger.ONE, false) assert.equal(privKey.pub.compressed, false) }) fixtures.valid.forEach(function(f) { it('calculates the matching pubKey for ' + f.d, function() { var d = new BigInteger(f.d) var privKey = new ECKey(d) assert.equal(privKey.pub.Q.toString(), f.Q) }) }) fixtures.invalid.constructor.forEach(function(f) { it('throws on ' + f.d, function() { var d = new BigInteger(f.d) assert.throws(function() { new ECKey(d) }, new RegExp(f.exception)) }) }) }) it('uses the secp256k1 curve by default', function() { 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) } }) describe('fromWIF', function() { fixtures.valid.forEach(function(f) { f.WIFs.forEach(function(wif) { it('imports ' + wif.string + ' correctly', function() { var privKey = ECKey.fromWIF(wif.string) assert.equal(privKey.d.toString(), f.d) assert.equal(privKey.pub.compressed, wif.compressed) }) }) }) fixtures.invalid.WIF.forEach(function(f) { it('throws on ' + f.string, function() { assert.throws(function() { ECKey.fromWIF(f.string) }, new RegExp(f.exception)) }) }) }) describe('toWIF', function() { fixtures.valid.forEach(function(f) { f.WIFs.forEach(function(wif) { it('exports ' + wif.string + ' correctly', function() { var privKey = ECKey.fromWIF(wif.string) var network = networks[wif.network] var result = privKey.toWIF(network) assert.equal(result, wif.string) }) }) }) }) describe('makeRandom', function() { var exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv' var exPrivKey = ECKey.fromWIF(exWIF) var exBuffer = exPrivKey.d.toBuffer(32) describe('uses default crypto RNG', function() { beforeEach(function() { sinon.stub(crypto, 'randomBytes').returns(exBuffer) }) afterEach(function() { crypto.randomBytes.restore() }) it('generates a ECKey', function() { var privKey = ECKey.makeRandom() assert.equal(privKey.toWIF(), exWIF) }) it('supports compression', function() { assert.equal(ECKey.makeRandom(true).pub.compressed, true) assert.equal(ECKey.makeRandom(false).pub.compressed, false) }) }) it('allows a custom RNG to be used', function() { function rng(size) { return exBuffer.slice(0, size) } var privKey = ECKey.makeRandom(undefined, rng) assert.equal(privKey.toWIF(), exWIF) }) }) describe('signing', function() { var hash = crypto.randomBytes(32) var priv = ECKey.makeRandom() var signature = priv.sign(hash) it('should verify against the public key', function() { assert(priv.pub.verify(hash, signature)) }) it('should not verify against the wrong public key', function() { var priv2 = ECKey.makeRandom() assert(!priv2.pub.verify(hash, signature)) }) }) })