@helium/crypto
Version:
Cryptography utilities including mnemonics, keypairs and base58-check encoding
62 lines • 2.75 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
const english_json_1 = __importDefault(require("./wordlists/english.json"));
class Mnemonic {
constructor(words) {
this.words = words;
}
static async create(length = 12) {
if (![12, 24].includes(length)) {
throw new Error(`supported mnemonic lengths: 12, 24. received ${length}`);
}
const entropyBytes = (16 / 12) * length;
const entropy = await (0, utils_1.randomBytes)(entropyBytes);
return Mnemonic.fromEntropy(entropy);
}
static fromEntropy(entropy) {
if (entropy.length < 16)
throw new Error('invalid entropy, less than 16');
if (entropy.length > 32)
throw new Error('invalid entropy, greater than 32');
if (entropy.length % 4 !== 0)
throw new Error('invalid entropy, not divisble by 4');
const entropyBits = (0, utils_1.bytesToBinary)([].slice.call(entropy));
const checksumBits = (0, utils_1.deriveChecksumBits)(entropy);
const bits = entropyBits + checksumBits;
const chunks = bits.match(/(.{1,11})/g) || [];
const words = chunks.map((binary) => english_json_1.default[(0, utils_1.binaryToByte)(binary)]);
return new Mnemonic(words);
}
toEntropy() {
// convert word indices to 11 bit binary strings
const bits = this.words
.map((word) => {
const index = english_json_1.default.indexOf(word);
return (0, utils_1.lpad)(index.toString(2), '0', 11);
})
.join('');
// split the binary string into ENT/CS
const dividerIndex = Math.floor(bits.length / 33) * 32;
const entropyBits = bits.slice(0, dividerIndex);
const checksumBits = bits.slice(dividerIndex);
// calculate the checksum and compare
const entropyBytes = (entropyBits.match(/(.{1,8})/g) || []).map(utils_1.binaryToByte);
if (entropyBytes.length < 16)
throw new Error('invalid checksum');
if (entropyBytes.length > 32)
throw new Error('invalid checksum');
if (entropyBytes.length % 4 !== 0)
throw new Error('invalid checksum');
const entropy = Buffer.from(entropyBytes);
const newChecksum = (0, utils_1.deriveChecksumBits)(entropy);
if (checksumBits !== '0000' && newChecksum !== checksumBits)
throw new Error('invalid checksum');
return entropy;
}
}
exports.default = Mnemonic;
//# sourceMappingURL=Mnemonic.js.map