Comparing version 1.0.4 to 1.1.0
80
index.js
@@ -1,6 +0,6 @@ | ||
var Crypto = require('crypto-js') | ||
var CryptoJS = require('crypto-js') | ||
var path = require('path') | ||
var includeFolder = require('include-folder') | ||
var Wordlists = includeFolder(path.join(__dirname, 'wordlists')) | ||
var randomBytes = require('crypto').randomBytes | ||
var crypto = require('crypto') | ||
@@ -15,15 +15,15 @@ module.exports = BIP39 | ||
BIP39.prototype.mnemonicToSeed = function(mnemonic, password){ | ||
var options = {iterations: 2048, hasher: Crypto.algo.SHA512, keySize: 512/32} | ||
return Crypto.PBKDF2(mnemonic, salt(password), options).toString(Crypto.enc.Hex) | ||
var options = {iterations: 2048, hasher: CryptoJS.algo.SHA512, keySize: 512/32} | ||
return CryptoJS.PBKDF2(mnemonic, salt(password), options).toString(CryptoJS.enc.Hex) | ||
} | ||
BIP39.prototype.entropyToMnemonic = function(entropy){ | ||
var entropyBytes = hexToBytes(entropy) | ||
var bits = bytesToBinary(entropyBytes) | ||
var entropyBuffer = new Buffer(entropy, 'hex') | ||
var hash = crypto.createHash('sha256').update(entropyBuffer).digest() | ||
var hash = Crypto.SHA256(bytesToWordArray(entropyBytes)) | ||
var checksumBits = bytesToBinary(wordsToBytes(hash.words)) | ||
var checksum = checksumBits.substr(0, bits.length / 32) | ||
var combined = Buffer.concat([entropyBuffer, hash]) | ||
var bitLength = entropyBuffer.length * 8 + entropyBuffer.length / 4 | ||
var bits = bytesToBinary([].slice.call(combined)).substr(0, bitLength) | ||
var chunks = (bits + checksum).match(/(.{1,11})/g) | ||
var chunks = (bits).match(/(.{1,11})/g) | ||
return chunks.map(function(binary){ | ||
@@ -37,6 +37,38 @@ var index = parseInt(binary, 2) | ||
strength = strength || 128 | ||
var entropy = randomBytes(strength/8).toString('hex') | ||
var entropy = crypto.randomBytes(strength/8).toString('hex') | ||
return this.entropyToMnemonic(entropy) | ||
} | ||
BIP39.prototype.validate = function(mnemonic){ | ||
mnemonic = mnemonic.split(' ') | ||
if(mnemonic.length % 3 !== 0) return false | ||
var wordlist = this.wordlist | ||
var belongToList = mnemonic.reduce(function(memo, m){ | ||
return memo && (wordlist.indexOf(m) > -1) | ||
}, true) | ||
if(!belongToList) return false | ||
var bits = mnemonic.map(function(m){ | ||
var id = wordlist.indexOf(m) | ||
return lpad(id.toString(2), '0', 11) | ||
}).join('') | ||
var length = bits.length | ||
var dividerIndex = Math.floor(length / 33) * 32 | ||
var checksum = bits.substring(dividerIndex) | ||
var data = bits.substring(0, dividerIndex) | ||
var bytes = data.match(/(.{1,8})/g).map(function(bin){ | ||
return parseInt(bin, 2) | ||
}) | ||
var hash = crypto.createHash('sha256').update(new Buffer(bytes)).digest() | ||
var checksumBits = bytesToBinary([].slice.call(hash)) | ||
var checksum2 = checksumBits.substr(0, length - dividerIndex) | ||
return checksum === checksum2 | ||
} | ||
function salt(password) { | ||
@@ -52,8 +84,2 @@ return encode_utf8('mnemonic' + (password || '')) | ||
function hexToBytes(hex) { | ||
return hex.match(/../g).map(function(x) { | ||
return parseInt(x,16) | ||
}); | ||
} | ||
function bytesToBinary(bytes) { | ||
@@ -65,22 +91,2 @@ return bytes.map(function(x) { | ||
function bytesToWordArray(bytes) { | ||
return new Crypto.lib.WordArray.init(bytesToWords(bytes), bytes.length) | ||
} | ||
function bytesToWords(bytes) { | ||
var words = []; | ||
for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { | ||
words[b >>> 5] |= bytes[i] << (24 - b % 32); | ||
} | ||
return words; | ||
} | ||
function wordsToBytes(words) { | ||
var bytes = []; | ||
for (var b = 0; b < words.length * 32; b += 8) { | ||
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); | ||
} | ||
return bytes; | ||
} | ||
function lpad(str, padString, length) { | ||
@@ -87,0 +93,0 @@ while (str.length < length) str = padString + str; |
{ | ||
"name": "bip39", | ||
"version": "1.0.4", | ||
"version": "1.1.0", | ||
"description": "Bitcoin BIP39: Mnemonic code for generating deterministic keys", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -29,1 +29,22 @@ var vectors = require('./vectors.json').english | ||
}) | ||
describe('validate', function(){ | ||
vectors.forEach(function(v, i){ | ||
it('passes check ' + i, function(){ | ||
assert(bip39.validate(v[1])) | ||
}) | ||
}) | ||
it('fails for mnemonics of wrong length', function(){ | ||
assert(!bip39.validate('sleep kitten')) | ||
assert(!bip39.validate('sleep kitten sleep kitten sleep kitten')) | ||
}) | ||
it('fails for mnemonics that contains words not from the word list', function(){ | ||
assert(!bip39.validate("turtle front uncle idea crush write shrug there lottery flower risky shell")) | ||
}) | ||
it('fails for mnemonics of invalid checksum', function(){ | ||
assert(!bip39.validate('sleep kitten sleep kitten sleep kitten sleep kitten sleep kitten sleep kitten')) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36730
2286