Bitcoin Forum
March 27, 2025, 11:02:59 PM *
News: Latest Bitcoin Core release: 28.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 ... 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 [370] 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 270611 times)
HABJo12
Newbie
*
Offline Offline

Activity: 6
Merit: 0


View Profile
February 19, 2025, 06:10:51 AM
 #7381

Dear Sir first try to know your RAM processor unit quantity your device generation and graphics cards then you can check it by making random code like this 
import ecdsa
import time

def generate_key():
    sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
    return sk.to_string().hex()

start_time = time.time()
num_keys = 1000  # number of keys to generate for testing
for _ in range(num_keys):
    generate_key()

end_time = time.time()
speed = num_keys / (end_time - start_time)
print(f"Generated {num_keys} keys in {end_time - start_time:.2f} seconds.")
print(f"Speed: {speed:.2f} keys per second.")             

frozenen
Newbie
*
Offline Offline

Activity: 42
Merit: 0


View Profile
February 19, 2025, 07:08:32 AM
 #7382

Wondering if anyone can help me with this.

Just curious - how long would it take for the average household desktop computer now in 2025 to get through 50% of the keys for puzzle 67?

I want to know to better explain this puzzle to my family/friends.

Thanks!!

#67 range is  73.79 quintillion
#68 range is 147.57 quintillion
#69 range is 295.15 quintillion

73.79 quintillion = 73790000000000000000

your new houshold Pc can prob do 8 Mkeys/s without high end GPU!

so about 292,277 years or  148,639 years for 50% of the range in #67 to answer your question!
nomachine
Member
**
Offline Offline

Activity: 602
Merit: 49


View Profile
February 19, 2025, 07:16:29 AM
Last edit: February 19, 2025, 07:37:38 AM by nomachine
 #7383

The fact that there are only 2^77 grains of sand on all the beaches in the world helps put the scale of the puzzle into perspective. This is a lot. It's like trying to find a specific grain of sand in a massive desert that’s far bigger than all the beaches in the world combined. Grin

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
fecell
Jr. Member
*
Offline Offline

Activity: 145
Merit: 2


View Profile
February 19, 2025, 09:33:46 AM
 #7384

You know, guys, I noticed that if you generate tame and wild correctly, then the kangaroo gets to the target very quickly.
with Python (3.11) on a 40-bit PK, at i5-9300H (2.4Ghz) with 32Gb (used only 20%)... it's only 3 seconds to solve. no any RND was used - only bit range and bit unique rules.
No CUDA, multithreading, and so on - just one-thread calculation.

Code:
[+] Precomputed jump points ready: 33
[+] Puzzle complexity: 40-bit
[+] Search range: 2^39 - 2^40
[+] Distinguished point rarity: 2^10
[+] Distinguished point rarity: 1024
[+] Expected hops: 2^21.09 (2233466)
[+] Tame and wild herds initialized. 00:00:00
[+] Tame and wild points initialized. 00:00:00

[+] PUZZLE SOLVED
[+] Private key (dec): 1003651412950

[+] Total hops: 1144040

[+] Search duration: 00:00:03
[+] Total execution time: 00:00:03

for 135-bit tame's and wild's values needs very long time (about 48h) to fill.
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 207
Merit: 3


View Profile
February 19, 2025, 10:05:59 AM
 #7385

for 135-bit tame's and wild's values needs very long time (about 48h) to fill.


You would need approximately 2^68.50 (417402170410649059328) hops to complete this. It’s unrealistic to achieve this within 48 hours, even if you precompute 2^33 hops.

Could you provide us some code to verify these calculations?
nomachine
Member
**
Offline Offline

Activity: 602
Merit: 49


View Profile
February 19, 2025, 10:24:44 AM
Last edit: February 19, 2025, 11:11:22 AM by nomachine
 #7386

No need to look at the code. I mentioned earlier that my Python script implementation is intended solely for educational, testing, and experimental purposes. Solving puzzle 135 is physically impossible on a typical PC due to fundamental physical limitations. Even with 3–4 high-end GPUs, it would be unfeasible (been there, done that). Literally due to the laws of physics. You would need at least 100 GPUs and extensive optimization in C++ and CUDA. Python alone cannot handle this.

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
fecell
Jr. Member
*
Offline Offline

Activity: 145
Merit: 2


View Profile
February 19, 2025, 10:39:50 AM
 #7387

Could you provide us some code to verify these calculations?

need to put at "twset" with name "twset_b11.py"
Code:
import gmpy2

def gen_tame_wild(lower_bound, upper_bound, herd_size, N):

    tame = []
    wild = []
    (lower, lower_idx), (upper, upper_idx) = closest_triangular_numbers(lower_bound)

    print(f'[~] Tame/Wild helds: {herd_size}, lower: {lower_bound}, upper: {upper_bound}, size: {upper_bound - lower_bound}')

    generator = get_next_triangular(upper, upper_idx, N, 1)
    while len(tame) != herd_size:
        (upper, upper_idx) = next(generator)
        if upper > upper_bound:
            print(f'\nFail fill Tame/Wild with N={N}')
            exit()
        tame.append(gmpy2.mpz(upper))
        wild.append(gmpy2.mpz(upper_idx))
        print(f'[~] Tame/Wild herds current: {len(tame)}', end = '\r')

    return (tame, wild)

