Bitcoin Forum
February 18, 2025, 09:06:13 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 ... 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 [185] 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 ... 369 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 255269 times)
nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 11, 2023, 10:17:14 AM
Last edit: October 14, 2023, 07:40:43 PM by nomachine
 #3681

PUZZLE SOLVED: Wed Oct 11 12:13:21 2023, total time: 13.47 sec
  • WIF:  -0000000000000000000000000000000000000000000000000022bd43c2e9354

nice catching again nomachine, is this programmable for 120th and up

Yes.
It takes about 3 minutes to start solving Puzzle 130 on my 12 Core - but will start.

Here is code for Puzzle130
Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

os.system("clear")

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = "\r[+] [Pindex]: {}".format(Pindex)
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

t = time.ctime()
sys.stdout.write("\033[01;33m")
sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
sys.stdout.flush()

# Configuration for the puzzle
puzzle = 130
compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130 
lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1 
kangaroo_power = puzzle // 8
Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
DP_rarity = 8 * puzzle
hop_modulo = (puzzle // 2) + 8

# Precompute powers of two for faster access
powers_of_two = generate_powers_of_two(hop_modulo)

T, t, dt = [], [], []
W, w, dw = [], [], []

if len(compressed_public_key) == 66:
    X = mpz(compressed_public_key[2:66], 16)
    Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
else:
    print("[error] pubkey len(66/130) invalid!")

print(f"[+] [Puzzle]: {puzzle}")
print(f"[+] [Lower range limit]: {lower_range_limit}")
print(f"[+] [Upper range limit]: {upper_range_limit}")
print("[+] [Xcoordinate]: %064x" % X)
print("[+] [Ycoordinate]: %064x" % Y)

W0 = Point(X, Y)
starttime = oldtime = time.time()

Hops = 0

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    with open("/dev/urandom", "rb") as urandom_file:
        ending_bytes = urandom_file.read(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nw)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()

I put only 2 bytes as a constant - the rest will be randomized through all CPU cores, since we don't know what the seed for 130 is. . .
constant_prefix = b'\xbc\x9b'
constant_prefix = b'' is all random

ON the smaller puzzles it is easy to guess what the seed is. You need to restart and restart app and you will find out which is the fastest seed by repetition. The script will show exactly which seed and which core hit the WIF. You can experiment with different ones as you like.

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
Denis_Hitov
Newbie
*
Offline Offline

Activity: 49
Merit: 0


View Profile
October 11, 2023, 08:37:34 PM
 #3682

PUZZLE SOLVED: Wed Oct 11 12:13:21 2023, total time: 13.47 sec
  • WIF:  -0000000000000000000000000000000000000000000000000022bd43c2e9354

nice catching again nomachine, is this programmable for 120th and up

Yes.
It takes about 3 minutes to start solving Puzzle 130 on my 12 Core - but will start.

Here is code for Puzzle130
Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = f"\r[+] [Pindex]: {mpz(Pindex)}"
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()  
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    with open("/dev/urandom", "rb") as urandom_file:
        ending_bytes = urandom_file.read(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)  
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nt)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    os.system("clear")
    t = time.ctime()
    sys.stdout.write("\033[01;33m")
    sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
    sys.stdout.flush()

    # Configuration for the puzzle
    puzzle = 130
    compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130  
    lower_range_limit = 2 ** (puzzle - 1)
    upper_range_limit = (2 ** puzzle) - 1  
    kangaroo_power = puzzle // 8
    Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
    DP_rarity = 8 * puzzle
    hop_modulo = (puzzle // 2) + 8

    # Precompute powers of two for faster access
    powers_of_two = generate_powers_of_two(hop_modulo)

    T, t, dt = [], [], []
    W, w, dw = [], [], []

    if len(compressed_public_key) == 66:
        X = mpz(compressed_public_key[2:66], 16)
        Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
    else:
        print("[error] pubkey len(66/130) invalid!")

    print(f"[+] [Puzzle]: {puzzle}")
    print(f"[+] [Lower range limit]: {lower_range_limit}")
    print(f"[+] [Upper range limit]: {upper_range_limit}")
    print("[+] [Xcoordinate]: %064x" % X)
    print("[+] [Ycoordinate]: %064x" % Y)

    W0 = Point(X, Y)
    starttime = oldtime = time.time()

    Hops = 0

    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()

I put only 2 bytes as a constant - the rest will be randomized through all CPU cores, since we don't know what the seed for 130 is. . .
constant_prefix = b'\xbc\x9b'
constant_prefix = b'' is all random

ON the smaller puzzles it is easy to guess what the seed is. You need to restart and restart app and you will find out which is the fastest seed by repetition. The script will show exactly which seed and which core hit the WIF. You can experiment with different ones as you like.



FileNotFoundError: [Errno 2] No such file or directory: '/dev/urandom'
digaran
Copper Member
Hero Member
*****
Offline Offline

Activity: 1330
Merit: 900

🖤😏


View Profile
October 12, 2023, 04:18:14 AM
 #3683

import random
import random

Why importing random twice? Lol, your script only generates one seed and the counter only stays at 1, how can I iterate through the range, come on man, look at me chest deep in the swamp, I need some pull.😉

Yo @nomachine, what's that error dev/urandom thingy?

Is it obvious I just opened my laptop and now trying all the scripts in one go, you will see more from me.😅

🖤😏
dextronomous
Full Member
***
Offline Offline

Activity: 438
Merit: 105


View Profile
October 12, 2023, 09:45:49 AM
 #3684

hi,
you = got to use wsl, that is the dev/urandom for.,

nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 12, 2023, 11:00:51 AM
Last edit: October 14, 2023, 07:41:51 PM by nomachine
 #3685

PUZZLE SOLVED: Wed Oct 11 12:13:21 2023, total time: 13.47 sec
  • WIF:  -0000000000000000000000000000000000000000000000000022bd43c2e9354

nice catching again nomachine, is this programmable for 120th and up

Yes.
It takes about 3 minutes to start solving Puzzle 130 on my 12 Core - but will start.

Here is code for Puzzle130
Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = f"\r[+] [Pindex]: {mpz(Pindex)}"
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()  
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    with open("/dev/urandom", "rb") as urandom_file:
        ending_bytes = urandom_file.read(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)  
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nt)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    os.system("clear")
    t = time.ctime()
    sys.stdout.write("\033[01;33m")
    sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
    sys.stdout.flush()

    # Configuration for the puzzle
    puzzle = 130
    compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130  
    lower_range_limit = 2 ** (puzzle - 1)
    upper_range_limit = (2 ** puzzle) - 1  
    kangaroo_power = puzzle // 8
    Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
    DP_rarity = 8 * puzzle
    hop_modulo = (puzzle // 2) + 8

    # Precompute powers of two for faster access
    powers_of_two = generate_powers_of_two(hop_modulo)

    T, t, dt = [], [], []
    W, w, dw = [], [], []

    if len(compressed_public_key) == 66:
        X = mpz(compressed_public_key[2:66], 16)
        Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
    else:
        print("[error] pubkey len(66/130) invalid!")

    print(f"[+] [Puzzle]: {puzzle}")
    print(f"[+] [Lower range limit]: {lower_range_limit}")
    print(f"[+] [Upper range limit]: {upper_range_limit}")
    print("[+] [Xcoordinate]: %064x" % X)
    print("[+] [Ycoordinate]: %064x" % Y)

    W0 = Point(X, Y)
    starttime = oldtime = time.time()

    Hops = 0

    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()

I put only 2 bytes as a constant - the rest will be randomized through all CPU cores, since we don't know what the seed for 130 is. . .
constant_prefix = b'\xbc\x9b'
constant_prefix = b'' is all random

ON the smaller puzzles it is easy to guess what the seed is. You need to restart and restart app and you will find out which is the fastest seed by repetition. The script will show exactly which seed and which core hit the WIF. You can experiment with different ones as you like.



FileNotFoundError: [Errno 2] No such file or directory: '/dev/urandom'


if you dont have '/dev/urandom'  here is script without '/dev/urandom'

Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

os.system("clear")

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = "\r[+] [Pindex]: {}".format(Pindex)
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

t = time.ctime()
sys.stdout.write("\033[01;33m")
sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
sys.stdout.flush()

# Configuration for the puzzle
puzzle = 130
compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130 
lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1 
kangaroo_power = puzzle // 8
Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
DP_rarity = 8 * puzzle
hop_modulo = (puzzle // 2) + 8

# Precompute powers of two for faster access
powers_of_two = generate_powers_of_two(hop_modulo)

T, t, dt = [], [], []
W, w, dw = [], [], []

if len(compressed_public_key) == 66:
    X = mpz(compressed_public_key[2:66], 16)
    Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
else:
    print("[error] pubkey len(66/130) invalid!")

print(f"[+] [Puzzle]: {puzzle}")
print(f"[+] [Lower range limit]: {lower_range_limit}")
print(f"[+] [Upper range limit]: {upper_range_limit}")
print("[+] [Xcoordinate]: %064x" % X)
print("[+] [Ycoordinate]: %064x" % Y)

W0 = Point(X, Y)
starttime = oldtime = time.time()

Hops = 0

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    with open("/dev/urandom", "rb") as urandom_file:
        ending_bytes = urandom_file.read(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nw)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()

p.s.
A good sign is when [Pindex] starts to slow down or stop at some compare points - it means that the kangaroo algorithm is starting to catch something through some seed. Grin

**** Asked via private message****
You can also setup any range you want.

Example

Puzzle 65

Code:
   # Configuration for the puzzle
    puzzle = 65
    compressed_public_key = "0230210c23b1a047bc9bdbb13448e67deddc108946de6de639bcc75d47c0216b1b"  
    lower_range_limit = 30568367312064202855    #2 ** (puzzle - 1)
    upper_range_limit = 30568387312064202855   #(2 ** puzzle) - 1

it will solve small ranges in minutes   Wink


bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
rosengold
Jr. Member
*
Offline Offline

Activity: 149
Merit: 7


View Profile
October 12, 2023, 01:13:54 PM
 #3686

If someone will please solve this puzzle for me then I will give you some of the profits I make.

Please let me know when you have a solution for me.  I am willing to pay up to 10% of all profits to you just for solving the puzzle for me.

Thanks.  Wink


So Someone will find the key "for you" and you will give 10% for that ?

Funny Joke.
bestie1549
Jr. Member
*
Offline Offline

Activity: 75
Merit: 5


View Profile
October 12, 2023, 01:16:37 PM
 #3687

If someone will please solve this puzzle for me then I will give you some of the profits I make.

Please let me know when you have a solution for me.  I am willing to pay up to 10% of all profits to you just for solving the puzzle for me.

Thanks.  Wink
I would gladly love to solve the puzzle for you and I accept the offer of your 10% profit. All you need is to load $200,000 in a vast ai GPU rental website in order for me to be able to proceed and I assure you a maximum result time of 3 days. We will be able to solve either puzzle 130 or 66 and share the profit as you've suggested in the sharing ratio of 90:10.
let me know or you can send me an inbox with the next steps. Thank you,
nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 12, 2023, 01:33:31 PM
 #3688

If someone will please solve this puzzle for me then I will give you some of the profits I make.

Please let me know when you have a solution for me.  I am willing to pay up to 10% of all profits to you just for solving the puzzle for me.

Thanks.  Wink
I would gladly love to solve the puzzle for you and I accept the offer of your 10% profit. All you need is to load $200,000 in a vast ai GPU rental website in order for me to be able to proceed and I assure you a maximum result time of 3 days. We will be able to solve either puzzle 130 or 66 and share the profit as you've suggested in the sharing ratio of 90:10.
let me know or you can send me an inbox with the next steps. Thank you,

This looks like a serious deal.  Smiley

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
abdenn0ur
Newbie
*
Offline Offline

Activity: 12
Merit: 0


View Profile
October 12, 2023, 04:35:47 PM
 #3689

If someone will please solve this puzzle for me then I will give you some of the profits I make.

Please let me know when you have a solution for me.  I am willing to pay up to 10% of all profits to you just for solving the puzzle for me.

Thanks.  Wink


Can you explain ? 
Denis_Hitov
Newbie
*
Offline Offline

Activity: 49
Merit: 0


View Profile
October 12, 2023, 07:02:12 PM
 #3690


if you dont have '/dev/urandom'  here is script without '/dev/urandom'

Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = f"\r[+] [Pindex]: {mpz(Pindex)}"
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b\x8cd'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    ending_bytes = os.urandom(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nt)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    os.system("clear")
    t = time.ctime()
    sys.stdout.write("\033[01;33m")
    sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
    sys.stdout.flush()

    # Configuration for the puzzle
    puzzle = 130
    compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130
    lower_range_limit = 2 ** (puzzle - 1)
    upper_range_limit = (2 ** puzzle) - 1
    kangaroo_power = puzzle // 8
    Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
    DP_rarity = 8 * puzzle
    hop_modulo = (puzzle // 2) + 8

    # Precompute powers of two for faster access
    powers_of_two = generate_powers_of_two(hop_modulo)

    T, t, dt = [], [], []
    W, w, dw = [], [], []

    if len(compressed_public_key) == 66:
        X = mpz(compressed_public_key[2:66], 16)
        Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
    else:
        print("[error] pubkey len(66/130) invalid!")

    print(f"[+] [Puzzle]: {puzzle}")
    print(f"[+] [Lower range limit]: {lower_range_limit}")
    print(f"[+] [Upper range limit]: {upper_range_limit}")
    print("[+] [Xcoordinate]: %064x" % X)
    print("[+] [Ycoordinate]: %064x" % Y)

    W0 = Point(X, Y)
    starttime = oldtime = time.time()

    Hops = 0

    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()



Now this error.

NameError: name 'W0' is not defined
nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 12, 2023, 08:26:24 PM
Last edit: October 14, 2023, 07:42:45 PM by nomachine
 #3691


if you dont have '/dev/urandom'  here is script without '/dev/urandom'

Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = f"\r[+] [Pindex]: {mpz(Pindex)}"
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b\x8cd'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    ending_bytes = os.urandom(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nt)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    os.system("clear")
    t = time.ctime()
    sys.stdout.write("\033[01;33m")
    sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
    sys.stdout.flush()

    # Configuration for the puzzle
    puzzle = 130
    compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130
    lower_range_limit = 2 ** (puzzle - 1)
    upper_range_limit = (2 ** puzzle) - 1
    kangaroo_power = puzzle // 8
    Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
    DP_rarity = 8 * puzzle
    hop_modulo = (puzzle // 2) + 8

    # Precompute powers of two for faster access
    powers_of_two = generate_powers_of_two(hop_modulo)

    T, t, dt = [], [], []
    W, w, dw = [], [], []

    if len(compressed_public_key) == 66:
        X = mpz(compressed_public_key[2:66], 16)
        Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
    else:
        print("[error] pubkey len(66/130) invalid!")

    print(f"[+] [Puzzle]: {puzzle}")
    print(f"[+] [Lower range limit]: {lower_range_limit}")
    print(f"[+] [Upper range limit]: {upper_range_limit}")
    print("[+] [Xcoordinate]: %064x" % X)
    print("[+] [Ycoordinate]: %064x" % Y)

    W0 = Point(X, Y)
    starttime = oldtime = time.time()

    Hops = 0

    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()



Now this error.

NameError: name 'W0' is not defined

I don't have any error on multiple machines. Make sure that is at least python3.9 installed. I changed the order of the code a bit. If there is still an error, something is wrong with python there.
The code use standard python libraries such as sys, os, time, random, hashlib, and multiprocessing, they are usually included with python..

Code:
pip3 install gmpy2

This will install the gmpy2 library

Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

os.system("clear")

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = "\r[+] [Pindex]: {}".format(Pindex)
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

t = time.ctime()
sys.stdout.write("\033[01;33m")
sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
sys.stdout.flush()

# Configuration for the puzzle
puzzle = 130
compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130 
lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1 
kangaroo_power = puzzle // 8
Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
DP_rarity = 8 * puzzle
hop_modulo = (puzzle // 2) + 8

# Precompute powers of two for faster access
powers_of_two = generate_powers_of_two(hop_modulo)

T, t, dt = [], [], []
W, w, dw = [], [], []

if len(compressed_public_key) == 66:
    X = mpz(compressed_public_key[2:66], 16)
    Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
else:
    print("[error] pubkey len(66/130) invalid!")

print(f"[+] [Puzzle]: {puzzle}")
print(f"[+] [Lower range limit]: {lower_range_limit}")
print(f"[+] [Upper range limit]: {upper_range_limit}")
print("[+] [Xcoordinate]: %064x" % X)
print("[+] [Ycoordinate]: %064x" % Y)

W0 = Point(X, Y)
starttime = oldtime = time.time()

Hops = 0

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    with open("/dev/urandom", "rb") as urandom_file:
        ending_bytes = urandom_file.read(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nw)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
Denis_Hitov
Newbie
*
Offline Offline

Activity: 49
Merit: 0


View Profile
October 12, 2023, 08:39:54 PM
 #3692


I don't have any error on multiple machines. Make sure that is at least python3.9 installed. I changed the order of the code a bit. If there is still an error, something is wrong with python there.

Code:
import sys
import os
import time
import random
import hashlib
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
import multiprocessing
from multiprocessing import Pool, cpu_count

os.system("clear")

# Constants
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Define Point class
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)

# Function to multiply a point by 2
def multiply_by_2(P, p=MODULO):
    c = gmpy2.f_mod(3 * P.x * P.x * gmpy2.powmod(2 * P.y, -1, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - 2 * P.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to add two points
def add_points(P, Q, p=MODULO):
    dx = Q.x - P.x
    dy = Q.y - P.y
    c = gmpy2.f_mod(dy * gmpy2.invert(dx, p), p)
    R = Point()
    R.x = gmpy2.f_mod(c * c - P.x - Q.x, p)
    R.y = gmpy2.f_mod(c * (P.x - R.x) - P.y, p)
    return R

# Function to calculate Y-coordinate from X-coordinate
@lru_cache(maxsize=None)
def x_to_y(X, y_parity, p=MODULO):
    Y = gmpy2.mpz(3)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    X = gmpy2.f_mod(tmp + 7, p)

    Y = gmpy2.f_div(gmpy2.add(p, 1), 4)
    tmp = gmpy2.mpz(1)

    while Y > 0:
        if Y % 2 == 1:
            tmp = gmpy2.f_mod(tmp * X, p)
        Y >>= 1
        X = gmpy2.f_mod(X * X, p)

    Y = tmp

    if Y % 2 != y_parity:
        Y = gmpy2.f_mod(-Y, p)

    return Y

# Function to compute a table of points
def compute_point_table():
    points = [PG]
    for k in range(255):
        points.append(multiply_by_2(points[k]))
    return points

POINTS_TABLE = compute_point_table()

# Global event to signal all processes to stop
STOP_EVENT = multiprocessing.Event()

# Function to check and compare points for potential solutions
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    check = gmpy2.f_mod(P.x, DP_rarity)
    if check == 0:
        message = f"\r[+] [Pindex]: {mpz(Pindex)}"
        messages = []
        messages.append(message)
        output = "\033[01;33m" + ''.join(messages) + "\r"
        sys.stdout.write(output)
        sys.stdout.flush()
        A.append(mpz(P.x))
        Ak.append(mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Function to compare two sets of points and find a common point
def comparator(A, Ak, B, Bk):
    global STOP_EVENT
    result = set(A).intersection(set(B))

    if result:
        sol_kt = A.index(next(iter(result)))
        sol_kw = B.index(next(iter(result)))
        difference = Ak[sol_kt] - Bk[sol_kw]
        HEX = "%064x" % difference
        t = time.ctime()
        pid = os.getpid()  # Get the process ID
        core_number = pid % cpu_count()  # Calculate the CPU core number
        total_time = time.time() - starttime
        print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.2f} sec, Core: {core_number+1:02} \033[0m")
        print(f"\033[32m[+] WIF: \033[32m {HEX} \033[0m")
        with open("KEYFOUNDKEYFOUND.txt", "a") as file:
            file.write("\n\nSOLVED " + t)
            file.write(f"\nTotal Time: {total_time:.2f} sec")
            file.write("\nPrivate Key (decimal): " + str(difference))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------\n"
            )

        STOP_EVENT.set()  # Set the stop event to signal all processes

# Memoization for point multiplication
ECMULTIPLY_MEMO = {}

# Function to multiply a point by a scalar
def ecmultiply(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        if k in ECMULTIPLY_MEMO:
            return ECMULTIPLY_MEMO[k]
        else:
            result = ecmultiply(k // 2, multiply_by_2(P, p), p)
            ECMULTIPLY_MEMO[k] = result
            return result
    else:
        return add_points(P, ecmultiply((k - 1) // 2, multiply_by_2(P, p), p))

# Recursive function to multiply a point by a scalar
def mulk(k, P=PG, p=MODULO):
    if k == 0:
        return ZERO_POINT
    elif k == 1:
        return P
    elif k % 2 == 0:
        return mulk(k // 2, multiply_by_2(P, p), p)
    else:
        return add_points(P, mulk((k - 1) // 2, multiply_by_2(P, p), p))

# Generate a list of powers of two for faster access
@lru_cache(maxsize=None)
def generate_powers_of_two(hop_modulo):
    return [mpz(1 << pw) for pw in range(hop_modulo)]

t = time.ctime()
sys.stdout.write("\033[01;33m")
sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n")
sys.stdout.flush()

# Configuration for the puzzle
puzzle = 130
compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130
lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1
kangaroo_power = puzzle // 8
Nt = Nw = (2 ** kangaroo_power // puzzle) * puzzle + 8
DP_rarity = 8 * puzzle
hop_modulo = (puzzle // 2) + 8

# Precompute powers of two for faster access
powers_of_two = generate_powers_of_two(hop_modulo)

T, t, dt = [], [], []
W, w, dw = [], [], []

if len(compressed_public_key) == 66:
    X = mpz(compressed_public_key[2:66], 16)
    Y = x_to_y(X, mpz(compressed_public_key[:2]) - 2)
else:
    print("[error] pubkey len(66/130) invalid!")

print(f"[+] [Puzzle]: {puzzle}")
print(f"[+] [Lower range limit]: {lower_range_limit}")
print(f"[+] [Upper range limit]: {upper_range_limit}")
print("[+] [Xcoordinate]: %064x" % X)
print("[+] [Ycoordinate]: %064x" % Y)

W0 = Point(X, Y)
starttime = oldtime = time.time()

Hops = 0

# Worker function for point search
def search_worker(
    Nt, Nw, puzzle, kangaroo_power, starttime, lower_range_limit, upper_range_limit
):
    global STOP_EVENT
    pid = os.getpid()
    core_number = pid % cpu_count()
    #Random seed Config
    #constant_prefix = b''  #back to no constant
    #constant_prefix = b'\xbc\x9b\x8cd\xfc\xa1?\xcf' #Puzzle 50 seed - 10-18s
    constant_prefix = b'\xbc\x9b\x8cd'
    prefix_length = len(constant_prefix)
    length = 8
    ending_length = length - prefix_length
    ending_bytes = os.urandom(ending_length)
    random_bytes = constant_prefix + ending_bytes
    print(f"[+] [Core]: {core_number+1:02}, [Random seed]: {random_bytes}")
    random.seed(random_bytes)
    t = [
        mpz(
            lower_range_limit
            + mpz(random.randint(0, upper_range_limit - lower_range_limit))
        )
        for _ in range(Nt)
    ]
    T = [mulk(ti) for ti in t]
    dt = [mpz(0) for _ in range(Nt)]
    w = [
        mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nt)
    ]
    W = [add_points(W0, mulk(wk)) for wk in w]
    dw = [mpz(0) for _ in range(Nw)]

    Hops, Hops_old = 0, 0

    oldtime = time.time()
    starttime = oldtime

    while True:
        for k in range(Nt):
            Hops += 1
            pw = T[k].x % hop_modulo
            dt[k] = powers_of_two[pw]
            solved = check(T[k], t[k], DP_rarity, T, t, W, w)
            if solved:
                STOP_EVENT.set()
                break
            t[k] = mpz(t[k]) + dt[k]  # Use mpz here
            T[k] = add_points(POINTS_TABLE[pw], T[k])

        for k in range(Nw):
            Hops += 1
            pw = W[k].x % hop_modulo
            dw[k] = powers_of_two[pw]
            solved = check(W[k], w[k], DP_rarity, W, w, T, t)
            if solved:
                STOP_EVENT.set()
                break
            w[k] = mpz(w[k]) + dw[k]  # Use mpz here
            W[k] = add_points(POINTS_TABLE[pw], W[k])

        if STOP_EVENT.is_set():
            break

# Main script
if __name__ == "__main__":
    process_count = cpu_count()
    print(f"[+] [Using  {process_count} CPU cores for parallel search]:")

    # Create a pool of worker processes
    pool = Pool(process_count)
    results = pool.starmap(
        search_worker,
        [
            (
                Nt,
                Nw,
                puzzle,
                kangaroo_power,
                starttime,
                lower_range_limit,
                upper_range_limit,
            )
        ]
        * process_count,
    )
    pool.close()
    pool.join()



Now it works.
Thank you.
nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 12, 2023, 10:01:26 PM
Last edit: October 12, 2023, 10:52:29 PM by nomachine
Merited by digaran (1)
 #3693



Yo @nomachine, what's that error dev/urandom thingy?



Computers are deterministic, predictable machines and are designed to blindly follow sets of instructions in a repeatable manner. This nature of computers has, of course, served us extremely well for most of the last century, but this design has a fundamental flaw: it cannot perform true random operations. True randomness is in quantum mechanics with time/space/gravity - I will stop here in order not to stray too far from the topic....

Most popular programming languages have some form of random number generator built in that programmers can use. These generators usually take as input the current date and time, encode this value using an algorithm and output a value so different from the input that we perceive them as random. A pseudorandom number generator, also known as a deterministic random bit generator, is an algorithm used to generate a sequence of numbers with properties that approximate those of truly random numbers.

On all Unix-like systems, including all Linux distributions, there is a pseudo device file
"/dev/urandom"

If it doesn't exist, it might indicate a problem with system's configuration or user permissions. Or is not Linux.

"Looks random to me" - is a pretty poor judgment for me in determining if something is random. Grin

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
albert0bsd
Hero Member
*****
Offline Offline

Activity: 1119
Merit: 718



View Profile
October 13, 2023, 03:04:42 AM
 #3694

Yo @nomachine, what's that error dev/urandom thingy?

There is no problem with urandom it is enough random for all cryptographic purposes.

Please all read the next article: https://www.2uo.de/myths-about-urandom/

@nomachine one of the Hardware device that it is include most modern Intel processors, that is used to feed the entropy of the CSRNG of the linux kernel and windows core, use Thermodinamic properties to generate True random data:

From: https://www.intel.com/content/www/us/en/developer/articles/guide/intel-digital-random-number-generator-drng-software-implementation-guide.html
Quote
The ES runs asynchronously on a self-timed circuit and uses thermal noise within the silicon to output a random stream of bits at the rate of 3 GHz. The ES needs no dedicated external power supply to run, instead using the same power supply as other core logic. The ES is designed to function properly over a wide range of operating conditions, exceeding the normal operating range of the processor.

So that means that most of the modern PC are cable to generate True Random data.
nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 13, 2023, 04:51:59 AM
Last edit: October 13, 2023, 09:04:46 AM by nomachine
Merited by citb0in (1)
 #3695

So that means that most of the modern PC are cable to generate True Random data.

I have been working on artificial intelligence research for years. If randomness is good enough to simulate reality and intelligence is part of reality(assuming that we ourselves are not living in a simulation),  
it should be good enough to simulate emotions and physical abilities - true intelligence.
if you have a True randomness in your PC you will have possibility to have consciousness in your computer.
To cut a long story short.
If that is true (in absolute terms) ,  Singularity is close  Grin

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
Ovixx
Newbie
*
Offline Offline

Activity: 30
Merit: 0


View Profile
October 13, 2023, 07:19:58 AM
Last edit: October 13, 2023, 09:19:45 AM by Ovixx
 #3696



Yo @nomachine, what's that error dev/urandom thingy?



................
If it doesn't exist, it might indicate a problem with system's configuration or user permissions. Or is not Linux.

"Looks random to me" - is a pretty poor judgment for me in determining if something is random. Grin


https://www.talkimg.com/images/2023/10/13/RExYZ.gif
nomachine
Member
**
Offline Offline

Activity: 511
Merit: 38


View Profile
October 13, 2023, 07:44:36 AM
Last edit: October 13, 2023, 08:05:02 AM by nomachine
 #3697



Yo @nomachine, what's that error dev/urandom thingy?



................
If it doesn't exist, it might indicate a problem with system's configuration or user permissions. Or is not Linux.

"Looks random to me" - is a pretty poor judgment for me in determining if something is random. Grin


You can also setup smaller range in the frame in this mammoth
Code:
# Configuration for the puzzle
puzzle = 130
compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130  
lower_range_limit =   680564733841876926926749214863536422911    #2 ** (puzzle - 1)
upper_range_limit =  738823525229305890094942779208630272000    #(2 ** puzzle) - 1

or even smaller

Code:
# Configuration for the puzzle
puzzle = 130
compressed_public_key = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852"  # Puzzle 130  
lower_range_limit =   680564733841876926926749214863536422911    #2 ** (puzzle - 1)
upper_range_limit =   680564733841876926926749314863536422911    #(2 ** puzzle) - 1

and so on...

bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
digaran
Copper Member
Hero Member
*****
Offline Offline

Activity: 1330
Merit: 900

🖤😏


View Profile
October 13, 2023, 10:29:19 AM
 #3698

@Zahid888 and @nomachine and all other seed lovers, I have something for you.  https://www.bleepingcomputer.com/news/security/bounty-offered-for-secret-nsa-seeds-behind-nist-elliptic-curves-algo/
You guys are really talented and I'm sure you can come up with a script to brute force those seeds, don't forget to share the script.😉

🖤😏
frozenen
Newbie
*
Offline Offline

Activity: 28
Merit: 0


View Profile
October 13, 2023, 10:37:39 AM
 #3699

@nomachine
Your #130 lotto script works very easily, gonna leave it running on one of my pcs 24/7!
I reckon:
  • [Lower range limit]: 1063382396627932698323045648224275660800
  • [Upper range limit]: 1334544907768055536395422288521465954303
virus-cyber
Newbie
*
Offline Offline

Activity: 26
Merit: 0


View Profile
October 13, 2023, 11:30:06 AM
 #3700

hi, can anyone install the KeyHunt-Cuda strid?
Pages: « 1 ... 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 [185] 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 ... 369 »
  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!