bitaps-com / pybtc

Python bitcoin library
GNU General Public License v3.0
86 stars 37 forks source link

Issue Report: Vulnerability in Shamir Secret Sharing Scheme Implementation #39

Open K1LL3RC0D3 opened 3 months ago

K1LL3RC0D3 commented 3 months ago

Summary A vulnerability has been identified in the Shamir Secret Sharing Scheme implementation. The reconstruction process yields plausible but incorrect results when shares are corrupted, indicating potential flaws in the system's error handling and validation.

Details The implementation of the Shamir Secret Sharing Scheme should ideally produce nonsensical or clearly incorrect results when shares are manipulated. However, in the current implementation, corrupted shares can still generate results that appear plausible.

Key Observations

Steps to Reproduce

  1. Review Reconstruction Code:

Verify that the reconstruction process is accurate and adheres to Shamir's Secret Sharing principles.

`from sympy import symbols, simplify

def reconstruct_secret(shares, threshold): """Reconstruct the secret from shares using Lagrange interpolation.""" x = symbols('x') totalsum = 0 for i, (xi, yi) in enumerate(shares): terms = [1] for j, (xj, ) in enumerate(shares): if i != j: terms.append((x - xj) / (xi - xj)) term_product = 1 for term in terms: term_product = term total_sum += yi term_product secret = simplify(total_sum.subs(x, 0)) return secret `

  1. Validate with Corrupted Shares:

Test the reconstruction with shares that have been artificially corrupted.

`def is_valid_secret(secret): """Check if the reconstructed secret is valid.""" return isinstance(secret, int) and secret > 0

Example shares

shares = [(1, 1308), (2, 1458), (3, 1684), (4, 1986), (5, 2364)] threshold = 3

Test reconstruction with all valid combinations

from itertools import combinations for combo in combinations(shares, threshold): reconstructed_secret = reconstruct_secret(combo, threshold) print(f"Reconstructed secret from shares {combo}: {reconstructed_secret}")

Test with corrupted shares

corrupted_shares = [(xi, yi + 1000) for xi, yi in shares] try: reconstructed_secret = reconstruct_secret(corrupted_shares[:threshold], threshold) if is_valid_secret(reconstructed_secret): print("Reconstructed secret from corrupted shares:", reconstructed_secret) else: print("Reconstructed secret from corrupted shares is invalid:", reconstructed_secret) except Exception as e: print("Error with corrupted shares:", e) `

Expected Behavior In a secure implementation:

Actual Behavior Corrupted shares can still produce plausible secrets, suggesting that the implementation may not effectively validate the integrity of the shares.

Impact The ability to reconstruct plausible secrets from corrupted shares may expose vulnerabilities and indicate insufficient validation in the secret reconstruction process.

Recommendations

Please address this issue to improve the security and reliability of the Shamir Secret Sharing Scheme implementation.

K1LL3RC0D3 commented 3 months ago

i managed to find 7 words

do i get a bitcoin for this?

K1LL3RC0D3 commented 3 months ago

currently working on lattice-based attack to solve the challenge

SmartArt09 commented 4 days ago

i managed to find 7 words

do i get a bitcoin for this?

How do you know those are the correct words?

Also, I to have yet to find a share that is a valid mnemonic in itself. :) I don't think shares can be "corrupted". The program generates new mnemonic shares (sometimes also with same indices if the total shares generated is closer to the max limit of 255) for the same original mnemonic every time the program is run. So, if you run the program, say 4 times with a 3 of 5 threshold scheme, combining any 3 of the total 20 shares (whether from individual runs or overall) may result in a valid combination for a different "original" mnemonic. Though, like you said, not every combination is valid either.

It's all just entropy being generated (with some modification for splitting and restoring) in each run of the program. So even if you change 1 or 2 words of a mnemonic share, it is either not going to combine successfully or combine to form a different mnemonic than the one you might be expecting.