diff --git a/src/crypto.js b/src/crypto.js index 64d69e6..6937f05 100644 --- a/src/crypto.js +++ b/src/crypto.js @@ -1,4 +1,5 @@ // Crypto, crypto, where art thou crypto +var assert = require('assert') var CryptoJS = require('crypto-js') var crypto = require('crypto') var convert = require('./convert') @@ -32,9 +33,23 @@ function sha256(buffer) { return crypto.createHash('sha256').update(buffer).digest() } +// FIXME: Name not consistent with others +function HmacSHA512(data, secret) { + assert(Buffer.isBuffer(data), 'Expected Buffer for data, got ' + data) + assert(Buffer.isBuffer(secret), 'Expected Buffer for secret, got ' + secret) + + var dataWords = convert.bytesToWordArray(data) + var secretWords = convert.bytesToWordArray(secret) + + var hash = CryptoJS.HmacSHA512(dataWords, secretWords) + + return new Buffer(convert.wordArrayToBytes(hash)) +} + module.exports = { sha1: sha1, sha256: sha256, hash160: hash160, - hash256: hash256 + hash256: hash256, + HmacSHA512: HmacSHA512 } diff --git a/src/hdwallet.js b/src/hdwallet.js index 513d08a..c0d68db 100644 --- a/src/hdwallet.js +++ b/src/hdwallet.js @@ -4,7 +4,6 @@ var convert = require('./convert') var Address = require('./address') var BigInteger = require('bigi') -var CJS = require('crypto-js') var crypto = require('./crypto') var ECKey = require('./eckey').ECKey var ECPubKey = require('./eckey').ECPubKey @@ -13,18 +12,6 @@ var networks = require('./networks') var sec = require('./sec') var ecparams = sec("secp256k1") -function HmacSHA512(data, secret) { - assert(Buffer.isBuffer(data)) - assert(Buffer.isBuffer(secret)) - - var dataWords = convert.bytesToWordArray(data) - var secretWords = convert.bytesToWordArray(secret) - - var hash = CJS.HmacSHA512(dataWords, secretWords) - - return new Buffer(convert.wordArrayToBytes(hash)) -} - function HDWallet(seed, networkString) { if (seed == undefined) return; // FIXME: Boo, should be stricter @@ -34,7 +21,7 @@ function HDWallet(seed, networkString) { throw new Error("Unknown network: " + this.network) } - var I = HmacSHA512(seed, HDWallet.MASTER_SECRET) + var I = crypto.HmacSHA512(seed, HDWallet.MASTER_SECRET) var IL = I.slice(0, 32) var IR = I.slice(32) @@ -217,7 +204,7 @@ HDWallet.prototype.derive = function(index) { ]) } - var I = HmacSHA512(data, this.chaincode) + var I = crypto.HmacSHA512(data, this.chaincode) var IL = I.slice(0, 32) var IR = I.slice(32) diff --git a/test/crypto.js b/test/crypto.js index 9b2068b..ff414d7 100644 --- a/test/crypto.js +++ b/test/crypto.js @@ -46,4 +46,18 @@ describe('Crypto', function() { }) }) }) + + describe('HMAC SHA512', function() { + it('matches the test vector', function() { + fixture.before.hex.forEach(function(hex, i) { + var data = new Buffer(hex, 'hex') + var secret = new Buffer(fixture.after.hmacsha512.secret) + + var actual = crypto.HmacSHA512(data, secret) + var expected = fixture.after.hmacsha512.hash[i] + + assert.equal(actual.toString('hex'), expected) + }) + }) + }) }) diff --git a/test/fixtures/crypto.js b/test/fixtures/crypto.js index 790fa9e..1600a06 100644 --- a/test/fixtures/crypto.js +++ b/test/fixtures/crypto.js @@ -32,6 +32,15 @@ module.exports = { '04abc8821a06e5a30937967d11ad10221cb5ac3b5273e434f1284ee87129a061', '12a3ae445661ce5dee78d0650d33362dec29c4f82af05e7e57fb595bbbacf0ca', 'a7fb8276035057ed6479c5f2305a96da100ac43f0ac10f277e5ab8c5457429da' - ] + ], + hmacsha512: { + secret: 'vires is numeris', + hash: [ + '4c0595aed1f5d066ea9f797727c060eb86cb55ff29d4d4fd2cd0ad3a012386763aea604c030619c79aa7fd8d03cda1b73a9ebd17906a3d2a350108d1a98b24ac', + 'f80b90d63b804b3d2ab03b9bfb3ac94ee271352eb8bddfb6b4f5cf2a4fc9176acea35f517728e64943d1eb8af1e4674a114082c81bc8874d88b408b3b406d6a4', + '134cf60c30a5cd412c7a5cd6c3f878279e139b47c19550b7456fa137fbf90e580ae0a923a22052f42ec801ac658db32821e271161b563eac4926285ba6b8f410', + '7dee95aa3c462d3eb7ecb61536cb215e471d1fa73d8643a967905946e26c536588c5058abd5a049a22b987db95a7fb420f3bff12359dc53d03d7ce7df714e029' + ] + } } }