Skip to content

Commit

Permalink
Merge pull request #9 from dcousens/backwards
Browse files Browse the repository at this point in the history
index: add mnemonicToEntropy backwards function
  • Loading branch information
weilu committed Aug 17, 2014
2 parents f14d875 + 4073704 commit 4976ee9
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 30 deletions.
73 changes: 43 additions & 30 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var assert = require('assert')
var CryptoJS = require('crypto-js')
var crypto = require('crypto')
var secureRandom = require('secure-random')
Expand All @@ -9,6 +10,41 @@ function mnemonicToSeedHex(mnemonic, password) {
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) {
wordlist = wordlist || DEFAULT_WORDLIST

Expand Down Expand Up @@ -37,37 +73,13 @@ function generateMnemonic(strength, rng, wordlist) {
}

function validateMnemonic(mnemonic, wordlist) {
wordlist = wordlist || DEFAULT_WORDLIST

var words = mnemonic.split(' ')

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)
try {
mnemonicToEntropy(mnemonic, wordlist)
} catch (e) {
return false
}

return newChecksum === checksum
return true
}

function checksumBits(entropyBuffer) {
Expand Down Expand Up @@ -103,6 +115,7 @@ function lpad(str, padString, length) {

module.exports = {
mnemonicToSeedHex: mnemonicToSeedHex,
mnemonicToEntropy: mnemonicToEntropy,
entropyToMnemonic: entropyToMnemonic,
generateMnemonic: generateMnemonic,
validateMnemonic: validateMnemonic
Expand Down
14 changes: 14 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
vectors.english.forEach(function(v, i) {
it('works for tests vector ' + i, function() {
Expand Down

0 comments on commit 4976ee9

Please sign in to comment.