diff --git a/bitcore.js b/bitcore.js
index 43de754..282a9c8 100644
--- a/bitcore.js
+++ b/bitcore.js
@@ -43,7 +43,7 @@ Object.defineProperty(module.exports, 'BIP32', {get: function() {
return require('./lib/HierarchicalKey');
}});
requireWhenAccessed('BIP39', './lib/BIP39');
-requireWhenAccessed('BIP39WordlistEn', './BIP39WordlistEn');
+requireWhenAccessed('BIP39WordlistEn', './lib/BIP39WordlistEn');
requireWhenAccessed('Point', './lib/Point');
requireWhenAccessed('Opcode', './lib/Opcode');
requireWhenAccessed('Script', './lib/Script');
diff --git a/browser/build.js b/browser/build.js
index e938663..364a986 100644
--- a/browser/build.js
+++ b/browser/build.js
@@ -27,6 +27,9 @@ var modules = [
'lib/Armory',
'lib/Base58',
'lib/HierarchicalKey',
+ 'lib/BIP39',
+ 'lib/BIP39WordlistEn',
+ 'lib/cryptox',
'lib/Block',
'lib/Bloom',
'lib/Connection',
diff --git a/lib/browser/cryptox.js b/lib/browser/cryptox.js
new file mode 100644
index 0000000..71647ea
--- /dev/null
+++ b/lib/browser/cryptox.js
@@ -0,0 +1,41 @@
+// Crypto extensions
+//
+// PBKDF2 with SHA512 - browser version
+
+var jssha = require('jssha')
+
+var pbkdf2_sha512 = function (password, salt, keylen, options) {
+ password = new Buffer(password);
+ salt = new Buffer(salt);
+ // Defaults
+ var iterations = options && options.iterations || 1;
+
+ // Pseudo-random function
+ function PRF(password, salt) {
+ var j = new jssha(salt.toString('hex'), 'HEX');
+ var hash = j.getHMAC(password.toString('hex'), "HEX", "SHA-512", "HEX");
+ return new Buffer(hash, 'hex');
+ }
+
+ // Generate key
+ var derivedKeyBytes = new Buffer([]),
+ blockindex = 1;
+ while (derivedKeyBytes.length < keylen) {
+ var block = PRF(password, salt.concat([0, 0, 0, blockindex]));
+ for (var u = block, i = 1; i < iterations; i++) {
+ u = PRF(password, u);
+ for (var j = 0; j < block.length; j++) block[j] ^= u[j];
+ }
+ derivedKeyBytes = derivedKeyBytes.concat(block);
+ blockindex++;
+ }
+
+ // Truncate excess bytes - TODO
+ //derivedKeyBytes.length = keylen;
+
+ return new Buffer(derivedKeyBytes);
+};
+
+exports.pbkdf2Sync_sha512 = function(password, salt, iterations, keylen) {
+ return pbkdf2_sha512(password, salt, keylen, {iterations: iterations});
+};
diff --git a/lib/cryptox.js b/lib/cryptox.js
index 240736c..7f382df 100644
--- a/lib/cryptox.js
+++ b/lib/cryptox.js
@@ -1,49 +1,5 @@
-// Crypto extensions
-//
-// PBKDF2 with SHA512
-
-var binding = require('bindings')('cryptox');
-
-exports.pbkdf2_sha512 = function(password, salt, iterations, keylen, callback) {
- if (typeof callback !== 'function')
- throw new Error('No callback provided to pbkdf2');
-
- return pbkdf2_sha512(password, salt, iterations, keylen, callback);
-};
-
-
-exports.pbkdf2Sync_sha512 = function(password, salt, iterations, keylen) {
- return pbkdf2_sha512(password, salt, iterations, keylen);
-};
-
-function toBuf(str, encoding) {
- encoding = encoding || 'binary';
- if (typeof str === 'string') {
- if (encoding === 'buffer')
- encoding = 'binary';
- str = new Buffer(str, encoding);
- }
- return str;
-}
-
-function pbkdf2_sha512(password, salt, iterations, keylen, callback) {
- password = toBuf(password);
- salt = toBuf(salt);
-
- if (exports.DEFAULT_ENCODING === 'buffer')
- return binding.PBKDF2(password, salt, iterations, keylen, callback);
-
- // at this point, we need to handle encodings.
- var encoding = exports.DEFAULT_ENCODING;
- if (callback) {
- binding.PBKDF2_sha512(password, salt, iterations, keylen, function(er, ret) {
- if (ret)
- ret = ret.toString(encoding);
- callback(er, ret);
- });
- } else {
- var ret = binding.PBKDF2_sha512(password, salt, iterations, keylen);
- //return ret.toString(encoding);
- return ret;
- }
+if (process.versions) {
+ module.exports = require('./node/cryptox');
+ return;
}
+module.exports = require('./browser/cryptox');
diff --git a/lib/node/cryptox.js b/lib/node/cryptox.js
new file mode 100644
index 0000000..240736c
--- /dev/null
+++ b/lib/node/cryptox.js
@@ -0,0 +1,49 @@
+// Crypto extensions
+//
+// PBKDF2 with SHA512
+
+var binding = require('bindings')('cryptox');
+
+exports.pbkdf2_sha512 = function(password, salt, iterations, keylen, callback) {
+ if (typeof callback !== 'function')
+ throw new Error('No callback provided to pbkdf2');
+
+ return pbkdf2_sha512(password, salt, iterations, keylen, callback);
+};
+
+
+exports.pbkdf2Sync_sha512 = function(password, salt, iterations, keylen) {
+ return pbkdf2_sha512(password, salt, iterations, keylen);
+};
+
+function toBuf(str, encoding) {
+ encoding = encoding || 'binary';
+ if (typeof str === 'string') {
+ if (encoding === 'buffer')
+ encoding = 'binary';
+ str = new Buffer(str, encoding);
+ }
+ return str;
+}
+
+function pbkdf2_sha512(password, salt, iterations, keylen, callback) {
+ password = toBuf(password);
+ salt = toBuf(salt);
+
+ if (exports.DEFAULT_ENCODING === 'buffer')
+ return binding.PBKDF2(password, salt, iterations, keylen, callback);
+
+ // at this point, we need to handle encodings.
+ var encoding = exports.DEFAULT_ENCODING;
+ if (callback) {
+ binding.PBKDF2_sha512(password, salt, iterations, keylen, function(er, ret) {
+ if (ret)
+ ret = ret.toString(encoding);
+ callback(er, ret);
+ });
+ } else {
+ var ret = binding.PBKDF2_sha512(password, salt, iterations, keylen);
+ //return ret.toString(encoding);
+ return ret;
+ }
+}
diff --git a/test/index.html b/test/index.html
index 7e036ce..c0bab93 100644
--- a/test/index.html
+++ b/test/index.html
@@ -20,6 +20,7 @@
+
diff --git a/test/test.BIP39.js b/test/test.BIP39.js
index 0f8d810..03118ec 100644
--- a/test/test.BIP39.js
+++ b/test/test.BIP39.js
@@ -154,7 +154,7 @@ describe('BIP39', function() {
var mnemonic1 = BIP39.to_mnemonic(BIP39WordlistEn, new Buffer(code, 'hex'));
var seed1 = BIP39.mnemonic_to_seed(mnemonic, 'TREZOR');
mnemonic1.should.equal(mnemonic);
- seed1.toString().should.equal(new Buffer(seed, 'hex').toString());
+ seed1.toString('hex').should.equal(seed)
}
});
});