Baskentliia
Jr. Member
Offline
Activity: 69
Merit: 1
34Sf4DnMt3z6XKKoWmZRw2nGyfGkDgNJZZ
|
|
October 17, 2023, 01:44:10 PM |
|
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("cls")
# 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)]
t = time.ctime() sys.stdout.write("\033[01;33m") sys.stdout.write(f"[+] [Kangaroo]: {t}" + "\n") sys.stdout.flush()
# Configuration for the puzzle puzzle = 70 compressed_public_key = "0290e6900a58d33393bc1097b5aed31f2e4e7cbd3e5466af958665bc0121248483" # Puzzle 70 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' 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__": process_count = 2 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()
Try this, it works for me on windows. Thank you brother I tried this and it worked
|
34Sf4DnMt3z6XKKoWmZRw2nGyfGkDgNJZZ
|
|
|
WanderingPhilospher
Sr. Member
Offline
Activity: 1232
Merit: 250
Shooters Shoot...
|
|
October 17, 2023, 05:23:03 PM Merited by albert0bsd (1) |
|
Guys/gals, don't waste your time with random search, random mode etc, there is no such a thing as "random" all events follow a pattern, we as humans have to interfere and change these patterns, by following logic and the power of our minds.
Instead of "hoping" for a "lucky" hit in a random search, start working on ways to find a stride for public key brute force. Example: Target = 127654 (unknown) we only know it's between 100,000 and 200,000. So we subtract it from 200,000 - 127654 = 72,346. Now we are certain our result is 100% smaller than 100,000 (start range), but since we don't know how much smaller, we'd just subtract it from half of start range, 50,000 - 72,346 = 22,346. And now we are 100% certain the result is smaller than 50,000 but we don't know how much, again we subtract it from 1/4 of start range 25,000 - 22,346 = 2,654.
Now tell me what do you see? 127654 2654 127654 - 2654 = 125000 What you need to work on is figuring out a stride to add to 125,000 till we reach our target, whether we add 13 at each step, 14 or 15, what happens when we reach 127698? Can we save the keys between 127654 and 127700 so when we are adding stride and land on one of the saved keys, we know right away and easily solve the key or not?
These things should be your priority, enough of running this tool/script and that tool/script, come up with an algorithm which doesn't require "random" and "luck" but requires math equations and numbers.
Sorry man, this either will not work because you went around the curve, or you will have trillions^trillions of strides to go through/take. Your example: Target = 127654 range = 100,000 - 200,000 Like you said, we do not know the target, only the range. So let's say the target's key is 199,999 Watch the math: 200,000 - 199,999 = 1 1 - 50,000 = -49,999 -49,999 - 25,000 = -74,999 You have now went backwards around the curve. So now, you can't even start your program to start striding from 0 or 1. But let's deal with your math above and talk about the strides. It's ok when a range is only 200,000 but now imagine a much larger range, say 2^130. If you have a stride of 13, 14, 15, etc., it will take you more than a lifetime to still get through that range.
|
|
|
|
nomachine
Member
Offline
Activity: 503
Merit: 38
|
|
October 17, 2023, 06:56:03 PM |
|
Here is new script.... Bytea HASH160 Search. Bitcoin addresses and hashes are typically represented as byte sequences. When you work with bytes, you can directly perform binary operations and comparisons, which is faster and more efficient than dealing with hexadecimal or string representations. In this context, the script generates private keys as integers and converts them into bytes to derive Bitcoin addresses. It then calculates the Hash160 of these addresses and compares it to the target Hash160. Script uses puzzle creator method - the b'\x00' * 32 line creates a 32-byte value composed entirely of zero bytes. This is just an initial placeholder value, and as the script progresses, it replaces parts of these zeros with the random bytes generated to create a valid private key for Bitcoin. You can also play with patterns and random seed values at the same time. import sys import os import time import random import binascii import base58 import hashlib import ecdsa from multiprocessing import cpu_count import threading
# Set the Hash 160 address you want to check for target_hex = "20d45a6a762535700ce9e0b216e31994335db8a5" add_set = bytes.fromhex(target_hex)
puzzle = 66 min_number = 2 ** (puzzle - 1) max_number = (2 ** puzzle) - 1
# Clear the terminal screen if os.name == 'nt': os.system('cls') else: os.system('clear')
# Print information about the program t = time.ctime() sys.stdout.write("\033[01;33m") sys.stdout.write("\033[?25l") sys.stdout.write(f"[+] [Bytea HASH160 Search] {t}" + "\n") sys.stdout.write(f"[+] [Puzzle]: {puzzle}" + "\n") sys.stdout.write(f"[+] [Lower range limit]: {min_number}" + "\n") sys.stdout.write(f"[+] [Upper range limit]: {max_number}" + "\n") sys.stdout.flush()
# Define the check_private_key function def check_private_key(add_set): while True: constant_prefix = b'' #Can be b'\xbc\x9b' or any random_bytes prefix_length = len(constant_prefix) length = 8 ending_length = length - prefix_length ending_bytes = os.urandom(ending_length) random_bytes = constant_prefix + ending_bytes random.seed(random_bytes) dec = random.randint(min_number, max_number) dec_bytes = dec.to_bytes((dec.bit_length() + 7) // 8, 'big') private_key_bytes = b'\x00' * 32 private_key_bytes = private_key_bytes[:-len(dec_bytes)] + dec_bytes signing_key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1) compressed_public_key = signing_key.get_verifying_key().to_string("compressed") sha256_hash = hashlib.sha256(compressed_public_key).digest() HASH160 = hashlib.new('ripemd160', sha256_hash).digest() extended_private_key = b'\x80' + private_key_bytes + b'\x01' extended_ripe160_hash = b'\x00' + HASH160 checksum = hashlib.sha256(hashlib.sha256(extended_private_key).digest()).digest()[:4] checksum_ripe160 = hashlib.sha256(hashlib.sha256(extended_ripe160_hash).digest()).digest()[:4] private_key_with_checksum = extended_private_key + checksum HASH160_wif = base58.b58encode(private_key_with_checksum).decode() address_bytes = extended_ripe160_hash + checksum_ripe160 bitcoin_address = base58.b58encode(address_bytes).decode() message = "\r[+] Public Key Hash (Hash 160): {} ".format(HASH160.hex()) messages = [] messages.append(message) output = "\033[01;33m" + ''.join(messages) + "\r" sys.stdout.write(output) sys.stdout.flush() if bitcoin_address.startswith("13zb1h"): sys.stdout.write(f"\n[+]\033[32m Pattern Found: {bitcoin_address}, {dec}, {random_bytes} \033[0m") sys.stdout.write(f"\n[+] continue...\n") if HASH160 == add_set: dec_to_hex = hex(dec).split('x')[-1] t = time.ctime() sys.stdout.write(f"\033[0m\n\n") sys.stdout.write(f"[+] SOLVED: |\033[32m{t} \033[0m\n") sys.stdout.write(f"[+] Key Found: |\033[32m {dec_to_hex} \033[0m\n" f"[+] WIF: |\033[32m {HASH160_wif} \033[0m\n" f"[+] Address: |\033[32m {bitcoin_address} \033[0m\n" f"[+] Seed: |\033[32m {random_bytes} \033[0m\n\n") sys.stdout.flush() with open("KEYFOUNDKEYFOUND.txt", "a") as f: f.write("SOLVED: " + str(t) + '\n' + "HEX: " + str(dec_to_hex) + '\n' + "Address: " + str(bitcoin_address) + '\n' + "Private Key: " + str(HASH160_wif)+ '\n' + "Random Seed: " + str(random_bytes) + '\n\n') f.flush() f.close() sys.stdout.write("\033[?25h") sys.stdout.flush() return
# Create multiple threads for generating addresses num_threads = cpu_count() threads = []
for _ in range(num_threads): thread = threading.Thread(target=check_private_key, args=(add_set,)) thread.start() threads.append(thread)
# Wait for all threads to finish for thread in threads: thread.join()
|
bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 900
🖤😏
|
|
October 17, 2023, 08:22:22 PM |
|
Like you said, we do not know the target, only the range. So let's say the target's key is 199,999
Alrighty then, to be exact, when it comes to slapping me suddenly the secure random generator gives us 199,999? And when we are working with 6 digits then as an example use 14, 15 etc, suddenly we go high as 2^130 and compare the numbers? So why not scaling up all the values and use actual 2^130 range/keys? Though you forgot that I was asking if the stride idea could be tweaked to find a perfect stride or not. Even if the key is e.g, 189776, we could still divide the end range and subtract from our target by different subranges, like 200,000 - 189776 = 10224, we could then try subtracting the result from endrange/4, er/6, er/8 etc.
Nvm that, I don't know anything about math, I'm not even working actively on 130, my target is much bigger. Btw, Legends_Never_Die is my alter ego account, time for a paint job on trust wall.😉
|
🖤😏
|
|
|
nomachine
Member
Offline
Activity: 503
Merit: 38
|
|
October 17, 2023, 11:59:44 PM Last edit: October 18, 2023, 12:33:18 AM by nomachine |
|
the secure random generator gives us 199,999
Try non-secure random generator import random puzzle = 18 lower_range_limit = 2 ** (puzzle - 1) upper_range_limit = (2 ** puzzle) - 1 seed = b'\x97h6\xd9\x7f\xcbh\xc4' random.seed(seed) dec = random.randint(lower_range_limit, upper_range_limit) print(f"{dec}, {seed}")
|
bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
|
|
|
WanderingPhilospher
Sr. Member
Offline
Activity: 1232
Merit: 250
Shooters Shoot...
|
|
October 18, 2023, 01:17:21 AM |
|
Like you said, we do not know the target, only the range. So let's say the target's key is 199,999
Alrighty then, to be exact, when it comes to slapping me suddenly the secure random generator gives us 199,999? And when we are working with 6 digits then as an example use 14, 15 etc, suddenly we go high as 2^130 and compare the numbers? So why not scaling up all the values and use actual 2^130 range/keys? Though you forgot that I was asking if the stride idea could be tweaked to find a perfect stride or not. Even if the key is e.g, 189776, we could still divide the end range and subtract from our target by different subranges, like 200,000 - 189776 = 10224, we could then try subtracting the result from endrange/4, er/6, er/8 etc.
Nvm that, I don't know anything about math, I'm not even working actively on 130, my target is much bigger. Btw, Legends_Never_Die is my alter ego account, time for a paint job on trust wall.😉I know you are used to spitting out random things and some are like ooooohhhhh ahhhhhhhhh, but you seldom listen lol. You could be working in a 50 bit range or a 256 bit range; and you can subtract, divide, multiply, etc. whatever you want to do, or you can use whatever stride you can some up with, 14, 87, 1234344564, 47398573854734834, etc., it won't work because again, you could go around the curve and you won't know where the key lies or where to start your stride function from. There is truly only one way to take advantage of a stride function; and I stated that months ago. My problem was, I could not create a stride function inside of CUDA. Or else I would have found 130's key already lol.
|
|
|
|
Kamoheapohea
Jr. Member
Offline
Activity: 48
Merit: 12
|
|
October 18, 2023, 02:10:12 AM |
|
I know you are used to spitting out random things and some are like ooooohhhhh ahhhhhhhhh, but you seldom listen lol.
He is just having a good time. Writing everything that comes to his mind here and creating alt accounts etc for additional drama . Why not. How many keys/s do you need for your approach to work?
|
|
|
|
WanderingPhilospher
Sr. Member
Offline
Activity: 1232
Merit: 250
Shooters Shoot...
|
|
October 18, 2023, 02:36:05 AM |
|
I know you are used to spitting out random things and some are like ooooohhhhh ahhhhhhhhh, but you seldom listen lol.
He is just having a good time. Writing everything that comes to his mind here and creating alt accounts etc for additional drama . Why not. How many keys/s do you need for your approach to work? If we are talking speed, I have a program (a variation of BitCrack) that will get around 400 MKey/s (per GPU) but honestly, that is to slow. I would like to get around 1,200 MKey/s (per card, low end 30xx card) and multiple cards per instance.
|
|
|
|
Kamoheapohea
Jr. Member
Offline
Activity: 48
Merit: 12
|
|
October 18, 2023, 05:43:06 AM |
|
If we are talking speed, I have a program (a variation of BitCrack) that will get around 400 MKey/s (per GPU) but honestly, that is to slow. I would like to get around 1,200 MKey/s (per card, low end 30xx card) and multiple cards per instance.
Ok I can help you with coding if I think it works. I also modified BitCrack and solved some of the early puzzles with pubkey.
|
|
|
|
nomachine
Member
Offline
Activity: 503
Merit: 38
|
|
October 18, 2023, 06:51:01 AM |
|
My problem was, I could not create a stride function inside of CUDA. Or else I would have found 130's key already lol.
Is there a built-in "stride" function specifically in the CUDA kernel? Or maybe there is a workaround in a grid-stride loop? Or do we have to write a new kernel?
|
bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
|
|
|
lordfrs
Jr. Member
Offline
Activity: 57
Merit: 1
|
|
October 18, 2023, 08:42:03 AM |
|
You could be working in a 50 bit range or a 256 bit range; and you can subtract, divide, multiply, etc. whatever you want to do, or you can use whatever stride you can some up with, 14, 87, 1234344564, 47398573854734834, etc., it won't work because again, you could go around the curve and you won't know where the key lies or where to start your stride function from.
There is truly only one way to take advantage of a stride function; and I stated that months ago. My problem was, I could not create a stride function inside of CUDA. Or else I would have found 130's key already lol.
If you write the exact step code you want, there will be friends who will try to help. If you draw the algorithm flow diagram they can help you
|
If you want to buy me a coffee
Btc = 3246y1G9YjnQQNRUrVMnaeCFrymZRgJAP7
Doge = DGNd8UTi8jVTVZ2twhKydyqicynbsERMjs
|
|
|
rosengold
Jr. Member
Offline
Activity: 149
Merit: 7
|
|
October 18, 2023, 11:58:22 AM |
|
You could be working in a 50 bit range or a 256 bit range; and you can subtract, divide, multiply, etc. whatever you want to do, or you can use whatever stride you can some up with, 14, 87, 1234344564, 47398573854734834, etc., it won't work because again, you could go around the curve and you won't know where the key lies or where to start your stride function from.
There is truly only one way to take advantage of a stride function; and I stated that months ago. My problem was, I could not create a stride function inside of CUDA. Or else I would have found 130's key already lol.
If you write the exact step code you want, there will be friends who will try to help. If you draw the algorithm flow diagram they can help you I wrote my own brute-forcer that implements stride on CUDA. actually I'm running it 24/7 for #66. glad to see that people are focusing on new algos and scripts, I feel that someone is closer to solution.
|
|
|
|
mcdouglasx
Full Member
Offline
Activity: 366
Merit: 112
New ideas will be criticized and then admired.
|
|
October 18, 2023, 02:29:49 PM |
|
My problem was, I could not create a stride function inside of CUDA. Or else I would have found 130's key already lol.
Is there a built-in "stride" function specifically in the CUDA kernel? Or maybe there is a workaround in a grid-stride loop? Or do we have to write a new kernel? If you mean by “stride” jumps of 2-2 like 2,4,6, or jumps of any other number, you simply have to modify G by the pub that corresponds to the number of jumps you want, this does not affect the speed of the scalar multiplication, BSGS, etc.
|
BTC bc1qxs47ttydl8tmdv8vtygp7dy76lvayz3r6rdahu
|
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 900
🖤😏
|
|
October 18, 2023, 07:33:04 PM |
|
Warning, random spits ahead, watch out!😉
So, as I was spitting out some random thoughts coming to my mind and having fun with myself for no apparent reason, what if we reduce the size of our curve down to for example 2^130, then we would change G to something like e.g, 0x1, 0x2 of course with a much much smaller prime (P), would that somehow help us to compute much faster if the size of our points is considerably small? There is one small problem, how can we map secp256k1 points to a small size curve???
Stay tuned for more spits, I'm dry right now.🤣
|
🖤😏
|
|
|
nomachine
Member
Offline
Activity: 503
Merit: 38
|
|
October 19, 2023, 08:44:08 AM Last edit: October 19, 2023, 09:14:02 AM by nomachine |
|
how can we map secp256k1 points to a small size curve???
You already got an answer to the same question here https://bitcointalk.org/index.php?topic=5469636;wapYou still hope that someone will tell you precise method before they grab the prize for themselves ?
|
bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 900
🖤😏
|
|
October 19, 2023, 10:04:55 AM |
|
how can we map secp256k1 points to a small size curve???
You already got an answer to the same question here https://bitcointalk.org/index.php?topic=5469636;wapYou still hope that someone will tell you precise method before they grab the prize for themselves ? I think you got it backwards, I'm trying to level the playing field for everyone to have equal opportunity/ time. I'm the one trying to find the precise algorithm. Lets correct the sentences above: We are trying to level the playing field, and We are trying to find the precise algorithm to solve this puzzle. As long as everybody thinks like the first version of wording above, no results will be achieved, only by team work this can have a result in much less time than going solo. I suggest you to watch Jigsaw movies once again, the key to the *victims success was always working as a team.
In that topic, there is no mention of changing G to a smaller size G. Let me spit explain what I'm hallucinating talking about : Let's change p to this one : Now what I'm having a problem to find, is to shrink down secp256k1's G to be the same size while acting as before, meaning if the size is changed, multiplying the new G by 10 should give me a point similar/distinguishable from secp256k1's 0xa public key. If that is even possible and how much more speed we could gain by having a smaller G?
*OMG, are we really like the victims of jigsaw puzzle? Lol.
|
🖤😏
|
|
|
nomachine
Member
Offline
Activity: 503
Merit: 38
|
|
October 19, 2023, 11:09:52 AM Last edit: October 19, 2023, 09:12:15 PM by nomachine |
|
Why simplify the matter when it can be complicated. . And even more complicated... overcomplicated or so abstract that even the Satoshi doesn't know what we talking about. Let's start from the the fact that all puzzles are created from 32 zeros in bytes private_key_bytes = b'\x00' * 32 or 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\x00\x00\x00\x00\x00\x00\x00\x00' Puzzle 1 have 1 bytes on end that is not zero Puzzle 10 have 2 bytes on end that is not zero Puzzle 20 have 3 bytes on end that is not zero Puzzle 40 have 5 bytes on end that is not zero Puzzle 50 have 7 bytes on end that is not zero Puzzle 66 have 9 bytes on end that is not zero Even the random.randrange is unnecessary - you can directly spit bytes into zeros random_bytes = os.urandom(9) private_key_bytes = b'\x00' * 32 private_key_bytes = private_key_bytes[:-len(random_bytes)] + random_bytes signing_key = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1) compressed_public_key = signing_key.get_verifying_key().to_string("compressed") and so on.... p.s. Testing how fast this is using only OpenSSL in C++
|
bc1qdwnxr7s08xwelpjy3cc52rrxg63xsmagv50fa8
|
|
|
dred28
Newbie
Offline
Activity: 3
Merit: 0
|
|
October 20, 2023, 04:59:03 PM Last edit: October 20, 2023, 06:23:36 PM by dred28 |
|
I wrote a small script that takes about 1min to solve puzzle 15, but takes forever to solve 130 I want to share it here in case someone can see what I mean to archive, or tell me where i'm going wrong. this is supposed to reverse the bits (bits_num) used for double and add, or just double. But I'm stuck at getting an education guess of which one to pick. I tried calculating the slope but no success, have a look at 130 or try it with puzzle 15 which is very fast UPDATE: this script is meant to reverse double and add or just double with a known private key bit number (hence -> bits_num). With a recursion up to 2^bits_num (this this where i need help), and go all the way back until u get the "G-SPOT", generator point. If you get the g-point then you just have to compute the first digit, will be 0 or 1. At the moment it runs all possible bits until the "G-SPOT" is found then you have the pvt in binary. Rev means reverse here. so its my own implementation of reverse for double and add, sub function reveses the point addition, 'Subtract; from bit import Key import ecdsa import binascii from ecdsa.curves import SECP256k1 import threading
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
curve = ecdsa.SECP256k1.curve results = []
def add(P1, P2): x1, y1 = P1 x2, y2 = P2
if P1 == P2: lam = (3 * x1 * x1) * pow(2 * y1, -1, p) else: lam = (y2 - y1) * pow(x2 - x1, -1, p)
x3 = (lam * lam - x1 - x2) % p y3 = (lam * (x1 - x3) - y1) % p
return (x3, y3)
def dbl(K): x,y = K P = ecdsa.ellipticcurve.Point(curve, x, y) k_dbl = 2 * P return (k_dbl.x(),k_dbl.y())
def mul(k,P): x,y = P point = ecdsa.ellipticcurve.Point(curve, x,y) r_p = point * k return (r_p.x(),r_p.y())
def revDbl(K,n): return mul((n+1)//2,K)
def sub(K,G,n): neg_G = (G[0], -G[1]) sub_K = add(K,neg_G)
return sub_K
def unCmp(pub): cmp_pub = binascii.unhexlify(pub) cmp_vk = ecdsa.VerifyingKey.from_string(cmp_pub, curve=ecdsa.SECP256k1) uncmp_pub = cmp_vk.to_string(encoding="uncompressed") uncmp_pub_hex = binascii.hexlify(uncmp_pub).decode('utf-8') uncmp_pub_hex = uncmp_pub_hex[2:] x = int(uncmp_pub_hex[:64],16) y = int(uncmp_pub_hex[64:],16) return (x,y)
def is_point_on_curve(point): x, y = point lhs = (y * y) % p rhs = (x * x * x + 7) % p return lhs == rhs
def runRev(K, bin_str, bits_num): hx = 0 if len(bin_str) != 0: hx = hex(int(bin_str,2))
print(len(bin_str), bin_str, hx, sep="\t") global results if len(results) > 0: return else: if len(bin_str) <= bits_num: # Rev DBL + ADD r_sub = sub(K,G,n) da_k = revDbl(r_sub,n) da_bin_str = "1" + bin_str if da_k == G: print("KEY FOUND", hx) results.append(da_bin_str) return elif is_point_on_curve(da_k): runRev(da_k, da_bin_str,bits_num) else: print("NOT ON CURVE")
# Rev DBL d_k = revDbl(K,n) d_bin_str = "0"+bin_str if d_k == G: results.append(d_bin_str) return elif is_point_on_curve(d_k): runRev(d_k, d_bin_str,bits_num) else: print("NOT ON CURVE") else: return
def main(): global results pub = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852" K = unCmp(pub)
bits_num = 130 bin_str = '' runRev(K, bin_str, bits_num) if len(results) > 0: print("KEY FOUND",results)
if __name__ == "__main__": main()
|
|
|
|
digaran
Copper Member
Hero Member
Offline
Activity: 1330
Merit: 900
🖤😏
|
|
October 20, 2023, 05:24:35 PM |
|
I wrote a small script that takes about 1min to solve puzzle 15, but takes forever to solve 130 I want to share it here in case someone can see what I mean to archive, or tell me where i'm going wrong. this is supposed to reverse the bits (bits_num) used for double and add, or just double. But I'm stuck at getting an education guess of which one to pick. I tried calculating the slope but no success, have a look at 130 or try it with puzzle 15 which is very fast from bit import Key import ecdsa import binascii from ecdsa.curves import SECP256k1 import threading
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)
curve = ecdsa.SECP256k1.curve results = []
def add(P1, P2): x1, y1 = P1 x2, y2 = P2
if P1 == P2: lam = (3 * x1 * x1) * pow(2 * y1, -1, p) else: lam = (y2 - y1) * pow(x2 - x1, -1, p)
x3 = (lam * lam - x1 - x2) % p y3 = (lam * (x1 - x3) - y1) % p
return (x3, y3)
def dbl(K): x,y = K P = ecdsa.ellipticcurve.Point(curve, x, y) k_dbl = 2 * P return (k_dbl.x(),k_dbl.y())
def mul(k,P): x,y = P point = ecdsa.ellipticcurve.Point(curve, x,y) r_p = point * k return (r_p.x(),r_p.y())
def revDbl(K,n): return mul((n+1)//2,K)
def sub(K,G,n): neg_G = (G[0], -G[1]) sub_K = add(K,neg_G)
return sub_K
def unCmp(pub): cmp_pub = binascii.unhexlify(pub) cmp_vk = ecdsa.VerifyingKey.from_string(cmp_pub, curve=ecdsa.SECP256k1) uncmp_pub = cmp_vk.to_string(encoding="uncompressed") uncmp_pub_hex = binascii.hexlify(uncmp_pub).decode('utf-8') uncmp_pub_hex = uncmp_pub_hex[2:] x = int(uncmp_pub_hex[:64],16) y = int(uncmp_pub_hex[64:],16) return (x,y)
def is_point_on_curve(point): x, y = point lhs = (y * y) % p rhs = (x * x * x + 7) % p return lhs == rhs
def runRev(K, bin_str, bits_num): hx = 0 if len(bin_str) != 0: hx = hex(int(bin_str,2))
print(len(bin_str), bin_str, hx, sep="\t") global results if len(results) > 0: return else: if len(bin_str) <= bits_num: # Rev DBL + ADD r_sub = sub(K,G,n) da_k = revDbl(r_sub,n) da_bin_str = "1" + bin_str if da_k == G: print("KEY FOUND", hx) results.append(da_bin_str) return elif is_point_on_curve(da_k): runRev(da_k, da_bin_str,bits_num) else: print("NOT ON CURVE")
# Rev DBL d_k = revDbl(K,n) d_bin_str = "0"+bin_str if d_k == G: results.append(d_bin_str) return elif is_point_on_curve(d_k): runRev(d_k, d_bin_str,bits_num) else: print("NOT ON CURVE") else: return
def main(): global results pub = "03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852" K = unCmp(pub)
bits_num = 130 bin_str = '' runRev(K, bin_str, bits_num) if len(results) > 0: print("KEY FOUND",results)
if __name__ == "__main__": main()
Can you explain the logic? I am not familiar with bit_num and rev dbl. Solving puzzle 15 in 1 minute is extremely slow. By working with standard secp256k1 parameters you won't get anywhere, what you need to do is finding a method to convert secp256k1 points to new points with a much smaller size, then you can have 1000 times more speed. Currently I can generate 1m keys in 20 seconds with my primitive and simple native implementation on an old android phone. So 26867 which is the decimal for #15, would take me half a second to solve.
Welcome! Don't be shy, come on in, mi woods su woods.😉
|
🖤😏
|
|
|
|