mirror of https://github.com/status-im/bip39.git
index: add mnemonicToEntropy backwards function
This commit is contained in:
parent
f14d8757f1
commit
40737046ab
73
index.js
73
index.js
|
@ -1,3 +1,4 @@
|
||||||
|
var assert = require('assert')
|
||||||
var CryptoJS = require('crypto-js')
|
var CryptoJS = require('crypto-js')
|
||||||
var crypto = require('crypto')
|
var crypto = require('crypto')
|
||||||
var secureRandom = require('secure-random')
|
var secureRandom = require('secure-random')
|
||||||
|
@ -9,6 +10,41 @@ function mnemonicToSeedHex(mnemonic, password) {
|
||||||
return CryptoJS.PBKDF2(mnemonic, salt(password), options).toString(CryptoJS.enc.Hex)
|
return CryptoJS.PBKDF2(mnemonic, salt(password), options).toString(CryptoJS.enc.Hex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mnemonicToEntropy(mnemonic, wordlist) {
|
||||||
|
wordlist = wordlist || DEFAULT_WORDLIST
|
||||||
|
|
||||||
|
var words = mnemonic.split(' ')
|
||||||
|
assert(words.length % 3 === 0, 'Invalid mnemonic')
|
||||||
|
|
||||||
|
var belongToList = words.every(function(word) {
|
||||||
|
return wordlist.indexOf(word) > -1
|
||||||
|
})
|
||||||
|
|
||||||
|
assert(belongToList, 'Invalid mnemonic')
|
||||||
|
|
||||||
|
// convert word indices to 11 bit binary strings
|
||||||
|
var bits = words.map(function(word) {
|
||||||
|
var index = wordlist.indexOf(word)
|
||||||
|
return lpad(index.toString(2), '0', 11)
|
||||||
|
}).join('')
|
||||||
|
|
||||||
|
// split the binary string into ENT/CS
|
||||||
|
var dividerIndex = Math.floor(bits.length / 33) * 32
|
||||||
|
var entropy = bits.slice(0, dividerIndex)
|
||||||
|
var checksum = bits.slice(dividerIndex)
|
||||||
|
|
||||||
|
// calculate the checksum and compare
|
||||||
|
var entropyBytes = entropy.match(/(.{1,8})/g).map(function(bin) {
|
||||||
|
return parseInt(bin, 2)
|
||||||
|
})
|
||||||
|
var entropyBuffer = new Buffer(entropyBytes)
|
||||||
|
var newChecksum = checksumBits(entropyBuffer)
|
||||||
|
|
||||||
|
assert(newChecksum === checksum, 'Invalid mnemonic checksum')
|
||||||
|
|
||||||
|
return entropyBuffer.toString('hex')
|
||||||
|
}
|
||||||
|
|
||||||
function entropyToMnemonic(entropy, wordlist) {
|
function entropyToMnemonic(entropy, wordlist) {
|
||||||
wordlist = wordlist || DEFAULT_WORDLIST
|
wordlist = wordlist || DEFAULT_WORDLIST
|
||||||
|
|
||||||
|
@ -37,37 +73,13 @@ function generateMnemonic(strength, rng, wordlist) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateMnemonic(mnemonic, wordlist) {
|
function validateMnemonic(mnemonic, wordlist) {
|
||||||
wordlist = wordlist || DEFAULT_WORDLIST
|
try {
|
||||||
|
mnemonicToEntropy(mnemonic, wordlist)
|
||||||
|
} catch (e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var words = mnemonic.split(' ')
|
return true
|
||||||
|
|
||||||
if (words.length % 3 !== 0) return false
|
|
||||||
|
|
||||||
var belongToList = words.every(function(word) {
|
|
||||||
return wordlist.indexOf(word) > -1
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!belongToList) return false
|
|
||||||
|
|
||||||
// convert word indices to 11 bit binary strings
|
|
||||||
var bits = words.map(function(word) {
|
|
||||||
var index = wordlist.indexOf(word)
|
|
||||||
return lpad(index.toString(2), '0', 11)
|
|
||||||
}).join('')
|
|
||||||
|
|
||||||
// split the binary string into ENT/CS
|
|
||||||
var dividerIndex = Math.floor(bits.length / 33) * 32
|
|
||||||
var entropy = bits.slice(0, dividerIndex)
|
|
||||||
var checksum = bits.slice(dividerIndex)
|
|
||||||
|
|
||||||
// calculate the checksum and compare
|
|
||||||
var entropyBytes = entropy.match(/(.{1,8})/g).map(function(bin) {
|
|
||||||
return parseInt(bin, 2)
|
|
||||||
})
|
|
||||||
var entropyBuffer = new Buffer(entropyBytes)
|
|
||||||
var newChecksum = checksumBits(entropyBuffer)
|
|
||||||
|
|
||||||
return newChecksum === checksum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checksumBits(entropyBuffer) {
|
function checksumBits(entropyBuffer) {
|
||||||
|
@ -103,6 +115,7 @@ function lpad(str, padString, length) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mnemonicToSeedHex: mnemonicToSeedHex,
|
mnemonicToSeedHex: mnemonicToSeedHex,
|
||||||
|
mnemonicToEntropy: mnemonicToEntropy,
|
||||||
entropyToMnemonic: entropyToMnemonic,
|
entropyToMnemonic: entropyToMnemonic,
|
||||||
generateMnemonic: generateMnemonic,
|
generateMnemonic: generateMnemonic,
|
||||||
validateMnemonic: validateMnemonic
|
validateMnemonic: validateMnemonic
|
||||||
|
|
|
@ -19,6 +19,20 @@ describe('BIP39', function() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('mnemonicToEntropy', function() {
|
||||||
|
vectors.english.forEach(function(v, i) {
|
||||||
|
it('works for tests vector ' + i, function() {
|
||||||
|
assert.equal(BIP39.mnemonicToEntropy(v[1]), v[0])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
vectors.custom.forEach(function(v, i) {
|
||||||
|
it('works for custom test vector ' + i, function() {
|
||||||
|
assert.equal(BIP39.mnemonicToEntropy(v[1], wordlists.custom), v[0])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('entropyToMnemonic', function() {
|
describe('entropyToMnemonic', function() {
|
||||||
vectors.english.forEach(function(v, i) {
|
vectors.english.forEach(function(v, i) {
|
||||||
it('works for tests vector ' + i, function() {
|
it('works for tests vector ' + i, function() {
|
||||||
|
|
Loading…
Reference in New Issue