in this example (python kangaroo parallel) :
with 4 cpu after changing little the code I have 73 second on laptop with Intel i5 for 2**50
you have "mismash" in code, you need clean code and rewrite
I updated the code to read and write "tame.txt & "wild.txt" files faster with buffering.
Entered the coordinates X, Y to show at start...etc...
I still don't have a time under 100 seconds for 2**50.
Can you show me where the "mismash" in code is?
Thanks in advance!
import time
import os
import sys
import io
import random
import math
import gmpy2
from gmpy2 import mpz
from functools import lru_cache
from multiprocessing import Pool, cpu_count
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 = x
self.y = y
PG = Point(Gx, Gy)
Z = Point(0, 0) # zero-point, infinite in real x,y-plane
def mul2(P, p=modulo):
c = (3 * P.x * P.x * pow(2 * P.y, -1, p)) % p
R = Point()
R.x = (c * c - 2 * P.x) % p
R.y = (c * (P.x - R.x) - P.y) % p
return R
def add(P, Q, p=modulo):
dx = Q.x - P.x
dy = Q.y - P.y
c = dy * gmpy2.invert(dx, p) % p
R = Point()
R.x = (c * c - P.x - Q.x) % p
R.y = (c * (P.x - R.x) - P.y) % p
return R
@lru_cache(maxsize=None)
def X2Y(X, y_parity, p=modulo):
Y = 3
tmp = 1
while Y:
if Y & 1:
tmp = tmp * X % p
Y >>= 1
X = X * X % p
X = (tmp + 7) % p
Y = (p + 1) // 4
tmp = 1
while Y:
if Y & 1:
tmp = tmp * X % p
Y >>= 1
X = X * X % p
Y = tmp
if Y % 2 != y_parity:
Y = -Y % p
return Y
def compute_P_table():
P = [PG]
for k in range(255):
P.append(mul2(P[k]))
return P
P = compute_P_table()
os.system("clear")
t = time.ctime()
sys.stdout.write("\033[01;33m")
sys.stdout.write("################################################" + "\n")
sys.stdout.write("Pollard-kangaroo PrivKey Recovery Tool multicore" + "\n")
sys.stdout.write("################################################" + "\n")
sys.stdout.write(t + "\n")
sys.stdout.write("P-table prepared" + "\n")
sys.stdout.write("tame and wild herds kangaroos is being prepared" + "\n")
sys.stdout.flush()
def comparator(A, Ak, B, Bk):
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 # Convert to a hexadecimal string
t = time.ctime()
total_time = time.time() - starttime
print("\033[01;33mSOLVED:", t, f"total time: {total_time:.2f} sec", HEX, "\n")
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"
)
return True
else:
return False
# Batch writing function
def batch_write_data_to_file(data, file_path, batch_size=5000):
with open(file_path, "a", buffering=1024 * 1024 * 1024) as fp:
for i in range(0, len(data), batch_size):
batch = data[i : i + batch_size]
fp.writelines(batch)
# Function to check and write data to file
def check(
P, Pindex, DP_rarity, file2save, A, Ak, B, Bk, buffer_size=1024 * 1024 * 1024
):
if P.x % DP_rarity == 0:
A.append(P.x)
Ak.append(Pindex)
data_to_write = ["%064x %d\n" % (P.x, Pindex)]
batch_write_data_to_file(data_to_write, file2save) # Batch write data to file
# Print the public key
message = "\rPublic key: {:064x}".format(P.x)
sys.stdout.write("\033[01;33m")
sys.stdout.write(message + "\r")
sys.stdout.flush()
return comparator(A, Ak, B, Bk)
else:
return False
def save2file(path, mode, data, buffer_size=1024 * 1024 * 1024):
with open(path, mode, encoding="utf-8") as fp:
if isinstance(data, (list, tuple, dict, set)):
for line in data:
if isinstance(line, str):
fp.write(line)
elif isinstance(line, int):
fp.write(str(line))
elif isinstance(data, (str, int)):
fp.write(str(data))
# Memoization for ecmultiply
ecmultiply_memo = {}
def ecmultiply(k, P=PG, p=modulo):
if k == 0:
return Z
elif k == 1:
return P
elif k % 2 == 0:
if k in ecmultiply_memo:
return ecmultiply_memo[k]
else:
result = ecmultiply(k // 2, mul2(P, p), p)
ecmultiply_memo[k] = result
return result
else:
return add(P, ecmultiply((k - 1) // 2, mul2(P, p), p))
def mulk(k, P=PG, p=modulo):
if k == 0:
return Z
elif k == 1:
return P
elif k % 2 == 0:
return mulk(k // 2, mul2(P, p), p)
else:
return add(P, mulk((k - 1) // 2, mul2(P, p), p))
def search(Nt, Nw, puzzle, kangoo_power, starttime):
DP_rarity = 1 << ((puzzle - 2 * kangoo_power) // 2 - 2)
hop_modulo = ((puzzle - 1) // 2) + kangoo_power
T, t, dt = [], [], []
W, w, dw = [], [], []
for k in range(Nt):
t.append((3 << (puzzle - 2)) + random.randint(1, (2 ** (puzzle - 1))))
T.append(mulk(t[k]))
dt.append(0)
for k in range(Nw):
w.append(random.randint(1, (1 << (puzzle - 1))))
W.append(add(W0, mulk(w[k])))
dw.append(0)
oldtime = time.time()
Hops, Hops_old = 0, 0
t0 = time.time()
oldtime = time.time()
starttime = oldtime
while True:
for k in range(Nt):
Hops += 1
pw = T[k].x % hop_modulo
dt[k] = 1 << pw
solved = check(T[k], t[k], DP_rarity, "tame.txt", T, t, W, w)
if solved:
return "sol. time: %.2f sec" % (time.time() - starttime)
t[k] += dt[k]
T[k] = add(P[pw], T[k])
for k in range(Nw):
Hops += 1
pw = W[k].x % hop_modulo
dw[k] = 1 << pw
solved = check(W[k], w[k], DP_rarity, "wild.txt", W, w, T, t)
if solved:
return "sol. time: %.2f sec" % (time.time() - starttime)
w[k] += dw[k]
W[k] = add(P[pw], W[k])
puzzle = 50
compressed_public_key = (
"03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6" # Puzzle 50
)
kangoo_power = 11 # For Puzzle 50-56 use 9 to 11, for Puzzle 60-80 use 14 to 16 / 24 cores or above preferred
Nt = Nw = 2**kangoo_power
# check format pubkey
if len(compressed_public_key) == 66:
X = int(compressed_public_key[2:66], 16)
# calculation Y from X if pubkey is compressed
Y = X2Y(X, gmpy2.mpz(compressed_public_key[:2]) - 2)
else:
print("[error] pubkey len(66/130) invalid!")
print(f"[Puzzle]: {puzzle}")
print("[Xcoordinate]: %064x" % X)
print("[Ycoordinate]: %064x" % Y)
W0 = Point(X, Y)
starttime = oldtime = time.time()
Hops = 0
random.seed()
hops_list = []
N_tests = kangoo_power
for k in range(N_tests):
# Create empty 'tame.txt' and 'wild.txt' files for each iteration
save2file("tame.txt", "w", "")
save2file("wild.txt", "w", "")
def parallel_search(process_count, Nt, Nw, puzzle, kangoo_power, starttime):
pool = Pool(process_count)
results = pool.starmap(
search, [(Nt, Nw, puzzle, kangoo_power, starttime)] * process_count
)
pool.close()
pool.join()
return results
if __name__ == "__main__":
process_count = cpu_count() # Use all available CPU cores
print(f"Using {process_count} CPU cores for parallel search.")
results = parallel_search(process_count, Nt, Nw, puzzle, kangoo_power, starttime)
for result in results:
print(result)