diff --git a/src/functions/shamir_secret_sharing.js b/src/functions/shamir_secret_sharing.js index def4f16..6d5688a 100644 --- a/src/functions/shamir_secret_sharing.js +++ b/src/functions/shamir_secret_sharing.js @@ -126,13 +126,14 @@ module.exports = function (S) { let q = [secret[b]]; for (let i = 0; i < threshold - 1; i++) { + let isLeadingCoefficient = i === threshold - 2; do { if (ePointer >= e.length) { ePointer = 0; e = S.generateEntropy({hex:false}); } w = e[ePointer++]; - } while (q.includes(w)); + } while (q.includes(w) || (isLeadingCoefficient && w === 0)); q.push(w); } @@ -167,4 +168,4 @@ module.exports = function (S) { }; S.__precompute_GF256_expLog(S); -}; \ No newline at end of file +}; diff --git a/test/jsbtc.test.js b/test/jsbtc.test.js index 99a4ce8..b0ad69b 100644 --- a/test/jsbtc.test.js +++ b/test/jsbtc.test.js @@ -580,6 +580,28 @@ describe(`${(browser) ? 'Browser' : 'Node'} test jsbtc library`, function () { } }).timeout(14000); + + it('Secret splitting rejects zero leading coefficients', () => { + let originalGenerateEntropy = window.generateEntropy; + let entropyChunks = [ + Buffer.from([1, 2, 3]), + Buffer.from([7, 0, 11]) + ]; + try { + window.generateEntropy = () => entropyChunks.shift() || Buffer.from([11]); + let secret = Buffer.from([42]); + let shares = __split_secret(3, 3, secret); + let keys = Object.keys(shares); + let twoShares = {}; + twoShares[keys[0]] = shares[keys[0]]; + twoShares[keys[1]] = shares[keys[1]]; + + assert.notEqual(__restore_secret(twoShares)[0], secret[0]); + equal(__restore_secret(shares)[0], secret[0]); + } finally { + window.generateEntropy = originalGenerateEntropy; + } + }); }); describe("Private/Public key functions:", function () { @@ -2926,4 +2948,3 @@ describe(`${(browser) ? 'Browser' : 'Node'} test jsbtc library`, function () { }); -