cipher-ethereum
Version:
An Ethereum library used by Cipher Browser, a mobile Ethereum client
143 lines (134 loc) • 5.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Mnemonic = undefined;
var _crypto = require('crypto');
var crypto = _interopRequireWildcard(_crypto);
var _wordlist = require('./wordlist.en');
var _wordlist2 = _interopRequireDefault(_wordlist);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var Mnemonic = /** @class */function () {
function Mnemonic(entropy, words) {
this._entropy = entropy;
this._words = words;
}
Mnemonic.generate = function (entropy) {
if (entropy.length % 4 !== 0) {
return null;
}
var ent = entropy.length * 8;
var cs = ent / 32;
var bits = flatten(Array.from(entropy).map(uint8ToBitArray));
var shasum = crypto.createHash('sha256').update(entropy).digest();
var checksum = flatten(Array.from(shasum).map(uint8ToBitArray)).slice(0, cs);
bits.push.apply(bits, checksum);
var words = [];
for (var i = 0; i < bits.length / 11; i++) {
var idx = elevenBitsToInt(bits.slice(i * 11, (i + 1) * 11));
words.push(_wordlist2.default[idx]);
}
return new Mnemonic(entropy, words);
};
Mnemonic.parse = function (phrase) {
var words = phrase.normalize('NFKD').split(' ');
if (words.length % 3 !== 0) return null;
var bitArrays = [];
for (var i = 0; i < words.length; i++) {
var word = words[i];
var idx = _wordlist2.default.indexOf(word);
if (idx === -1) return null;
bitArrays.push(uint11ToBitArray(idx));
}
var bits = flatten(bitArrays);
var cs = bits.length / 33;
if (cs !== Math.floor(cs)) return null;
var checksum = bits.slice(-cs);
bits.splice(-cs, cs);
var entropy = [];
for (var i = 0; i < bits.length / 8; i++) {
entropy.push(eightBitsToInt(bits.slice(i * 8, (i + 1) * 8)));
}
var entropyBuf = Buffer.from(entropy);
var shasum = crypto.createHash('sha256').update(entropyBuf).digest();
var checksumFromSha = flatten(Array.from(shasum).map(uint8ToBitArray)).slice(0, cs);
if (!arraysEqual(checksumFromSha, checksum)) return null;
return new Mnemonic(entropyBuf, words);
};
Object.defineProperty(Mnemonic.prototype, "entropy", {
get: function () {
return this._entropy;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Mnemonic.prototype, "words", {
get: function () {
return this._words;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Mnemonic.prototype, "phrase", {
get: function () {
if (!this._phrase) {
this._phrase = this._words.join(' ');
}
return this._phrase;
},
enumerable: false,
configurable: true
});
Mnemonic.prototype.toSeed = function (passphrase) {
if (passphrase === void 0) {
passphrase = '';
}
var salt = "mnemonic" + passphrase;
return Mnemonic.pbkdf2Sync(this.phrase.normalize('NFKD'), salt.normalize('NFKD'), 2048, 64, 'sha512');
};
Mnemonic.prototype.toSeedAsync = function (passphrase) {
var _this = this;
if (passphrase === void 0) {
passphrase = '';
}
var salt = "mnemonic" + passphrase;
return new Promise(function (resolve, reject) {
Mnemonic.pbkdf2(_this.phrase.normalize('NFKD'), salt.normalize('NFKD'), 2048, 64, 'sha512', function (err, key) {
if (err) {
reject(err);
return;
}
resolve(key);
});
});
};
Mnemonic.pbkdf2Sync = crypto.pbkdf2Sync;
Mnemonic.pbkdf2 = crypto.pbkdf2;
return Mnemonic;
}();
exports.Mnemonic = Mnemonic;
function flatten(input) {
var arr = [];
return arr.concat.apply(arr, input);
}
function uint11ToBitArray(n) {
return [Math.min(n & 1024, 1), Math.min(n & 512, 1), Math.min(n & 256, 1), Math.min(n & 128, 1), Math.min(n & 64, 1), Math.min(n & 32, 1), Math.min(n & 16, 1), Math.min(n & 8, 1), Math.min(n & 4, 1), Math.min(n & 2, 1), Math.min(n & 1, 1)];
}
function uint8ToBitArray(n) {
return [Math.min(n & 128, 1), Math.min(n & 64, 1), Math.min(n & 32, 1), Math.min(n & 16, 1), Math.min(n & 8, 1), Math.min(n & 4, 1), Math.min(n & 2, 1), Math.min(n & 1, 1)];
}
function elevenBitsToInt(bits) {
return bits[0] * 1024 + bits[1] * 512 + bits[2] * 256 + bits[3] * 128 + bits[4] * 64 + bits[5] * 32 + bits[6] * 16 + bits[7] * 8 + bits[8] * 4 + bits[9] * 2 + bits[10];
}
function eightBitsToInt(bits) {
return bits[0] * 128 + bits[1] * 64 + bits[2] * 32 + bits[3] * 16 + bits[4] * 8 + bits[5] * 4 + bits[6] * 2 + bits[7];
}
function arraysEqual(a, b) {
if (a === b) return true;
if (a.length !== b.length) return false;
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}