################################################################################################
def check_consecutive_bits(number, N):
    if N == 0:
        return True
       
    count_zeros = 0
    count_ones = 0
   
    # Пpoxoдим пo кaждoмy битy чиcлa
    while number > 0:
        # Пpoвepяeм тeкyщий бит чиcлa
        if number & 1 == 0:
            count_zeros += 1
            count_ones = 0
        else:
            count_ones += 1
            count_zeros = 0
       
        # Ecли пoдpяд N oдинaкoвыx битoв нaйдeнo, вoзвpaщaeм True
        if count_zeros > N or count_ones > N:
            return False
       
        # Cдвигaeм чиcлo нa 1 впpaвo для пpoвepки cлeдyющeгo битa
        number >>= 1
   
    # Ecли нe нaшли пoдpяд N oдинaкoвыx битoв
    return True

def closest_triangular_numbers(n):
    def triangular_number(i):
        return (i * (i + 1)) // 2

    left, right = 1, int((2 * n) ** 0.5) + 1

    while left <= right:
        mid = (left + right) // 2
        t_mid = triangular_number(mid)
        if t_mid == n:
            upper_i = mid + 1
            upper_t = triangular_number(upper_i)
            return ( (t_mid, mid), (upper_t, upper_i) )
        elif t_mid < n:
            left = mid + 1
        else:
            right = mid - 1

    lower_i = right
    lower_t = triangular_number(lower_i)
    upper_i = right + 1
    upper_t = triangular_number(upper_i)
    return ( (lower_t, lower_i), (upper_t, upper_i) )

def get_next_triangular(value, index, N, operation):
    while True:
        index += operation
        value += index * operation
        if check_consecutive_bits(value, N) and check_consecutive_bits(index, N):
            yield (value, index)


################################################################################################
def test(puzzle_complexity, compressed_pubkey, N):

    import time
    start_time = time.time()


    herd_size   = 2 ** (puzzle_complexity // 5)
    lower_bound = 2 ** (puzzle_complexity - 1)
    upper_bound = (2 ** puzzle_complexity) - 1

    tame_start_values, wild_start_values = gen_tame_wild(lower_bound, upper_bound, herd_size, N)

    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'\n[+] Tame and Wild herds initialized. {elapsed_str}')

    for x in tame_start_values:
        print(bin(x)[2:])
    for x in wild_start_values:
        print(bin(x)[2:])


if __name__ == '__main__':

    N = 4

    puzzle_complexity = 40
    compressed_pubkey = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4"
   
    #puzzle_complexity = 53
    #compressed_pubkey = "020faaf5f3afe58300a335874c80681cf66933e2a7aeb28387c0d28bb048bc6349"
   
    test(puzzle_complexity, compressed_pubkey, N)

main code:
Code:
import gmpy2

from twset.twset_b11 import gen_tame_wild
#from twset.twset_b12 import gen_tame_wild
#from twset.twset_b21 import gen_tame_wild
#from twset.twset_b22 import gen_tame_wild

N = gmpy2.mpz(6)

puzzle_complexity = 40
compressed_pubkey = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4"

#puzzle_complexity = 41
#compressed_pubkey = "03b357e68437da273dcf995a474a524439faad86fc9effc300183f714b0903468b"

#puzzle_complexity = 160
#compressed_pubkey = "02e0a8b039282faf6fe0fd769cfbc4b6b4cf8758ba68220eac420e32b91ddfa673"

#puzzle_complexity = 135
#compressed_pubkey = "02145d2611c823a396ef6712ce0f712f09b9b4f3135e3e0aa3230fb9b6d08d1e16"

#puzzle_complexity = 53
#compressed_pubkey = "020faaf5f3afe58300a335874c80681cf66933e2a7aeb28387c0d28bb048bc6349"

#puzzle_complexity = 20
#compressed_pubkey = "033c4a45cbd643ff97d77f41ea37e843648d50fd894b864b0d52febc62f6454f7c"

##########################################################################################

import time
import os
import sys
import random
from math import log2, sqrt, log

# Oчиcткa экpaнa в зaвиcимocти oт OC
if os.name == 'nt':
    os.system('cls')
else:
    os.system('clear')
current_time = time.ctime()
sys.stdout.write("\033[?25l")  # Cкpыть кypcop
sys.stdout.write(f"\033[01;33m[+] Kangaroo: {current_time}\n")
sys.stdout.flush()

# Пapaмeтpы эллиптичecкoй кpивoй secp256k1
modulus = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
curve_order = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
generator_x = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
generator_y = gmpy2.mpz(0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)

base_point = (generator_x, generator_y)

def elliptic_curve_add(point1, point2):
    infinity = (0, 0)
    if point1 == infinity:
        return point2
    if point2 == infinity:
        return point1
   
    x1, y1 = point1
    x2, y2 = point2

    if x1 == x2:
        if y1 == y2:
            # Удвoeниe тoчки
            denominator = (y1 << 1) % modulus
            inv_denominator = gmpy2.invert(denominator, modulus)
            slope = (3 * x1 * x1 * inv_denominator) % modulus
        else:
            return infinity
    else:
        x_diff = (x2 - x1) % modulus
        inv_x_diff = gmpy2.invert(x_diff, modulus)
        slope = ((y2 - y1) * inv_x_diff) % modulus

    result_x = (slope * slope - x1 - x2) % modulus
    result_y = (slope * (x1 - result_x) - y1) % modulus
   
    return (result_x, result_y)

def scalar_multiply(scalar, point=base_point):
    result = (0, 0)
    current_point = point
    while scalar:
        if scalar & 1:
            result = elliptic_curve_add(result, current_point)
        current_point = elliptic_curve_add(current_point, current_point)
        scalar >>= 1
    return result

def x_to_y(x_coord, y_parity, prime=modulus):
    x_cubed = gmpy2.powmod(x_coord, 3, prime)
    x_squared = gmpy2.powmod(x_coord, 2, prime)
    y_squared = (x_cubed + 7) % prime
    y_coord = gmpy2.powmod(y_squared, (prime + 1) // 4, prime)
   
    if y_parity == 1:
        y_coord = (-y_coord) % prime
    return y_coord

def generate_power_steps(max_power):
    return [gmpy2.mpz(1 << power) for power in range(max_power)]

def handle_found_solution(private_key):
    hex_representation = "%064x" % abs(private_key)
    decimal_value = int(hex_representation, 16)
    print("\n\033[32m[+] PUZZLE SOLVED \033[0m")
    print(f"\033[32m[+] Private key (dec): {decimal_value} \033[0m")
    with open("KEYFOUNDKEYFOUND.txt", "a") as file:
        file.write(f"\n\nSOLVED {current_time}")
        file.write(f"\nPrivate Key (decimal): {decimal_value}")
        file.write(f"\nPrivate Key (hex): {hex_representation}")
        file.write(f"\n{'-' * 100}\n")
    return True

def kangaroo_search(precomputed_points, wild_start_point, dp_rarity, herd_size,
                   max_hop_power, upper_bound, lower_bound, power_steps):

    solution_found = False

    # Инициaлизaция кeнгypy
    start_time0 = time.time()

    start_time = time.time()
    tame_start_values, wild_start_values = gen_tame_wild(lower_bound, upper_bound, herd_size, N)
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'\n[+] Tame and wild herds initialized. {elapsed_str}')

    start_time = time.time()
    tame_points = [scalar_multiply(value) for value in tame_start_values]
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Tame points initialized. {elapsed_str}')

    start_time = time.time()
    wild_points = [elliptic_curve_add(wild_start_point, scalar_multiply(value)) for value in wild_start_values]
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Wild points initialized. {elapsed_str}')
   
    start_time = time.time()
    tame_steps = [gmpy2.mpz(0) for _ in range(herd_size)]
    wild_steps = tame_steps.copy()
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Tame and wild steps initialized. {elapsed_str}')
   
    hours, rem = divmod(time.time() - start_time0, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Tame and wild points initialized. {elapsed_str}')
   
    total_hops = 0
    previous_hops_count = 0
    tame_distinguished_points = {}
    wild_distinguished_points = {}
    last_print_time = time.time()
    search_start_time = time.time()
   
    while True:
        # Oбpaбoткa pyчныx кeнгypy
        for idx in range(herd_size):
            total_hops += 1
            power_index = int(tame_points[idx][0] % max_hop_power)
            step_size = power_steps[power_index]
           
            if tame_points[idx][0] % dp_rarity == 0:
                x_coord = tame_points[idx][0]
                if x_coord in wild_distinguished_points:
                    solution = wild_distinguished_points[x_coord] - tame_start_values[idx]
                    solution_found = handle_found_solution(solution)
                    break
                tame_distinguished_points[x_coord] = tame_start_values[idx]
           
            tame_start_values[idx] += step_size
            tame_points[idx] = elliptic_curve_add(precomputed_points[power_index], tame_points[idx])
        if solution_found: break

        # Oбpaбoткa дикиx кeнгypy
        for idx in range(herd_size):
            total_hops += 1
            power_index = int(wild_points[idx][0] % max_hop_power)
            step_size = power_steps[power_index]
           
            if wild_points[idx][0] % dp_rarity == 0:
                x_coord = wild_points[idx][0]
                if x_coord in tame_distinguished_points:
                    solution = wild_start_values[idx] - tame_distinguished_points[x_coord]
                    solution_found = handle_found_solution(solution)
                    break
                wild_distinguished_points[x_coord] = wild_start_values[idx]
           
            wild_start_values[idx] += step_size
            wild_points[idx] = elliptic_curve_add(precomputed_points[power_index], wild_points[idx])
        if solution_found: break
       
        # Bывoд cтaтиcтики
        current_time = time.time()
        if current_time - last_print_time >= 5:
            elapsed_since_last = current_time - last_print_time
            hops_since_last = total_hops - previous_hops_count
            hops_per_sec = hops_since_last / elapsed_since_last if elapsed_since_last > 0 else 0
           
            total_elapsed = current_time - search_start_time
            hours, rem = divmod(total_elapsed, 3600)
            minutes, seconds = divmod(rem, 60)
            elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
           
            last_print_time = current_time
            previous_hops_count = total_hops
           
            print(f'[+] [Hops: 2^{log2(total_hops):.2f} <-> {hops_per_sec:.0f} h/s] [{elapsed_str}]',
                  end='\r', flush=True)

    print()
    print(f'[+] Total hops: {total_hops}')
    hours, rem = divmod(time.time() - search_start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Search duration: {elapsed_str}')
    return solution_found

lower_bound = 2 ** (puzzle_complexity - 1)
upper_bound = (2 ** puzzle_complexity) - 1
dp_rarity = 1 << ((puzzle_complexity - 1) // 2 - 2) // 2 + 2

max_hop_power = round(log(2 ** puzzle_complexity) + 5)
herd_size = 2 ** (puzzle_complexity // 5)
power_steps = generate_power_steps(max_hop_power)

# Дeкoдиpoвaниe пyбличнoгo ключa
if len(compressed_pubkey) == 66:
    x_coord = gmpy2.mpz(int(compressed_pubkey[2:66], 16))
    y_parity = int(compressed_pubkey[:2]) - 2
    y_coord = x_to_y(x_coord, y_parity)
else:
    print("[ERROR] Invalid public key format")
    sys.exit(1)

wild_start_point = (x_coord, y_coord)

# Пpeдвapитeльный pacчeт тoчeк для пpыжкoв
precomputed_points = [base_point]
for _ in range(max_hop_power - 1):
    precomputed_points.append(elliptic_curve_add(precomputed_points[-1], precomputed_points[-1]))
print(f'[+] Precomputed jump points ready: {max_hop_power}')

# Зaпycк пoиcкa
search_start_time = time.time()
print(f"[+] Puzzle complexity: {puzzle_complexity}-bit")
print(f"[+] N: {N}-bit")
print(f"[+] Search range: 2^{puzzle_complexity-1} - 2^{puzzle_complexity}")
print(f"[+] Distinguished point rarity: 2^{int(log2(dp_rarity))}")
print(f"[+] Distinguished point rarity: {dp_rarity}")
expected_hops = 2.13 * sqrt(2 ** puzzle_complexity)
print(f"[+] Expected hops: 2^{log2(expected_hops):.2f} ({int(expected_hops)})")

search_start_time_begin = kangaroo_search(
    precomputed_points,
    wild_start_point,
    dp_rarity,
    herd_size,
    max_hop_power,
    upper_bound,
    lower_bound,
    power_steps
)

hours, rem = divmod(time.time() - search_start_time, 3600)
minutes, seconds = divmod(rem, 60)
elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
print(f"[+] Total execution time: {elapsed_str}")
karrask
Newbie
*
Offline Offline

Activity: 38
Merit: 0


View Profile
February 19, 2025, 10:58:46 AM
 #7388

Could you provide us some code to verify these calculations?

need to put at "twset" with name "twset_b11.py"
Code:
import gmpy2

def gen_tame_wild(lower_bound, upper_bound, herd_size, N):

    tame = []
    wild = []
    (lower, lower_idx), (upper, upper_idx) = closest_triangular_numbers(lower_bound)

    print(f'[~] Tame/Wild helds: {herd_size}, lower: {lower_bound}, upper: {upper_bound}, size: {upper_bound - lower_bound}')

    generator = get_next_triangular(upper, upper_idx, N, 1)
    while len(tame) != herd_size:
        (upper, upper_idx) = next(generator)
        if upper > upper_bound:
            print(f'\nFail fill Tame/Wild with N={N}')
            exit()
        tame.append(gmpy2.mpz(upper))
        wild.append(gmpy2.mpz(upper_idx))
        print(f'[~] Tame/Wild herds current: {len(tame)}', end = '\r')

    return (tame, wild)

################################################################################################
def check_consecutive_bits(number, N):
    if N == 0:
        return True
       
    count_zeros = 0
    count_ones = 0
   
    # Пpoxoдим пo кaждoмy битy чиcлa
    while number > 0:
        # Пpoвepяeм тeкyщий бит чиcлa
        if number & 1 == 0:
            count_zeros += 1
            count_ones = 0
        else:
            count_ones += 1
            count_zeros = 0
       
        # Ecли пoдpяд N oдинaкoвыx битoв нaйдeнo, вoзвpaщaeм True
        if count_zeros > N or count_ones > N:
            return False
       
        # Cдвигaeм чиcлo нa 1 впpaвo для пpoвepки cлeдyющeгo битa
        number >>= 1
   
    # Ecли нe нaшли пoдpяд N oдинaкoвыx битoв
    return True

def closest_triangular_numbers(n):
    def triangular_number(i):
        return (i * (i + 1)) // 2

    left, right = 1, int((2 * n) ** 0.5) + 1

    while left <= right:
        mid = (left + right) // 2
        t_mid = triangular_number(mid)
        if t_mid == n:
            upper_i = mid + 1
            upper_t = triangular_number(upper_i)
            return ( (t_mid, mid), (upper_t, upper_i) )
        elif t_mid < n:
            left = mid + 1
        else:
            right = mid - 1

    lower_i = right
    lower_t = triangular_number(lower_i)
    upper_i = right + 1
    upper_t = triangular_number(upper_i)
    return ( (lower_t, lower_i), (upper_t, upper_i) )

def get_next_triangular(value, index, N, operation):
    while True:
        index += operation
        value += index * operation
        if check_consecutive_bits(value, N) and check_consecutive_bits(index, N):
            yield (value, index)


################################################################################################
def test(puzzle_complexity, compressed_pubkey, N):

    import time
    start_time = time.time()


    herd_size   = 2 ** (puzzle_complexity // 5)
    lower_bound = 2 ** (puzzle_complexity - 1)
    upper_bound = (2 ** puzzle_complexity) - 1

    tame_start_values, wild_start_values = gen_tame_wild(lower_bound, upper_bound, herd_size, N)

    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'\n[+] Tame and Wild herds initialized. {elapsed_str}')

    for x in tame_start_values:
        print(bin(x)[2:])
    for x in wild_start_values:
        print(bin(x)[2:])


if __name__ == '__main__':

    N = 4

    puzzle_complexity = 40
    compressed_pubkey = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4"
   
    #puzzle_complexity = 53
    #compressed_pubkey = "020faaf5f3afe58300a335874c80681cf66933e2a7aeb28387c0d28bb048bc6349"
   
    test(puzzle_complexity, compressed_pubkey, N)

main code:
Code:
import gmpy2

from twset.twset_b11 import gen_tame_wild
#from twset.twset_b12 import gen_tame_wild
#from twset.twset_b21 import gen_tame_wild
#from twset.twset_b22 import gen_tame_wild

N = gmpy2.mpz(6)

puzzle_complexity = 40
compressed_pubkey = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4"

#puzzle_complexity = 41
#compressed_pubkey = "03b357e68437da273dcf995a474a524439faad86fc9effc300183f714b0903468b"

#puzzle_complexity = 160
#compressed_pubkey = "02e0a8b039282faf6fe0fd769cfbc4b6b4cf8758ba68220eac420e32b91ddfa673"

#puzzle_complexity = 135
#compressed_pubkey = "02145d2611c823a396ef6712ce0f712f09b9b4f3135e3e0aa3230fb9b6d08d1e16"

#puzzle_complexity = 53
#compressed_pubkey = "020faaf5f3afe58300a335874c80681cf66933e2a7aeb28387c0d28bb048bc6349"

#puzzle_complexity = 20
#compressed_pubkey = "033c4a45cbd643ff97d77f41ea37e843648d50fd894b864b0d52febc62f6454f7c"

##########################################################################################

import time
import os
import sys
import random
from math import log2, sqrt, log

# Oчиcткa экpaнa в зaвиcимocти oт OC
if os.name == 'nt':
    os.system('cls')
else:
    os.system('clear')
current_time = time.ctime()
sys.stdout.write("\033[?25l")  # Cкpыть кypcop
sys.stdout.write(f"\033[01;33m[+] Kangaroo: {current_time}\n")
sys.stdout.flush()

# Пapaмeтpы эллиптичecкoй кpивoй secp256k1
modulus = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
curve_order = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
generator_x = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
generator_y = gmpy2.mpz(0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8)

base_point = (generator_x, generator_y)

def elliptic_curve_add(point1, point2):
    infinity = (0, 0)
    if point1 == infinity:
        return point2
    if point2 == infinity:
        return point1
   
    x1, y1 = point1
    x2, y2 = point2

    if x1 == x2:
        if y1 == y2:
            # Удвoeниe тoчки
            denominator = (y1 << 1) % modulus
            inv_denominator = gmpy2.invert(denominator, modulus)
            slope = (3 * x1 * x1 * inv_denominator) % modulus
        else:
            return infinity
    else:
        x_diff = (x2 - x1) % modulus
        inv_x_diff = gmpy2.invert(x_diff, modulus)
        slope = ((y2 - y1) * inv_x_diff) % modulus

    result_x = (slope * slope - x1 - x2) % modulus
    result_y = (slope * (x1 - result_x) - y1) % modulus
   
    return (result_x, result_y)

def scalar_multiply(scalar, point=base_point):
    result = (0, 0)
    current_point = point
    while scalar:
        if scalar & 1:
            result = elliptic_curve_add(result, current_point)
        current_point = elliptic_curve_add(current_point, current_point)
        scalar >>= 1
    return result

def x_to_y(x_coord, y_parity, prime=modulus):
    x_cubed = gmpy2.powmod(x_coord, 3, prime)
    x_squared = gmpy2.powmod(x_coord, 2, prime)
    y_squared = (x_cubed + 7) % prime
    y_coord = gmpy2.powmod(y_squared, (prime + 1) // 4, prime)
   
    if y_parity == 1:
        y_coord = (-y_coord) % prime
    return y_coord

def generate_power_steps(max_power):
    return [gmpy2.mpz(1 << power) for power in range(max_power)]

def handle_found_solution(private_key):
    hex_representation = "%064x" % abs(private_key)
    decimal_value = int(hex_representation, 16)
    print("\n\033[32m[+] PUZZLE SOLVED \033[0m")
    print(f"\033[32m[+] Private key (dec): {decimal_value} \033[0m")
    with open("KEYFOUNDKEYFOUND.txt", "a") as file:
        file.write(f"\n\nSOLVED {current_time}")
        file.write(f"\nPrivate Key (decimal): {decimal_value}")
        file.write(f"\nPrivate Key (hex): {hex_representation}")
        file.write(f"\n{'-' * 100}\n")
    return True

def kangaroo_search(precomputed_points, wild_start_point, dp_rarity, herd_size,
                   max_hop_power, upper_bound, lower_bound, power_steps):

    solution_found = False

    # Инициaлизaция кeнгypy
    start_time0 = time.time()

    start_time = time.time()
    tame_start_values, wild_start_values = gen_tame_wild(lower_bound, upper_bound, herd_size, N)
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'\n[+] Tame and wild herds initialized. {elapsed_str}')

    start_time = time.time()
    tame_points = [scalar_multiply(value) for value in tame_start_values]
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Tame points initialized. {elapsed_str}')

    start_time = time.time()
    wild_points = [elliptic_curve_add(wild_start_point, scalar_multiply(value)) for value in wild_start_values]
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Wild points initialized. {elapsed_str}')
   
    start_time = time.time()
    tame_steps = [gmpy2.mpz(0) for _ in range(herd_size)]
    wild_steps = tame_steps.copy()
    hours, rem = divmod(time.time() - start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Tame and wild steps initialized. {elapsed_str}')
   
    hours, rem = divmod(time.time() - start_time0, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Tame and wild points initialized. {elapsed_str}')
   
    total_hops = 0
    previous_hops_count = 0
    tame_distinguished_points = {}
    wild_distinguished_points = {}
    last_print_time = time.time()
    search_start_time = time.time()
   
    while True:
        # Oбpaбoткa pyчныx кeнгypy
        for idx in range(herd_size):
            total_hops += 1
            power_index = int(tame_points[idx][0] % max_hop_power)
            step_size = power_steps[power_index]
           
            if tame_points[idx][0] % dp_rarity == 0:
                x_coord = tame_points[idx][0]
                if x_coord in wild_distinguished_points:
                    solution = wild_distinguished_points[x_coord] - tame_start_values[idx]
                    solution_found = handle_found_solution(solution)
                    break
                tame_distinguished_points[x_coord] = tame_start_values[idx]
           
            tame_start_values[idx] += step_size
            tame_points[idx] = elliptic_curve_add(precomputed_points[power_index], tame_points[idx])
        if solution_found: break

        # Oбpaбoткa дикиx кeнгypy
        for idx in range(herd_size):
            total_hops += 1
            power_index = int(wild_points[idx][0] % max_hop_power)
            step_size = power_steps[power_index]
           
            if wild_points[idx][0] % dp_rarity == 0:
                x_coord = wild_points[idx][0]
                if x_coord in tame_distinguished_points:
                    solution = wild_start_values[idx] - tame_distinguished_points[x_coord]
                    solution_found = handle_found_solution(solution)
                    break
                wild_distinguished_points[x_coord] = wild_start_values[idx]
           
            wild_start_values[idx] += step_size
            wild_points[idx] = elliptic_curve_add(precomputed_points[power_index], wild_points[idx])
        if solution_found: break
       
        # Bывoд cтaтиcтики
        current_time = time.time()
        if current_time - last_print_time >= 5:
            elapsed_since_last = current_time - last_print_time
            hops_since_last = total_hops - previous_hops_count
            hops_per_sec = hops_since_last / elapsed_since_last if elapsed_since_last > 0 else 0
           
            total_elapsed = current_time - search_start_time
            hours, rem = divmod(total_elapsed, 3600)
            minutes, seconds = divmod(rem, 60)
            elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
           
            last_print_time = current_time
            previous_hops_count = total_hops
           
            print(f'[+] [Hops: 2^{log2(total_hops):.2f} <-> {hops_per_sec:.0f} h/s] [{elapsed_str}]',
                  end='\r', flush=True)

    print()
    print(f'[+] Total hops: {total_hops}')
    hours, rem = divmod(time.time() - search_start_time, 3600)
    minutes, seconds = divmod(rem, 60)
    elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
    print(f'[+] Search duration: {elapsed_str}')
    return solution_found

lower_bound = 2 ** (puzzle_complexity - 1)
upper_bound = (2 ** puzzle_complexity) - 1
dp_rarity = 1 << ((puzzle_complexity - 1) // 2 - 2) // 2 + 2

max_hop_power = round(log(2 ** puzzle_complexity) + 5)
herd_size = 2 ** (puzzle_complexity // 5)
power_steps = generate_power_steps(max_hop_power)

# Дeкoдиpoвaниe пyбличнoгo ключa
if len(compressed_pubkey) == 66:
    x_coord = gmpy2.mpz(int(compressed_pubkey[2:66], 16))
    y_parity = int(compressed_pubkey[:2]) - 2
    y_coord = x_to_y(x_coord, y_parity)
else:
    print("[ERROR] Invalid public key format")
    sys.exit(1)

wild_start_point = (x_coord, y_coord)

# Пpeдвapитeльный pacчeт тoчeк для пpыжкoв
precomputed_points = [base_point]
for _ in range(max_hop_power - 1):
    precomputed_points.append(elliptic_curve_add(precomputed_points[-1], precomputed_points[-1]))
print(f'[+] Precomputed jump points ready: {max_hop_power}')

# Зaпycк пoиcкa
search_start_time = time.time()
print(f"[+] Puzzle complexity: {puzzle_complexity}-bit")
print(f"[+] N: {N}-bit")
print(f"[+] Search range: 2^{puzzle_complexity-1} - 2^{puzzle_complexity}")
print(f"[+] Distinguished point rarity: 2^{int(log2(dp_rarity))}")
print(f"[+] Distinguished point rarity: {dp_rarity}")
expected_hops = 2.13 * sqrt(2 ** puzzle_complexity)
print(f"[+] Expected hops: 2^{log2(expected_hops):.2f} ({int(expected_hops)})")

search_start_time_begin = kangaroo_search(
    precomputed_points,
    wild_start_point,
    dp_rarity,
    herd_size,
    max_hop_power,
    upper_bound,
    lower_bound,
    power_steps
)

hours, rem = divmod(time.time() - search_start_time, 3600)
minutes, seconds = divmod(rem, 60)
elapsed_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
print(f"[+] Total execution time: {elapsed_str}")
пpeкpacнo! I would like your knowledge....
fecell
Jr. Member
*
Offline Offline

Activity: 145
Merit: 2


View Profile
February 19, 2025, 11:46:21 AM
 #7389

You would need approximately 2^68.50 (417402170410649059328) hops to complete this.

this is a question.

for initial values, for 40 bits, 1024 values ​​(tame and wild, i.e. 2048) are enough. 3 seconds on PYTHON! PK found.

for 135 bits, only 134,217,728 (*2 for all kangaroos).

the question is how does the kangaroo work.

you need to understand that a private key is a set of random bits. the average statistical distribution assumes from 40% to 60% of 'ones' and 'zeros' (the minimum condition) in the private key in bit representation: i.e. two values ​​- tame and wild kangaroo - should give in difference a number in which there should be a statistically normal distribution of bits.

Thus, one can initially select the most reliable values ​​for "tame" and "wild" that will guaranted assume the result of the most possible private key.
kTimesG
Member
**
Offline Offline

Activity: 420
Merit: 75


View Profile
February 19, 2025, 11:47:34 AM
 #7390

for 135-bit tame's and wild's values needs very long time (about 48h) to fill.

48h or 48 millenia?

It was proven several times since 1994 that the lower bound for finding the discrete log in a generic group is sqrt(N) steps, and there is no magical way to go lower than that within classical computation, and there is no way to ever come up with a lower complexity than sqrt(N). Anyone who argues this is an idiot (and I use the word lightly).

Of course, EC is not a generic group, so any algo that lowers the complexity must take into account the curve's properties, otherwise they are simply methods of a generic group, and follow the above conclusion.

Off the grid, training pigeons to broadcast signed messages.
fecell
Jr. Member
*
Offline Offline

Activity: 145
Merit: 2


View Profile
February 19, 2025, 11:52:20 AM
 #7391

48h or 48 millenia?
We know probability theory. We know that a private key is determined by probability conditions. We can, using probability theory, limit the search area for a private key.
1000000000..00000000000001 is possible but not real key.
101011011011..000111011001 more real key by theory.

so, for exampe, if we do 0b100000000 (tame) minus 0b10 (wild) we have a poor result 100% (a lot of 'zero' in PK is abnormal).
so, correct initial 'tame' and 'wild' values for huge PubKey is very important.
kTimesG
Member
**
Offline Offline

Activity: 420
Merit: 75


View Profile
February 19, 2025, 12:09:28 PM
 #7392

48h or 48 millenia?
We know probability theory. We know that a private key is determined by probability conditions. We can, using probability theory, limit the search area for a private key.
1000000000..00000000000001 is possible but not real key.
101011011011..000111011001 more real key by theory.

so, for exampe, if we do 0b100000000 (tame) minus 0b10 (wild) we have a poor result 100% (a lot of 'zero' in PK is abnormal).
so, correct initial 'tame' and 'wild' values for huge PubKey is very important.


Amazing, I can't dispute this.

QQ: if I pick a number in my mind from 1 to 100, it is less likely to pick a number that has an abnormal amount of 0 or 1 (in base 2)?

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

Activity: 602
Merit: 49


View Profile
February 19, 2025, 12:15:44 PM
 #7393

3 seconds on PYTHON! PK found.

You can halve that in 1.5 seconds with Inverse Wild Herd.

But you'll still need a hall full of GPUs for puzzle 135. Grin


bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 207
Merit: 3


View Profile
February 19, 2025, 12:25:59 PM
 #7394

But you'll still need a hall full of GPUs for puzzle 135. Grin

So, the whole point of this story is pointless without that many graphics cards? Are we just wasting our time and nerves here?  Cry
kTimesG
Member
**
Offline Offline

Activity: 420
Merit: 75


View Profile
February 19, 2025, 12:39:02 PM
 #7395

But you'll still need a hall full of GPUs for puzzle 135. Grin

So, the whole point of this story is pointless without that many graphics cards? Are we just wasting our time and nerves here?  Cry

So TSMC responded after 3 months...

Quote
From: ****.*****@*****.****.**
Subject: Re: Inquiry about Special ASIC for secp256k1 Hardware Acceleration

Dear **** ********,

Thank you for reaching out to TSMC regarding your request for a custom ASIC tailored to secp256k1 calculations. We appreciate your interest in creating a specialized chip that includes hardware circuits for modular inversions, batch point additions (using a single inversion), automatic distinct-point detection, and overall hardware acceleration for the Pollard Kangaroo algorithm.

Below is a brief overview of what we can offer and some preliminary information about costs:

Design and Technology Options

TSMC provides a wide range of process nodes, from legacy (180nm/130nm) up to advanced nodes (7nm, 5nm). Choosing the right node depends on desired performance, power consumption, and budget.
We can work directly with your design team or with an external IP partner to integrate the cryptographic hardware blocks required for your application.
Cost Estimates

NRE (Non-Recurring Engineering): This includes design, verification, mask creation, and initial test runs. For a mature node like 28nm, NRE can range from $5–8 million for a moderately complex design, possibly exceeding $15 million if the design is very intricate. For advanced nodes (7nm/5nm), NRE can go beyond $20–30 million.
Per-Wafer Costs: Once the mask set is completed, the cost per wafer varies by node. At 28nm, each wafer might be a few thousand dollars, while at 7nm it could be between $10,000 and $15,000 per wafer. Final unit cost depends heavily on volume and yield.
Production Volume: Higher volumes help amortize NRE more effectively.
Timeline: Typically, after design completion and tape-out, it can take 6–9 months to receive the first wafers for mature nodes, and possibly longer for advanced nodes due to additional verification steps.
Special Requirements for Pollard Kangaroo Acceleration

Adding hardware support for modular inversion, batch point additions, and automatic point distinction detection will require specialized cryptographic IP.
Costs may rise if new IP blocks need to be developed or if advanced security features are required.
TSMC will work with your chosen IP vendor or design partner to ensure the integration and validation of these specialized functions.
Next Steps

To provide a more accurate quote, we would need further details on performance targets (frequency, power constraints), security/certification requirements, estimated production volume, and your target budget/timeline.
Based on your inputs, we can recommend the most suitable process node and give you a detailed pricing breakdown.
Please let us know if you have any questions or would like to arrange a call to discuss technical specifics. We appreciate your interest in TSMC and look forward to working with you on this project.

Best regards,
******* *** *****
Head of Technical Inquiries,
TSMC (Taiwan Semiconductor Manufacturing Company)

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

Activity: 602
Merit: 49


View Profile
February 19, 2025, 01:06:59 PM
 #7396

Cost Estimates
NRE (Non-Recurring Engineering): This includes design, verification, mask creation, and initial test runs. For a mature node like 28nm, NRE can range from $5–8 million for a moderately complex design, possibly exceeding $15 million if the design is very intricate. For advanced nodes (7nm/5nm), NRE can go beyond $20–30 million.
Per-Wafer Costs: Once the mask set is completed, the cost per wafer varies by node. At 28nm, each wafer might be a few thousand dollars, while at 7nm it could be between $10,000 and $15,000 per wafer. Final unit cost depends heavily on volume and yield.

Finally, a concrete proposal for building an ASIC running the Kangaroo algorithm. The challenge, as expected, is the cost.  Unless there’s serious financial backing or a strong business case, it’s a massive investment for a niche application. Grin

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
singlethread1
Newbie
*
Offline Offline

Activity: 5
Merit: 0


View Profile
February 19, 2025, 01:49:00 PM
 #7397

Wondering if anyone can help me with this.

Just curious - how long would it take for the average household desktop computer now in 2025 to get through 50% of the keys for puzzle 67?

I want to know to better explain this puzzle to my family/friends.

Thanks!!

#67 range is  73.79 quintillion
#68 range is 147.57 quintillion
#69 range is 295.15 quintillion

73.79 quintillion = 73790000000000000000

your new houshold Pc can prob do 8 Mkeys/s without high end GPU!

so about 292,277 years or  148,639 years for 50% of the range in #67 to answer your question!

Awesome, thanks!
hoanghuy2912
Newbie
*
Offline Offline

Activity: 19
Merit: 0


View Profile
February 19, 2025, 03:14:09 PM
 #7398


Could you explain more how you were doing this?



It will be pointless. 99.9% of ideas are criticized and easily destroyed.
Therefore, I see no point in showing my results, because they are rather based on chance and the dark side. lol.

But for 67 my approach is still the same. I also keep a log of prefixes so I can understand what ranges I've gone through. It makes absolutely no sense, but I just like to see thats prefixes.

I have some good work on random libraries, but not perfect. For example, for 130 bits, my library guesses from 90 to 95 bits in 15-25 seconds.
But for example for 66 from 50 to 58 bits.
Likewise for 40 from 30 to 39 bits.
https://www.talkimg.com/images/2025/02/18/qPIol.png
https://www.talkimg.com/images/2025/02/18/qPsx1.png
https://www.talkimg.com/images/2025/02/18/qPNuo.png

For any prefix 67bits these are the results.
https://www.talkimg.com/images/2025/02/18/qPyCC.png
67, I have absolutely no idea where he might be. I’m probably doing this for the sake of an idea, since bots will instantly change tx. This is of course very disappointing.
Good luck everyone.

can you show me how to do it?
casperas20
Newbie
*
Offline Offline

Activity: 5
Merit: 0


View Profile
February 19, 2025, 03:43:42 PM
 #7399

there is this Mara method to take the reward before the bots   if u find out the pv
Cryptoman2009
Newbie
*
Offline Offline

Activity: 16
Merit: 1


View Profile
February 19, 2025, 05:35:59 PM
 #7400

no technique, no artifact, no math.
Only the IMPROBABLE luck will give the chance to discover the puzzles 135-140-145-150-155-160.

Unless you invest tens of thousands of $ in GPU and electricity + time.
Pages: « 1 ... 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 [370] 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 »
  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!