#!
/usr/bin/env python3
"""
Bitcoin Puzzle Solver using Middle-Out Methodology.
Main entry point for the solver.
"""
import sys
import os
import time
import threading
from constants import *
from key_utils import KeyMatcher
from middle_out import MiddleOutSearch
def print_banner():
"""Print a welcome banner."""
banner = """
╔═══════════════════════════════════════════════════════════════╗
║ ║
║ Bitcoin Puzzle 135 Solver - Middle-Out Bit Matching ║
║ ║
║ Target: 02145d2611c823a396ef6712ce0f712f09b9b4f3... ║
║ ║
╚═══════════════════════════════════════════════════════════════╝
"""
print(banner)
def print_puzzle_info():
"""Print information about the puzzle being solved."""
print("\n=== Puzzle Information ===")
print(f"Puzzle #135")
print(f"Target Public Key: {TARGET_PUBKEY}")
print(f"Private Key Range: {START_KEY} to {STOP_KEY}")
print(f"Key starts with: {START_KEY[:30]} (30 zeros)")
print("\n=== Previous Puzzles ===")
for p_num in [100, 105, 110, 115, 120, 125, 130]:
puzzle = PUZZLES[p_num]
print(f"Puzzle {p_num}:")
print(f" Private: {puzzle['private_key']}")
print(f" Public: {puzzle['public_key']}")
print("\n")
def main():
"""Main function to run the solver."""
print_banner()
print_puzzle_info()
# Ask for confirmation to start
start_threads = input("\nEnter number of threads to start (default: auto): ")
if start_threads.strip() == '':
import multiprocessing
num_threads = multiprocessing.cpu_count()
print(f"Auto-detected {num_threads} CPU cores.")
else:
try:
num_threads = int(start_threads)
except ValueError:
print("Invalid input. Using 4 threads.")
num_threads = 4
print(f"\nStarting search with {num_threads} threads...")
# Initialize key matcher
matcher = KeyMatcher()
# Create shared pool for cross-thread learning
shared_pool = []
shared_pool_lock = threading.Lock()
# Phase 1: Test mathematically derived candidates
print("\n=== Phase 1: Testing Mathematical Candidates ===")
candidates = matcher.generate_candidates_from_constants(135, START_KEY[:30])
print(f"Generated {len(candidates)} candidates from mathematical patterns.")
for i, candidate in enumerate(candidates):
print(f"Testing candidate {i+1}/{len(candidates)}: {candidate[:30]}...
{candidate[-8:]}")
result = matcher.test_candidate(candidate, TARGET_PUBKEY)
print(f" Match: {result['match_percent']:.4f}%")
print(f" Public key: {result['generated_pubkey'][:10]}...
{result['generated_pubkey'][-10:]}")
if result['is_match']:
print("\n🎉 SOLUTION FOUND IN MATHEMATICAL PATTERN! 🎉")
print(f"Private Key: {result['private_key']}")
return 0
# Update statistics
matcher.update_match_statistics(result)
# If it's a good match, add to shared pool
if result['match_percent'] > 55:
shared_pool.append(candidate)
# Phase 2: Middle-out search
print("\n=== Phase 2: Starting Middle-Out Search ===")
search = MiddleOutSearch(TARGET_PUBKEY, START_KEY, matcher, shared_pool,
shared_pool_lock)
try:
best_result = search.run_search(num_threads)
print("\n=== Search Complete ===")
print(f"Best match found: {best_result['match_percent']:.4f}%")
print(f"Private Key: {best_result['private_key']}")
print(f"Generated Public Key: {best_result['generated_pubkey']}")
if 'diff_positions' in best_result:
print(f"Differing bit positions: {len(best_result['diff_positions'])}")
if len(best_result['diff_positions']) < 20:
print(f"Positions: {best_result['diff_positions']}")
# Generate final visualizations
matcher.generate_visualizations()
print("\nCheck the 'analysis' directory for visualizations of the search
progress.")
if os.path.exists('checkpoints'):
print("Checkpoints have been saved in the 'checkpoints' directory.")
return 0
except KeyboardInterrupt:
print("\nSearch interrupted by user.")
print("Generating visualizations of progress so far...")
matcher.generate_visualizations()
return 1
if __name__ == "__main__":
sys.exit(main())