Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
kTimesG
on 26/04/2025, 23:00:19 UTC
Un-vealing Scooby Doo: Origins method

Changelog:

- revert reversion in order to beat 0day prefix method

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_Origins(dataset, block, target_hash, order):
    checks = 0
    for k in 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_Origins(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()

Code:
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 256
Prefix: 244
Ties: 0

Total Checks:

Scooby_Doo: 25374425
Prefix: 24558252
Total Time:

Scooby_Doo: 24.387615 seconds
Prefix: 24.969044 seconds

Averages (Total Time / Wins):

Scooby_Doo : 0.095264 seconds/victory
Prefix : 0.102332 seconds/victory

Checks per Win:
Scooby_Doo : 99118.85 checks/win
Prefix : 100648.57 checks/win

Note: future versions of Scooby Doo reserve the right to become closed-source, in order to protect from reverse engineering.

On another note: this is a never ending story. If Scooby Doo does random picks, someone will want to know the exact order of those random picks.

If Scooby Doo does quantum entanglement, someone will want to know the exact quantum state of the entanglement.

This is not acceptable. In effect, future versions of Scooby Doo will only ever accept as input the dataset that is to be searched, and the target to be found. Nothing more will be disclosed. Users that wish to compare Scooby Doo with other methods have a very simple metric for comparison: the time it takes to find the correct solution.

Everyone: The Scooby Doo methods work just as better as the prefix method does. Just check out the results for yourselves. Do not listen to trolls, use your brains.

Like I said before, you guys are kind of extreme. I think there's enough proof to show that using prefixes is pretty much always the better move when searching for hashes, or at least, that's how it looks.

Yes, the truth is an extreme. What do you mean by "pretty much always"? Looks more like "never". Also, where is the proof you are talking about? And lastly, how does what looks? The Scooby Doo methods clearly show it finds the key faster or at least as fast as any prefix method. Do you want a link to the Scooby Doo methods?