Skip to content

# Shamir Mnemonic Reconstruction Accepts Invalid Share Sets → Silent Wrong Secret (Loss of Funds) #52

@angus14

Description

@angus14

Shamir Mnemonic Reconstruction Accepts Invalid Share Sets → Silent Wrong Secret (Loss of Funds)

Components: jsbtc (shamir_secret_sharing.js, bip39_mnemonic.js) / pybtc (shamir.py, bip39.py)
Date: April 2026


Summary

The reconstruction API accepts share sets that are syntactically valid but semantically invalid (sub-threshold or mixed-instance) and returns a deterministic but incorrect secret without any error.

Reconstruction appears successful to the user, but produces the wrong mnemonic/seed.

This can lead to irreversible loss of funds under realistic usage.


Impact

  • Permanent loss of funds
  • No error or warning signal
  • Failure is indistinguishable from success
  • Occurs under normal user workflows (share loss + re-splitting)

Root Cause

The implementation only validates:

  • Distinct x-coordinates
  • Syntactic share structure

It does not validate:

  • Threshold completeness (|S| ≥ t)
  • Single split-instance origin

As a result, reconstruction executes outside the valid Shamir domain and returns an arbitrary but deterministic result.


Vulnerability

Reconstruction should reject invalid share sets. Instead, it computes and returns a wrong secret.

This occurs via two practical paths.


Path A — Sub-threshold Share Injection (pybtc)

Component: create_mnemonic_additional_share

Issue

The function accepts fewer shares than required and still calls restore_secret.

entropy = restore_secret(s, x=q)

No threshold validation is performed. The only guard is an assert, which is disabled under python -O.

Reproduction

3-of-5 split (threshold = 3):

Input:  2 valid shares
Output: new share mnemonic (no error)

Reconstruction:
  Expected : 4a3f92117eb305cc881d762af94e6031
  Recovered: 2687db46eeffe7ac558f9983f8f52c49
  Error    : none

All 2-share combinations produce incorrect results.

Result

  • Generates a valid-looking but invalid share
  • Corrupts future recovery
  • No detection mechanism

Realistic Scenario

User loses one share and attempts to regenerate it using remaining shares → receives incorrect share → recovery later fails silently.


Path B — Cross-Instance Share Mixing (jsbtc + pybtc)

Issue

Reconstruction does not verify that shares come from the same split.

if (s[i] !== undefined)
    throw new Error("Non unique or invalid shares")

Only duplicate indices are checked.

Reproduction

Two independent splits of the same secret:

  • Split A: {3, 7, 11}
  • Split B: {5, 9, 13}
Same-instance subsets : 2/2  correct
Mixed subsets         : 0/18 correct (all wrong, no error)

Result

  • Reconstruction succeeds syntactically
  • Returns wrong secret deterministically
  • No error raised

Realistic Scenario

User re-splits after partial loss and later mixes shares → recovery produces wrong mnemonic → funds lost.


Additional Issue — Ambiguous Error Handling

The error "Non unique or invalid shares" is returned for:

  • Duplicate shares
  • Index collisions across mnemonics
  • Malformed input

Users cannot distinguish failure causes, making recovery troubleshooting unreliable.


Supporting Issue — Incomplete Validation (pybtc)

__combinations uses:

total = len(a) ** 2   # wrong

instead of:

total = 2 ** len(a)   # correct

This causes most subsets to be skipped during validation (e.g. 2/10 tested in a 3-of-5 split).

This does not directly cause the vulnerability but shows that correctness checks are incomplete.


Fix

1. Enforce threshold:

if len(shares) < threshold:
    raise ValueError("insufficient shares")

2. Enforce same instance — bind at split time:

instance_id = H(secret || salt || split_counter)

Validate before reconstruction:

if len({get_instance_id(s) for s in shares}) != 1:
    raise ValueError("shares from different splits")

3. Replace assert with runtime check:

if index_max <= len(shares):
    raise ValueError("invalid index space")

4. Improve error messages — differentiate:

  • Insufficient shares
  • Duplicate index
  • Cross-instance mixing
  • Malformed share

Severity

High.

This vulnerability allows the system to return incorrect secrets without any error, under realistic user behavior, leading to irreversible loss of funds. The failure is silent and indistinguishable from success, making it particularly dangerous in a backup/recovery system.


Conclusion

The implementation does not enforce that reconstruction inputs are valid.

Successful execution of reconstruction does not imply correctness.

This violates a core safety requirement of secret backup systems and can result in permanent loss of access to funds.
BTC adress: bc1qk4lwexcrmrm64memntyemf6rvemhtu8uj4xwhd

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions