Just info.
Think in your own way and your own point of view about this WIF range
Do we have GPU crackers for WIF Private Keys? or do we have someone that can build 1? these have more potentials for brute forcing puzzle 66 from the Random Point of view for probably the last 16 - 18 characters ranges scanned sequentially, compared to the hexadecimal private keys because of the checksum involved in the WIF Private keys... this might be it, every hexadecimal key is valid but not all WIFs are which brings us to the point where scanning might be fun to play with What is the point of this if what you see in every row is just representation of padded zeros? That is the point right there "padded zeros" as explained earlier, the hexadecimal is just from 0 to F base16 whereas the WIF is a base58 equivalent of that base 16 hexadecimal representation... so what point does this make? Well, I can have 3.625 of the hexadecimal character represented as just 1 character of the WIF... this in otherwords simply means if you are able to hit the correct first 3 WIF characters, then you probably don't have too much range to scan compared to hitting the correct first 3 characters of the hexadecimal representation of the same key... you've got a long way to go bro... So i See some potentials in this WIF bruteforcing for the puzzle 66 Key search range 66 KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3q ZVfMsBQggk69993Lj3p KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3q aCtgAeZDbST4e5pMroG We can't do anything with this information. In fact, it will be the same brute force of keys. There is no difference in what format to sort through the keys, even in binary, even in hex, even in base58.
|
|
|
bro i said that because the newbie members always share the same idea, from years we see the same ideas and reply to it, please for newbie to read this and the other thread of the puzzle do not spam thats what i want to say
I don't understand newbie preposition here! If you are referring me as new BIE than, I am happy to be it or even born bie if you like it! But the thing is we are all here making an effort to achieve a certain collective goal i guess. Someone posted logic, when I read it, I simply posted that Script that I developed probably 8 months ago, way before joining this forum! Well that didn't make me newbie there did it? Anyway, I shared my script, its simplest possible reasoning and logic behind,, the reason I said why digaran suggested formula won't work, the reason I commented on it because i tested it and tested it really hard not just spinning around! So basically I wanted to save someone's time pursuing something like that which has already proven to be waste of time, so that one can focus on other fresh ideas instead of wasting time on old ones!!! BTW how long one remains here a newBIE? This doesn't call for a debate though... Let us collectively achieve the goal we're all hoping to achieve in this forum. By the way, does anyone know how to write codes for AntMiners? I suggest the AntMiners are way faster than the GPUs in computational tasks. We can solve 66, 67, 68 and 69 in one night if someone can write something to work on them these machines are not profitable for now, so we need to gear them towards something that's worth it... like solving these puzzles Let me know if anyone here knows how we can achieve that These, like any other mining machines, cannot do such things, since the ASIC chips from the factory are capable of performing one operation. It is possible to port something only to FPGA, and even then not to all. https://www.researchgate.net/publication/371337493_EC-Crypto_Highly_Efficient_Area-Delay_Optimized_Elliptic_Curve_Cryptography_Processor
|
|
|
I tried to substitute data from lower bit ranges. 20 bits in less than a minute. I can't find 30 bits for half an hour already. I understand that you need to know the exact number of digits 1?
|
|
|
How about percentage ?? import time import random import gmpy2 from functools import lru_cache import multiprocessing from tqdm import tqdm
modulo = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy = 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, p=modulo): if p % 4 != 3: print('prime must be 3 modulo 4') return 0 X = (X ** 3 + 7) % p pw = (p + 1) // 4 Y = 1 tmp = X for w in range(256): if (pw >> w) & 1 == 1: Y = (Y * tmp) % p tmp = pow(tmp, 2, 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()
print('P-table prepared')
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))) d = Ak[sol_kt] - Bk[sol_kw] print('SOLVED:', d) with open("results.txt", 'a') as file: file.write(('%d' % (Ak[sol_kt] - Bk[sol_kw])) + "\n") file.write("---------------\n") return True else: return False
def check(P, Pindex, DP_rarity, file2save, A, Ak, B, Bk): if P.x % DP_rarity == 0: A.append(P.x) Ak.append(Pindex) with open(file2save, 'a') as file: file.write(('%064x %d' % (P.x, Pindex)) + "\n") return comparator(A, Ak, B, Bk) else: return False
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(process_id, Nt, Nw, problem, kangoo_power, starttime): DP_rarity = 1 << ((problem - 2 * kangoo_power) // 2 - 2) hop_modulo = ((problem - 1) // 2) + kangoo_power T, t, dt = [], [], [] W, w, dw = [], [], [] for k in range(Nt): t.append((3 << (problem - 2)) + random.randint(1, (1 << (problem - 1)))) T.append(mulk(t[k])) dt.append(0) for k in range(Nw): w.append(random.randint(1, (1 << (problem - 1)))) W.append(add(W0, mulk(w[k]))) dw.append(0)
print('tame and wild herds are prepared')
oldtime = time.time() Hops, Hops_old = 0, 0 t0 = time.time() starttime = oldtime = time.time()
total_tame_iterations = Nt * (problem - 2 * kangoo_power - 2) total_wild_iterations = Nw * (problem - 2 * kangoo_power - 2) total_iterations = total_tame_iterations + total_wild_iterations
pbar_t = tqdm(total=total_tame_iterations, desc=f"Process {process_id}: tame", position=process_id, leave=False, ncols=50, bar_format="{desc:<0}|{bar} | {percentage:3.2f}% | ") pbar_w = tqdm(total=total_wild_iterations, desc=f"Process {process_id}: wild", position=process_id, leave=False, ncols=50, bar_format="{desc:<0}|{bar} | {percentage:3.2f}% | ")
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: pbar_t.close() pbar_w.close() elapsed_time_t = time.time() - starttime percentage_completed = (Hops / total_iterations) * 100 print(f'Process {process_id}: tame completed: %.2f%%' % (percentage_completed % 100)) return f'Process {process_id}: tame sol. time: %.2f sec' % elapsed_time_t t[k] += dt[k] T[k] = add(P[pw], T[k]) pbar_t.update(1)
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: pbar_t.close() pbar_w.close() elapsed_time_w = time.time() - starttime percentage_completed = (Hops / total_iterations) * 100 print(f'Process {process_id}: wild completed: %.2f%%' % (percentage_completed % 100)) return f'Process {process_id}: wild sol. time: %.2f sec' % elapsed_time_w w[k] += dw[k] W[k] = add(P[pw], W[k]) pbar_w.update(1)
def search_wrapper(args): return search(*args)
if __name__ == "__main__": start = 2147483647 end = 4294967295 search_range = end - start + 1 problem = search_range.bit_length()
compressed_public_key = "0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69" #Puzzle 32 kangoo_power = 3 Nt = Nw = 2 ** kangoo_power
X = int(compressed_public_key, 16) Y = X2Y(X % (2 ** 256)) if Y % 2 != (X >> 256) % 2: Y = modulo - Y X = X % (2 ** 256) W0 = Point(X, Y) starttime = oldtime = time.time()
num_cpus = multiprocessing.cpu_count() N_tests = num_cpus # Use the number of CPU cores as the number of tests
args = [(i, Nt, Nw, problem, kangoo_power, starttime) for i in range(N_tests)]
with multiprocessing.Pool(processes=N_tests) as pool: results = list(tqdm(pool.imap(search_wrapper, args), total=N_tests, bar_format="{desc:<0}|{bar} | {percentage:3.2f}% | ", ncols=50))
total_time = sum(float(result.split(': ')[-1][:-4]) for result in results if result is not None) print('Average time to solve: %.2f sec' % (total_time / N_tests))
Result: P-table prepared | | 0.00% | tame and wild herds are prepared Process 0: wild| | 0.00% | tame and wild herds are prepared tame and wild herds are prepared tame and wild herds are prepared Process 0: wild| | 0.00% | SOLVED: -3093472814 Process 0: wild completed: 61.46% |█████████▎ | 25.00% | SOLVED: -3093472814 Process 1: wild| | 0.00% | Process 2: wild completed: 28.39% Process 2: wild| | 0.00% | SOLVED: 3093472814 Process 1: tame| | 0.00% | Process 1: tame completed: 34.64% |██████████████████▌ | 50.00% | SOLVED: -3093472814 Process 3: wild| | 0.00% | Process 3: wild completed: 19.01% |████████████████████████████████████ | 100.00% | Average time to solve: 1.53 sec | 0.00% |
Process 1: wild| | 0.00% | Process 15: tame completed: 5.73% Process 12: wild| | 0.00% | Process 12: wild| | 0.00% | SOLVED: -3093472814 Process 29: wild completed: 44.53% | 0.00% | SOLVED: 3093472814 Process 0: wild| | 0.00% | SOLVED: -3093472814 Process 45: wild completed: 99.74% Process 13: tame| | 0.00% | SOLVED: 3093472814 Process 38: tame completed: 67.45% | 0.00% | SOLVED: -3093472814 Process 41: wild completed: 12.24% | 0.00% | Process 0: wild| | 0.00% | SOLVED: 3093472814 Process 1: tame| | 0.00% | Process 19: tame completed: 13.28% Process 0: wild| | 0.00% | SOLVED: -3093472814 Process 0: wild completed: 62.50% |▊ | 2.08% | SOLVED: -3093472814 Process 25: wild completed: 11.20% | 0.00% | Process 31: tame completed: 87.76% SOLVED: 3093472814 Process 26: tame completed: 34.64% | 0.00% | Process 42: tame completed: 64.06% SOLVED: -3093472814 Process 27: wild completed: 19.01% | 0.00% | Process 12: wild| | 0.00% | SOLVED: 3093472814 Process 1: wild| | 0.00% | Process 13: tame completed: 39.32% SOLVED: 3093472814 Process 1: wild| | 0.00% | Process 12: tame completed: 58.85% SOLVED: -3093472814 | 0.00% | Process 5: wild| | 0.00% | Process 1: wild completed: 40.10% |█▌ | 4.17% | SOLVED: 3093472814 Process 36: tame completed: 0.78% | 0.00% | SOLVED: 3093472814 | 0.00% | Process 13: wild| | 0.00% | Process 5: tame completed: 75.26% SOLVED: -3093472814 Process 39: wild completed: 65.10% | 0.00% | |████████████████████████████████████ | 100.00% | Average time to solve: 1.89 sec | 0.00% |
|
|
|
is there a multicore version out or can we edit this to do that , thanks mate for sharing.
Sure, here's the full script with multiprocessing added: import time import random import gmpy2 from functools import lru_cache import multiprocessing
modulo = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy = 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, p=modulo): if p % 4 != 3: print('prime must be 3 modulo 4') return 0 X = (X ** 3 + 7) % p pw = (p + 1) // 4 Y = 1 tmp = X for w in range(256): if (pw >> w) & 1 == 1: Y = (Y * tmp) % p tmp = pow(tmp, 2, 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()
print('P-table prepared')
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))) print('total time: %.2f sec' % (time.time() - starttime)) d = Ak[sol_kt] - Bk[sol_kw] print('SOLVED:', d) with open("results.txt", 'a') as file: file.write(('%d' % (Ak[sol_kt] - Bk[sol_kw])) + "\n") file.write("---------------\n") return True else: return False
def check(P, Pindex, DP_rarity, file2save, A, Ak, B, Bk): if P.x % DP_rarity == 0: A.append(P.x) Ak.append(Pindex) with open(file2save, 'a') as file: file.write(('%064x %d' % (P.x, Pindex)) + "\n") return comparator(A, Ak, B, Bk) else: return False
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(process_id, Nt, Nw, problem, kangoo_power, starttime): DP_rarity = 1 << ((problem - 2 * kangoo_power) // 2 - 2) hop_modulo = ((problem - 1) // 2) + kangoo_power T, t, dt = [], [], [] W, w, dw = [], [], [] for k in range(Nt): t.append((3 << (problem - 2)) + random.randint(1, (1 << (problem - 1)))) T.append(mulk(t[k])) dt.append(0) for k in range(Nw): w.append(random.randint(1, (1 << (problem - 1)))) W.append(add(W0, mulk(w[k]))) dw.append(0) print('tame and wild herds are prepared') 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]) t1 = time.time() if (t1 - t0) > 5: print('%.3f h/s' % ((Hops - Hops_old) / (t1 - t0))) t0 = t1 Hops_old = Hops
start = 2147483647 end = 4294967295 search_range = end - start + 1 problem = search_range.bit_length()
compreessed_public_key = "0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69" #Puzzle 32 kangoo_power = 3 Nt = Nw = 2 ** kangoo_power
X = int(compreessed_public_key, 16) Y = X2Y(X % (2 ** 256)) if Y % 2 != (X >> 256) % 2: Y = modulo - Y X = X % (2 ** 256) W0 = Point(X, Y) starttime = oldtime = time.time()
Hops = 0 random.seed()
hops_list = [] N_tests = 3
def search_wrapper(process_id): return search(process_id, Nt, Nw, problem, kangoo_power, starttime)
if __name__ == "__main__": num_cpus = multiprocessing.cpu_count() N_tests = num_cpus # Use the number of CPU cores as the number of tests
with multiprocessing.Pool(processes=N_tests) as pool: results = pool.map(search_wrapper, range(N_tests))
for result in results: print(result) M, D = 0, 0 if len(hops_list) > 0: M = sum(hops_list) * 1.0 / len(hops_list) D = sum((xi - M) ** 2 for xi in hops_list) * 1.0 / len(hops_list) print(M, '+/-', (D / (len(hops_list) - 1)) ** 0.5) print('Average time to solve: %.2f sec' % ((time.time() - starttime) / N_tests))
In the __name__ == "__main__" block, the number of available CPU cores is determined using multiprocessing.cpu_count(), and N_tests is set to this number. This means that the script will create a separate process for each CPU core available for parallel processing. If you're going to use multiprocessing, try not to print anything or do any I/O until the very end because the disk access bottleneck will slow the whole loop down (even on SSD - it can never possibly be as fast as a CPU's clock speed). Actually you should even import tqdm and create a progress bar for that, and then customize the progress bar to show you the key being worked on, how many have already been done, etc. Much better than printing since there are not synchronized with a mutex (by default). You are right. Using a progress bar is a much better approach than printing progress statements, especially when dealing with multiprocessing. The tqdm library is an excellent choice for displaying progress bars in Python. New script: import time import random import gmpy2 from functools import lru_cache import multiprocessing from tqdm import tqdm
modulo = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy = 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, p=modulo): if p % 4 != 3: print('prime must be 3 modulo 4') return 0 X = (X ** 3 + 7) % p pw = (p + 1) // 4 Y = 1 tmp = X for w in range(256): if (pw >> w) & 1 == 1: Y = (Y * tmp) % p tmp = pow(tmp, 2, 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()
print('P-table prepared')
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))) d = Ak[sol_kt] - Bk[sol_kw] print('SOLVED:', d) with open("results.txt", 'a') as file: file.write(('%d' % (Ak[sol_kt] - Bk[sol_kw])) + "\n") file.write("---------------\n") return True else: return False
def check(P, Pindex, DP_rarity, file2save, A, Ak, B, Bk): if P.x % DP_rarity == 0: A.append(P.x) Ak.append(Pindex) with open(file2save, 'a') as file: file.write(('%064x %d' % (P.x, Pindex)) + "\n") return comparator(A, Ak, B, Bk) else: return False
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(process_id, Nt, Nw, problem, kangoo_power, starttime): DP_rarity = 1 << ((problem - 2 * kangoo_power) // 2 - 2) hop_modulo = ((problem - 1) // 2) + kangoo_power T, t, dt = [], [], [] W, w, dw = [], [], [] for k in range(Nt): t.append((3 << (problem - 2)) + random.randint(1, (1 << (problem - 1)))) T.append(mulk(t[k])) dt.append(0) for k in range(Nw): w.append(random.randint(1, (1 << (problem - 1)))) W.append(add(W0, mulk(w[k]))) dw.append(0)
# Move the "tame and wild herds are prepared" line here print('tame and wild herds are prepared')
oldtime = time.time() Hops, Hops_old = 0, 0 t0 = time.time() starttime = oldtime pbar_t = tqdm(total=Nt, desc=f"Process {process_id}: tame", position=process_id, dynamic_ncols=True, leave=False, ncols=100) pbar_w = tqdm(total=Nw, desc=f"Process {process_id}: wild", position=process_id, dynamic_ncols=True, leave=False, ncols=100)
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: pbar_t.close() pbar_w.close() elapsed_time_t = time.time() - starttime print(f'Process {process_id}: tame sol. time: %.2f sec' % elapsed_time_t) return f'Process {process_id}: tame sol. time: %.2f sec' % elapsed_time_t t[k] += dt[k] T[k] = add(P[pw], T[k]) pbar_t.update(1)
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: pbar_t.close() pbar_w.close() elapsed_time_w = time.time() - starttime print(f'Process {process_id}: wild sol. time: %.2f sec' % elapsed_time_w) return f'Process {process_id}: wild sol. time: %.2f sec' % elapsed_time_w w[k] += dw[k] W[k] = add(P[pw], W[k]) pbar_w.update(1)
def search_wrapper(args): return search(*args)
if __name__ == "__main__": start = 2147483647 end = 4294967295 search_range = end - start + 1 problem = search_range.bit_length()
compreessed_public_key = "0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69" #Puzzle 32 kangoo_power = 3 Nt = Nw = 2 ** kangoo_power
X = int(compreessed_public_key, 16) Y = X2Y(X % (2 ** 256)) if Y % 2 != (X >> 256) % 2: Y = modulo - Y X = X % (2 ** 256) W0 = Point(X, Y) starttime = oldtime = time.time()
num_cpus = multiprocessing.cpu_count() N_tests = num_cpus # Use the number of CPU cores as the number of tests
args = [(i, Nt, Nw, problem, kangoo_power, starttime) for i in range(N_tests)]
with multiprocessing.Pool(processes=N_tests) as pool: results = list(tqdm(pool.imap(search_wrapper, args), total=N_tests))
# Output the average time to solve total_time = sum(float(result.split(': ')[-1][:-4]) for result in results if result is not None) print('Average time to solve: %.2f sec' % (total_time / N_tests))
It shows that the "P-table prepared" message is printed at the beginning, and then it displays progress bars for both "tame" and "wild" processes. After finishing the wild process, it shows "Process 0: wild" progress and the completion time. P-table prepared 0%| | 0/4 [00:00<?, ?it/s]tame and wild herds are prepared tame and wild herds are prepared tame and wild herds are prepared Process 0: wild: 0%| | 0/8 [00:00<?, ?it/stame and wild herds are prepared Process 0: wild: 28464it [00:01, 13883.45it/s]SOLVED: -3093472814 Process 1: tame: 28652it [00:01, 13869.72it/s]Process 2: wild sol. time: 1.83 sec Process 2: tame: 28550it [00:01, 13659.12it/s]SOLVED: 3093472814 Process 0: tame sol. time: 1.86 sec 25%|███████████████████████████SOLVED: 3093472814 | 1/4 [00:01<00:05, 1.89s/it] Process 1: tame: 47801it [00:02, 36580.65it/s]Process 1: tame sol. time: 2.35 sec 50%|██████████████████████████████████████████SOLVED: 3093472814 | 2/4 [00:02<00:02, 1.08s/it] Process 3: wild: 68509it [00:02, 29066.35it/s] Process 3: tame sol. time: 3.26 sec 100%|██████████████████████████████████████████████████████████████████████| 4/4 [00:03<00:00, 1.21it/s] Average time to solve: 2.33 sec3, 51300.68it/s]
Process 0: wild: 76121it [00:03, 29910.37it/s]]SOLVED: -3093472814 Process 1: wild: 64721it [00:03, 30101.92it/s]Process 6: wild sol. time: 3.27 sec Process 5: tame: 68144it [00:03, 25783.91it/s]] Process 6: tame: 65643it [00:03, 25683.95it/s]SOLVED: -3093472814 Process 7: tame: 67557it [00:03, 29223.45it/s]] ... (more hidden) ... Process 9: wild: 64425it [00:03, 20663.78it/s]] Process 5: tame: 70777it [00:03, 24056.88it/s]] Process 19: tame: 62187it [00:03, 27300.44it/s] Process 7: wild: 69993it [00:03, 29536.12it/s]] Process 21: wild: 49623it [00:03, 17401.26it/s] Process 9: wild: 66541it [00:03, 19560.90it/s] Process 20: wild: 55521it [00:03, 25278.08it/s] Process 16: tame: 72577it [00:03, 29203.31it/s] Process 12: tame: 65833it [00:03, 30571.12it/s]
Process 19: tame: 65118it [00:03, 27876.14it/s] Process 17: wild: 57313it [00:03, 29236.38it/s] Process 16: wild: 75633it [00:03, 29890.75it/s]
Process 20: wild: 58713it [00:03, 27127.54it/s]Process 21: wild sol. time: 3.29 sec SOLVED: 30934728144309it [00:03, 20556.27it/s] Process 40: tame sol. time: 3.24 sec Process 0: wild: 82297it [00:03, 30400.36it/s]]SOLVED: -3093472814 Process 1: wild: 70905it [00:03, 30503.65it/s]
It gives me such nonsense)
|
|
|
An update of my "solve66" tool for puzzle #66 is available!- improved search options - bugfixes
WARNING: - NEVER DOWNLOAD THIS TOOL FROM ANY OTHER SOURCE THAN THE LINK IN MY PROFILE! - READ README.TXT FIRST BEFORE USING THIS TOOL!
Without source code, there is no trust in your application. It is not known what kind of application you are distributing.
|
|
|
I keep asking myself how that works but always get very confused too. If there were an alleged calculator you could prescribe and a little bit of some explanation as to how the addition and subtraction works it'd be very understandable. I even tried to write a code to add and multiply below is the code. still all I got was an awkward result. "import argparse import ecdsa from ecdsa.ellipticcurve import Point # Function ato perform point addition def point_addition(point1, point2): return point1 + point2 # Function to perform point subtraction def point_subtraction(point1, point2): return point1 - point2 # Function to perform point multiplication def point_multiplication(point, scalar): return scalar * point # Function to perform point division (using scalar multiplication by the inverse) def point_division(point, scalar): return point_multiplication(point, ecdsa.numbertheory.inverse_mod(scalar, curve.order())) # Parse command-line arguments parser = argparse.ArgumentParser(description="Elliptic Curve Point Operations") parser.add_argument("-p1", dest="public_key1", type=str, help="Public key 1 (in hexadecimal)") parser.add_argument("-p2", dest="public_key2", type=str, help="Public key 2 (in hexadecimal)") parser.add_argument("operation", choices=["+", "-", "*", "/"], help="Operation to perform (+ for add, - for subtract, * for multiply, / for divide)") args = parser.parse_args() # Define the elliptic curve parameters (SECP256k1 in Bitcoin) curve = ecdsa.SECP256k1 # Parse the public keys from the command-line arguments public_key1 = ecdsa.VerifyingKey.from_string(bytes.fromhex(args.public_key1), curve=curve).pubkey.point public_key2 = ecdsa.VerifyingKey.from_string(bytes.fromhex(args.public_key2), curve=curve).pubkey.point # Perform the specified operation on the public keys if args.operation == "+": result_point = point_addition(public_key1, public_key2) elif args.operation == "-": result_point = point_subtraction(public_key1, public_key2) elif args.operation == "*": scalar = int(input("Enter the scalar value (private key): "), 16) result_point = point_multiplication(public_key1, scalar) elif args.operation == "/": scalar = int(input("Enter the scalar value (private key): "), 16) result_point = point_division(public_key1, scalar) # Print the coordinates of the result point result_x, result_y = ecdsa.util.number_to_string(result_point.x(), curve.order), ecdsa.util.number_to_string(result_point.y(), curve.order) print("Result Point (x, y):", result_x.hex(), ",", result_y.hex())" result was awkward but anyway, how do we go about the addition and subtraction, division and multiplication and how do we make sense off of the result from this process?? what tools are required? Calculators and procedures involved. I'm down to learn too https://github.com/albertobsd/ecctools
|
|
|
I spent about $30k over a couple of years renting cloud services to attack these puzzles with no luck. I'm down to about $1k a year in electrical costs running my own equipment right now. It would be interesting to know how much others are willing to gamble on this. Given a large enough pool of money, we should set up a LLC to attempt this in a more organized and professonal manner. If 120 and 125 was cracked by the same person/group then I'm going to suggest that it was done by an investment fund.
Not only that, the person that cracked 120 and 125, are also attacking 130 now. So we need to unite. funny thing about that group or the person that solved it is that they moved the funds and never touched it. They didn't need to buy more computers or rent more GPUs. I must think they probably must be using some forms of manual calculations to beat the puzzles. Because if they needed more computational force, they probably might be needing to spend from the money to get that achieved. Or probably they had saved so much money from the beginning before starting. It's just a guess anyway. More force doesn't mean higher chances. I have wasted over $15k renting GPUs trying to beat level 66 but I'm out of funds now. The only issue here is the levels with the public keys seem to be more prone to calculations without the need for too many computers if you know what you're doing though. But the levels without the public keys, I'm sure you need a pool of resources to beat those levels. I'm about ready to give up right now but where do I start from if I give up now? here the opinion has already been expressed that the person who solved the last keys of the puzzle has a large number of farms for mining. He does not need to purchase equipment, since after the completion of the mining of the ether, there are a lot of video cards left, which has nowhere to apply. there is a possibility that he even used only part of the equipment. People reason that the next key will be decided in January, February next year. But I think it will happen much sooner. Now the reward is high and large miners have joined, so ordinary people have nothing to do here. In principle, it was the same with mining. At the initial stages, you can mine coins with a processor, and then there is nothing to catch there, since large players are connected.
|
|
|
What if we could divide by bits the range all the way to 1 bit? All keys are the modular inverse of the first key start point. Thanks to Quite the Contrary for teaching me how to do this https://youtu.be/Vlqy1zB-QkE ecdsa secp256k1 algorithm explained. How do you propose we divide by bits down to 1? And who taught you what exactly, the youtube you meant?
As I see it, it's just 7 divided in half
He just subtracted 7 from N and divided the result by 2, and as I see it, it's just 15 divided in half, because dividing 7 in half would give you 3.5 where you could see 3 as the first character and that .5 as a huge number, here is the example : 3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d9052 As you see, the .5 which is a fraction has turned to something different, this is the beauty of big numbers combined with elliptic curves.😉 0х7/2 ./keymath 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc / 2 Result: 03592152c398d6c719636a03a6dad64246a5a6814aa62c156b0ce5332f6759b031 We get the result divided in half in the middle of the key range of the bitcoin curve. https://privatekeys.pw/key/7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a4#public
|
|
|
Guys I'm still waiting for my answer, since I revealed the exact range of my public key, it is no use if anyone can tell me the range. 03cefd304a9a8da40666e97b2d9650e31a71a9a9fcd29a24724d31a2fabbc8ea0e I just want you to drop the second digit from my private key having just my public key above.
Mathematical problems are solved in decimals, if you work in hex or binary you will only confuse your research, once you get results you apply the conversions, if you work in hex or binary you overlook important details such as the sum of the Y coordinates of a mirrored pubkey (negative) Y+(-Y) always equals
or why? these pk share the same X coordinates.
57896044618658097711785492504343953926418782139537452191302581570759080747172
57896044618658097711785492504343953926418782139537452191302581570759080747165
I'm a bit lost after reading your reply, what is this exactly 7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a4 And this one? 7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b209d Why did you post 2 random keys with only 7 keys difference between them? I'm asking this because my private key has 7 in it, can you just tell me where did you get the 2 private keys above?
To the rest of you guys, don't fight and argue, there are hundreds if bitcoins waiting for you to collect, you can show your skills by collecting them.😉 As I see it, it's just 7 divided in half. https://privatekeys.pw/keys/bitcoin/1286578769303513282484122055652087865031528491989721159806724034905757349938#7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0
|
|
|
There is even a way to find out the range in which the key is located, ...
Really? So tell us what the range is where #66 is lying I apologize for not providing clarification. You can find out the range from the public key. Then it will not be difficult for you to determine in what range this public key is located. 0359c777fb4a0bf9c16ba308259eb4f5ef2abfd2928a8f499cbdc47300f9dcb8d5 What strange people. You don't take my word for it, you always want confirmation. And then this and this. I regret that I again fell into the trap I fell into a year ago on the same forum. Everyone laughed at me. No more comments. Good luck to everyone. 1000000000000000000000000000000000000000 F000000000000000000000000000000000000000 8000000000000000000000000000000000000023 I don't understand how, but you're absolutely right. But could you share a way to determine the range? At least a hint.
|
|
|
There is even a way to find out the range in which the key is located, ...
Really? So tell us what the range is where #66 is lying I apologize for not providing clarification. You can find out the range from the public key. Then it will not be difficult for you to determine in what range this public key is located. 0359c777fb4a0bf9c16ba308259eb4f5ef2abfd2928a8f499cbdc47300f9dcb8d5
|
|
|
In the 30+ minutes that I wasted hammering (and subsequently trashing) a reply to this, I just updated the pkarith script to spit out the correct end points... took me just two minutes and 2 lines of code change. https://gist.github.com/ZenulAbidin/e8687d9e16189c99d192e97d37e71dbeSee how more effectively and faster I can implement stuff when I have all the info I need, clearly (emphasis on that), beforehand? I can only work with information I have at hand (without guessing random stuff). Nowhere was it said that you had to divide max value by 32 and add that to start value to get the end value... take a look back at them yourself. Otherwise you get stuff like a broken Kangaroo-256 with a borked hashtable lookup function. There wouldn't have even been a flamewar if I had that info. Instead I got "0.01325 to 0.0625" which I understood to mean that the zones themselves are the start and end points. With this info, making an assumption about division at that stage would've been a guess. And none of this was resolved until Counselor explained this important point a few posts up. Hello. I read the topic from the end and saw this script and discussion. I checked how it works, but no matches are found when searching for public keys with the ranges that go in the same block in the keyhunt. Do the public keys in the output of this script match the ranges?
|
|
|
We can use fraction-kangaroo or just a python script that will divide #130 puzzles into 2^20 pieces. Each hunter will look at least for 1 key in the range of 109 bits. What if we divide the pubkey by x amount. we will say divide #130 pubkey by 10; that gives us 1,024 pubkeys and reduces the range to 2^120/2^119. I will run tames and then we just need 1,024 people (or less if multiple people run multiple pubkeys) to run wilds. I will post tame points (text files with all tame points) and then all who run wild points just need to verify if they have a match. If there is a match, we can share/split the reward. This way 2 people will share prize and people can run as many pubkeys as they want to. We can decide on the best number to divide by, if interested. Example tame points: 72eaff741b31e674e823570ea0000000 0ef943b6b900c758c17bd6f0c0000000 f8536da415411e4bb2c0177600000000 0bc01c4051c4b9d2b80c5d6900000000 e14aec9c4a01765c809410a5c0000000 c9bc2740735b478ee9cd841d80000000 31b580628f072553f30f5167c0000000 dac9c736237cd07117b71490a0000000 321f92692348055814d4eb5d00000000 eade44fe5ae49ffbfa972e5180000000 ad54552d665c1baaba46068d20000000 aab1759d8241aba0015fa611c0000000 e5ab9e9fd481a789f178b93a40000000 7e92ee441d924c83faee5d6800000000 2e8512535a029c1b5a841a3de0000000 8dcadd24e8f2990df80c961420000000 9d14e08ed9c558904c26892620000000 d93fda5a52d6112e7b9de460a0000000 405607ddd7a740b1f2903be2a0000000 ab6ebbdb77d55b14053f5a5900000000 17000a072245075a9ed2d66600000000 b8d81acdc5431b721dd5cb6140000000 3e825233033301486048390960000000 fc3b3117a291d34b4a865050a0000000 d315708ef56dfef75d2d640120000000 056bbb63a91be97200c435af60000000 94addc9dc093f8e54c86ab0600000000 eaa896be8970e3bdb8e0d1e2e0000000 c3f7c22c2b06460ce977a8cce0000000 45f68f5450fc5a8dfa6a7d9880000000 8b25ed6f78450eb98b86bd4420000000 6fc311534d7a988a92adf36c40000000 e223581788f08cf6f7e9e1de20000000 e0bf51daee64355694adeae480000000 a4ff4aaa40b238d16b2b3110c0000000 fc10fad238d54db43be74eb680000000 740959dd6375f90af1c10a8c40000000 3ef027cc12a6160697e2c453a0000000 df9de9947e9bc75dba0b6c22c0000000 d32d019d02b333e60d05b95140000000
And all anyone has to do is check their wild points against the above; if match, winner winner. Can you suggest how this happens. How can I view working files, how to separate wild and tame kangaroos?
|
|
|
Interested here is a question. If the end of the key is known, but there is no possibility of reverse recovery. Is it possible to restore the full key in this case? I remember there used to be a wif-solver-cuda program for wif, but is there such a program for hex private key?
https://github.com/Mizogg/Tkinter-Power-MiniWIF HEX DEC Recovery Tools As I see this project in python and does not use GPU, how long will it take to recover the lost 9 characters from the example above?
|
|
|
Interested here is a question. If the end of the key is known, but there is no possibility of reverse recovery. Is it possible to restore the full key in this case? I remember there used to be a wif-solver-cuda program for wif, but is there such a program for hex private key?
It doesn't matter that the keys are in HEX. You can convert them to WIF and then use the according base keys to generate valid address. I encountered the same problem. WIF validation may be correct however there are way too many possible keys. What is interesting is uncompressed format there is a few less bytes to deal with, which in turn could be converted back to compressed if needed. Ill leave a couple examples here. EC 0000000000000000000000000000000000000000000000000000000000000001 KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf EC 0000000000000000000000000000000000000000000000000000000000000003 KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreB1FQ8BZ EC 00000000000000000000000000000000000000000000000000000022382FACD0 KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9P3MahktLW5315v 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB4BW8dsj4c9a6g EC 000000000000000000000000000000000000000000000001A838B13505B26867 - puzzle 65 KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qZM21gaY8WN2CdwnTG57 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ipCnYRNeQuRFKarWVVs KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74sHUHy8S KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9P3MahktLW5315v KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qZM21gaY8WN2CdwnTG57 So we could say upcoming puzzles private key 66 will start with... KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3 Can you show an example, for example on puzzle 80, by removing the middle part of the key? And how long will this work take? 00000000000000000000000000000000000000000000ExxxxxxxxxC11B5AD180
|
|
|
Interested here is a question. If the end of the key is known, but there is no possibility of reverse recovery. Is it possible to restore the full key in this case? I remember there used to be a wif-solver-cuda program for wif, but is there such a program for hex private key?
|
|
|
If there is a need to look for alot of different public keys in the same search range using kangaroo, then you can make your work faster. For example, our search range is 74 bits 0x4000000000000000000:0x7ffffffffffffffffff First we need to prepare a working file. To do this, you need to run a kangaroo in this range with -w, and some public key that is definitely not in this range. This is necessary in order to get enough tame kangaroos. For 74 bit expected operations: 2^38.47 with DP16 it is 2^22.47 DPs and we need compute at least 3 times more kangaroos around 2^24.1 DPs. Then we need remove wild kangaroos from working file. Our file wil contain around 2^23.05 tame kangaroos that is randomly distributed and continue their path. After working file ready we must change the public key in the this file to the one of interest. Also we need a version of kangaroo that produce only wild kangaroo, we don't need new tame kangaroo anymore. Don`t forget that we need change the public key in the working file every time when change interest. So every time we start with the same working file that contain only tame kangaroos but with changed public key in file. And kangaroo programm got job from this working file. For testing i a use randomly generated public keys in range 2^74, some are very close to the beginning, some near the end. Here is result: Expected operations: 2^38.47 [728.59 MK/s][GPU 728.59 MK/s][Count 2^37.44][Dead 2][04:49 (Avg 08:41)][347.2/440.5MB] Key# 0 [1S]Pub: 0x03B043758AC54072BB816BDE28ECF833560D85286E1D86A3CD365C76882A8C87C6 Priv: 0x402E66057958F4E9E0E [727.18 MK/s][GPU 727.18 MK/s][Count 2^37.41][Dead 0][04:43 (Avg 08:42)][345.2/438.0MB] Key# 0 [1S]Pub: 0x02633305FFE6B6238982F24044C864479C8A7DCFF444D7B9446732617F888D788B Priv: 0x414C10C6D7D89F38873 [730.19 MK/s][GPU 730.19 MK/s][Count 2^36.35][Dead 0][02:15 (Avg 08:40)][300.8/382.5MB] Key# 0 [1S]Pub: 0x026ACEBA7AD37487DFAF24CAFE4302B379C3688ACA7CF332DC0FFB9050EA72F27F Priv: 0x46D59B75FE1AD6FCBB3 [749.64 MK/s][GPU 749.64 MK/s][Count 2^34.70][Dead 0][42s (Avg 08:26)][273.1/347.9MB] Key# 0 [1S]Pub: 0x036E152745E2CB09DDA8F0E8FE5E6939111F751895E5E222EF50E25361E4751702 Priv: 0x49CA4F75FC4DD4A0E98
[736.65 MK/s][GPU 736.65 MK/s][Count 2^36.19][Dead 0][02:01 (Avg 08:35)][296.6/377.3MB] Key# 0 [1S]Pub: 0x02AE1FDEF6FB06E68EAAC3E0342A65E37ADDE369AD82B2C5B41AAE488A6C30BB48 Priv: 0x539F9F353128FA9E829 [730.97 MK/s][GPU 730.97 MK/s][Count 2^36.92][Dead 0][03:20 (Avg 08:39)][320.5/407.2MB] Key# 0 [1S]Pub: 0x022E7A857A9891F872A4610396FCAE10AC638B0D89D588B127A3C1423DA41174EF Priv: 0x554AEDB740506B9EFD1 [729.24 MK/s][GPU 729.24 MK/s][Count 2^37.33][Dead 0][04:27 (Avg 08:40)][340.6/432.2MB] Key# 0 [1S]Pub: 0x027BBD8C6F41B43046A3E128037326EEC9807EC767C20E9529CD51034B5361963E Priv: 0x6BDFFBDB6411F328BB9
[738.33 MK/s][GPU 738.33 MK/s][Count 2^34.87][Dead 0][48s (Avg 08:34)][274.7/349.9MB] Key# 0 [1S]Pub: 0x020DFBA9B7C4D7A53A6EE985AB11ACC06BEACC47EBC53D0751B455323F21CBD1B6 Priv: 0x6D9D613445EFF402945
[741.74 MK/s][GPU 741.74 MK/s][Count 2^36.69][Dead 1][02:50 (Avg 08:32)][311.9/396.4MB] Key# 0 [1S]Pub: 0x022FCF70783B01AE1EDDE1CAD273926E089D65CDC4D1510A5C642D9E10A527743F Priv: 0x71C02F72D735ABC20C9 [733.28 MK/s][GPU 733.28 MK/s][Count 2^35.80][Dead 0][01:33 (Avg 08:38)][288.1/366.6MB] Key# 0 [1S]Pub: 0x026893801A8A18773DEC6C166C8E9081B09FB6B724F8D3B9825E5C20EDEA9085D6 Priv: 0x7A54720FF5235105605
[722.31 MK/s][GPU 722.31 MK/s][Count 2^36.94][Dead 0][03:26 (Avg 08:45)][321.7/408.6MB] Key# 0 [1S]Pub: 0x03150058CFFA65835192FBC8076C40377355189A810D04150882578E55FEB50672 Priv: 0x7DBA59C1B7ACF79825E As you can see all time we do not reach even expected operations/2 We do not count tame kangaroos that were produced once at the beginning. Can you explain in more detail how to prepare a working file? Than it can be opened for viewing and editing. And of course, where to get a version of kangaroo that only creates wild kangaroos.
|
|
|
|