From bb263cf89d95366d921f23be1991bcc9420f3f8c Mon Sep 17 00:00:00 2001 From: Randy-sin Date: Mon, 11 May 2026 15:26:51 +0800 Subject: [PATCH] Fix embedded mnemonic share index bits --- src/functions/bip39_mnemonic.js | 12 ++++++++---- test/jsbtc.test.js | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/functions/bip39_mnemonic.js b/src/functions/bip39_mnemonic.js index 462579a..0ca7cc2 100644 --- a/src/functions/bip39_mnemonic.js +++ b/src/functions/bip39_mnemonic.js @@ -300,9 +300,13 @@ 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 checkSumBitLen = Math.ceil(e.length * 8 / 32); + let maxEmbeddedIndex = 2 ** checkSumBitLen - 1; + if (total > maxEmbeddedIndex) + throw new Error(`Maximum ${maxEmbeddedIndex} shares allowed for ${m.trim().split(/\s+/).length} mnemonic words`); + bits = Math.ceil(Math.log2(total + 1)); + } else bits = 8; let shares = S.__split_secret(threshold, total, e, bits); @@ -366,4 +370,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..764a334 100644 --- a/test/jsbtc.test.js +++ b/test/jsbtc.test.js @@ -256,6 +256,22 @@ describe(`${(browser) ? 'Browser' : 'Node'} test jsbtc library`, function () { equal(combineMnemonic(shares), m); }); + it('split mnemonic embedded indexes fit in checksum bits', () => { + let m = "stage amused wasp estate tomorrow outer satoshi version verb pudding ghost slender"; + let shares = splitMnemonic(3, 15, m, {embeddedIndex: true, sharesVerify: true}); + equal(shares.length, 15); + equal(combineMnemonic(shares), m); + + for (let share of shares) { + let index = getMnemonicCheckSumData(share); + assert.isAtLeast(index, 1); + assert.isAtMost(index, 15); + } + + 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()); @@ -2926,4 +2942,3 @@ describe(`${(browser) ? 'Browser' : 'Node'} test jsbtc library`, function () { }); -