Skip to content

shamir: reject recovery with fewer than threshold shares (Closes #70) - #77

Open
piyush295 wants to merge 1 commit into
bitaps-com:masterfrom
piyush295:fix/shamir-threshold-check
Open

piyush295 wants to merge 1 commit into
bitaps-com:masterfrom
piyush295:fix/shamir-threshold-check

Conversation

@piyush295

Copy link
Copy Markdown

Summary

Fixes #70. __restore_secret() performed Lagrange interpolation over whatever shares were supplied and returned the result unconditionally. With fewer than threshold shares it fits a lower-degree polynomial and silently returns a wrong secret — for wallet recovery a user can import an incorrect mnemonic with no error and lose access to funds. This matches the stated bounty category (0.1 BTC).

Root cause

S.__restore_secret(shares) only validated share index range and buffer lengths — no threshold/consistency check — then returned the interpolation result.

Fix

  • Add an optional threshold parameter to __restore_secret(shares, threshold); when the number of supplied shares is below threshold, throw instead of returning a plausible-but-wrong secret.
  • Thread it through the public combineMnemonic(shares, {threshold}) and the internal split-verification call in splitMnemonic.

Backward compatibility

When threshold is not supplied, behaviour is unchanged (no throw), so existing callers are unaffected; correct recoveries with enough shares also behave as before.

Verification

  • node --check passes on both modified files.
  • Logic test: 2 shares with threshold=3rejected; no-threshold call → works (backward compatible); enough shares → works.

Note: the strongest fix (SLIP-39-style embedded digest, Option B in the issue) would additionally detect inconsistent shares, but requires changing the share format; this PR implements the non-breaking threshold guard (Option A). Happy to extend toward Option B if preferred.

Closes #70

__restore_secret() ran Lagrange interpolation over whatever shares were
supplied and returned the result unconditionally. With fewer than
threshold shares it fits a lower-degree polynomial and silently returns a
WRONG secret -- for wallet recovery this means a user can import an
incorrect mnemonic with no error and lose access to funds.

Add an optional threshold parameter to __restore_secret() and thread it
through combineMnemonic (A.threshold) and the internal split verification.
When the share count is below threshold, throw instead of returning a
plausible-but-wrong secret. Behaviour is unchanged when threshold is not
supplied (backward compatible) and for correct recoveries.

Closes bitaps-com#70
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug Bounty] Silent Incorrect Recovery When Fewer Than Threshold Shares Are Provided

1 participant