Daniel Cousens
10 years ago
20 changed files with 266 additions and 670 deletions
@ -1,143 +0,0 @@ |
|||
/* global describe, it */ |
|||
/* eslint-disable no-new */ |
|||
|
|||
var assert = require('assert') |
|||
var ecurve = require('ecurve') |
|||
var networks = require('../src/networks') |
|||
var proxyquire = require('proxyquire') |
|||
var randomBytes = require('randombytes') |
|||
|
|||
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) |
|||
|
|||
it("uses the RNG provided by the 'randombytes' module by default", function () { |
|||
var stub = { randombytes: function () { return exBuffer } } |
|||
var ProxiedECKey = proxyquire('../src/eckey', stub) |
|||
|
|||
var privKey = ProxiedECKey.makeRandom() |
|||
|
|||
assert.equal(privKey.toWIF(), exWIF) |
|||
}) |
|||
|
|||
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) |
|||
}) |
|||
|
|||
it('supports compression', function () { |
|||
assert.equal(ECKey.makeRandom(true).pub.compressed, true) |
|||
assert.equal(ECKey.makeRandom(false).pub.compressed, false) |
|||
}) |
|||
}) |
|||
|
|||
describe('signing', function () { |
|||
var hash = 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)) |
|||
}) |
|||
}) |
|||
}) |
@ -1,120 +0,0 @@ |
|||
/* global describe, it, beforeEach */ |
|||
|
|||
var assert = require('assert') |
|||
var crypto = require('../src/crypto') |
|||
var networks = require('../src/networks') |
|||
|
|||
var BigInteger = require('bigi') |
|||
var ECPubKey = require('../src/ecpubkey') |
|||
|
|||
var ecurve = require('ecurve') |
|||
var curve = ecurve.getCurveByName('secp256k1') |
|||
|
|||
var fixtures = require('./fixtures/ecpubkey.json') |
|||
|
|||
describe('ECPubKey', function () { |
|||
var Q |
|||
|
|||
beforeEach(function () { |
|||
Q = ecurve.Point.fromAffine( |
|||
curve, |
|||
new BigInteger(fixtures.Q.x), |
|||
new BigInteger(fixtures.Q.y) |
|||
) |
|||
}) |
|||
|
|||
describe('constructor', function () { |
|||
it('defaults to compressed', function () { |
|||
var pubKey = new ECPubKey(Q) |
|||
|
|||
assert.equal(pubKey.compressed, true) |
|||
}) |
|||
|
|||
it('supports the uncompressed flag', function () { |
|||
var pubKey = new ECPubKey(Q, false) |
|||
|
|||
assert.equal(pubKey.compressed, false) |
|||
}) |
|||
}) |
|||
|
|||
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 = ECPubKey.curve[property] |
|||
var expected = secp256k1[property] |
|||
|
|||
assert.deepEqual(actual, expected) |
|||
} |
|||
}) |
|||
|
|||
describe('fromHex/toHex', function () { |
|||
it('supports compressed points', function () { |
|||
var pubKey = ECPubKey.fromHex(fixtures.compressed.hex) |
|||
|
|||
assert(pubKey.Q.equals(Q)) |
|||
assert.equal(pubKey.toHex(), fixtures.compressed.hex) |
|||
assert.equal(pubKey.compressed, true) |
|||
}) |
|||
|
|||
it('supports uncompressed points', function () { |
|||
var pubKey = ECPubKey.fromHex(fixtures.uncompressed.hex) |
|||
|
|||
assert(pubKey.Q.equals(Q)) |
|||
assert.equal(pubKey.toHex(), fixtures.uncompressed.hex) |
|||
assert.equal(pubKey.compressed, false) |
|||
}) |
|||
}) |
|||
|
|||
describe('getAddress', function () { |
|||
it('calculates the expected hash (compressed)', function () { |
|||
var pubKey = new ECPubKey(Q, true) |
|||
var address = pubKey.getAddress() |
|||
|
|||
assert.equal(address.hash.toString('hex'), fixtures.compressed.hash160) |
|||
}) |
|||
|
|||
it('calculates the expected hash (uncompressed)', function () { |
|||
var pubKey = new ECPubKey(Q, false) |
|||
var address = pubKey.getAddress() |
|||
|
|||
assert.equal(address.hash.toString('hex'), fixtures.uncompressed.hash160) |
|||
}) |
|||
|
|||
it('supports alternative networks', function () { |
|||
var pubKey = new ECPubKey(Q) |
|||
var address = pubKey.getAddress(networks.testnet) |
|||
|
|||
assert.equal(address.version, networks.testnet.pubKeyHash) |
|||
assert.equal(address.hash.toString('hex'), fixtures.compressed.hash160) |
|||
}) |
|||
}) |
|||
|
|||
describe('verify', function () { |
|||
var pubKey, signature |
|||
beforeEach(function () { |
|||
pubKey = new ECPubKey(Q) |
|||
|
|||
signature = { |
|||
r: new BigInteger(fixtures.signature.r), |
|||
s: new BigInteger(fixtures.signature.s) |
|||
} |
|||
}) |
|||
|
|||
it('verifies a valid signature', function () { |
|||
var hash = crypto.sha256(fixtures.message) |
|||
|
|||
assert(pubKey.verify(hash, signature)) |
|||
}) |
|||
|
|||
it("doesn't verify the wrong signature", function () { |
|||
var hash = crypto.sha256('mushrooms') |
|||
|
|||
assert(!pubKey.verify(hash, signature)) |
|||
}) |
|||
}) |
|||
}) |
@ -1,102 +0,0 @@ |
|||
{ |
|||
"valid": [ |
|||
{ |
|||
"d": "1", |
|||
"Q": "(55066263022277343669578718895168534326250603453777594175500187360389116729240,32670510020758816978083085130507043184471273380659243275938904335757337482424)", |
|||
"WIFs": [ |
|||
{ |
|||
"network": "bitcoin", |
|||
"string": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn", |
|||
"compressed": true |
|||
}, |
|||
{ |
|||
"network": "bitcoin", |
|||
"string": "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf", |
|||
"compressed": false |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"d": "19898843618908353587043383062236220484949425084007183071220218307100305431102", |
|||
"Q": "(83225686012142088543596389522774768397204444195709443235253141114409346958144,23739058578904784236915560265041168694780215705543362357495033621678991351768)", |
|||
"WIFs": [ |
|||
{ |
|||
"network": "bitcoin", |
|||
"string": "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o", |
|||
"compressed": true |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"d": "48968302285117906840285529799176770990048954789747953886390402978935544927851", |
|||
"Q": "(30095590000961171681152428142595206241714764354580127609094760797518133922356,93521207164355458151597931319591130635754976513751247168472016818884561919702)", |
|||
"WIFs": [ |
|||
{ |
|||
"network": "bitcoin", |
|||
"string": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx", |
|||
"compressed": true |
|||
}, |
|||
{ |
|||
"network": "bitcoin", |
|||
"string": "5JdxzLtFPHNe7CAL8EBC6krdFv9pwPoRo4e3syMZEQT9srmK8hh", |
|||
"compressed": false |
|||
}, |
|||
{ |
|||
"network": "testnet", |
|||
"string": "cRD9b1m3vQxmwmjSoJy7Mj56f4uNFXjcWMCzpQCEmHASS4edEwXv", |
|||
"compressed": true |
|||
}, |
|||
{ |
|||
"network": "testnet", |
|||
"string": "92Qba5hnyWSn5Ffcka56yMQauaWY6ZLd91Vzxbi4a9CCetaHtYj", |
|||
"compressed": false |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
"d": "115792089237316195423570985008687907852837564279074904382605163141518161494336", |
|||
"Q": "(55066263022277343669578718895168534326250603453777594175500187360389116729240,83121579216557378445487899878180864668798711284981320763518679672151497189239)", |
|||
"WIFs": [ |
|||
{ |
|||
"network": "bitcoin", |
|||
"string": "L5oLkpV3aqBjhki6LmvChTCV6odsp4SXM6FfU2Gppt5kFLaHLuZ9", |
|||
"compressed": true |
|||
} |
|||
] |
|||
} |
|||
], |
|||
"invalid": { |
|||
"constructor": [ |
|||
{ |
|||
"exception": "Private key must be greater than 0", |
|||
"d": "-1" |
|||
}, |
|||
{ |
|||
"exception": "Private key must be greater than 0", |
|||
"d": "0" |
|||
}, |
|||
{ |
|||
"exception": "Private key must be less than the curve order", |
|||
"d": "115792089237316195423570985008687907852837564279074904382605163141518161494337" |
|||
}, |
|||
{ |
|||
"exception": "Private key must be less than the curve order", |
|||
"d": "115792089237316195423570985008687907853269984665640564039457584007913129639935" |
|||
} |
|||
], |
|||
"WIF": [ |
|||
{ |
|||
"exception": "Invalid compression flag", |
|||
"string": "ju9rooVsmagsb4qmNyTysUSFB1GB6MdpD7eoGjUTPmZRAApJxRz" |
|||
}, |
|||
{ |
|||
"exception": "Invalid WIF payload length", |
|||
"string": "7ZEtRQLhCsDQrd6ZKfmcESdXgas8ggZPN24ByEi5ey6VJW" |
|||
}, |
|||
{ |
|||
"exception": "Invalid WIF payload length", |
|||
"string": "5qibUKwsnMo1qDiNp3prGaQkD2JfVJa8F8Na87H2CkMHvuVg6uKhw67Rh" |
|||
} |
|||
] |
|||
} |
|||
} |
@ -1,19 +0,0 @@ |
|||
{ |
|||
"Q": { |
|||
"x": "55066263022277343669578718895168534326250603453777594175500187360389116729240", |
|||
"y": "32670510020758816978083085130507043184471273380659243275938904335757337482424" |
|||
}, |
|||
"compressed": { |
|||
"hex": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", |
|||
"hash160": "751e76e8199196d454941c45d1b3a323f1433bd6" |
|||
}, |
|||
"uncompressed": { |
|||
"hex": "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", |
|||
"hash160": "91b24bf9f5288532960ac687abb035127b1d28a5" |
|||
}, |
|||
"message": "vires in numeris", |
|||
"signature": { |
|||
"r": "68972263025625296948424563184904289678530916807200550828762374724416876919710", |
|||
"s": "43478152510424186005054433052302509227777805602212468112169549534899266476898" |
|||
} |
|||
} |
Loading…
Reference in new issue