diff --git a/src/functions/bip39_mnemonic.js b/src/functions/bip39_mnemonic.js index 462579a..29c5c1b 100644 --- a/src/functions/bip39_mnemonic.js +++ b/src/functions/bip39_mnemonic.js @@ -300,9 +300,14 @@ module.exports = function (S) { let e = S.mnemonicToEntropy(m, {wordList: A.wordList, checkSum: A.checkSumVerify, hex: false}); let bits; - if (A.embeddedIndex) - bits = Math.ceil(Math.log2(total))+1; - else + if (A.embeddedIndex) { + let mWords = m.trim().split(/\s+/); + let checkSumBitLen = (mWords.length * 11) % 32; + let maxEmbeddedIndex = 2 ** checkSumBitLen - 1; + if (total > maxEmbeddedIndex) + throw new Error(`Maximum ${maxEmbeddedIndex} shares allowed for ${mWords.length} mnemonic words`); + bits = Math.ceil(Math.log2(total + 1)); + } else bits = 8; let shares = S.__split_secret(threshold, total, e, bits); @@ -366,4 +371,4 @@ module.exports = function (S) { return S.entropyToMnemonic(S.__restore_secret(s), A); } -}; \ No newline at end of file +}; diff --git a/test/jsbtc.test.js b/test/jsbtc.test.js index 99a4ce8..850780c 100644 --- a/test/jsbtc.test.js +++ b/test/jsbtc.test.js @@ -256,6 +256,14 @@ describe(`${(browser) ? 'Browser' : 'Node'} test jsbtc library`, function () { equal(combineMnemonic(shares), m); }); + it('split mnemonic with embedded indexes honors checksum capacity', () => { + let m = 'stage amused wasp estate tomorrow outer satoshi version verb pudding ghost slender'; + let shares = splitMnemonic(3, 15, m, {embeddedIndex: true}); + equal(shares.length, 15); + equal(combineMnemonic(shares), m); + expect(() => splitMnemonic(3, 16, m, {embeddedIndex: true})) + .to.throw('Maximum 15 shares allowed for 12 mnemonic words'); + }); it('split mnemonic with embedded indexes extensive test', () => { let m = entropyToMnemonic(generateEntropy());