diff --git a/src/eckey.js b/src/eckey.js index 66982e3..e59e140 100644 --- a/src/eckey.js +++ b/src/eckey.js @@ -21,29 +21,22 @@ function ECKey(D, compressed) { } // Static constructors -ECKey.fromBuffer = function(buffer, compressed) { - assert(Buffer.isBuffer(buffer), 'First argument must be a Buffer') - assert.strictEqual(buffer.length, 32, 'Invalid buffer length') - - var D = BigInteger.fromBuffer(buffer) - return new ECKey(D, compressed) -} - -ECKey.fromHex = function(hex, compressed) { - return ECKey.fromBuffer(new Buffer(hex, 'hex'), compressed) -} - ECKey.fromWIF = function(string) { var decode = base58check.decode(string) - var payload = decode.payload + var compressed = false + if (payload.length === 33) { assert.strictEqual(payload[32], 0x01, 'Invalid WIF string') - return ECKey.fromBuffer(payload.slice(0, 32), true) + payload = payload.slice(0, -1) + compressed = true } - return ECKey.fromBuffer(payload, false) + assert.equal(payload.length, 32, 'Invalid WIF payload length') + + var D = BigInteger.fromBuffer(payload.slice(0, 32)) + return new ECKey(D, compressed) } ECKey.makeRandom = function(compressed, rng) { @@ -56,24 +49,11 @@ ECKey.makeRandom = function(compressed, rng) { return new ECKey(D, compressed) } -// Operations -ECKey.prototype.sign = function(hash) { - return ecdsa.sign(hash, this.D) -} - // Export functions -ECKey.prototype.toBuffer = function() { - return this.D.toBuffer(32) -} - -ECKey.prototype.toHex = function() { - return this.toBuffer().toString('hex') -} - ECKey.prototype.toWIF = function(version) { version = version || networks.bitcoin.wif - var buffer = this.toBuffer() + var buffer = this.D.toBuffer(32) if (this.pub.compressed) { buffer = Buffer.concat([buffer, new Buffer([0x01])]) } @@ -81,4 +61,9 @@ ECKey.prototype.toWIF = function(version) { return base58check.encode(buffer, version) } +// Operations +ECKey.prototype.sign = function(hash) { + return ecdsa.sign(hash, this.D) +} + module.exports = ECKey diff --git a/src/hdwallet.js b/src/hdwallet.js index 8e8f747..cd0787d 100644 --- a/src/hdwallet.js +++ b/src/hdwallet.js @@ -26,7 +26,9 @@ function HDWallet(seed, networkString) { var IR = I.slice(32) // In case IL is 0 or >= n, the master key is invalid (handled by ECKey.fromBuffer) - this.priv = ECKey.fromBuffer(IL, true) + var pIL = BigInteger.fromBuffer(IL) + + this.priv = new ECKey(pIL, true) this.pub = this.priv.pub this.chaincode = IR @@ -103,7 +105,10 @@ HDWallet.fromBuffer = function(input) { // 33 bytes: the public key or private key data (0x02 + X or 0x03 + X for // public keys, 0x00 + k for private keys) if (type == 'priv') { - hd.priv = ECKey.fromBuffer(input.slice(46, 78), true) + assert.equal(input.readUInt8(45), 0, 'Invalid private key') + var D = BigInteger.fromBuffer(input.slice(46, 78)) + + hd.priv = new ECKey(D, true) hd.pub = hd.priv.pub } else { hd.pub = ECPubKey.fromBuffer(input.slice(45, 78), true) @@ -153,7 +158,7 @@ HDWallet.prototype.toBuffer = function(priv) { // 0x00 + k for private keys buffer.writeUInt8(0, 45) - this.priv.toBuffer().copy(buffer, 46) + this.priv.D.toBuffer(32).copy(buffer, 46) } else { // X9.62 encoding for public keys diff --git a/test/ecdsa.js b/test/ecdsa.js index 2e9a028..b4014a7 100644 --- a/test/ecdsa.js +++ b/test/ecdsa.js @@ -16,7 +16,7 @@ describe('ecdsa', function() { describe('deterministicGenerateK', function() { it('matches the test vectors', function() { fixtures.forEach(function(f) { - var priv = BigInteger.fromHex(f.privateKey) + var priv = BigInteger.fromHex(f.D) var h1 = crypto.sha256(f.message) var k = ecdsa.deterministicGenerateK(h1, priv) @@ -39,7 +39,8 @@ describe('ecdsa', function() { describe('sign', function() { it('matches the test vectors', function() { fixtures.forEach(function(f) { - var priv = ECKey.fromHex(f.privateKey) + var D = BigInteger.fromHex(f.D) + var priv = new ECKey(D) var hash = crypto.sha256(f.message) var sig = ecdsa.parseSig(priv.sign(hash)) @@ -49,7 +50,7 @@ describe('ecdsa', function() { }) it('should sign with low S value', function() { - var priv = ECKey.fromHex('ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458') + var priv = ECKey.makeRandom() var hash = crypto.sha256('Vires in numeris') var signature = priv.sign(hash) var psig = ecdsa.parseSig(signature) @@ -62,7 +63,8 @@ describe('ecdsa', function() { describe('verifyRaw', function() { it('matches the test vectors', function() { fixtures.forEach(function(f) { - var priv = ECKey.fromHex(f.privateKey) + var D = BigInteger.fromHex(f.D) + var priv = new ECKey(D) var r = BigInteger.fromHex(f.signature.slice(0, 64)) var s = BigInteger.fromHex(f.signature.slice(64)) diff --git a/test/eckey.js b/test/eckey.js index 2ef218b..9b4a696 100644 --- a/test/eckey.js +++ b/test/eckey.js @@ -1,81 +1,89 @@ var assert = require('assert') var crypto = require('../src/crypto') +var BigInteger = require('bigi') var ECKey = require('../src/eckey') -var ECPubKey = require('../src/ecpubkey') + +var fixtures = require('./fixtures/eckey') +var networks = require('../src/networks') describe('ECKey', function() { describe('constructor', function() { - it('parses hex', function() { - var priv = '18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725' - var pub = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b235' + - '22cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6' - var key = ECKey.fromHex(priv, false) - - assert.equal(key.pub.toHex(), pub) - assert.equal(key.pub.compressed, false) + it('defaults to compressed', function() { + var privKey = new ECKey(BigInteger.ONE) + + assert.equal(privKey.pub.compressed, true) }) - it('parses WIF', function() { - var priv = '5HwoXVkHoRM8sL2KmNRS217n1g8mPPBomrY7yehCuXC1115WWsh' - var pub = '044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0' + - 'f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1' - var addr = '1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a' - var key = ECKey.fromWIF(priv) + it('supports the uncompressed flag', function() { + var privKey = new ECKey(BigInteger.ONE, false) - assert.equal(key.pub.compressed, false) - assert.equal(key.pub.toHex(), pub) - assert.equal(key.pub.getAddress().toString(), addr) + assert.equal(privKey.pub.compressed, false) }) - it('parses compressed WIF', function() { - var priv = 'KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp' - var pub = '034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa' - var addr = '1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9' - var key = ECKey.fromWIF(priv) + it('calculates the matching pubKey', function() { + fixtures.valid.forEach(function(f) { + var privKey = new ECKey(new BigInteger(f.D)) - assert.equal(key.pub.compressed, true) - assert.equal(key.pub.toHex(), pub) - assert.equal(key.pub.getAddress().toString(), addr) + assert.equal(privKey.pub.Q.toString(), f.Q.toString()) + }) }) - it('alternative constructor syntax', function() { - var priv = 'ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458' - var pub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199' + - '283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566' - var key = ECKey.fromHex(priv, false) - - assert.equal(key.pub.toHex(), pub) - assert.equal(key.pub.compressed, false) - assert.equal(key.toHex(), priv) + fixtures.invalid.constructor.forEach(function(f) { + it('throws on ' + f.description, function() { + assert.throws(function() { + new ECKey(new BigInteger(f.D)) + }) + }) }) }) - describe('signing', function() { - var hpriv = 'ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458' - var hcpub = '024b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea811992' - var hash = crypto.sha256('Vires in numeris') + describe('fromWIF', function() { + it('matches the test vectors', function() { + fixtures.valid.forEach(function(f) { + f.WIFs.forEach(function(wif) { + var privKey = ECKey.fromWIF(wif.string) - it('should verify against the private key', function() { - var priv = ECKey.fromHex(hpriv) - var signature = priv.sign(hash) - - assert(priv.pub.verify(hash, signature)) + assert.equal(privKey.D.toString(), f.D) + assert.equal(privKey.pub.compressed, wif.compressed) + }) + }) }) - it('should verify against the public key', function() { - var priv = ECKey.fromHex(hpriv) - var pub = ECPubKey.fromHex(hcpub, true) - var signature = priv.sign(hash) + fixtures.invalid.WIF.forEach(function(f) { + it('throws on ' + f.description, function() { + assert.throws(function() { + ECKey.fromWIF(f.string) + }) + }) + }) + }) - assert(pub.verify(hash, signature)) + describe('toWIF', function() { + it('matches the test vectors', function() { + fixtures.valid.forEach(function(f) { + f.WIFs.forEach(function(wif) { + var privKey = ECKey.fromWIF(wif.string) + var version = networks[wif.network].wif + var result = privKey.toWIF(version) + + assert.equal(result, wif.string) + }) + }) }) + }) + + describe('signing', function() { + var hash = crypto.sha256('Vires in numeris') + var priv = ECKey.makeRandom() + var signature = priv.sign(hash) - it('should not verify against the wrong private key', function() { - var priv1 = ECKey.fromHex(hpriv) - var priv2 = ECKey.fromHex('1111111111111111111111111111111111111111111111111111111111111111') + it('should verify against the public key', function() { + assert(priv.pub.verify(hash, signature)) + }) - var signature = priv1.sign(hash) + it('should not verify against the wrong public key', function() { + var priv2 = ECKey.makeRandom() assert(!priv2.pub.verify(hash, signature)) }) diff --git a/test/ecpubkey.js b/test/ecpubkey.js index faf338d..c7aefd8 100644 --- a/test/ecpubkey.js +++ b/test/ecpubkey.js @@ -1,95 +1,104 @@ var assert = require('assert') +var crypto = require('../src/crypto') +var sec = require('../src/sec') +var ecparams = sec('secp256k1') +var BigInteger = require('bigi') +var ECPointFp = require('../src/ec').ECPointFp var ECPubKey = require('../src/ecpubkey') +var fixtures = require('./fixtures/ecpubkey') + describe('ECPubKey', function() { - describe('toBuffer/toHex', function() { - var hcpub = '024b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea811992' - var hpub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566' + var Q + + beforeEach(function() { + var curve = ecparams.getCurve() + + Q = new ECPointFp( + curve, + curve.fromBigInteger(new BigInteger(fixtures.Q.x)), + curve.fromBigInteger(new BigInteger(fixtures.Q.y)) + ) + }) - it('using toHex should support compression', function() { - var pub = ECPubKey.fromHex(hcpub) + describe('constructor', function() { + it('defaults to compressed', function() { + var pubKey = new ECPubKey(Q) - assert.equal(pub.toHex(), hcpub) - assert.equal(pub.compressed, true) + assert.equal(pubKey.compressed, true) }) - it('using toHex should support uncompressed', function() { - var pub = ECPubKey.fromHex(hpub) + it('supports the uncompressed flag', function() { + var pubKey = new ECPubKey(Q, false) - assert.equal(pub.toHex(), hpub) - assert.equal(pub.compressed, false) + assert.equal(pubKey.compressed, false) + }) + }) + + 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() { - var privkeys = [ - 'ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458', - '1111111111111111111111111111111111111111111111111111111111111111', - '18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725' - ] - - // compressed pubkeys - var cpubkeys = [ - '024b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea811992', - '034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa', - '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352' - ] - - var pubkeys = cpubkeys.map(function(x) { - var pk = ECPubKey.fromHex(x) - pk.compressed = false - return pk.toHex() + 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('bitcoin', function() { - var addresses = [ - '19SgmoUj4xowEjwtXvNAtYTAgbvR9iBCui', - '1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a', - '16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM' - ] - var compressedAddresses = [ - '1AA4sjKW2aUmbtN3MtegdvhYtDBbDEke1q', - '1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9', - '1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs', - ] - - for (var i = 0; i < addresses.length; ++i) { - var pub = ECPubKey.fromHex(pubkeys[i]) - var cpub = ECPubKey.fromHex(cpubkeys[i]) - cpub.compressed = true - - var addr = addresses[i] - var caddr = compressedAddresses[i] - - assert.equal(pub.getAddress().toString(), addr) - assert.equal(cpub.getAddress().toString(), caddr) - } + 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(0x09) + + assert.equal(address.version, 0x09) + assert.equal(address.hash.toString('hex'), fixtures.compressed.hash160) }) + }) + + describe('verify', function() { + var pubKey, signature + beforeEach(function() { + pubKey = new ECPubKey(Q) - it('testnet', function() { - var addresses = [ - '19SgmoUj4xowEjwtXvNAtYTAgbvR9iBCui', - '1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a', - '16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM' - ] - var compressedAddresses = [ - '1AA4sjKW2aUmbtN3MtegdvhYtDBbDEke1q', - '1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9', - '1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs', - ] - - for (var i = 0; i < addresses.length; ++i) { - var pub = ECPubKey.fromHex(pubkeys[i]) - var cpub = ECPubKey.fromHex(cpubkeys[i]) - cpub.compressed = true - - var addr = addresses[i] - var caddr = compressedAddresses[i] - - assert.equal(pub.getAddress().toString(), addr) - assert.equal(cpub.getAddress().toString(), caddr) + 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.ok(pubKey.verify(hash, signature)) + }) + + it('doesn\'t verify the wrong signature', function() { + var hash = crypto.sha256('mushrooms') + + assert.ok(!pubKey.verify(hash, signature)) + }) }) }) diff --git a/test/fixtures/ecdsa.js b/test/fixtures/ecdsa.js index 94e278a..631475e 100644 --- a/test/fixtures/ecdsa.js +++ b/test/fixtures/ecdsa.js @@ -1,49 +1,49 @@ // Test Vectors for RFC 6979 ECDSA, secp256k1, SHA-256 module.exports = [ { - "privateKey": "0000000000000000000000000000000000000000000000000000000000000001", + "D": "0000000000000000000000000000000000000000000000000000000000000001", "k": "8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15", "message": "Satoshi Nakamoto", "signature": "934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d82442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5" }, { - "privateKey": "0000000000000000000000000000000000000000000000000000000000000001", + "D": "0000000000000000000000000000000000000000000000000000000000000001", "k": "38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3", "message": "All those moments will be lost in time, like tears in rain. Time to die...", "signature": "8600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21" }, { - "privateKey": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140", + "D": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "k": "33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90", "message": "Satoshi Nakamoto", "signature": "fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d06b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5" }, { - "privateKey": "f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181", + "D": "f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181", "k": "525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1", "message": "Alan Turing", "signature": "7063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c58dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea" }, { - "privateKey": "e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2", + "D": "e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2", "k": "1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d", "message": "There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!", "signature": "b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6" }, { - "privateKey": "0000000000000000000000000000000000000000000000000000000000000001", + "D": "0000000000000000000000000000000000000000000000000000000000000001", "k": "ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5", "message": "Everything should be made as simple as possible, but not simpler.", "signature": "33a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c96f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262" }, { - "privateKey": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "D": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "k": "9dc74cbfd383980fb4ae5d2680acddac9dac956dca65a28c80ac9c847c2374e4", "message": "Equations are more important to me, because politics is for the present, but an equation is something for eternity.", "signature": "54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5" }, { - "privateKey": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "D": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "k": "fd27071f01648ebbdd3e1cfbae48facc9fa97edc43bbbc9a7fdc28eae13296f5", "message": "Not only is the Universe stranger than we think, it is stranger than we can think.", "signature": "ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd06fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283" diff --git a/test/fixtures/eckey.js b/test/fixtures/eckey.js new file mode 100644 index 0000000..1751ae8 --- /dev/null +++ b/test/fixtures/eckey.js @@ -0,0 +1,98 @@ +module.exports = { + "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": [ + { + "description": "Private key ZERO", + "D": "0" + }, + { + "description": "Private key equal to the curve order", + "D": "115792089237316195423570985008687907852837564279074904382605163141518161494337" + }, + { + "description": "Private key greater than the curve order", + "D": "115792089237316195423570985008687907853269984665640564039457584007913129639935" + } + ], + "WIF": [ + { + "description": "Invalid compression flag", + "string": "ju9rooVsmagsb4qmNyTysUSFB1GB6MdpD7eoGjUTPmZRAApJxRz" + }, + { + "description": "Payload too short", + "string": "7ZEtRQLhCsDQrd6ZKfmcESdXgas8ggZPN24ByEi5ey6VJW" + }, + { + "description": "Payload too long", + "string": "5qibUKwsnMo1qDiNp3prGaQkD2JfVJa8F8Na87H2CkMHvuVg6uKhw67Rh" + } + ] + } +} \ No newline at end of file diff --git a/test/fixtures/ecpubkey.js b/test/fixtures/ecpubkey.js new file mode 100644 index 0000000..77b9b42 --- /dev/null +++ b/test/fixtures/ecpubkey.js @@ -0,0 +1,19 @@ +module.exports = { + "Q": { + "x": "55066263022277343669578718895168534326250603453777594175500187360389116729240", + "y": "32670510020758816978083085130507043184471273380659243275938904335757337482424" + }, + "compressed": { + "hex": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "hash160": "751e76e8199196d454941c45d1b3a323f1433bd6" + }, + "uncompressed": { + "hex": "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "hash160": "91b24bf9f5288532960ac687abb035127b1d28a5" + }, + "message": "vires in numeris", + "signature": { + "r": "68972263025625296948424563184904289678530916807200550828762374724416876919710", + "s": "43478152510424186005054433052302509227777805602212468112169549534899266476898" + } +} \ No newline at end of file diff --git a/test/hdwallet.js b/test/hdwallet.js index 1207f76..b0284f7 100644 --- a/test/hdwallet.js +++ b/test/hdwallet.js @@ -41,7 +41,7 @@ describe('HDWallet', function() { it('creates from binary seed', function() { var hd = new HDWallet(seed) - assert.equal(hd.priv.toHex(), expectedPrivateKey) + assert.equal(hd.priv.D.toHex(), expectedPrivateKey) assert(hd.pub) }) @@ -49,7 +49,7 @@ describe('HDWallet', function() { it('creates from hex seed', function() { var hd = HDWallet.fromSeedHex(seed.toString('hex')) - assert.equal(hd.priv.toHex(), expectedPrivateKey) + assert.equal(hd.priv.D.toHex(), expectedPrivateKey) assert(hd.pub) }) }) @@ -63,7 +63,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), '3442193e1bb70916e914552172cd4e2dbc9df811') assert.equal(b2h(hd.getFingerprint()), '3442193e') assert.equal(hd.getAddress().toString(), '15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma') - assert.equal(hd.priv.toHex(), 'e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35') assert.equal(hd.priv.toWIF(), 'L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW') assert.equal(hd.pub.toHex(), '0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2') assert.equal(b2h(hd.chaincode), '873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508') @@ -77,7 +76,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), '5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7') assert.equal(b2h(hd.getFingerprint()), '5c1bd648') assert.equal(hd.getAddress().toString(), '19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh') - assert.equal(hd.priv.toHex().slice(0, 64), 'edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea') assert.equal(hd.priv.toWIF(), 'L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT') assert.equal(hd.pub.toHex(), '035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56') assert.equal(b2h(hd.chaincode), '47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141') @@ -91,7 +89,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), 'bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe') assert.equal(b2h(hd.getFingerprint()), 'bef5a2f9') assert.equal(hd.getAddress().toString(), '1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj') - assert.equal(hd.priv.toHex().slice(0, 64), '3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368') assert.equal(hd.priv.toWIF(), 'KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM') assert.equal(hd.pub.toHex(), '03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c') assert.equal(b2h(hd.chaincode), '2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19') @@ -105,7 +102,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), 'ee7ab90cde56a8c0e2bb086ac49748b8db9dce72') assert.equal(b2h(hd.getFingerprint()), 'ee7ab90c') assert.equal(hd.getAddress().toString(), '1NjxqbA9aZWnh17q1UW3rB4EPu79wDXj7x') - assert.equal(hd.priv.toHex().slice(0, 64), 'cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca') assert.equal(hd.priv.toWIF(), 'L43t3od1Gh7Lj55Bzjj1xDAgJDcL7YFo2nEcNaMGiyRZS1CidBVU') assert.equal(hd.pub.toHex(), '0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2') assert.equal(b2h(hd.chaincode), '04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f') @@ -119,7 +115,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), 'd880d7d893848509a62d8fb74e32148dac68412f') assert.equal(b2h(hd.getFingerprint()), 'd880d7d8') assert.equal(hd.getAddress().toString(), '1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt') - assert.equal(hd.priv.toHex().slice(0, 64), '0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4') assert.equal(hd.priv.toWIF(), 'KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR') assert.equal(hd.pub.toHex(), '02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29') assert.equal(b2h(hd.chaincode), 'cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd') @@ -133,7 +128,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), 'd69aa102255fed74378278c7812701ea641fdf32') assert.equal(b2h(hd.getFingerprint()), 'd69aa102') assert.equal(hd.getAddress().toString(), '1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam') - assert.equal(hd.priv.toHex().slice(0, 64), '471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8') assert.equal(hd.priv.toWIF(), 'Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs') assert.equal(hd.pub.toHex(), '022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011') assert.equal(b2h(hd.chaincode), 'c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e') @@ -150,7 +144,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), 'bd16bee53961a47d6ad888e29545434a89bdfe95') assert.equal(b2h(hd.getFingerprint()), 'bd16bee5') assert.equal(hd.getAddress().toString(), '1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg') - assert.equal(hd.priv.toHex().slice(0, 64), '4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e') assert.equal(hd.priv.toWIF(), 'KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy') assert.equal(hd.pub.toHex(), '03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7') assert.equal(b2h(hd.chaincode), '60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689') @@ -164,7 +157,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), '5a61ff8eb7aaca3010db97ebda76121610b78096') assert.equal(b2h(hd.getFingerprint()), '5a61ff8e') assert.equal(hd.getAddress().toString(), '19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ') - assert.equal(hd.priv.toHex().slice(0, 64), 'abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e') assert.equal(hd.priv.toWIF(), 'L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj') assert.equal(hd.pub.toHex(), '02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea') assert.equal(b2h(hd.chaincode), 'f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c') @@ -178,7 +170,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), 'd8ab493736da02f11ed682f88339e720fb0379d1') assert.equal(b2h(hd.getFingerprint()), 'd8ab4937') assert.equal(hd.getAddress().toString(), '1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk') - assert.equal(hd.priv.toHex().slice(0, 64), '877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93') assert.equal(hd.priv.toWIF(), 'L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr') assert.equal(hd.pub.toHex(), '03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b') assert.equal(b2h(hd.chaincode), 'be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9') @@ -192,7 +183,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), '78412e3a2296a40de124307b6485bd19833e2e34') assert.equal(b2h(hd.getFingerprint()), '78412e3a') assert.equal(hd.getAddress().toString(), '1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW') - assert.equal(hd.priv.toHex().slice(0, 64), '704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7') assert.equal(hd.priv.toWIF(), 'KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2') assert.equal(hd.pub.toHex(), '03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9') assert.equal(b2h(hd.chaincode), 'f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb') @@ -206,7 +196,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), '31a507b815593dfc51ffc7245ae7e5aee304246e') assert.equal(b2h(hd.getFingerprint()), '31a507b8') assert.equal(hd.getAddress().toString(), '15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R') - assert.equal(hd.priv.toHex().slice(0, 64), 'f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d') assert.equal(hd.priv.toWIF(), 'L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF') assert.equal(hd.pub.toHex(), '02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0') assert.equal(b2h(hd.chaincode), '637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29') @@ -220,7 +209,6 @@ describe('HDWallet', function() { assert.equal(b2h(hd.getIdentifier()), '26132fdbe7bf89cbc64cf8dafa3f9f88b8666220') assert.equal(b2h(hd.getFingerprint()), '26132fdb') assert.equal(hd.getAddress().toString(), '14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt') - assert.equal(hd.priv.toHex().slice(0, 64), 'bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23') assert.equal(hd.priv.toWIF(), 'L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK') assert.equal(hd.pub.toHex(), '024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c') assert.equal(b2h(hd.chaincode), '9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271')