BIP39 in browser
This commit is contained in:
parent
f2472e691b
commit
79d50e92d4
|
@ -43,7 +43,7 @@ Object.defineProperty(module.exports, 'BIP32', {get: function() {
|
||||||
return require('./lib/HierarchicalKey');
|
return require('./lib/HierarchicalKey');
|
||||||
}});
|
}});
|
||||||
requireWhenAccessed('BIP39', './lib/BIP39');
|
requireWhenAccessed('BIP39', './lib/BIP39');
|
||||||
requireWhenAccessed('BIP39WordlistEn', './BIP39WordlistEn');
|
requireWhenAccessed('BIP39WordlistEn', './lib/BIP39WordlistEn');
|
||||||
requireWhenAccessed('Point', './lib/Point');
|
requireWhenAccessed('Point', './lib/Point');
|
||||||
requireWhenAccessed('Opcode', './lib/Opcode');
|
requireWhenAccessed('Opcode', './lib/Opcode');
|
||||||
requireWhenAccessed('Script', './lib/Script');
|
requireWhenAccessed('Script', './lib/Script');
|
||||||
|
|
|
@ -27,6 +27,9 @@ var modules = [
|
||||||
'lib/Armory',
|
'lib/Armory',
|
||||||
'lib/Base58',
|
'lib/Base58',
|
||||||
'lib/HierarchicalKey',
|
'lib/HierarchicalKey',
|
||||||
|
'lib/BIP39',
|
||||||
|
'lib/BIP39WordlistEn',
|
||||||
|
'lib/cryptox',
|
||||||
'lib/Block',
|
'lib/Block',
|
||||||
'lib/Bloom',
|
'lib/Bloom',
|
||||||
'lib/Connection',
|
'lib/Connection',
|
||||||
|
|
|
@ -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});
|
||||||
|
};
|
|
@ -1,49 +1,5 @@
|
||||||
// Crypto extensions
|
if (process.versions) {
|
||||||
//
|
module.exports = require('./node/cryptox');
|
||||||
// PBKDF2 with SHA512
|
return;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
module.exports = require('./browser/cryptox');
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
<script src="test.basic.js"></script>
|
<script src="test.basic.js"></script>
|
||||||
<script src="test.Bignum.browser.js"></script>
|
<script src="test.Bignum.browser.js"></script>
|
||||||
<script src="test.BIP32.js"></script>
|
<script src="test.BIP32.js"></script>
|
||||||
|
<script src="test.BIP39.js"></script>
|
||||||
<script src="test.Block.js"></script>
|
<script src="test.Block.js"></script>
|
||||||
<script src="test.Bloom.js"></script>
|
<script src="test.Bloom.js"></script>
|
||||||
<script src="test.Connection.js"></script>
|
<script src="test.Connection.js"></script>
|
||||||
|
|
|
@ -154,7 +154,7 @@ describe('BIP39', function() {
|
||||||
var mnemonic1 = BIP39.to_mnemonic(BIP39WordlistEn, new Buffer(code, 'hex'));
|
var mnemonic1 = BIP39.to_mnemonic(BIP39WordlistEn, new Buffer(code, 'hex'));
|
||||||
var seed1 = BIP39.mnemonic_to_seed(mnemonic, 'TREZOR');
|
var seed1 = BIP39.mnemonic_to_seed(mnemonic, 'TREZOR');
|
||||||
mnemonic1.should.equal(mnemonic);
|
mnemonic1.should.equal(mnemonic);
|
||||||
seed1.toString().should.equal(new Buffer(seed, 'hex').toString());
|
seed1.toString('hex').should.equal(seed)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue