many people make similar mistakes when they are in a hurry. To be honest, I only noticed the error myself.
The main thing is that 1000 kW hours of energy were not wasted. Please
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.
anyway, I just solved Puzzle 60 in 16 seconds
- STARTED: Sat Dec 23 11:52:59 2023
- [Puzzle]: 60
- [Lower range limit]: 576460752303423488
- [Upper range limit]: 1152921504606846975
- [Using 12 CPU cores for parallel search]:
- [Core]: 11, [Random seed]: b'a\xc6?\xb5\xd8$\xc9*\xe1'
- [Core]: 12, [Random seed]: b'\x17\xd7%&\xaa&\xbfL\x94'
- [Core]: 02, [Random seed]: b'\xca[s\xfex3\x9d\xe3I'
- [Core]: 04, [Random seed]: b'\xf9\x84Z\x16\xeb\xd4\xef%\x83'
- [Core]: 03, [Random seed]: b'\xab\xba\xaa\x90\xd0\xd5H\xa0\xeb'
- [Core]: 05, [Random seed]: b'\xd6\x1aA{]\xb3s\xc8\x0f'
- [Core]: 06, [Random seed]: b'<\x04t\xacV0LB\xc5'
- [Core]: 08, [Random seed]: b'\xde\x1d\x1f\xef\xab\x8aL\xbb\xc6'
- [Core]: 10, [Random seed]: b'\x03\xadO\x97\xd8\xdf \xf4\x08'
- [Core]: 11, [Random seed]: b'*E\x99\xf3f\xe9\xf6\xb48'
- [Core]: 12, [Random seed]: b'\xa0\xb7\xf4r\xc2*\x1b"\xc4'
- [Core]: 01, [Random seed]: b'ahP+B\xb6rJ\xf6'
- PUZZLE SOLVED: Sat Dec 23 11:53:15 2023, total time: 16.213455915 sec
- WIF: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYkzijLsc5qE43yZ5eLV
- PUZZLE SOLVED! Stopping the loop.
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()
Loop script in bash (seed hunter)
#!/bin/bash
while true; do
timeout 30 python3 puzzle.py
sleep 2
if [ -n "$(find . -maxdepth 1 -type f -name 'KEYFOUNDKEYFOUND.txt' -print -quit)" ]; then
echo "[+] PUZZLE SOLVED! Stopping the loop."
break
fi
done
set the timeout as you wish.