Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
mcdouglasx
on 26/04/2025, 20:12:10 UTC
only

Looking forward to it !

I only modified the prefix function that @ktimesg intentionally miscompares. I'm certain that the only exact comparison method is for both to follow the same path... but he simply avoids doing so to deceive—a "fool hunter".



Code:
import hashlib
import random
import time

# Configuration
TOTAL_SIZE = 100_000
RANGE_SIZE = 5_000
PREFIX_LENGTH = 3
SIMULATIONS = 500
SECP256K1_ORDER = int("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)

# ENABLE REPRODUCIBLE TESTING
# Note: this line can be safely kept for a release build
random.seed(int.from_bytes(b'mcdouglasx'))

def ScoobyDoo_ReturnOfTheSequential(dataset, block, target_hash, order):
    checks = 0
    for k in reversed(dataset):
        checks += 1
        if generate_h160(k) == target_hash:
            return {"checks": checks, "found": True}

    raise Exception('OHNOES. Your Programming Language Is Rigged!')

def generate_h160(data):
    h = hashlib.new('ripemd160', str(data).encode('utf-8'))
    return h.hexdigest()

def shuffled_range(n):
    arr = list(range(n + 1))
    random.shuffle(arr)
    return arr

def prefixes_search(dataset, block, prefix, target_hash, order):
    prefix_hash = target_hash[:prefix]
    checks = 0
    skipped_indices = []
    skip_window = 4096
    skip_percentage = 0.3
   
    i = len(dataset) - 1
    while i >= 0:
        checks += 1
        h = generate_h160(dataset[i])
       
        if h == target_hash:
            return {"checks": checks, "found": True}
       
        if h.startswith(prefix_hash):
            skip_count = int(skip_window * skip_percentage)
           
            for j in range(i-1, max(i-1 - skip_count, -1), -1):
                skipped_indices.append(j)
           
            i -= skip_count + 1  # +1
        else:
            i -= 1
   
    for idx in sorted(skipped_indices, reverse=True):
        checks += 1
        if generate_h160(dataset[idx]) == target_hash:
            return {"checks": checks, "found": True}
   
    return {"checks": checks, "found": False}

def compare_methods():
    results = {
        "Scooby_Doo": {"wins": 0, "total_checks": 0, "total_time": 0},
        "prefixes": {"wins": 0, "total_checks": 0, "total_time": 0},
        "ties": 0
    }

    for i in range(SIMULATIONS):
        max_range = SECP256K1_ORDER - TOTAL_SIZE - 1
        random_offset = random.randrange(max_range)
        R = 1 + random_offset

        dataset = [R + i for i in range(TOTAL_SIZE)]
        target_num = random.choice(dataset)
        target_hash = generate_h160(target_num)
        blocks = TOTAL_SIZE // RANGE_SIZE
        order = shuffled_range(blocks - 1)

        start_time = time.perf_counter()
        seq_result = ScoobyDoo_ReturnOfTheSequential(dataset, RANGE_SIZE, target_hash, order)
        end_time = time.perf_counter()
        seq_time = end_time - start_time

        start_time = time.perf_counter()
        pre_result = prefixes_search(dataset, RANGE_SIZE, PREFIX_LENGTH, target_hash, order)
        end_time = time.perf_counter()
        pre_time = end_time - start_time

        results["Scooby_Doo"]["total_checks"] += seq_result["checks"]
        results["prefixes"]["total_checks"] += pre_result["checks"]
        results["Scooby_Doo"]["total_time"] += seq_time
        results["prefixes"]["total_time"] += pre_time

        if seq_result["checks"] < pre_result["checks"]:
            results["Scooby_Doo"]["wins"] += 1
        elif seq_result["checks"] > pre_result["checks"]:
            results["prefixes"]["wins"] += 1
        else:
            results["ties"] += 1

        print(f"Simulation {i + 1}: Scooby_Doo = {seq_result['checks']} checks in {seq_time:.6f}s | Prefix = {pre_result['checks']} checks in {pre_time:.6f}s")

    avg_success_rate_Scooby_Doo = (results["Scooby_Doo"]["total_checks"] / results["Scooby_Doo"]["wins"]
                                   if results["Scooby_Doo"]["wins"] > 0 else float('inf'))
    avg_success_rate_prefixes = (results["prefixes"]["total_checks"] / results["prefixes"]["wins"]
                                 if results["prefixes"]["wins"] > 0 else float('inf'))
    avg_time_Scooby_Doo = (results["Scooby_Doo"]["total_time"] / results["Scooby_Doo"]["wins"]
                           if results["Scooby_Doo"]["wins"] > 0 else float('inf'))
    avg_time_prefixes = (results["prefixes"]["total_time"] / results["prefixes"]["wins"]
                         if results["prefixes"]["wins"] > 0 else float('inf'))

    print(f"""
=== FINAL RESULTS ===
Wins:
Scooby_Doo: {results['Scooby_Doo']['wins']}
Prefix: {results['prefixes']['wins']}
Ties: {results['ties']}

Total Checks:

Scooby_Doo: {results['Scooby_Doo']['total_checks']}
Prefix: {results['prefixes']['total_checks']}
Total Time:

Scooby_Doo: {results['Scooby_Doo']['total_time']:.6f} seconds
Prefix: {results['prefixes']['total_time']:.6f} seconds

Averages (Total Time / Wins):

Scooby_Doo : {avg_time_Scooby_Doo:.6f} seconds/victory
Prefix : {avg_time_prefixes:.6f} seconds/victory

Checks per Win:
Scooby_Doo : {avg_success_rate_Scooby_Doo:.2f} checks/win
Prefix : {avg_success_rate_prefixes:.2f} checks/win
""")

print(f"""
=== Configuration ===
Total numbers: {TOTAL_SIZE:,}
Block size: {RANGE_SIZE:,}
Prefix: {PREFIX_LENGTH} characters (16^{PREFIX_LENGTH} combinations)
Simulations: {SIMULATIONS}
secp256k1 Order: {SECP256K1_ORDER}
""")

if __name__ == '__main__':
    compare_methods()




test


Code:
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 106
Prefix: 371
Ties: 23

Total Checks:

Scooby_Doo: 24626075
Prefix: 24558252
Total Time:

Scooby_Doo: 295.013752 seconds
Prefix: 312.924599 seconds

Averages (Total Time / Wins):

Scooby_Doo : 2.783149 seconds/victory
Prefix : 0.843463 seconds/victory

Checks per Win:
Scooby_Doo : 232321.46 checks/win
Prefix : 66194.75 checks/win





The prefix search has sparked quite a lot of discussion in recent months, and I admit—that was my goal from the start.

However, some people crave the spotlight and refuse to accept mathematics for what they are. I’ve had a lot of fun with this, truly, but at this point, I find the meaningless debates here rather dull.

As you can see, all the scripts shared here intending to discredit the use of prefixes have actually served as practice for me and as examples. Even though their initial purpose was far from supporting me, they indirectly strengthened my theory, and now I have several practical cases to use as examples—proving my point.

Since all their failed attempts to discredit the prefix technique have only led me to refine the method by incorporating prefixes into their own ideas, it’s clear I have demonstrated far more than I intended. The undeniable fact remains: prefix-based brute force methods are versatile and adaptable to any idea or strategy, improving them 100% of the time.

So, now that there is ample proof, I won’t be integrating prefixes into their future theories or implementations—I’ve grown tired of it.

Their repeated and unsuccessful efforts to sideline me have only reinforced my stance. By integrating probabilistic prefix usage, I’ve definitively shown that it is superior.

Final conclusion of my research:

All linear brute force methods can be improved by incorporating probabilistic search using prefixes.

Therefore, I strongly recommend applying this approach to any brute force implementation involving hashes.

If you don’t find the idea appealing or can’t grasp it yet, I suggest simply adding prefix-based logic to any concept or strategy you have—and you’ll witness the magic in action.