diff --git a/src/convert.js b/src/convert.js index b0449c8..0188ffa 100644 --- a/src/convert.js +++ b/src/convert.js @@ -24,15 +24,6 @@ function hexToBytes(hex) { }) } -/** - * Create a byte array representing a number with the given length - */ -function numToBytes(num, bytes) { - if (bytes === undefined) bytes = 8 - if (bytes === 0) return [] - return [num % 256].concat(numToBytes(Math.floor(num / 256), bytes - 1)) -} - /** * Convert a byte array to the number that it represents */ @@ -41,42 +32,6 @@ function bytesToNum(bytes) { return bytes[0] + 256 * bytesToNum(bytes.slice(1)) } -/** - * Turn an integer into a "var_int". - * - * "var_int" is a variable length integer used by Bitcoin's binary format. - * - * Returns a byte array. - */ -function numToVarInt(num) { - if (num < 253) return [num] - if (num < 65536) return [253].concat(numToBytes(num, 2)) - if (num < 4294967296) return [254].concat(numToBytes(num, 4)) - return [255].concat(numToBytes(num, 8)) -} - -/** - * Turn an VarInt into an integer - * - * "var_int" is a variable length integer used by Bitcoin's binary format. - * - * Returns { bytes: bytesUsed, number: theNumber } - */ -function varIntToNum(bytes) { - var prefix = bytes[0] - - var viBytes = - prefix < 253 ? bytes.slice(0, 1) - : prefix === 253 ? bytes.slice(1, 3) - : prefix === 254 ? bytes.slice(1, 5) - : bytes.slice(1, 9) - - return { - bytes: prefix < 253 ? viBytes : bytes.slice(0, viBytes.length + 1), - number: bytesToNum(viBytes) - } -} - function bytesToWords(bytes) { assert(Array.isArray(bytes) || Buffer.isBuffer(bytes), 'Input must be a byte array') var words = [] @@ -110,10 +65,7 @@ module.exports = { lpad: lpad, bytesToHex: bytesToHex, hexToBytes: hexToBytes, - numToBytes: numToBytes, bytesToNum: bytesToNum, - numToVarInt: numToVarInt, - varIntToNum: varIntToNum, bytesToWords: bytesToWords, wordsToBytes: wordsToBytes, bytesToWordArray: bytesToWordArray, diff --git a/src/hdwallet.js b/src/hdwallet.js index 11c5a94..7b57986 100644 --- a/src/hdwallet.js +++ b/src/hdwallet.js @@ -179,10 +179,11 @@ HDWallet.prototype.toBase58 = function(priv) { } HDWallet.prototype.derive = function(i) { - var iBytes = convert.numToBytes(i, 4).reverse() - , cPar = this.chaincode - , usePriv = i >= HDWallet.HIGHEST_BIT - , SHA512 = CJS.algo.SHA512 + var IB = new Buffer(4) + IB.writeUInt32BE(i, 0) + + var cPar = this.chaincode + var usePriv = i >= HDWallet.HIGHEST_BIT var I if (usePriv) { @@ -191,18 +192,18 @@ HDWallet.prototype.derive = function(i) { // If 1, private derivation is used: // let I = HMAC-SHA512(Key = cpar, Data = 0x00 || kpar || i) [Note:] var kPar = this.priv.toBuffer().slice(0, 32) - kPar = Array.prototype.slice.call(kPar) + IB = Buffer.concat([new Buffer([0]), kPar, IB], 37) // FIXME: Dislikes buffers - I = HmacFromBytesToBytes(SHA512, [0].concat(kPar, iBytes), cPar) + I = HmacFromBytesToBytes(CJS.algo.SHA512, Array.prototype.slice.call(IB), cPar) } else { // If 0, public derivation is used: // let I = HMAC-SHA512(Key = cpar, Data = χ(kpar*G) || i) var KPar = this.pub.toBuffer() - KPar = Array.prototype.slice.call(KPar) + IB = Buffer.concat([KPar, IB]) // FIXME: Dislikes buffers - I = HmacFromBytesToBytes(SHA512, KPar.concat(iBytes), cPar) + I = HmacFromBytesToBytes(CJS.algo.SHA512, Array.prototype.slice.call(IB), cPar) } diff --git a/src/message.js b/src/message.js index f389398..2091156 100644 --- a/src/message.js +++ b/src/message.js @@ -1,24 +1,20 @@ /// Implements Bitcoin's feature for signing arbitrary messages. var Address = require('./address') -var convert = require('./convert') +var BufferExt = require('./buffer') var crypto = require('./crypto') var ecdsa = require('./ecdsa') var ECPubKey = require('./eckey').ECPubKey -// FIXME: magicHash is incompatible with other magic messages -var magicBytes = new Buffer('Bitcoin Signed Message:\n') +// FIXME: incompatible with other networks (Litecoin etc) +var magicBuffer = new Buffer('\x18Bitcoin Signed Message:\n') function magicHash(message) { - var messageBytes = new Buffer(message) - - var buffer = Buffer.concat([ - new Buffer(convert.numToVarInt(magicBytes.length)), - magicBytes, - new Buffer(convert.numToVarInt(messageBytes.length)), - messageBytes - ]) + var mB = new Buffer(message) + var mVI = new Buffer(BufferExt.varIntSize(mB.length)) + BufferExt.writeVarInt(mVI, mB.length, 0) + var buffer = Buffer.concat([magicBuffer, mVI, mB]) return crypto.hash256(buffer) } diff --git a/test/convert.js b/test/convert.js index 26b3307..a22907f 100644 --- a/test/convert.js +++ b/test/convert.js @@ -52,67 +52,6 @@ describe('convert', function() { }) }) - describe('numToVarInt', function() { - describe('works', function() { - var data = [ - 0, 128, 252, // 8-bit - 256, 512, 1024, // 16-bit - 65541, // 32-bit - 4294967299, // 64-bit - ] - var expected = [ - [0], [128], [252], // 8-bit - [253, 0, 1], [253, 0, 2], [253, 0, 4], // 16-bit - [254, 5, 0, 1, 0], // 32-bit - [255, 3, 0, 0, 0, 1, 0, 0, 0] // 64-bit - ] - - for (var i = 0; i < data.length; ++i) { - var actual = convert.numToVarInt(data[i]) - assert.deepEqual(actual, expected[i]) - } - }) - }) - - describe('varIntToNum', function() { - it('works on valid input', function() { - var data = [ - [0], [128], [252], // 8-bit - [253, 0, 1], [253, 0, 2], [253, 0, 4], // 16-bit - [254, 5, 0, 1, 0], // 32-bit - [255, 3, 0, 0, 0, 1, 0, 0, 0] // 64-bit - ] - var expected = [ - 0, 128, 252, // 8-bit - 256, 512, 1024, // 16-bit - 65541, // 32-bit - 4294967299, // 64-bit - ] - - for (var i = 0; i < data.length; ++i) { - var actual = convert.varIntToNum(data[i]) - assert.equal(actual.number, expected[i]) - assert.deepEqual(actual.bytes, data[i]) - } - }) - - it('uses only what is necessary', function() { - var data = [ - [0, 99], - [253, 0, 1, 99], - [254, 5, 0, 1, 0, 99], - [255, 3, 0, 0, 0, 1, 0, 0, 0, 99] - ] - var expected = [0, 256, 65541, 4294967299] - - for (var i = 0; i < data.length; ++i) { - var actual = convert.varIntToNum(data[i]) - assert.equal(actual.number, expected[i]) - assert.deepEqual(actual.bytes, data[i].slice(0, -1)) - } - }) - }) - describe('reverseEndian', function() { it('works', function() { var bigEndian = "6a4062273ac4f9ea4ffca52d9fd102b08f6c32faa0a4d1318e3a7b2e437bb9c7"