mnemonic: optimize fromPhrase.
This commit is contained in:
parent
fbd99ea1b9
commit
bff9e25796
@ -19,6 +19,12 @@ const wordlist = require('./wordlist');
|
|||||||
const common = require('./common');
|
const common = require('./common');
|
||||||
const nfkd = require('../utils/nfkd');
|
const nfkd = require('../utils/nfkd');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Constants
|
||||||
|
*/
|
||||||
|
|
||||||
|
const wordlistCache = new Map();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HD Mnemonic
|
* HD Mnemonic
|
||||||
* @alias module:hd.Mnemonic
|
* @alias module:hd.Mnemonic
|
||||||
@ -191,7 +197,7 @@ Mnemonic.prototype.getPhrase = function getPhrase() {
|
|||||||
|
|
||||||
// Build the mnemonic by reading
|
// Build the mnemonic by reading
|
||||||
// 11 bit indexes from the entropy.
|
// 11 bit indexes from the entropy.
|
||||||
const wordlist = Mnemonic.getWordlist(this.language);
|
const list = Mnemonic.getWordlist(this.language);
|
||||||
|
|
||||||
let phrase = [];
|
let phrase = [];
|
||||||
for (let i = 0; i < bits / 11; i++) {
|
for (let i = 0; i < bits / 11; i++) {
|
||||||
@ -203,7 +209,7 @@ Mnemonic.prototype.getPhrase = function getPhrase() {
|
|||||||
index <<= 1;
|
index <<= 1;
|
||||||
index |= (entropy[oct] >>> (7 - bit)) & 1;
|
index |= (entropy[oct] >>> (7 - bit)) & 1;
|
||||||
}
|
}
|
||||||
phrase.push(wordlist[index]);
|
phrase.push(list.words[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Japanese likes double-width spaces.
|
// Japanese likes double-width spaces.
|
||||||
@ -224,6 +230,9 @@ Mnemonic.prototype.getPhrase = function getPhrase() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) {
|
Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) {
|
||||||
|
assert(typeof phrase === 'string');
|
||||||
|
assert(phrase.length <= 1000);
|
||||||
|
|
||||||
const words = phrase.split(/[ \u3000]+/);
|
const words = phrase.split(/[ \u3000]+/);
|
||||||
let bits = words.length * 11;
|
let bits = words.length * 11;
|
||||||
const cbits = bits % 32;
|
const cbits = bits % 32;
|
||||||
@ -240,14 +249,14 @@ Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) {
|
|||||||
ent.fill(0);
|
ent.fill(0);
|
||||||
|
|
||||||
const lang = Mnemonic.getLanguage(words[0]);
|
const lang = Mnemonic.getLanguage(words[0]);
|
||||||
const wordlist = Mnemonic.getWordlist(lang);
|
const list = Mnemonic.getWordlist(lang);
|
||||||
|
|
||||||
// Rebuild entropy bytes.
|
// Rebuild entropy bytes.
|
||||||
for (let i = 0; i < words.length; i++) {
|
for (let i = 0; i < words.length; i++) {
|
||||||
const word = words[i];
|
const word = words[i];
|
||||||
const index = wordlist.indexOf(word);
|
const index = list.map.get(word);
|
||||||
|
|
||||||
if (index === -1)
|
if (index == null)
|
||||||
throw new Error('Could not find word.');
|
throw new Error('Could not find word.');
|
||||||
|
|
||||||
for (let j = 0; j < 11; j++) {
|
for (let j = 0; j < 11; j++) {
|
||||||
@ -267,9 +276,9 @@ Mnemonic.prototype.fromPhrase = function fromPhrase(phrase) {
|
|||||||
for (let i = 0; i < cbits; i++) {
|
for (let i = 0; i < cbits; i++) {
|
||||||
const bit = i % 8;
|
const bit = i % 8;
|
||||||
const oct = (i - bit) / 8;
|
const oct = (i - bit) / 8;
|
||||||
const a = (chk1[oct] >>> (7 - bit)) & 1;
|
const b1 = (chk1[oct] >>> (7 - bit)) & 1;
|
||||||
const b = (chk2[oct] >>> (7 - bit)) & 1;
|
const b2 = (chk2[oct] >>> (7 - bit)) & 1;
|
||||||
if (a !== b)
|
if (b1 !== b2)
|
||||||
throw new Error('Invalid checksum.');
|
throw new Error('Invalid checksum.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,8 +346,8 @@ Mnemonic.fromEntropy = function fromEntropy(entropy, lang) {
|
|||||||
|
|
||||||
Mnemonic.getLanguage = function getLanguage(word) {
|
Mnemonic.getLanguage = function getLanguage(word) {
|
||||||
for (const lang of Mnemonic.languages) {
|
for (const lang of Mnemonic.languages) {
|
||||||
const wordlist = Mnemonic.getWordlist(lang);
|
const list = Mnemonic.getWordlist(lang);
|
||||||
if (wordlist.indexOf(word) !== -1)
|
if (list.map.has(word))
|
||||||
return lang;
|
return lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,12 +356,22 @@ Mnemonic.getLanguage = function getLanguage(word) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the wordlist for a language.
|
* Retrieve the wordlist for a language.
|
||||||
* @param {String} language
|
* @param {String} lang
|
||||||
* @returns {String[]}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Mnemonic.getWordlist = function getWordlist(language) {
|
Mnemonic.getWordlist = function getWordlist(lang) {
|
||||||
return wordlist.get(language);
|
const cache = wordlistCache.get(lang);
|
||||||
|
|
||||||
|
if (cache)
|
||||||
|
return cache;
|
||||||
|
|
||||||
|
const words = wordlist.get(lang);
|
||||||
|
const list = new WordList(words);
|
||||||
|
|
||||||
|
wordlistCache.set(lang, list);
|
||||||
|
|
||||||
|
return list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -530,6 +549,23 @@ Mnemonic.isMnemonic = function isMnemonic(obj) {
|
|||||||
&& typeof obj.toSeed === 'function';
|
&& typeof obj.toSeed === 'function';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Word List
|
||||||
|
* @constructor
|
||||||
|
* @ignore
|
||||||
|
* @param {Array} words
|
||||||
|
*/
|
||||||
|
|
||||||
|
function WordList(words) {
|
||||||
|
this.words = words;
|
||||||
|
this.map = new Map();
|
||||||
|
|
||||||
|
for (let i = 0; i < words.length; i++) {
|
||||||
|
const word = words[i];
|
||||||
|
this.map.set(word, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user