nomachine
Member
Offline
Activity: 406
Merit: 23
|
|
October 09, 2023, 08:21:37 PM Last edit: October 09, 2023, 09:20:28 PM by nomachine |
|
Yes. Only he edited the high bits. Or maybe bytes Puzzle 65 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xa88\xb15\x05\xb2hg' Puzzle 64 b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x05\x1f'\xb0\x91\x12\xd4" Puzzle 63 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xce^\xfd\xac\xcfh\x08' and so on....
|
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 899
🖤😏
|
|
October 09, 2023, 08:25:00 PM |
|
It doesn't matter what our target is, even or odd you just need to correctly guess the last 2 hex characters and then you can use the script I posted above to divide your key by 1024, but first you'd need to subtract n/4 from the result on 1024 - index. Try it yourself and you will see, even if we guess the last 2 chars incorrectly, there is a way to again calculate p/1024 no matter what. God willing I should be able to figure that out, it's complicated I know but once it's solved you realize how easy it was.
Spent a lot of time, but I haven't gotten the correct result. How come?, here put this on scalar_1 = 0x00000000000000000000000000000000003aab07a231499b94e9412cb6d34334 Scalar_2 = 0x0000000000000000000000000000000000000000000000000000000000000034 Start range = 1024, end range = 1025, the result is : 3fffffffffffffffffffffffffffffffaeabc5e46dbab46156d9d1f37f3b4521 Then subtract n/4 from above = 3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d9050 Result = 0000000000000000000000000000000000000eaac1e88c5266e53a504b2db4d1 Multiplied by 1024 = 00000000000000000000000000000000003aab07a231499b94e9412cb6d34400
You are not supposed to get the exact result, but if you add and subtract to your target public key like adding 1k G, sub 1k G, and have those 2k keys saved, when you multiply by 1024 you should see a match.
|
🖤😏
|
|
|
Denis_Hitov
Newbie
Offline
Activity: 49
Merit: 0
|
|
October 09, 2023, 09:26:37 PM |
|
It doesn't matter what our target is, even or odd you just need to correctly guess the last 2 hex characters and then you can use the script I posted above to divide your key by 1024, but first you'd need to subtract n/4 from the result on 1024 - index. Try it yourself and you will see, even if we guess the last 2 chars incorrectly, there is a way to again calculate p/1024 no matter what. God willing I should be able to figure that out, it's complicated I know but once it's solved you realize how easy it was.
Spent a lot of time, but I haven't gotten the correct result. How come?, here put this on scalar_1 = 0x00000000000000000000000000000000003aab07a231499b94e9412cb6d34334 Scalar_2 = 0x0000000000000000000000000000000000000000000000000000000000000034 Start range = 1024, end range = 1025, the result is : 3fffffffffffffffffffffffffffffffaeabc5e46dbab46156d9d1f37f3b4521 Then subtract n/4 from above = 3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d9050 Result = 0000000000000000000000000000000000000eaac1e88c5266e53a504b2db4d1 Multiplied by 1024 = 00000000000000000000000000000000003aab07a231499b94e9412cb6d34400
You are not supposed to get the exact result, but if you add and subtract to your target public key like adding 1k G, sub 1k G, and have those 2k keys saved, when you multiply by 1024 you should see a match. Bro, you've completely confused everyone here. Which script should I insert this data into???
|
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 899
🖤😏
|
|
October 09, 2023, 11:00:18 PM |
|
Bro, you've completely confused everyone here. Which script should I insert this data into???
I only provide the concept and the logics, you can't directly and easily solve a key with my scripts, first you need to work with scalar to learn how each key reacts to different numbers when divided. Now I see why you are confused, sorry for that, here use this one I posted here https://bitcointalk.org/index.php?topic=5469636.msg62964103#msg62964103Just replace scalar_1 and scalar_2, start range, end range with above values. Also set this line for i in range(start_range + (start_range%2), end_range, 1): make sure it's 1 instead of 2, I bolded 1 to make it easier to notice. When you learned how it works, Let me know and I will point you to a script using public keys instead of scalar.😉
|
🖤😏
|
|
|
ing1996
Newbie
Offline
Activity: 8
Merit: 0
|
|
October 11, 2023, 04:45:01 AM |
|
hello everyone. There is one question, I'm sorry that it's a little off topic. There is half of the qr code of the private key, (half of the top of the qr code), the question is, is it possible to recover the remaining half? (Half of the lower part).
|
|
|
|
nomachine
Member
Offline
Activity: 406
Merit: 23
|
|
October 11, 2023, 05:40:42 AM |
|
hello everyone. There is one question, I'm sorry that it's a little off topic. There is half of the qr code of the private key, (half of the top of the qr code), the question is, is it possible to recover the remaining half? (Half of the lower part).
oftopic. better open a new topic. https://aioo.be/2015/07/28/Decoding-a-partial-QR-code.html
|
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 899
🖤😏
|
|
October 11, 2023, 06:59:16 AM |
|
Do we look like the kind of people capable of helping anyone? I mean can't they see we're waist deep in this swamp? Dude if we knew how to "solve" anything we would have solved our problem.🤣
Alright back on topic, I might have found a solution to divide a key with stride of 2, MEANING God willing we may be able to halve the entire key range and then search our way to find a key, this is hot out of oven.
My problem is when I find a solution I forget what it was after 10 minutes. Only if I can repeat it several times, then it stays with me.
Everything I have managed to accomplish so far ( which is none, lol ), been with the help of scalar operations instead of curve ops.
For a few days I have been wondering, where are those guys who said they were working on some new scripts to divide by 3 etc, reduce bits etc? More importantly, why are we publicly trying to crack a potentially $2 trillion vault, have we lost our minds or just don't care about anything but a few coins for ourselves? Taunting indeed.😅
|
🖤😏
|
|
|
nomachine
Member
Offline
Activity: 406
Merit: 23
|
|
October 11, 2023, 09:55:45 AM Last edit: October 14, 2023, 07:21:40 PM by nomachine |
|
I managed to prove experimentally on 5 different computers that everything is in seed. You can speed up solving the puzzle by a million years if you know the correct seed. And the best thing is that you can always achieve the same result in the same time. Proof is in the pudding. PC-1 - [Kangaroo]: Wed Oct 11 11:51:00 2023
- [Puzzle]: 50
- [Lower range limit]: 562949953421312
- [Upper range limit]: 1125899906842623
- [Xcoordinate]: f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6
- [Ycoordinate]: eb3dfcc04c320b55c529291478550be6072977c0c86603fb2e4f5283631064fb
- [Using 4 CPU cores for parallel search]:
- [Core]: 03, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 01, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 04, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 02, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- PUZZLE SOLVED: Wed Oct 11 11:51:18 2023, total time: 18.38 sec, Core: 04
- WIF: -0000000000000000000000000000000000000000000000000022bd43c2e9354
PC-2 - [Kangaroo]: Wed Oct 11 11:53:38 2023
- [Puzzle]: 50
- [Lower range limit]: 562949953421312
- [Upper range limit]: 1125899906842623
- [Xcoordinate]: f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6
- [Ycoordinate]: eb3dfcc04c320b55c529291478550be6072977c0c86603fb2e4f5283631064fb
- [Using 12 CPU cores for parallel search]:
- [Core]: 10, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 11, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 12, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 01, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 02, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 03, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 04, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 05, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 06, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 07, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 08, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- [Core]: 09, [Random seed]: b'\xbc\x9b\x8cd\xfc\xa1?\xcf'
- PUZZLE SOLVED: Wed Oct 11 11:53:57 2023, total time: 18.96 sec , Core: 03
- WIF: -0000000000000000000000000000000000000000000000000022bd43c2e9354
It will solve Puzzle 50 in 18 seconds regardless of which computer i was using. 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 = 50 compressed_public_key = "03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6" # Puzzle 50 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\xfc\xa1?\xcf' 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()
|
|
|
|
dextronomous
|
|
October 11, 2023, 10:14:23 AM |
|
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
|
|
|
|
nomachine
Member
Offline
Activity: 406
Merit: 23
|
|
October 11, 2023, 10:17:14 AM Last edit: October 14, 2023, 07:40:43 PM by nomachine |
|
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 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.
|
|
|
|
Denis_Hitov
Newbie
Offline
Activity: 49
Merit: 0
|
|
October 11, 2023, 08:37:34 PM |
|
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 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
Activity: 1330
Merit: 899
🖤😏
|
|
October 12, 2023, 04:18:14 AM |
|
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
|
|
October 12, 2023, 09:45:49 AM |
|
hi, you = got to use wsl, that is the dev/urandom for.,
|
|
|
|
nomachine
Member
Offline
Activity: 406
Merit: 23
|
|
October 12, 2023, 11:00:51 AM Last edit: October 14, 2023, 07:41:51 PM by nomachine |
|
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 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' 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. **** Asked via private message**** You can also setup any range you want. Example Puzzle 65 # 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
|
|
|
|
rosengold
Jr. Member
Offline
Activity: 149
Merit: 7
|
|
October 12, 2023, 01:13:54 PM |
|
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
Activity: 75
Merit: 5
|
|
October 12, 2023, 01:16:37 PM |
|
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
Activity: 406
Merit: 23
|
|
October 12, 2023, 01:33:31 PM |
|
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.
|
|
|
|
abdenn0ur
Newbie
Offline
Activity: 9
Merit: 0
|
|
October 12, 2023, 04:35:47 PM |
|
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
Activity: 49
Merit: 0
|
|
October 12, 2023, 07:02:12 PM |
|
if you dont have '/dev/urandom' here is script without '/dev/urandom' 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
Activity: 406
Merit: 23
|
|
October 12, 2023, 08:26:24 PM Last edit: October 14, 2023, 07:42:45 PM by nomachine |
|
if you dont have '/dev/urandom' here is script without '/dev/urandom' 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.. This will install the gmpy2 library 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()
|
|
|
|
|