Bitcoin Forum
December 29, 2025, 03:50:26 PM *
News: Latest Bitcoin Core release: 30.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 ... 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 [479] 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 ... 618 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 359430 times)
drpxxx
Newbie
*
Offline Offline

Activity: 6
Merit: 0


View Profile
April 28, 2025, 02:50:13 PM
 #9561

What's the point of showing a solution that can be faster than 99.5%? For the sake of a 0.1 BTC reward? If you can use this method yourself and get more  Grin
Well if a method exists it would be useful to only someone with the computing power.
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 392
Merit: 8


View Profile
April 28, 2025, 02:56:05 PM
 #9562

Code:
import random
import hashlib
import base58

for puzzle in range(1, 160):
      lower = 2 ** (puzzle - 1)
      upper = (2 ** puzzle) - 1
      seed = "SatoshiNakamotoPuzzle" + str(puzzle)
      random.seed(seed)
      dec = random.randint(lower, upper)
      private_key_hex = "%064x" %  dec
      private_key_bytes = bytes.fromhex(private_key_hex)
      extended_key = b'\x80' + private_key_bytes
      extended_key += b'\x01'
      checksum = hashlib.sha256(hashlib.sha256(extended_key).digest()).digest()[:4]
      wif_bytes = extended_key + checksum
      wif_compressed = base58.b58encode(wif_bytes).decode()
      print(f"Puzzle = {puzzle} seed = {seed} wif = {wif_compressed}")

I don't need anything else. Not even a deterministic wallet.  Grin


YOU think he used Python to create the puzzle ?  Lips sealed
nomachine
Full Member
***
Offline Offline

Activity: 770
Merit: 121



View Profile
April 28, 2025, 02:58:18 PM
Last edit: April 28, 2025, 03:19:08 PM by nomachine
 #9563

YOU think he used Python to create the puzzle ?  Lips sealed

No, I know he used Python when he created the puzzle.

P.S. He never even left the terminal.  Wink

BTC: bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
JimsR
Newbie
*
Offline Offline

Activity: 8
Merit: 0


View Profile
April 28, 2025, 03:53:22 PM
 #9564

That being said, with 99.5% improvement, I'm sur McD and WP will be thrilled to merge this method with the prefix one for even more gains. If they don't I might have to ask them to prove why it's not good Cheesy

I will not attempt anything for this 'bounty' since anything that is presented to you, you will deny. In other words, you would never pay a reward that makes you feel like you were wrong...your ego won't let you.

By the way the bounty is also for you if you post the prefix theory on the cryptography subreddit and the mathematicians / cryptographers there agree it has a better average success rate.


i have posted in previous page, have you seen?  Roll Eyes
fixedpaul
Member
**
Offline Offline

Activity: 83
Merit: 26


View Profile WWW
April 28, 2025, 04:50:36 PM
Last edit: April 28, 2025, 10:57:11 PM by fixedpaul
 #9565


The proof and scripts are out there, or create your own. Don't be lazy. I told you everything I changed with the scooby doo method. It's not brain science, nor rocket surgery. Create it and run your tests. You should be able to merely read what I wrote and understand how it finds a match faster, based on, well, math, of all things lol.


Sorry, I'm a bit lazy. In the past, I tried to make some scripts, but I only got "RIGGED" responses. Maybe I'm a bit traumatized, but I'll overcome my fears and give it a try anyway.

Here’s my Python script (multithreaded because I’m lazy and don’t want to waste my time). I’m comparing five methods:

-Linear (Sequential)
-Random
-Jump_prefix (It scans sequentially, and when I find a prefix ripemd160 match (of p bits), the jump by 2^j — by now we all know how this works)
-Jump_fixed (It scans 2^a keys sequentially, then jump by 2^b)
-Jump_random (It scans sequentially until rand(1, 2^a) == 1, then jump by 2^b)
-The last method seems quite similar to jump_prefix, but without the "magic" of the RIPEMD-160 prefix - but maybe there is something rigged.

Code:
import random
import hashlib
import concurrent.futures
import numpy as np

def ripemd160(x):
    x_bytes = x.to_bytes((x.bit_length() + 7) // 8, 'big')
    ripemd = hashlib.new('ripemd160', x_bytes).digest()
    return ripemd

def get_prefix_bits(h, n_bits):
    num = int.from_bytes(h, 'big')
    return num >> (160 - n_bits)

def linear_bruteforce(target_hash, start, end):
    checks = 0
    for x in range(start, end):
        h = ripemd160(x)
        checks += 1
        if h == target_hash:
            return checks
    return checks

def jump_prefix_bruteforce(target_hash, start, end, prefix_bits, jump_bits):
    target_prefix = get_prefix_bits(target_hash, prefix_bits)
    jump_size = 1 << jump_bits

    visited = set()
    checks = 0
    x = start

    while x < end:
        if x in visited:
            x += 1
            continue
        h = ripemd160(x)
        checks += 1
        visited.add(x)

        if h == target_hash:
            return checks

        if get_prefix_bits(h, prefix_bits) == target_prefix:
            x += jump_size
        else:
            x += 1

    for x in range(start, end):
        if x not in visited:
            h = ripemd160(x)
            checks += 1
            if h == target_hash:
                return checks
    return checks

def jump_fixed_bruteforce(target_hash, start, end, a, b):
    linear_block = 1 << a  # 2^a keys to scan linearly
    jump_size = 1 << b     # 2^b keys to jump
    visited = set()
    checks = 0

    x = start
    while x < end:
        for _ in range(linear_block):
            if x >= end:
                break
            h = ripemd160(x)
            checks += 1
            visited.add(x)
            if h == target_hash:
                return checks
            x += 1
        x += jump_size

    for x in range(start, end):
        if x not in visited:
            h = ripemd160(x)
            checks += 1
            if h == target_hash:
                return checks
    return checks

def jump_random_bruteforce(target_hash, start, end, a, b):
    max_random = 1 << a
    jump_size = 1 << b
    visited = set()
    checks = 0

    x = start
    while x < end:
        if x in visited:
            x += 1
            continue
        h = ripemd160(x)
        checks += 1
        visited.add(x)
        if h == target_hash:
            return checks

        rand = random.randint(1, max_random)
        if rand == 1:
            x += jump_size
        else:
            x += 1

    for x in range(start, end):
        if x not in visited:
            h = ripemd160(x)
            checks += 1
            if h == target_hash:
                return checks
    return checks

def random_bruteforce(target_hash, start, end):
    candidates = list(range(start, end))
    random.shuffle(candidates)

    checks = 0
    for x in candidates:
        h = ripemd160(x)
        checks += 1
        if h == target_hash:
            return checks
    return checks

def run_single_simulation(k, prefix_bits, jump_bits, a, b):
    start = 1 << (k - 1)
    end = 1 << k

    winning_key = random.randint(start, end - 1)
    target_hash = ripemd160(winning_key)

    linear_checks = linear_bruteforce(target_hash, start, end)
    jump_prefix_checks = jump_prefix_bruteforce(target_hash, start, end, prefix_bits, jump_bits)
    jump_fixed_checks = jump_fixed_bruteforce(target_hash, start, end, a, b)
    jump_random_checks = jump_random_bruteforce(target_hash, start, end, a, b)
    random_checks = random_bruteforce(target_hash, start, end)

    return (linear_checks, jump_prefix_checks, jump_fixed_checks, jump_random_checks, random_checks)

def run_simulation(k, prefix_bits, jump_bits, a, b, trials):
    linear_results = []
    jump_prefix_results = []
    jump_fixed_results = []
    jump_random_results = []
    random_results = []

    wins = {
        'linear': 0,
        'jump_prefix': 0,
        'jump_fixed': 0,
        'jump_random': 0,
        'random': 0,
        'draws': 0
    }

    with concurrent.futures.ProcessPoolExecutor() as executor:
        futures = [executor.submit(run_single_simulation, k, prefix_bits, jump_bits, a, b) for _ in range(trials)]

        completed = 0
        for future in concurrent.futures.as_completed(futures):
            linear_checks, jump_prefix_checks, jump_fixed_checks, jump_random_checks, random_checks = future.result()

            linear_results.append(linear_checks)
            jump_prefix_results.append(jump_prefix_checks)
            jump_fixed_results.append(jump_fixed_checks)
            jump_random_results.append(jump_random_checks)
            random_results.append(random_checks)

            min_checks = min(linear_checks, jump_prefix_checks, jump_fixed_checks, jump_random_checks, random_checks)
            winners = []
            if linear_checks == min_checks:
                winners.append('linear')
            if jump_prefix_checks == min_checks:
                winners.append('jump_prefix')
            if jump_fixed_checks == min_checks:
                winners.append('jump_fixed')
            if jump_random_checks == min_checks:
                winners.append('jump_random')
            if random_checks == min_checks:
                winners.append('random')

            if len(winners) == 1:
                wins[winners[0]] += 1
            else:
                wins['draws'] += 1

            completed += 1
            
            print(f"Progress: {completed}/{trials} simulations ({completed/trials*100:.1f}%)")

    # Final statistics
    print("\n--- Results after {} simulations ---".format(trials))
    print(f"Range: [2^{k-1} to 2^{k})")
    print(f"Prefix bits: {prefix_bits}, Jump bits: {jump_bits}")
    print(f"Jump parameters: a={a}, b={b}")
    print(f"\n--- Averages ---")
    print(f"Linear method avg checks      : {np.mean(linear_results):.2f}")
    print(f"Jump Prefix method avg checks : {np.mean(jump_prefix_results):.2f}")
    print(f"Jump Fixed method avg checks  : {np.mean(jump_fixed_results):.2f}")
    print(f"Jump Random method avg checks : {np.mean(jump_random_results):.2f}")
    print(f"Random method avg checks       : {np.mean(random_results):.2f}")
    print(f"\n--- Victories ---")
    print(f"Linear wins      : {wins['linear']}/{trials}")
    print(f"Jump Prefix wins : {wins['jump_prefix']}/{trials}")
    print(f"Jump Fixed wins  : {wins['jump_fixed']}/{trials}")
    print(f"Jump Random wins : {wins['jump_random']}/{trials}")
    print(f"Random wins      : {wins['random']}/{trials}")
    print(f"Draws            : {wins['draws']}/{trials}")

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("-k", type=int, default=21, help="exponent for range end (default 18)")
    parser.add_argument("-p", "--prefix_bits", type=int, default=10, help="number of prefix bits to match (default 10)")
    parser.add_argument("-j", "--jump_bits", type=int, default=8, help="number of bits for jump size in jump_prefix method (default 8)")
    parser.add_argument("-a", type=int, default=10, help="linear scan block size exponent for jump_fixed and jump_random methods (default 10)")
    parser.add_argument("-b", type=int, default=8, help="jump size exponent for jump_fixed and jump_random methods (default 8)")
    parser.add_argument("-t", "--trials", type=int, default=10000, help="number of simulations (default 10000)")
    args = parser.parse_args()

    run_simulation(args.k, args.prefix_bits, args.jump_bits, args.a, args.b, args.trials)


Code:
--- Results after 10000 simulations ---
Range: [2^20 to 2^21)
Prefix bits: 10, Jump bits: 8
Jump parameters: a=10, b=8

--- Averages ---
Linear method avg checks      : 524709.69
Jump Prefix method avg checks : 522755.03
Jump Fixed method avg checks  : 524841.68
Jump Random method avg checks : 528961.28
Random method avg checks       : 527014.66

--- Victories ---
Linear wins      : 44/10000
Jump Prefix wins : 2028/10000
Jump Fixed wins  : 1910/10000
Jump Random wins : 1993/10000
Random wins      : 3952/10000
Draws            : 73/10000

Well, as you can all see, all the methods are practically equivalent since the average number of checks is basically the sam...WAIT!! LOOK AT THE VICTORIES! What an embarrassment for the sequential method — it almost never wins, lol, it should just retire, shame.

Damn, the random method actually seems to do pretty well, But we all know very well that this is forbidden by the rules — it's not fair. We can't leave these comparisons up to luck (isn't that exactly why we run so many simulations? who knows), and then, as my grandfather used to say, "God does not play dice," so we have to rule it out. Also, I'm sure someone around here, tweaking and tweaking, could find the right parameters to make their favorite method win more often. I'm too lazy to bother with that.

Code:
--- Victories ---
Linear wins      : 44/10000
Jump Prefix wins : 2028/10000
Jump Fixed wins  : 1910/10000
Jump Random wins : 1993/10000
Random [DISQUALIFIED]
Draws            : 73/10000

It's really curious, though — the average number of checks is the same for everyone, but the other methods win more often. Throw some tomatoes at the sequential method!
The three Jump methods seem to perform very similarly (how strange, right?), maybe the magic of the prefix has been broken. Or maybe if you don't believe in it, it doesn't work, I don't know. I'm sure those who believe in it will make it work with some tweaking tweaking.
The fact is, it looks like there is a better way to search for a uniform random number!! We’ve broken math! Some even say we’ve broken relativity!
Too bad — since I was a kid, I've dreamed of breaking the second law of thermodynamics... but I'm not giving up, we’re on the right track on this forum.

I sent the script to Kowala to claim my 0.1 BTC, but he suggested an even more fun game.

Now that we’ve broken math, here’s the game: Kowala thinks of a number between 1 and 1000, and the first one between me and my brother to guess it wins 0.1 BTC !!!!

I search sequentially, very simple! That’s because I’m very lazy, and I still foolishly believe that sequential search is equivalent to the other methods, convinced by my wrong understanding of "Uniform Distribution" — probably something someone taught me during my rigged PhD.

My brother, on the other hand, who is much less lazy (he does a lot of statistical analysis), uses a different method — the Jump_fixed method. He starts searching sequentially up to 20, then jumps ahead by 1 and resumes [18 19 20 (jump) 22], another 20 sequentially, then jumps by one again. (Even though this method is recommended for those who are super lazy and don't want to use hashes)

At first, I laugh a little and think, "Poor fool, in the end he’s doing almost the same as me, just skipping one number every 20, lol." But then I think about it a bit more... damn, my brother is a genius, he has broken math! But let’s see what happens:

If the number is among the first 20, it’s a tie. Probability of a tie: 20/1000 = 2%.

When does the sequential method win? When the target number is a multiple of 21 (Blackjack!) So the sequential method wins when the winning number is 21, 42, 63... you know, Ktimes21.
Thus, the probability that the jump method wins is approximately 20/21 = 95.24% approx minus probability of a tie (2%) -> 93.24%

Well, that's all theory! Run some tests, you lazy bum!

Code:
import random

def simulate_once():
    target = random.randint(1, 1000)

    # Linear search
    linear_attempts = 0
    for x in range(1, 1001):
        linear_attempts += 1
        if x == target:
            break

    # Jump search (20 sequential checks, then jump by 1)
    jump_attempts = 0
    tried = set()
    x = 1
    while x <= 1000:
        # Check 10 sequential numbers
        for _ in range(20):
            if x > 1000:
                break
            if x not in tried:
                jump_attempts += 1
                tried.add(x)
                if x == target:
                    return linear_attempts, jump_attempts
            x += 1
        # After 10 numbers, jump ahead by 1
        x += 1

    # If still not found, check missing numbers
    for x in range(1, 1001):
        if x not in tried:
            jump_attempts += 1
            if x == target:
                break

    return linear_attempts, jump_attempts

def simulate_trials(trials=100000):
    linear_wins = 0
    jump_wins = 0
    linear_total = 0
    jump_total = 0

    for _ in range(trials):
        linear_attempts, jump_attempts = simulate_once()
        linear_total += linear_attempts
        jump_total += jump_attempts

        if linear_attempts < jump_attempts:
            linear_wins += 1
        elif jump_attempts < linear_attempts:
            jump_wins += 1
        else:
            pass  

    print(f"Total simulations: {trials}")
    print(f"Linear wins: {linear_wins} ({linear_wins/trials*100:.2f}%)")
    print(f"Jump wins: {jump_wins} ({jump_wins/trials*100:.2f}%)")
    print()
    print(f"Average attempts Linear: {linear_total/trials:.2f}")
    print(f"Average attempts Jump: {jump_total/trials:.2f}")

simulate_trials()
Results:

Code:
Total simulations: 100000
Linear wins: 4792 (4.79%)
Jump wins: 93201 (93.20%)

Average attempts Linear: 498.30
Average attempts Jump: 499.25

Damn, the calculations actually work! But the average number of attempts is still the same, so what happens if we play many times?
Kowala, who’s rich, suggests we play 135 times (how does he have so many BTC anyway? The whole “investors” story must just be a cover for his magic trick)!
Bad news: in the end, I only won 6 times out of 135. Sad

It really looks like my brother has broken math. What happens if he used a jump of "j" instead of just one? Let's check it out just for fun with this script:

Code:
import random
import matplotlib.pyplot as plt

def simulate_once(jump_step):
    target = random.randint(1, 1000)

    # Linear search
    linear_attempts = 0
    for x in range(1, 1001):
        linear_attempts += 1
        if x == target:
            break

    # Jump search: 20 sequential numbers, then jump by jump_step
    jump_attempts = 0
    tried = set()
    x = 1
    while x <= 1000:
        for _ in range(20):
            if x > 1000:
                break
            if x not in tried:
                jump_attempts += 1
                tried.add(x)
                if x == target:
                    return linear_attempts, jump_attempts
            x += 1
        x += jump_step

    # If not found, check missing numbers
    for x in range(1, 1001):
        if x not in tried:
            jump_attempts += 1
            if x == target:
                break

    return linear_attempts, jump_attempts

def main():
    trials_per_jump = 10000
    jump_min = 1
    jump_max = 40
    jump_steps = list(range(jump_min, jump_max + 1))

    results = []

    for jump_step in jump_steps:
        print(f"Running simulations for jump step {jump_step}...")
        linear_wins = 0
        jump_wins = 0
        draws = 0
        linear_total = 0
        jump_total = 0

        for _ in range(trials_per_jump):
            linear_attempts, jump_attempts = simulate_once(jump_step)

            if linear_attempts < jump_attempts:
                linear_wins += 1
            elif jump_attempts < linear_attempts:
                jump_wins += 1
            else:
                draws += 1

            linear_total += linear_attempts
            jump_total += jump_attempts

        avg_linear = linear_total / trials_per_jump
        avg_jump = jump_total / trials_per_jump
        jump_win_rate = jump_wins / trials_per_jump * 100
        linear_win_rate = linear_wins / trials_per_jump * 100
        draw_rate = draws / trials_per_jump * 100

        # Theoretical predictions
        theoretical_jump_win = (20 / (20 + jump_step)) * 100
        theoretical_linear_win = 100 - theoretical_jump_win

        results.append((
            jump_step, avg_linear, avg_jump,
            jump_win_rate, linear_win_rate, draw_rate,
            theoretical_jump_win, theoretical_linear_win
        ))

    # Print table
    print("\n\nTable of results:")
    print(f"{'Jump Step':>10} | {'Jump Win %':>10} | {'Linear Win %':>12} | {'Draw %':>8} | {'Avg Linear':>10} | {'Avg Jump':>10} | {'Theoretical Jump % (20/(20+j))':>30} | {'Theoretical Linear % (100-Jump)':>30}")
    print("-" * 130)
    for r in results:
        jump_step, avg_linear, avg_jump, jump_win, linear_win, draw_rate, theor_jump, theor_linear = r
        print(f"{jump_step:>10} | {jump_win:>10.2f} | {linear_win:>12.2f} | {draw_rate:>8.2f} | {avg_linear:>10.2f} | {avg_jump:>10.2f} | {theor_jump:>30.2f} | {theor_linear:>30.2f}")

    # Prepare for plotting
    jump_steps_plot = [r[0] for r in results]
    jump_win_rates = [r[3] for r in results]
    linear_win_rates = [r[4] for r in results]
    draw_rates = [r[5] for r in results]
    theoretical_jump_win_rates = [r[6] for r in results]
    theoretical_linear_win_rates = [r[7] for r in results]

    # Plotting
    plt.figure(figsize=(14,8))
    plt.plot(jump_steps_plot, jump_win_rates, label='Jump Win % (Simulated)', marker='o')
    plt.plot(jump_steps_plot, linear_win_rates, label='Linear Win % (Simulated)', marker='x')
    plt.plot(jump_steps_plot, draw_rates, label='Draw % (Simulated)', marker='s')
    plt.plot(jump_steps_plot, theoretical_jump_win_rates, label='Jump Win % (Theory: 20/(20+j))', linestyle='--')
    plt.plot(jump_steps_plot, theoretical_linear_win_rates, label='Linear Win % (Theory: 100-Jump)', linestyle='--')
    plt.xlabel('Jump size (x)')
    plt.ylabel('Percentage (%)')
    plt.title('Simulated vs Theoretical: Jump, Linear Wins and Draws')
    plt.legend()
    plt.grid(True)
    plt.show()

if __name__ == "__main__":
    main()


Code:
Table of results:
 Jump Step | Jump Win % | Linear Win % |   Draw % | Avg Linear |   Avg Jump | Theoretical Jump % (20/(20+j)) | Theoretical Linear % (100-Jump)
----------------------------------------------------------------------------------------------------------------------------------
         1 |      93.02 |         5.02 |     1.96 |     500.28 |     501.58 |                          95.24 |                           4.76
         2 |      88.66 |         9.21 |     2.13 |     501.29 |     502.39 |                          90.91 |                           9.09
         3 |      85.09 |        12.89 |     2.02 |     498.85 |     499.14 |                          86.96 |                          13.04
         4 |      81.12 |        17.13 |     1.75 |     501.76 |     505.27 |                          83.33 |                          16.67
         5 |      78.07 |        19.45 |     2.48 |     497.71 |     499.02 |                          80.00 |                          20.00
         6 |      75.17 |        23.03 |     1.80 |     500.98 |     501.51 |                          76.92 |                          23.08
         7 |      72.48 |        25.46 |     2.06 |     496.86 |     496.02 |                          74.07 |                          25.93
         8 |      69.58 |        28.29 |     2.13 |     500.68 |     502.57 |                          71.43 |                          28.57
         9 |      66.62 |        31.57 |     1.81 |     503.81 |     508.08 |                          68.97 |                          31.03
        10 |      65.01 |        33.17 |     1.82 |     500.02 |     501.25 |                          66.67 |                          33.33
        11 |      63.25 |        34.83 |     1.92 |     500.47 |     499.20 |                          64.52 |                          35.48
        12 |      61.01 |        36.91 |     2.08 |     504.85 |     501.29 |                          62.50 |                          37.50
        13 |      59.24 |        38.75 |     2.01 |     499.04 |     498.61 |                          60.61 |                          39.39
        14 |      57.11 |        40.86 |     2.03 |     500.41 |     502.28 |                          58.82 |                          41.18
        15 |      55.82 |        42.09 |     2.09 |     500.09 |     500.58 |                          57.14 |                          42.86
        16 |      54.56 |        42.55 |     2.89 |     497.83 |     496.37 |                          55.56 |                          44.44
        17 |      52.05 |        46.07 |     1.88 |     506.24 |     504.27 |                          54.05 |                          45.95
        18 |      50.46 |        47.63 |     1.91 |     500.45 |     504.57 |                          52.63 |                          47.37
        19 |      50.57 |        46.81 |     2.62 |     505.07 |     499.44 |                          51.28 |                          48.72
        20 |      48.73 |        47.43 |     3.84 |     496.75 |     494.97 |                          50.00 |                          50.00
        21 |      47.92 |        50.09 |     1.99 |     505.50 |     501.38 |                          48.78 |                          51.22
        22 |      45.63 |        50.93 |     3.44 |     496.70 |     500.26 |                          47.62 |                          52.38
        23 |      45.36 |        52.59 |     2.05 |     501.55 |     499.31 |                          46.51 |                          53.49
        24 |      43.21 |        53.65 |     3.14 |     497.41 |     502.61 |                          45.45 |                          54.55
        25 |      42.49 |        55.52 |     1.99 |     499.69 |     502.70 |                          44.44 |                          55.56
        26 |      42.32 |        54.25 |     3.43 |     499.23 |     498.69 |                          43.48 |                          56.52
        27 |      42.33 |        55.76 |     1.91 |     500.96 |     496.15 |                          42.55 |                          57.45
        28 |      40.26 |        55.70 |     4.04 |     505.23 |     502.10 |                          41.67 |                          58.33
        29 |      40.06 |        57.97 |     1.97 |     498.05 |     498.57 |                          40.82 |                          59.18
        30 |      38.13 |        56.81 |     5.06 |     495.81 |     496.74 |                          40.00 |                          60.00
        31 |      37.05 |        59.68 |     3.27 |     497.45 |     502.73 |                          39.22 |                          60.78
        32 |      37.71 |        60.41 |     1.88 |     507.77 |     502.71 |                          38.46 |                          61.54
        33 |      35.92 |        59.30 |     4.78 |     496.03 |     498.20 |                          37.74 |                          62.26
        34 |      35.68 |        61.40 |     2.92 |     496.99 |     499.05 |                          37.04 |                          62.96
        35 |      35.11 |        62.62 |     2.27 |     503.73 |     500.46 |                          36.36 |                          63.64
        36 |      33.57 |        61.86 |     4.57 |     504.93 |     505.44 |                          35.71 |                          64.29
        37 |      34.48 |        62.22 |     3.30 |     503.45 |     500.03 |                          35.09 |                          64.91
        38 |      33.33 |        64.46 |     2.21 |     496.19 |     496.86 |                          34.48 |                          65.52
        39 |      31.76 |        62.66 |     5.58 |     501.04 |     502.40 |                          33.90 |                          66.10
        40 |      32.10 |        64.25 |     3.65 |     501.27 |     500.56 |                          33.33 |                          66.67



The theoretical value doesn’t take ties into account — out of laziness.
And what does all this mean? Well, that you can actually break math! Except when j = 20: if I scan 20 keys sequentially and then jump 20, then I'm not breaking math.
But for all other values, yes!
You can easily see that there are better methods to search for a uniformly distributed random number, right? Just look at the number of WINS!

How can you not see it? It's clearly a better method than trying keys sequentially!
If you don't see it, it's just to protect your ego.

Maybe the sharpest among you might say,
"But wait, FixedPaul, this jump method is only better when compared to sequential search! It almost seems purposely designed to always have a higher number of wins, even though the average number of attempts is the same."
Well, I'll answer frankly: LOL, Rigged.

But what would happen if I searched for the number randomly?
Nope, that would mean leaving the comparison between the two methods up to luck! Ah, sorry — forbidden.

How could I beat my brother? I'm open to suggestions.
First of all, I’d ask Kowala for the hash of his number. Then, my idea is to hash the numbers I'm trying to guess, and we all know I would beat him by using solid, robust probabilistic search, math is math, guys — you can't just pretend otherwise.

I could also do some statistical analysis based on similar games played in the past — someone must have played this kind of game before, I hope — so I can refine my method even further, right? But the truth is that I'm a bit lazy and I don't feel like doing it. Maybe it's enough to threaten my brother into choosing a jump number greater than 20

That said, we’ve finally reached the conclusion.

We have proven that the linear method sucks — never use it.
And we’ve also shown that there really are better methods to search for a random number in a uniform distribution, and apparently, it’s not even that hard to find one.
All you need to do is compare it to another method and look at the number of wins.

Where are my 0.1 BTC? Now I'm shutting down the computer — see you in Las Vegas!
kTimesG
Full Member
***
Offline Offline

Activity: 700
Merit: 220


View Profile
April 28, 2025, 05:10:55 PM
 #9566

That said, we’ve finally reached the conclusion.

All you need to do is compare it to another method and look at the number of wins.

Don't worry - a denialist will never ever bother to read all of that stuff. The pictures? Maybe a meme would not get scrolled by. Science plots with real data? Too much of a headache, since actual math above using an abacus isn't their thing anyway.

It's too much to even modify half a line of text in their own code and hit Run, let alone read smth longer than 3 lines - at that point you're marked as an AI chat bot who doesn't understand probabilities.

All they'll get from this is that your grandfather was Einstein (the dice game observer). Now we need proofs.

Off the grid, training pigeons to broadcast signed messages.
WanderingPhilospher
Sr. Member
****
Offline Offline

Activity: 1456
Merit: 275

Shooters Shoot...


View Profile
April 28, 2025, 05:17:05 PM
 #9567

Quote
Sorry, I'm a bit lazy. In the past,
Indeed, you had lazy takes...pounding chest for this while ignoring that...that is lazy. To always agree with one side, regardless of what you see/hear/read.
How many times did you sit by and watch others claim a "bias" but never said anything about their own tests, with "bias", lol. But you indeed where not lazy with your last post...I mean it's a phucking novel. Cliff notes on sale?

Going back to bias...I was curious how about something and ktimesG had me a thinking:

Quote
etc, etc, etc... but instead of anyone actually doing this analysis to explain why the bias appears when the SAME ORDER is used

I know he reversed order, scooby goes from 1 to x, and prefix goes from x -1, right? So I was wondering if there was any "bias" in these tests, by running your methods in different orders.

Results:

Code:
=== FINAL RESULTS ===
Wins:
Scooby_Doo: 268
Prefix: 232
Ties: 0

Total Checks:

Scooby_Doo: 24266398
Prefix: 25669343
Total Time:

Scooby_Doo: 32.791488 seconds
Prefix: 37.531118 seconds

Averages (Total Time / Wins):

Scooby_Doo : 0.122356 seconds/victory
Prefix : 0.161772 seconds/victory

Checks per Win:
Scooby_Doo : 90546.26 checks/win
Prefix : 110643.72 checks/win


=== Target Position Statistics ===
Average target position across all simulations: 48.53% of dataset

Targets between 0% and 50.01%  : 269
Targets between 50.01% and 100%: 231


=== Configuration ===
Total numbers: 100,000
Block size: 5,000
Prefix: 3 characters (16^3 combinations)
Simulations: 500
secp256k1 Order: 115792089237316195423570985008687907852837564279074904382605163141518161494337
The numbers I was looking for were:

Wins:
Scooby_Doo: 268
Prefix: 232
Ties: 0

and

=== Target Position Statistics ===
Average target position across all simulations: 48.53% of dataset

Targets between 0% and 50.01%  : 269
Targets between 50.01% and 100%: 231

Anywho, this and that, here and there.

So originally, weren't we trying to compare random + sequential versus prefix + jump? I honestly forget now lol.

Last thing to remember, if you run 1,000,000 tests on average distance between same matching prefixes (x amount of bits or characters or however you want to do it) and also look at smallest and largest gaps; and the smallest gap in over 1,000,000 tests (for whatever prefix match size and range size) is 0x10000; so you run another 10,000,000 tests, and the smallest gap is again 0x10000, that to me is a good bottom number for a jump size. If you run sequential versus prefix jump, and use the jump size of 0x10000, and you run from 1 - x, the prefix method will win 100% of the time. If you want to throw some anomaly in there, fine, then it will win 99.99% of the time. So it is not breaking math or crypto or the curve or any uniformed this or that. It's just using tests, analyzing and coming up with a jump size that meets your risk/reward requirements.

Sure, run tests where one method starts at the front, one at the end, or both start at random positions...but if you do that, ensure you capture where the target was randomly set, in relation to where each method started.

Seriously, what are the flaws in this test, I know there has to be 1 or 2:
Code:
import hashlib
import random
import time

# Configuration
TOTAL_SIZE = 2**17  # 131,072 keys
PREFIX_LENGTH = 3
SIMULATIONS = 500
SECP256K1_ORDER = int("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)

# ENABLE REPRODUCIBLE TESTING
random.seed(int(time.time()))

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

def ScoobyDoo_Origins(dataset, target_hash, start_index):
    checks = 0
    total_keys = len(dataset)
    i = start_index
    visited = 0

    while visited < total_keys:
        checks += 1
        if generate_h160(dataset[i]) == target_hash:
            return {"checks": checks, "found": True}

        i -= 1
        if i < 0:
            i = total_keys - 1
        visited += 1

    return {"checks": checks, "found": False}

def prefixes_search(dataset, prefix_length, target_hash, start_index):
    prefix_hash = target_hash[:prefix_length]
    total_keys = len(dataset)
    scanned = [False] * total_keys
    checks = 0
    skip_window = 16

    i = start_index
    visited = 0

    while visited < total_keys:
        if not scanned[i]:
            checks += 1
            h = generate_h160(dataset[i])

            if h == target_hash:
                return {"checks": checks, "found": True}

            if h.startswith(prefix_hash):
                for j in range(i, total_keys):
                    scanned[j] = True
                i -= skip_window
                continue

            scanned[i] = True
        i -= 1
        if i < 0:
            i = total_keys - 1
        visited += 1

    # Second pass: search remaining unscanned
    for i in range(total_keys - 1, -1, -1):
        if not scanned[i]:
            checks += 1
            h = generate_h160(dataset[i])
            if h == target_hash:
                return {"checks": checks, "found": True}

    return {"checks": checks, "found": False}

def compare_methods_random_sequential():
    results = {
        "ScoobyDoo": {"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)

        # Random starting points for each method
        scooby_start = random.randint(0, TOTAL_SIZE - 1)
        prefix_start = random.randint(0, TOTAL_SIZE - 1)

        start_time = time.perf_counter()
        seq_result = ScoobyDoo_Origins(dataset, target_hash, scooby_start)
        end_time = time.perf_counter()
        seq_time = end_time - start_time

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

        results["ScoobyDoo"]["total_checks"] += seq_result["checks"]
        results["prefixes"]["total_checks"] += pre_result["checks"]

        results["ScoobyDoo"]["total_time"] += seq_time
        results["prefixes"]["total_time"] += pre_time

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

        print(f"Simulation {i + 1}: Starts -> Scooby {scooby_start} | Prefix {prefix_start}")
        print(f"           Checks -> ScoobyDoo {seq_result['checks']} | Prefix {pre_result['checks']}")

    # Averages
    avg_success_rate_ScoobyDoo = (results["ScoobyDoo"]["total_checks"] / results["ScoobyDoo"]["wins"]
                                  if results["ScoobyDoo"]["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_ScoobyDoo = (results["ScoobyDoo"]["total_time"] / results["ScoobyDoo"]["wins"]
                          if results["ScoobyDoo"]["wins"] > 0 else float('inf'))
    avg_time_prefixes = (results["prefixes"]["total_time"] / results["prefixes"]["wins"]
                         if results["prefixes"]["wins"] > 0 else float('inf'))

    # Big Final Print
    print(f"""
=== FINAL RESULTS (Random + Sequential, Full Range with Random Starts) ===
Wins:
ScoobyDoo  : {results['ScoobyDoo']['wins']}
Prefix     : {results['prefixes']['wins']}
Ties       : {results['ties']}

Total Checks:

ScoobyDoo  : {results['ScoobyDoo']['total_checks']}
Prefix     : {results['prefixes']['total_checks']}

Total Time:

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

Averages (Total Time / Wins):

ScoobyDoo  : {avg_time_ScoobyDoo:.6f} seconds/victory
Prefix     : {avg_time_prefixes:.6f} seconds/victory

Checks per Win:
ScoobyDoo  : {avg_success_rate_ScoobyDoo:,.2f} checks/win
Prefix     : {avg_success_rate_prefixes:,.2f} checks/win
""")

    # Average checks per simulation
    print(f"""
Average Checks per Simulation:

ScoobyDoo  : {results['ScoobyDoo']['total_checks'] / SIMULATIONS:,.2f} checks/simulation
Prefix     : {results['prefixes']['total_checks'] / SIMULATIONS:,.2f} checks/simulation
""")

if __name__ == '__main__':
    compare_methods_random_sequential()

kTimesG
Full Member
***
Offline Offline

Activity: 700
Merit: 220


View Profile
April 28, 2025, 06:27:08 PM
Last edit: April 28, 2025, 06:48:14 PM by kTimesG
 #9568

OK. I cooked up something that uses all cores to build all the points in a given range.
well I have 4 cores so I am technically cooked.
"300k inserts/s" I have a c++ script that gives 30k/s but the way it works is different and will take some days to finish the billion ,it opens 3200 per time until it finishes the hall range storing only the specific prefix opened files .

As promised, here's my extremely fast Secp256k1 range points generator.

https://bitcointalk.org/index.php?topic=5539843

I'm getting 18 MK/s single-threaded on a laptop CPU, and up to 80 MK/s with using 8 threads.

So your billion points are done in 12 seconds. The problem? Inserting the results into a database is gonna hit you down to maybe 300 - 400 thousands keys / second, if you choose to save them.

Anyways - this tool can be easily used to search a range in SEQUENCE - it only takes two multiplications, everything else is pure point addition using batches of added intervals, and traversing all the areas by multiple cores in a given amount of scheduled launches.

It can also be used quite effectively to re-ensure everyone that a sequential traversal will always, always beat anything that requires recomputing a public key from some random-positioned private key.

But there is no hashing part built there - I'm sure someone like @nomachine can do it though. After all, he said it's easier to go fishing then to build this. So I did it for him as well.
Cheesy

Off the grid, training pigeons to broadcast signed messages.
Denevron
Newbie
*
Offline Offline

Activity: 121
Merit: 0


View Profile
April 28, 2025, 06:43:57 PM
 #9569

What's the point of showing a solution that can be faster than 99.5%? For the sake of a 0.1 BTC reward? If you can use this method yourself and get more  Grin
Well if a method exists it would be useful to only someone with the computing power.

if such a method exists, it will be useful even for those who do not have the capacity... and those who do have the capacity, let them look for this method themselves Wink
stwenhao
Hero Member
*****
Offline Offline

Activity: 574
Merit: 1362


View Profile
April 28, 2025, 07:10:23 PM
Merited by pbies (1)
 #9570

Quote
How could this be reconstructed, if it is even possible?
By using the same deterministic wallet, with the same seed. There are many choices, but you can limit them to some extent, if you check, when the puzzle was created. Because if you have any HD wallet, which was created after January 2015, then you can reject it right away.

Also, you can quite quickly reject many wallets, just after checking some low keys. For example: the second private key can be equal to 2 or 3. In the original puzzle, it is equal to 3. Which means, that whatever method you will pick, if it gives you 2, then you can reject a given seed, so in this way, you can reject every second candidate seed, after testing only this thing.

And then, when you will have more and more seeds, giving you more and more matching puzzles for low keys, it should lead you in the right direction, if you picked the same HD wallet, as the creator did in 2015.

Another hint you can also use, is related to revealed public keys from puzzles in 161-256 range. In this case, the last 256th address contains 255 bits of entropy (because the first bit was masked with one). Which means, that you have only two possible cases for the original key, and it should match exactly, bit-by-bit.

I guess if you would know everything about the puzzle, except the creator's seed, then there would be only one matching solution, which would produce all 256 keys, exactly as in the puzzle. Because when it comes to needed entropy, you have 1 + 2 + ... + 255 bits of information, stored in the puzzle. You have 32,640 bits of information, produced out of some 128-bit, 256-bit, or maybe 512-bit seed.

I don't think the creator used more than 3,000 words in the original seed, to achieve multiple solutions. The only possible barriers could be related to collisions inside hash functions, but even in that case, grinding a single collision is one thing, but grinding 256 collisions, where everything matches exactly, is very unlikely.

So, after solving all 160 keys, there will still be a question (without any financial incentive) about private keys to everything in range 161-256 (which may be irrelevant in case of RIPEMD160 hashes, but if we would have pubkey-based puzzle, then it would still matter, just to check, how strong raw public keys are). And after solving all 256 keys, there will still be a huge question about the seed, which would connect everything together, and form an exact match for all 256 keys, when derived in a given way.

Quote
How would you create a puzzle if you were the creator?
First, I would create a new wallet, then generate 256 new keys, then extract private keys out of them, and then apply a bit-mask on each address, by using many leading zeroes, a final one-bit, and the rest bits from the wallet.

Which means, that the first generated key would be fully discarded (because it would always be simplified into private key equal to one), and the last key would begin with one-bit, and all other 255 bits would be taken out of it.

Proof of Work puzzle in mainnet, testnet4 and signet.
fixedpaul
Member
**
Offline Offline

Activity: 83
Merit: 26


View Profile WWW
April 28, 2025, 10:15:54 PM
 #9571

All they'll get from this is that your grandfather was Einstein (the dice game observer). Now we need proofs.

I have curly hair and I hate quantum mechanics. Coincidence?
Virtuose
Jr. Member
*
Offline Offline

Activity: 60
Merit: 1


View Profile
April 28, 2025, 11:59:38 PM
 #9572

In your parallel_prefilter function, you still return immediately when the first chunk finds a solution
This means you lose the operations done by the other threads.

I'm not sure he does now, there's a shared variable incrementing. But the kicker is there :

# Compute t2 for SHA256 prefilter if pubkey provided

Too bad we dont have public key in puzzle 69.
You're literally giving part of the solution of the search to your method Smiley
That was fun, but your code is obviously AI generated, and I'm not an LLM code fixer. So you're officially disqualified from the bounty.

That being said, with 99.5% improvement, I'm sur McD and WP will be thrilled to merge this method with the prefix one for even more gains. If they don't I might have to ask them to prove why it's not good Cheesy

It's not AI my friend, but Spyder IDE, https://www.spyder-ide.org/, but a lot of people are making up stories here ^^

Good luck  Smiley
Benjade
Jr. Member
*
Offline Offline

Activity: 40
Merit: 1


View Profile WWW
April 29, 2025, 12:57:44 AM
 #9573

Um, no, I can't afford chatgpt and I only have a old desktop computer with 4 cpu  ^^

ChatGPT is free to use on lower tiers which is more than enough to generate code.

But if you could give me your linear in that case, share it and I'll show you, based on your code, that linear is crap in a box Smiley

You can simply update your own script doing something like this (Did not test it, but you should be able to understand the change required) :

Code:

# Decode address target to hex
ADDRESS_TARGET = b58decode(ADDRESS_TARGET)

# Compare with hex version of target instead of B58
def linear_scan(start: int, end: int, target: str):
    ops = 0
    for x in range(start, end+1):
        ops += 1
        if hash160_pubkey(x) == target:
            return x, ops
    return None, ops


That won't change anything, my friend. Are you sure you're coding it yourself? Maybe you're a chatgpt or a fiverr fan but I'm not. ^^
You can't compete with a c-bit prefilter for your linear.


Code:
#!/usr/bin/env python3
# coding: utf-8
"""
proof.py

Hash160 linear scan vs c-bit prefilter on puzzle 21.
Uses only hash160 comparisons and no Base58 encoding.
"""

import hashlib, math
from ecdsa import SECP256k1, util
from multiprocessing import Pool, cpu_count

# --- Configuration ---
ADDRESS_TARGET = "14oFNXucftsHiUMY8uctg6N487riuyXs4h"
HASH160_TARGET = "29a78213caa9eea824acf08022ab9dfc83414f56"
RANGE_HEX      = "100000:1fffff"
FILTER_BITS    = 2     # c ≥ 1 ⇒ >5% reduction
THRESHOLD      = 5.0   # percent
# ---------------------

G     = SECP256k1.generator
ORDER = SECP256k1.order
B58   = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

# Base58Check decode to raw payload (1-byte version + 20-byte hash160)
def b58decode(s: str) -> bytes:
    num = 0
    for ch in s:
        num = num*58 + B58.index(ch)
    nbytes = (num.bit_length() + 7)//8
    b = num.to_bytes(nbytes, 'big') if nbytes else b'\x00'
    pad = len(s) - len(s.lstrip('1'))
    full = b'\x00'*pad + b
    payload, chk = full[:-4], full[-4:]
    if hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4] != chk:
        raise ValueError("Invalid Base58 checksum")
    return payload

# Compute RIPEMD-160(SHA256(pubkey))
def hash160_pubkey(x: int) -> bytes:
    P = x * G
    prefix = b'\x02' if (P.y() & 1)==0 else b'\x03'
    pub = prefix + util.number_to_string(P.x(), ORDER)
    return hashlib.new('ripemd160', hashlib.sha256(pub).digest()).digest()

# Prepare target H160 bytes once
def get_target_h160() -> bytes:
    if HASH160_TARGET:
        return bytes.fromhex(HASH160_TARGET)
    payload = b58decode(ADDRESS_TARGET)
    return payload[1:]

# Simple linear scan comparing hash160 directly
def linear_scan(start: int, end: int, target_h: bytes):
    ops = 0
    for x in range(start, end+1):
        ops += 1
        if hash160_pubkey(x) == target_h:
            return x, ops
    return None, ops

# Worker for prefilter scan chunk
def prefilter_chunk(args):
    idx, start, end, c, t1, target_h = args
    for i, x in enumerate(range(start, end+1), start=1):
        h2 = hash160_pubkey(x)
        if (int.from_bytes(h2, 'big') >> (160-c)) != t1:
            continue
        if h2 == target_h:
            return idx, i, x
    return idx, None, None

# Parallel prefilter scan using hash160 comparisons
def parallel_prefilter(start: int, end: int, c: int, target_h: bytes, workers: int):
    N = end - start + 1
    chunk = math.ceil(N / workers)
    t1 = int.from_bytes(target_h, 'big') >> (160 - c)
    args = [(i, start + i*chunk, min(start + (i+1)*chunk - 1, end), c, t1, target_h)
            for i in range(workers)]
    with Pool(workers) as p:
        results = p.map(prefilter_chunk, args)
    for idx, ops, x in sorted(results, key=lambda r: r[0]):
        if ops:
            return x, ops
    return None, 0

# Main entry
def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--workers", type=int, default=0,
                        help="number of processes (default = CPU count)")
    args = parser.parse_args()

    workers = args.workers or cpu_count()
    s_hex, e_hex = RANGE_HEX.split(':')
    start, end = int(s_hex, 16), int(e_hex, 16)
    N = end - start + 1

    print(f"Target address: {ADDRESS_TARGET}")
    print(f"Range: 0x{s_hex} .. 0x{e_hex} (N = {N})")
    print(f"Filter bits: {FILTER_BITS}, Processes: {workers}\n")

    target_h = get_target_h160()

    # Linear scan
    print("→ Linear hash160 scan…")
    x_lin, ops_lin = linear_scan(start, end, target_h)
    print(f"  ✅ Found x = 0x{x_lin:x} in {ops_lin} H160 ops")

    # Prefilter scan
    print("\n→ Parallel prefilter scan…")
    x_pre, ops_pre = parallel_prefilter(start, end, FILTER_BITS, target_h, workers)
    print(f"  ✅ Found x = 0x{x_pre:x} in {ops_pre} heavy ops")

    # Statistics
    pct_lin = 100.0
    pct_pre = ops_pre / ops_lin * 100.0 if ops_lin else 0.0
    reduction = pct_lin - pct_pre

    print(f"\nPercent checks: hash160 = {pct_lin:.2f}%, prefilter = {pct_pre:.2f}%")
    print(f"Reduction = {reduction:.2f}%")
    print(("✅" if reduction>THRESHOLD else "⚠️") +
          f" Reduction {'exceeds' if reduction>THRESHOLD else 'below'} {THRESHOLD}%")
    winner = "Prefilter" if ops_pre < ops_lin else "Hash160"
    print("🏆 Winner: " + winner + " scan")

if __name__ == "__main__":
    main()

root:~# python3 proof.py
Target address: 14oFNXucftsHiUMY8uctg6N487riuyXs4h
Range: 0x100000 .. 0x1fffff (N = 1048576)
Filter bits: 2, Processes: 4

→ Linear hash160 scan…
  ✅ Found x = 0x1ba534 in 763189 H160 ops

→ Parallel prefilter scan…
  ✅ Found x = 0x1ba534 in 238901 heavy ops

Percent checks: hash160 = 100.00%, prefilter = 31.30%
Reduction = 68.70%
✅ Reduction exceeds 5.0%
🏆 Winner: Prefilter scan

I'm going to end up believing that you're just lucky  Tongue




Wow, that’s a really interesting approach. I’ll probably include it in KeyQuest version 2 after running some feasibility tests, or maybe turn it into a standalone program. In any case, it’s promising… If you’re up for teaming up on it, that could be fun Smiley https://github.com/Benjade/KeyQuest
kTimesG
Full Member
***
Offline Offline

Activity: 700
Merit: 220


View Profile
April 29, 2025, 06:27:46 AM
Last edit: April 29, 2025, 06:42:23 AM by kTimesG
 #9574

At this point, anyone who is too lazy to read fixedpaul's excellent explanation on how "math is broken" when jumping through a pre-fixed sequence of values, deserve their faith.

WanderingPhilospher: since you like to make experiments in order to believe stuff, here's one for you:

At every simulation, use a shared list of traversed positions, and send it to both methods.
You don't even need to build it in advance - simply start with an empty one.

- method A:
   - compute a new random position that isn't yet in the list
   - append position to shared list
   - check dataset[pos] as usual

- method B ("magic method"):
   - traverse list of positions, and do the prefix stuff just as you did as if you traversed a normal block or whatever.
   - when you skip: you skip remaining items from the shared list of positions
   - if the list has no more items: compute a new random (or not random, as it makes no difference) position that isn't yet in the list

OK. So now - we have nothing more than a "random pick" method that is being compared to a "random pick prefix" method, correct? Bare with me here. If I understand correctly, the prefix theory makes use of something called "proximity bias", so these two methods should have somewhat identical results, in terms of wins or anything else. Because the prefixes jump in some random order, right? And we also, uhm, only use random numbers everywhere now. Total identical conditions!

Now - I'm willing to bet an arm and a leg that the "same random order picks prefix method" will be like, a definitive winner.

However, I think everyone and their dog should know by now, that it is only a winner because it was compared with the "same random order method without prefix jumps".

As soon as you DARE to maybe choose another random order for either of the two methods, then it's gonna be obvious there are no advantages.

Ooops, I forgot - it's totally forbidden, because we are not doing the search in the same way. Well - now we do! Everyone knows this is how you're supposed to compare stuff, because, sure, the key might be at different random positions, and it's a total fallacy to ever compare something that starts from the end, with something that starts from the beginning. Doing that adds bias to the results, especially when doing lots of different simulations, all different! Duh...

Off the grid, training pigeons to broadcast signed messages.
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 392
Merit: 8


View Profile
April 29, 2025, 08:02:20 AM
 #9575

Now - I'm willing to bet an arm and a leg that the "same random order picks prefix method" will be like, a definitive winner.

This is all nonsense. No one is going to get rich here by taking a shortcut.  Undecided
Bram24732
Member
**
Offline Offline

Activity: 224
Merit: 22


View Profile
April 29, 2025, 09:20:54 AM
 #9576

Now - I'm willing to bet an arm and a leg that the "same random order picks prefix method" will be like, a definitive winner.

This is all nonsense. No one is going to get rich here by taking a shortcut.  Undecided

Tell you did not understand the post without telling me you didn’t understand the post Cheesy
Virtuose
Jr. Member
*
Offline Offline

Activity: 60
Merit: 1


View Profile
April 29, 2025, 11:03:42 AM
 #9577

Now - I'm willing to bet an arm and a leg that the "same random order picks prefix method" will be like, a definitive winner.

This is all nonsense. No one is going to get rich here by taking a shortcut.  Undecided

Tell you did not understand the post without telling me you didn’t understand the post Cheesy

That's rather pretentious coming from someone in bad faith who doesn't know how to read code.  Cheesy
Benjade
Jr. Member
*
Offline Offline

Activity: 40
Merit: 1


View Profile WWW
April 29, 2025, 11:59:00 AM
 #9578

Um, no, I can't afford chatgpt and I only have a old desktop computer with 4 cpu  ^^

ChatGPT is free to use on lower tiers which is more than enough to generate code.

But if you could give me your linear in that case, share it and I'll show you, based on your code, that linear is crap in a box Smiley

You can simply update your own script doing something like this (Did not test it, but you should be able to understand the change required) :

Code:

# Decode address target to hex
ADDRESS_TARGET = b58decode(ADDRESS_TARGET)

# Compare with hex version of target instead of B58
def linear_scan(start: int, end: int, target: str):
    ops = 0
    for x in range(start, end+1):
        ops += 1
        if hash160_pubkey(x) == target:
            return x, ops
    return None, ops


That won't change anything, my friend. Are you sure you're coding it yourself? Maybe you're a chatgpt or a fiverr fan but I'm not. ^^
You can't compete with a c-bit prefilter for your linear.


Code:
#!/usr/bin/env python3
# coding: utf-8
"""
proof.py

Hash160 linear scan vs c-bit prefilter on puzzle 21.
Uses only hash160 comparisons and no Base58 encoding.
"""

import hashlib, math
from ecdsa import SECP256k1, util
from multiprocessing import Pool, cpu_count

# --- Configuration ---
ADDRESS_TARGET = "14oFNXucftsHiUMY8uctg6N487riuyXs4h"
HASH160_TARGET = "29a78213caa9eea824acf08022ab9dfc83414f56"
RANGE_HEX      = "100000:1fffff"
FILTER_BITS    = 2     # c ≥ 1 ⇒ >5% reduction
THRESHOLD      = 5.0   # percent
# ---------------------

G     = SECP256k1.generator
ORDER = SECP256k1.order
B58   = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

# Base58Check decode to raw payload (1-byte version + 20-byte hash160)
def b58decode(s: str) -> bytes:
    num = 0
    for ch in s:
        num = num*58 + B58.index(ch)
    nbytes = (num.bit_length() + 7)//8
    b = num.to_bytes(nbytes, 'big') if nbytes else b'\x00'
    pad = len(s) - len(s.lstrip('1'))
    full = b'\x00'*pad + b
    payload, chk = full[:-4], full[-4:]
    if hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4] != chk:
        raise ValueError("Invalid Base58 checksum")
    return payload

# Compute RIPEMD-160(SHA256(pubkey))
def hash160_pubkey(x: int) -> bytes:
    P = x * G
    prefix = b'\x02' if (P.y() & 1)==0 else b'\x03'
    pub = prefix + util.number_to_string(P.x(), ORDER)
    return hashlib.new('ripemd160', hashlib.sha256(pub).digest()).digest()

# Prepare target H160 bytes once
def get_target_h160() -> bytes:
    if HASH160_TARGET:
        return bytes.fromhex(HASH160_TARGET)
    payload = b58decode(ADDRESS_TARGET)
    return payload[1:]

# Simple linear scan comparing hash160 directly
def linear_scan(start: int, end: int, target_h: bytes):
    ops = 0
    for x in range(start, end+1):
        ops += 1
        if hash160_pubkey(x) == target_h:
            return x, ops
    return None, ops

# Worker for prefilter scan chunk
def prefilter_chunk(args):
    idx, start, end, c, t1, target_h = args
    for i, x in enumerate(range(start, end+1), start=1):
        h2 = hash160_pubkey(x)
        if (int.from_bytes(h2, 'big') >> (160-c)) != t1:
            continue
        if h2 == target_h:
            return idx, i, x
    return idx, None, None

# Parallel prefilter scan using hash160 comparisons
def parallel_prefilter(start: int, end: int, c: int, target_h: bytes, workers: int):
    N = end - start + 1
    chunk = math.ceil(N / workers)
    t1 = int.from_bytes(target_h, 'big') >> (160 - c)
    args = [(i, start + i*chunk, min(start + (i+1)*chunk - 1, end), c, t1, target_h)
            for i in range(workers)]
    with Pool(workers) as p:
        results = p.map(prefilter_chunk, args)
    for idx, ops, x in sorted(results, key=lambda r: r[0]):
        if ops:
            return x, ops
    return None, 0

# Main entry
def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("--workers", type=int, default=0,
                        help="number of processes (default = CPU count)")
    args = parser.parse_args()

    workers = args.workers or cpu_count()
    s_hex, e_hex = RANGE_HEX.split(':')
    start, end = int(s_hex, 16), int(e_hex, 16)
    N = end - start + 1

    print(f"Target address: {ADDRESS_TARGET}")
    print(f"Range: 0x{s_hex} .. 0x{e_hex} (N = {N})")
    print(f"Filter bits: {FILTER_BITS}, Processes: {workers}\n")

    target_h = get_target_h160()

    # Linear scan
    print("→ Linear hash160 scan…")
    x_lin, ops_lin = linear_scan(start, end, target_h)
    print(f"  ✅ Found x = 0x{x_lin:x} in {ops_lin} H160 ops")

    # Prefilter scan
    print("\n→ Parallel prefilter scan…")
    x_pre, ops_pre = parallel_prefilter(start, end, FILTER_BITS, target_h, workers)
    print(f"  ✅ Found x = 0x{x_pre:x} in {ops_pre} heavy ops")

    # Statistics
    pct_lin = 100.0
    pct_pre = ops_pre / ops_lin * 100.0 if ops_lin else 0.0
    reduction = pct_lin - pct_pre

    print(f"\nPercent checks: hash160 = {pct_lin:.2f}%, prefilter = {pct_pre:.2f}%")
    print(f"Reduction = {reduction:.2f}%")
    print(("✅" if reduction>THRESHOLD else "⚠️") +
          f" Reduction {'exceeds' if reduction>THRESHOLD else 'below'} {THRESHOLD}%")
    winner = "Prefilter" if ops_pre < ops_lin else "Hash160"
    print("🏆 Winner: " + winner + " scan")

if __name__ == "__main__":
    main()

root:~# python3 proof.py
Target address: 14oFNXucftsHiUMY8uctg6N487riuyXs4h
Range: 0x100000 .. 0x1fffff (N = 1048576)
Filter bits: 2, Processes: 4

→ Linear hash160 scan…
  ✅ Found x = 0x1ba534 in 763189 H160 ops

→ Parallel prefilter scan…
  ✅ Found x = 0x1ba534 in 238901 heavy ops

Percent checks: hash160 = 100.00%, prefilter = 31.30%
Reduction = 68.70%
✅ Reduction exceeds 5.0%
🏆 Winner: Prefilter scan

I'm going to end up believing that you're just lucky  Tongue




Wow, that’s a really interesting approach. I’ll probably include it in KeyQuest version 2 after running some feasibility tests, or maybe turn it into a standalone program. In any case, it’s promising… If you’re up for teaming up on it, that could be fun Smiley https://github.com/Benjade/KeyQuest

KeyQuest is messy with animations.
On ubuntu 24 i got only flashing screen, win10 totally broken.
Why not just simple console print?


Because I like vintage design lol
More seriously, I would do something simpler for V2 soon or both I don't know.
Bram24732
Member
**
Offline Offline

Activity: 224
Merit: 22


View Profile
April 29, 2025, 01:26:28 PM
 #9579

Now - I'm willing to bet an arm and a leg that the "same random order picks prefix method" will be like, a definitive winner.

This is all nonsense. No one is going to get rich here by taking a shortcut.  Undecided

Tell you did not understand the post without telling me you didn’t understand the post Cheesy

That's rather pretentious coming from someone in bad faith who doesn't know how to read code.  Cheesy

A bit of irony
denyAKA BLACKANGEL
Newbie
*
Offline Offline

Activity: 14
Merit: 1


View Profile
April 29, 2025, 05:53:54 PM
 #9580

I finally found how the puzzle was made. I searched the internet for mathematical methods, and there are many, I haven't tested them all yet. I thought maybe someone has a better idea. But I think this hypothesis can work. I haven't finished everything yet. But I can only show one part. Maybe someone has a better idea. I think the creator used mersenne prime numbers (514 = 2 × 257)
bitwise test key = previous_key << n + k ( 21 = 8 << 1 + 5)
arithmetic sequences 3 → 7 → 8 → 21 deltas +4, +1, +13) I wrote more code with the help of AI of course because it can find every error in the code faster and also information. But my idea is that the creator used raylicite methods for every 3 or 5 or 8 address. I haven't tested everything yet. But I want to share it with you. Maybe someone has an idea. But definitely more brains, more ideas and success. one thing is certain that the addresses are generated with some patterns, I have the method for the first 10 addresses,i am currently writing the code for the rest.

ps..
please write your opinion, i m very interested.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 29 16:24:01 2025

@author: blackangel
"""

import hashlib
from coincurve import PrivateKey

# Known solved private keys (puzzle_number: hex_private_key)
SOLVED_KEYS = {
    1: '0000000000000000000000000000000000000000000000000000000000000001',
    2: '0000000000000000000000000000000000000000000000000000000000000003',
    3: '0000000000000000000000000000000000000000000000000000000000000007',
    4: '0000000000000000000000000000000000000000000000000000000000000008',
    5: '0000000000000000000000000000000000000000000000000000000000000015',
    #6: '0000000000000000000000000000000000000000000000000000000000000031',
    7: '000000000000000000000000000000000000000000000000000000000000004c',
    #8: '00000000000000000000000000000000000000000000000000000000000000e0',
    #9: '00000000000000000000000000000000000000000000000000000000000001d3',
    #10: '0000000000000000000000000000000000000000000000000000000000000202',
    11: '0000000000000000000000000000000000000000000000000000000000000483',
    #12: '0000000000000000000000000000000000000000000000000000000000000a7b',
    13: '0000000000000000000000000000000000000000000000000000000000001460',  
    #14: '0000000000000000000000000000000000000000000000000000000000002930',
    15: '00000000000000000000000000000000000000000000000000000000000068f3',
    16: '000000000000000000000000000000000000000000000000000000000000c936',  
    17: '000000000000000000000000000000000000000000000000000000000001764f',
    18: '000000000000000000000000000000000000000000000000000000000003080d',
    19: '000000000000000000000000000000000000000000000000000000000005749f',
    20: '00000000000000000000000000000000000000000000000000000000000d2c55',  


}





# -------------------------------------------------------------------------------
# Hypothesis 1: Mersenne-like numbers (2^n - 1)
# -------------------------------------------------------------------------------
def test_mersenne_hypothesis():
    print("\nHypothesis 1: Mersenne numbers (2^n - 1)")
    matches = 0
    for puzzle_number in SOLVED_KEYS:
        expected_key = (2 ** puzzle_number) - 1
        expected_hex = format(expected_key, '064x')
        actual_hex = SOLVED_KEYS[puzzle_number]
        if expected_hex == actual_hex:
            matches += 1
            print(f"  Puzzle {puzzle_number}: MATCH (Expected {expected_hex})")
        else:
            print(f"  Puzzle {puzzle_number}: FAIL (Expected {expected_hex}, Actual {actual_hex})")
    print(f"Matches: {matches}/{len(SOLVED_KEYS)}")

# -------------------------------------------------------------------------------
# Hypothesis 2: Hash-based generation (SHA-256 of puzzle number)
# -------------------------------------------------------------------------------
def test_hash_hypothesis():
    print("\nHypothesis 2: SHA-256 of puzzle number")
    matches = 0
    for puzzle_number in SOLVED_KEYS:
        #compute SHA-256 of puzzle number ( "5" -> hash)
        data = str(puzzle_number).encode()
        hash_hex = hashlib.sha256(data).hexdigest()
        
        # Truncate to 64 hex chars (32 bytes) to match private key format
        expected_hex = hash_hex[:64]
        actual_hex = SOLVED_KEYS[puzzle_number]
        
        if expected_hex == actual_hex:
            matches += 1
            print(f"  Puzzle {puzzle_number}: MATCH (Hash {hash_hex})")
        else:
            print(f"  Puzzle {puzzle_number}: FAIL (Hash {hash_hex}, Actual {actual_hex})")
    print(f"Matches: {matches}/{len(SOLVED_KEYS)}")

# -------------------------------------------------------------------------------
# Hypothesis 3: Bitwise shift with increment
# -------------------------------------------------------------------------------
def test_bitwise_hypothesis():
    print("\nHypothesis 3: Bitwise shift + increment")
    matches = 0
    prev_key = 0
    for puzzle_number in sorted(SOLVED_KEYS.keys()):
        actual_key = int(SOLVED_KEYS[puzzle_number], 16)
        if puzzle_number == 1:
            expected_key = 1
        else:
            expected_key = (prev_key << 1) + 1  # e.g., 1 -> 3 (0b11), 3 -> 7 (0b111)
        
        if expected_key == actual_key:
            matches += 1
            print(f"  Puzzle {puzzle_number}: MATCH (Expected {hex(expected_key)})")
        else:
            print(f"  Puzzle {puzzle_number}: FAIL (Expected {hex(expected_key)}, Actual {hex(actual_key)})")
        prev_key = actual_key
    print(f"Matches: {matches}/{len(SOLVED_KEYS)}")

# -------------------------------------------------------------------------------
# Hypothesis 4: Address generation from private key (for verification)
# -------------------------------------------------------------------------------
def generate_address(private_key_hex):
    private_key = PrivateKey.from_hex(private_key_hex)
    public_key = private_key.public_key.format().hex()
    return public_key  # Simplified for demonstration

# -------------------------------------------------------------------------------
# Main Execution
# -------------------------------------------------------------------------------
if __name__ == "__main__":
    print("Testing hypotheses for private key generation...")
    
    # Test Hypothesis 1: Mersenne numbers
    test_mersenne_hypothesis()
    
    # Test Hypothesis 2: Hash-based generation
    test_hash_hypothesis()
    
    # Test Hypothesis 3: Bitwise shift
    test_bitwise_hypothesis()

    # Example: Generate address for Puzzle 1's key
    puzzle_1_key = SOLVED_KEYS[1]
    print(f"\nExample: Address for Puzzle 1 (Public Key): {generate_address(puzzle_1_key)}")  




%runfile /home/blackangel/untitled20.py --wdir
Testing hypotheses for private key generation...

Hypothesis 1: Mersenne numbers (2^n - 1)
  Puzzle 1: MATCH (Expected 0000000000000000000000000000000000000000000000000000000000000001)
  Puzzle 2: MATCH (Expected 0000000000000000000000000000000000000000000000000000000000000003)
  Puzzle 3: MATCH (Expected 0000000000000000000000000000000000000000000000000000000000000007)
  Puzzle 4: FAIL (Expected 000000000000000000000000000000000000000000000000000000000000000f, Actual 0000000000000000000000000000000000000000000000000000000000000008)
  Puzzle 5: FAIL (Expected 000000000000000000000000000000000000000000000000000000000000001f, Actual 0000000000000000000000000000000000000000000000000000000000000015)
  Puzzle 7: FAIL (Expected 000000000000000000000000000000000000000000000000000000000000007f, Actual 000000000000000000000000000000000000000000000000000000000000004c)
  Puzzle 11: FAIL (Expected 00000000000000000000000000000000000000000000000000000000000007ff, Actual 0000000000000000000000000000000000000000000000000000000000000483)
  Puzzle 13: FAIL (Expected 0000000000000000000000000000000000000000000000000000000000001fff, Actual 0000000000000000000000000000000000000000000000000000000000001460)
  Puzzle 15: FAIL (Expected 0000000000000000000000000000000000000000000000000000000000007fff, Actual 00000000000000000000000000000000000000000000000000000000000068f3)
  Puzzle 16: FAIL (Expected 000000000000000000000000000000000000000000000000000000000000ffff, Actual 000000000000000000000000000000000000000000000000000000000000c936)
  Puzzle 17: FAIL (Expected 000000000000000000000000000000000000000000000000000000000001ffff, Actual 000000000000000000000000000000000000000000000000000000000001764f)
  Puzzle 18: FAIL (Expected 000000000000000000000000000000000000000000000000000000000003ffff, Actual 000000000000000000000000000000000000000000000000000000000003080d)
  Puzzle 19: FAIL (Expected 000000000000000000000000000000000000000000000000000000000007ffff, Actual 000000000000000000000000000000000000000000000000000000000005749f)
  Puzzle 20: FAIL (Expected 00000000000000000000000000000000000000000000000000000000000fffff, Actual 00000000000000000000000000000000000000000000000000000000000d2c55)
Matches: 3/14

Hypothesis 2: SHA-256 of puzzle number
  Puzzle 1: FAIL (Hash 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b, Actual 0000000000000000000000000000000000000000000000000000000000000001)
  Puzzle 2: FAIL (Hash d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35, Actual 0000000000000000000000000000000000000000000000000000000000000003)
  Puzzle 3: FAIL (Hash 4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce, Actual 0000000000000000000000000000000000000000000000000000000000000007)
  Puzzle 4: FAIL (Hash 4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a, Actual 0000000000000000000000000000000000000000000000000000000000000008)
  Puzzle 5: FAIL (Hash ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d, Actual 0000000000000000000000000000000000000000000000000000000000000015)
  Puzzle 7: FAIL (Hash 7902699be42c8a8e46fbbb4501726517e86b22c56a189f7625a6da49081b2451, Actual 000000000000000000000000000000000000000000000000000000000000004c)
  Puzzle 11: FAIL (Hash 4fc82b26aecb47d2868c4efbe3581732a3e7cbcc6c2efb32062c08170a05eeb8, Actual 0000000000000000000000000000000000000000000000000000000000000483)
  Puzzle 13: FAIL (Hash 3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278, Actual 0000000000000000000000000000000000000000000000000000000000001460)
  Puzzle 15: FAIL (Hash e629fa6598d732768f7c726b4b621285f9c3b85303900aa912017db7617d8bdb, Actual 00000000000000000000000000000000000000000000000000000000000068f3)
  Puzzle 16: FAIL (Hash b17ef6d19c7a5b1ee83b907c595526dcb1eb06db8227d650d5dda0a9f4ce8cd9, Actual 000000000000000000000000000000000000000000000000000000000000c936)
  Puzzle 17: FAIL (Hash 4523540f1504cd17100c4835e85b7eefd49911580f8efff0599a8f283be6b9e3, Actual 000000000000000000000000000000000000000000000000000000000001764f)
  Puzzle 18: FAIL (Hash 4ec9599fc203d176a301536c2e091a19bc852759b255bd6818810a42c5fed14a, Actual 000000000000000000000000000000000000000000000000000000000003080d)
  Puzzle 19: FAIL (Hash 9400f1b21cb527d7fa3d3eabba93557a18ebe7a2ca4e471cfe5e4c5b4ca7f767, Actual 000000000000000000000000000000000000000000000000000000000005749f)
  Puzzle 20: FAIL (Hash f5ca38f748a1d6eaf726b8a42fb575c3c71f1864a8143301782de13da2d9202b, Actual 00000000000000000000000000000000000000000000000000000000000d2c55)
Matches: 0/14

Hypothesis 3: Bitwise shift + increment
  Puzzle 1: MATCH (Expected 0x1)
  Puzzle 2: MATCH (Expected 0x3)
  Puzzle 3: MATCH (Expected 0x7)
  Puzzle 4: FAIL (Expected 0xf, Actual 0x8)
  Puzzle 5: FAIL (Expected 0x11, Actual 0x15)
  Puzzle 7: FAIL (Expected 0x2b, Actual 0x4c)
  Puzzle 11: FAIL (Expected 0x99, Actual 0x483)
  Puzzle 13: FAIL (Expected 0x907, Actual 0x1460)
  Puzzle 15: FAIL (Expected 0x28c1, Actual 0x68f3)
  Puzzle 16: FAIL (Expected 0xd1e7, Actual 0xc936)
  Puzzle 17: FAIL (Expected 0x1926d, Actual 0x1764f)
  Puzzle 18: FAIL (Expected 0x2ec9f, Actual 0x3080d)
  Puzzle 19: FAIL (Expected 0x6101b, Actual 0x5749f)
  Puzzle 20: FAIL (Expected 0xae93f, Actual 0xd2c55)
Matches: 3/14

Example: Address for Puzzle 1 (Public Key): 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798  

 

Pages: « 1 ... 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 [479] 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 ... 618 »
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!