From e27c97a791a9b3088a7693a03dea4462099b89af Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Tue, 13 May 2014 16:44:29 +1000 Subject: [PATCH] ECPubKey/ECKey: separate to two files --- src/eckey.js | 60 +++-------------------------- src/ecpubkey.js | 58 ++++++++++++++++++++++++++++ src/hdwallet.js | 4 +- src/index.js | 4 +- src/message.js | 2 +- src/transaction.js | 2 +- test/eckey.js | 90 ------------------------------------------- test/ecpubkey.js | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 164 insertions(+), 151 deletions(-) create mode 100644 src/ecpubkey.js create mode 100644 test/ecpubkey.js diff --git a/src/eckey.js b/src/eckey.js index fa238a9..66982e3 100644 --- a/src/eckey.js +++ b/src/eckey.js @@ -4,15 +4,12 @@ var ecdsa = require('./ecdsa') var networks = require('./networks') var secureRandom = require('secure-random') -var Address = require('./address') -var crypto = require('./crypto') +var BigInteger = require('bigi') +var ECPubKey = require('./ecpubkey') var sec = require('./sec') var ecparams = sec('secp256k1') -var BigInteger = require('bigi') -var ECPointFp = require('./ec').ECPointFp - function ECKey(D, compressed) { assert(D.compareTo(BigInteger.ZERO) > 0, 'Private key must be greater than 0') assert(D.compareTo(ecparams.getN()) < 0, 'Private key must be less than the curve order') @@ -31,6 +28,7 @@ ECKey.fromBuffer = function(buffer, compressed) { var D = BigInteger.fromBuffer(buffer) return new ECKey(D, compressed) } + ECKey.fromHex = function(hex, compressed) { return ECKey.fromBuffer(new Buffer(hex, 'hex'), compressed) } @@ -67,6 +65,7 @@ ECKey.prototype.sign = function(hash) { ECKey.prototype.toBuffer = function() { return this.D.toBuffer(32) } + ECKey.prototype.toHex = function() { return this.toBuffer().toString('hex') } @@ -82,53 +81,4 @@ ECKey.prototype.toWIF = function(version) { return base58check.encode(buffer, version) } -////////////////////////////////////////////////////// - -function ECPubKey(Q, compressed) { - assert(Q instanceof ECPointFp, 'Q must be an ECPointFP') - - if (compressed == undefined) compressed = true - assert.strictEqual(typeof compressed, 'boolean', 'Invalid compression flag') - - this.compressed = compressed - this.Q = Q -} - -// Static constructors -ECPubKey.fromBuffer = function(buffer) { - var type = buffer.readUInt8(0) - assert(type >= 0x02 || type <= 0x04, 'Invalid public key') - - var compressed = (type !== 0x04) - assert.strictEqual(buffer.length, compressed ? 33 : 65, 'Invalid public key') - - var Q = ECPointFp.decodeFrom(ecparams.getCurve(), buffer) - return new ECPubKey(Q, compressed) -} -ECPubKey.fromHex = function(hex) { - return ECPubKey.fromBuffer(new Buffer(hex, 'hex')) -} - -// Operations -ECPubKey.prototype.verify = function(hash, sig) { - return ecdsa.verify(hash, sig, this.Q) -} - -ECPubKey.prototype.getAddress = function(version) { - version = version || networks.bitcoin.pubKeyHash - - return new Address(crypto.hash160(this.toBuffer()), version) -} - -// Export functions -ECPubKey.prototype.toBuffer = function() { - return new Buffer(this.Q.getEncoded(this.compressed)) -} -ECPubKey.prototype.toHex = function() { - return this.toBuffer().toString('hex') -} - -module.exports = { - ECKey: ECKey, - ECPubKey: ECPubKey -} +module.exports = ECKey diff --git a/src/ecpubkey.js b/src/ecpubkey.js new file mode 100644 index 0000000..8bcf984 --- /dev/null +++ b/src/ecpubkey.js @@ -0,0 +1,58 @@ +var assert = require('assert') +var crypto = require('./crypto') +var ecdsa = require('./ecdsa') +var networks = require('./networks') + +var Address = require('./address') +var ECPointFp = require('./ec').ECPointFp + +var sec = require('./sec') +var ecparams = sec('secp256k1') + +function ECPubKey(Q, compressed) { + assert(Q instanceof ECPointFp, 'Q must be an ECPointFP') + + if (compressed == undefined) compressed = true + assert.strictEqual(typeof compressed, 'boolean', 'Invalid compression flag') + + this.compressed = compressed + this.Q = Q +} + +// Static constructors +ECPubKey.fromBuffer = function(buffer) { + var type = buffer.readUInt8(0) + assert(type >= 0x02 || type <= 0x04, 'Invalid public key') + + var compressed = (type !== 0x04) + assert.strictEqual(buffer.length, compressed ? 33 : 65, 'Invalid public key') + + var Q = ECPointFp.decodeFrom(ecparams.getCurve(), buffer) + return new ECPubKey(Q, compressed) +} + +ECPubKey.fromHex = function(hex) { + return ECPubKey.fromBuffer(new Buffer(hex, 'hex')) +} + +// Operations +ECPubKey.prototype.getAddress = function(version) { + version = version || networks.bitcoin.pubKeyHash + + return new Address(crypto.hash160(this.toBuffer()), version) +} + +ECPubKey.prototype.verify = function(hash, sig) { + return ecdsa.verify(hash, sig, this.Q) +} + +// Export functions +ECPubKey.prototype.toBuffer = function() { + return new Buffer(this.Q.getEncoded(this.compressed)) +} + +ECPubKey.prototype.toHex = function() { + return this.toBuffer().toString('hex') +} + +module.exports = ECPubKey diff --git a/src/hdwallet.js b/src/hdwallet.js index c0d68db..8e8f747 100644 --- a/src/hdwallet.js +++ b/src/hdwallet.js @@ -5,8 +5,8 @@ var convert = require('./convert') var Address = require('./address') var BigInteger = require('bigi') var crypto = require('./crypto') -var ECKey = require('./eckey').ECKey -var ECPubKey = require('./eckey').ECPubKey +var ECKey = require('./eckey') +var ECPubKey = require('./ecpubkey') var networks = require('./networks') var sec = require('./sec') diff --git a/src/index.js b/src/index.js index 8423409..274f1aa 100644 --- a/src/index.js +++ b/src/index.js @@ -11,9 +11,9 @@ module.exports = { crypto: require('./crypto'), ec: ec, ecdsa: require('./ecdsa'), - ECKey: Key.ECKey, + ECKey: require('./eckey'), ECPointFp: ec.ECPointFp, - ECPubKey: Key.ECPubKey, + ECPubKey: require('./ecpubkey'), Message: require('./message'), Opcode: require('./opcode'), HDWallet: require('./hdwallet'), diff --git a/src/message.js b/src/message.js index 90df6c8..526c665 100644 --- a/src/message.js +++ b/src/message.js @@ -3,7 +3,7 @@ var Address = require('./address') var bufferutils = require('./bufferutils') var crypto = require('./crypto') var ecdsa = require('./ecdsa') -var ECPubKey = require('./eckey').ECPubKey +var ECPubKey = require('./ecpubkey') // FIXME: incompatible with other networks (Litecoin etc) var MAGIC_PREFIX = new Buffer('\x18Bitcoin Signed Message:\n') diff --git a/src/transaction.js b/src/transaction.js index 8fe2537..b21f851 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -7,7 +7,7 @@ var bufferutils = require('./bufferutils') var Script = require('./script') var convert = require('./convert') var crypto = require('./crypto') -var ECKey = require('./eckey').ECKey +var ECKey = require('./eckey') var ecdsa = require('./ecdsa') function Transaction(doc) { diff --git a/test/eckey.js b/test/eckey.js index 3af0e93..58847b5 100644 --- a/test/eckey.js +++ b/test/eckey.js @@ -51,77 +51,6 @@ describe('ECKey', function() { }) }) - describe('toAddress', 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('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('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) - } - }) - }) - describe('signing', function() { var hpriv = 'ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458' var hcpub = '024b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea811992' @@ -151,23 +80,4 @@ describe('ECKey', function() { assert(!priv2.pub.verify(hash, signature)) }) }) - - describe('output of ECPubKey', function() { - var hcpub = '024b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea811992' - var hpub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566' - - it('using toHex should support compression', function() { - var pub = ECPubKey.fromHex(hcpub) - - assert.equal(pub.toHex(), hcpub) - assert.equal(pub.compressed, true) - }) - - it('using toHex should support uncompressed', function() { - var pub = ECPubKey.fromHex(hpub) - - assert.equal(pub.toHex(), hpub) - assert.equal(pub.compressed, false) - }) - }) }) diff --git a/test/ecpubkey.js b/test/ecpubkey.js new file mode 100644 index 0000000..dfa2955 --- /dev/null +++ b/test/ecpubkey.js @@ -0,0 +1,95 @@ +var assert = require('assert') + +var ECPubKey = require('..').ECPubKey + +describe('ECPubKey', function() { + describe('toBuffer/toHex', function() { + var hcpub = '024b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea811992' + var hpub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566' + + it('using toHex should support compression', function() { + var pub = ECPubKey.fromHex(hcpub) + + assert.equal(pub.toHex(), hcpub) + assert.equal(pub.compressed, true) + }) + + it('using toHex should support uncompressed', function() { + var pub = ECPubKey.fromHex(hpub) + + assert.equal(pub.toHex(), hpub) + assert.equal(pub.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('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('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) + } + }) + }) +})