Thank you very much - I changed it in the original post. This is proof that I'm not an AI...I admit when I'm wrong.
import sys, os, time, hashlib, gmpy2, random, multiprocessing
from multiprocessing import Pool, cpu_count
from gmpy2 import mpz
import secp256k1 as ice
if os.name=='nt':os.system('cls')
else:os.system('clear')
t = time.ctime()
sys.stdout.write(f"\033[?25l")
sys.stdout.write(f"\033[01;33m[+] STARTED: {t}\n")
sys.stdout.flush()
MODULO = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
ORDER = gmpy2.mpz(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
GX = gmpy2.mpz(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
GY = gmpy2.mpz(0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
class Point:
def __init__(self, x=0, y=0):
self.x = gmpy2.mpz(x)
self.y = gmpy2.mpz(y)
PG = Point(GX, GY)
ZERO_POINT = Point(0, 0)
def multiply_by_2(P, p=MODULO):
x_squared = P.x**2 % p
c = (3 * x_squared * gmpy2.invert((P.y + P.y) % p, p)) % p
R = Point()
R.x = (c**2 - 2 * P.x) % p
R.y = (c * (P.x - R.x) - P.y) % p
return R
def add_points(P, Q, p=MODULO):
dx = Q.x - P.x
dx_inv = gmpy2.invert(dx, p)
dy_dx_inv = (Q.y - P.y) * dx_inv
R = Point()
R.x = (dy_dx_inv**2 - P.x - Q.x) % p
R.y = (dy_dx_inv * (P.x - R.x) - P.y) % p
return R
def mod_pow(base, exponent, modulus):
result = 1
base = base % modulus
while exponent > 0:
if exponent % 2 == 1:
result = (result * base) % modulus
exponent = exponent // 2
base = (base * base) % modulus
return result
def x_to_y(X, y_parity, p=MODULO):
X_cubed = (X**3) % p
X = (X_cubed + 7) % p
Y = (p + 1) // 4
tmp = mod_pow(X, Y, p)
if gmpy2.is_odd(tmp) != y_parity:
tmp = -tmp % p
return tmp
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()
STOP_EVENT = multiprocessing.Event()
def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
check = gmpy2.f_mod(P.x, DP_rarity)
if check == 0:
A.append(mpz(P.x))
Ak.append(mpz(Pindex))
message = "\r[+] [Pindex]: {}".format(Pindex)
messages = []
messages.append(message)
output = ''.join(messages) + "\r"
sys.stdout.write(output)
sys.stdout.flush()
return comparator(A, Ak, B, Bk)
else:
return False
def comparator(A, Ak, B, Bk):
global STOP_EVENT
result = set(A).intersection(set(B))
if result:
t = time.ctime()
total_time = time.time() - starttime
sol_kt = A.index(next(iter(result)))
sol_kw = B.index(next(iter(result)))
HEX = "%064x" % abs(Ak[sol_kt] - Bk[sol_kw])
dec = int(HEX, 16)
wifc = ice.btc_pvk_to_wif(HEX)
wifu = ice.btc_pvk_to_wif(HEX, False)
caddr = ice.privatekey_to_address(0, True, dec)
uaddr = ice.privatekey_to_address(0, False, dec)
pid = os.getpid() # Get the process ID
core_number = pid % cpu_count() # Calculate the CPU core number
sys.stdout.write("\033[?25h")
sys.stdout.flush()
print(f"\033[32m[+] PUZZLE SOLVED: {t}, total time: {total_time:.9f} sec, Core: {core_number+1:02} \033[0m")
print(f"\033[32m[+] WIF: \033[32m {wifc} \033[0m")
with open("KEYFOUNDKEYFOUND.txt", "a") as file:
file.write("\n\nSOLVED " + t)
file.write(f"\nTotal Time: {total_time:.9f} sec")
file.write("\nPrivate Key (decimal): " + str(dec))
file.write("\nPrivate Key (hex): " + HEX)
file.write("\nPrivate key (wif) Compressed : " + wifc)
file.write("\nPrivate key (wif) Uncompressed: " + wifu)
file.write("\nBitcoin address Compressed: " + caddr)
file.write("\nBitcoin address Uncompressed: " + uaddr)
file.write(
"\n-------------------------------------------------------------------------------------------------------------------------------------------\n"
)
STOP_EVENT.set() # Set the stop event to signal all processes
ECMULTIPLY_MEMO = {}
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))
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))
def generate_powers_of_two(hop_modulo):
return [mpz(1 << pw) for pw in range(hop_modulo)]
# Configuration for the Puzzle
puzzle = 60
compressed_public_key = "0348e843dc5b1bd246e6309b4924b81543d02b16c8083df973a89ce2c7eb89a10d"
lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1
power = (puzzle // cpu_count()) + 1
Nt = Nw = (2 ** power // puzzle) * puzzle + cpu_count()
DP_rarity = (puzzle * puzzle)
hop_modulo = (puzzle // 2) + cpu_count()
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}")
W0 = Point(X, Y)
starttime = oldtime = time.time()
Hops = 0
def search_worker(
Nt, Nw, puzzle, 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'' # b'' is back to no constant
prefix_length = len(constant_prefix)
length = 9
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(random.randint(lower_range_limit, upper_range_limit)) for _ in range(Nt)]
T = [mulk(ti) for ti in t]
dt = [mpz(0) for _ in range(Nt)]
w = [mpz(random.randint(lower_range_limit, upper_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
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,
power,
starttime,
lower_range_limit,
upper_range_limit,
)
]
* process_count,
)
pool.close()
pool.join()
set the timeout as you wish.