Author

Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it - page 153. (Read 230098 times)

copper member
Activity: 1330
Merit: 899
🖤😏

Why are you using base58 encode, rmd160 checksum? You don't need any of them, just input rmd160 as your targets and stop the process at rmd160, once you generate the rmd160 don't do anything else with it other than comparing them with targets.  Remember, from rmd160 to address there are 2 sha256 hashing and 1 base58 encoding, both are heavy. Get rid of them.

Hello, can you help me add a stride for the GPU? KeyHunt-Cuda

Do you want to recompile it yourself? You'd need to change the generator point or to make it easier add an option to manually input G, then you can use the public key of e.g, 237, if you want to have a stride jump of 237 at every step.
member
Activity: 499
Merit: 38
Code:
print("Glass sound (indicating script completion)")
subprocess.run(["afplay", "/System/Library/Sounds/glass.aiff"])

You will have a heart attack if this sound is activated, even by mistake  Grin
newbie
Activity: 17
Merit: 0
I wrote a simple python script that only uses the range from puzzle 66 (2000...-2ffff) to search for puzzles 67,68,69,71 all at once. i can also adjust the big step.. its a cool script i can also try each number combination by the quadrillions. anything I should add? feel free to try your luck! at current BTC price, I am searching for $995,000 on this 1 hex range: 20000000000000000 - 2ffffffffffffffff  Grin




Code:
import subprocess
import time
import os
from decimal import Decimal
import base58
import hashlib
import ecdsa

# Function to clear the terminal screen
def clear_terminal():
    subprocess.call('clear', shell=True)

# Function to convert a decimal number to a compressed Bitcoin address
def decimal_to_compressed_address(decimal_number):
    private_key = int(decimal_number).to_bytes(32, byteorder='big')
    signing_key = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
    verifying_key = signing_key.verifying_key
    compressed_public_key = verifying_key.to_string("compressed")
    hashed_string = hashlib.sha256(compressed_public_key).digest()
    ripemd_string = hashlib.new('ripemd160', hashed_string).digest()
    ripemd_string = b'\x00' + ripemd_string
    hashed_string = hashlib.sha256(ripemd_string).digest()
    hashed_string = hashlib.sha256(hashed_string).digest()
    checksum = hashed_string[:4]
    address = ripemd_string + checksum
    base58_address = base58.b58encode(address)
    return base58_address.decode()

# Function to convert a decimal number to a private key in hexadecimal format
def decimal_to_private_key_hex(decimal_number):
    private_key_bytes = int(decimal_number).to_bytes(32, byteorder='big')
    private_key_hex = private_key_bytes.hex()
    private_key_hex_flipped = private_key_hex.replace('2', '3', 2)
    return private_key_hex, private_key_hex_flipped

# Function to check if a target address is found
def check_target_address(address, decimal_number, private_key_hex):
    if address in target_addresses:
        target_addresses_found.append(address)
        print(f"Target address found: {address}")
        print(f"Decimal Number: {decimal_number}")
        print(f"Private Key Hex: {private_key_hex}")

        # Write the found address to the file add to found addresses.txt
        with open("found_addresses.txt", "a") as found_file:
            found_file.write(f"Target address found: {address}\n")
            found_file.write(f"Decimal Number: {decimal_number}\n")
            found_file.write(f"Private Key Hex: {private_key_hex}\n\n")
            found_file.flush()  # Flush the buffer to ensure data is written immediately

        return True
    return False

# List of target Bitcoin addresses to search for
target_addresses = ['13zb1hQbWVsc2S7ZTZnP2G4undNNpdh5so', '1BY8GQbnueYofwSuFAT3USAhGjPrkxDdW9', '1MVDYgVaSN6iKKEsbzRUAYFrYJadLYZvvZ', '19vkiEajfhuZ8bs8Zu2jgmC6oqZbWqhxhG', '1PWo3JeB9jrGwfHDNpdGK54CRas7fsVzXU']

# List of additional hex numbers to modify the decimal number
additional_hex_numbers = ['3','4','5','6','7','8', '9', 'a', 'b', 'c', 'd', 'e', 'f','10','11','12','13','14','15','16','17','18','19','1a', '1b', '1c','1d', '1e', '1f'
,'40','41','42','43','44','45','46','47','48','49','4a', '4b', '4c','4d', '4e', '4f' ,'50','51','52','53','54','55','56','57','58','59','5a', '5b', '5c','5d', '5e', '5f' ,'60','61','62','63','64','65','66','67','68','69','6a', '6b', '6c','6d', '6e', '6f' ,'70','71','72','73','74','75','76','77','78','79','7a', '7b', '7c','7d', '7e', '7f' ]

# Define the lower and upper bounds for the decimal number search range
lower_bound = Decimal('37000000000000000000')
upper_bound = Decimal('55340232221128654832')

target_addresses_found = []

# Initialize time and iteration tracking variables
start_time = time.time()
total_iterations = 0

# Function to search for target addresses within a specified range
def search_decimal_range(decimal_number, upper_bound):
    global total_iterations  # Use the global variable
    iterations = 0
    update_interval = 1
    step_size = 100000000000000  # Initial step size

    while decimal_number <= upper_bound:
        compressed_address = decimal_to_compressed_address(decimal_number)
        private_key_hex, flipped_private_key_hex = decimal_to_private_key_hex(decimal_number)

        if check_target_address(compressed_address, decimal_number, private_key_hex):
            return True  # Stop the loop if a match is found

        found_match = False

        additional_addresses = []
        for hex_number in additional_hex_numbers:
            modified_decimal_number = int(hex(int(decimal_number))[2:].replace('2', hex_number, 1), 16)
            modified_compressed_address = decimal_to_compressed_address(modified_decimal_number)
            additional_addresses.append(modified_compressed_address)

            if check_target_address(modified_compressed_address, modified_decimal_number, private_key_hex):
                found_match = True
                break

        if found_match:
            return True

        if len(target_addresses_found) == len(target_addresses):
            return True

        if iterations % update_interval == 0:
            elapsed_time = time.time() - start_time
            iterations_per_second = iterations / elapsed_time
            print(f"Reached {iterations} iterations.")
            print(f"Elapsed Time: {elapsed_time:.2f} seconds")
            print(f"Iterations per Second: {iterations_per_second:.2f}")
            print(f"Decimal Number: {decimal_number}")
            print(f"Compressed Bitcoin Address: {compressed_address}")
            print(f"Private Key Hex: {private_key_hex}")
            if target_addresses_found:
                print_addresses_side_by_side(target_addresses_found[-1], decimal_number, private_key_hex, additional_addresses)
            print("\n")

        if iterations % 100000 == 0:
            clear_terminal()

        decimal_number += step_size  # Increase the decimal number by the current step size
        iterations += 1

        # Adjust the step size dynamically based on the search space
        if iterations % 1000 == 0:
            step_size *= 2  # Double the step size every 1 million iterations

# Function to print the target address and additional addresses side by side
def print_addresses_side_by_side(target_address, decimal_number, private_key_hex, additional_addresses):
    print(f"Decimal Number: {decimal_number}")
    print(f"Target Address: {target_address}")
    print(f"Private Key Hex: {private_key_hex}")
    for i, address in enumerate(additional_addresses):
        print(f" ({additional_hex_numbers[i]}): {address}")
    print("\n")

# Function to continuously search for target addresses in the specified range
def continuous_search(lower_bound, upper_bound):
    global total_iterations, start_time  # Use the global variables
    current_decimal = lower_bound

    while True:
        elapsed_time = time.time() - start_time
        total_iterations += 1

        if search_decimal_range(current_decimal, upper_bound):
            print("All target addresses found. Restarting search...")
            time.sleep(0)  # Optional: Add a delay before restarting the search
            current_decimal = lower_bound  # Reset the current_decimal to the lower_bound
        else:
            current_decimal += 1  # Increment by 1

# Start the continuous search
while True:
    continuous_search(lower_bound, upper_bound)

# Add sound notification when the script completes
print("Glass sound (indicating script completion)")
subprocess.run(["afplay", "/System/Library/Sounds/glass.aiff"])
newbie
Activity: 26
Merit: 0
Hello, can you help me add a stride for the GPU? KeyHunt-Cuda
member
Activity: 499
Merit: 38

"G-SPOT"

Good luck with that, I think that's the million dollar question every man asks at least once in his life, "where is the G-spot". Why do I feel we are talking about vagina instead of curve. 😅
You can check my thread on project development, you will find ground breaking ultimate hack scripts. Look for point torsion script, maybe that's what you are looking for.

“Ground breaking” 😁

rarely laughed so hard, just ridiculous - you guys make my day  Grin Grin Grin Grin


Currently I can generate 1m keys in 20 seconds

TO Back on topic....

I made a new script in C++ based on my last post ...

https://bitcointalksearch.org/topic/m.63020009


I'm too slow and lazy to make a CUDA GPU version.
Version is still a beta version for testing, there are a lot of things that can be fail or improve.
This is the first time I am dealing with this part of OpenSSL .
I'm still learning what can be done with this swiss army knife.


Install the OpenSSL development package:
Code:
sudo apt install libssl-dev


Code:
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

// Function to convert a byte vector to a hexadecimal string
std::string bytesToHex(const std::vector& bytes) {
    std::stringstream ss;
    for (unsigned char byte : bytes) {
        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast(byte);
    }
    return ss.str();
}

// Function to calculate the RIPEMD160 hash of a byte vector
std::vector calculateRIPEMD160(const std::vector& data) {
    std::vector hash(RIPEMD160_DIGEST_LENGTH);
    RIPEMD160(data.data(), data.size(), hash.data());
    return hash;
}

int main() {
    // Initialize the OpenSSL library
    if (OpenSSL_add_all_algorithms() != 1) {
        std::cerr << "OpenSSL initialization failed." << std::endl;
        return 1;
    }

    // Set the target Hash160 value (replace with your target hash)
    std::string target_hash160_hex = "fe7c45126731f7384640b0b0045fd40bac72e2a2";

    int puzzle = 15;   // The puzzle number (Bits)

    // Clear the console
    std::system("clear");
    std::cout << "\r\033[01;33m[+] Bytea HASH160 Search by NoMachine" << "\n";
    time_t currentTime = std::time(nullptr);
    std::cout << "\r\033[01;33m[+] " << std::ctime(¤tTime) << "\r";
    std::cout << "\r\033[01;33m[+] Puzzle: " << puzzle << "\033[0m" << std::endl;
    std::cout.flush();

    // Calculate the maximum bytes value based on the puzzle
    BIGNUM* limit_int = BN_new();
    BN_set_word(limit_int, 1);
    BN_lshift(limit_int, limit_int, puzzle);
    BN_sub_word(limit_int, 1);
    int max_bytes = (BN_num_bits(limit_int) + 7) / 8;

    // Create an EC_KEY object
    EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);

    // Calculate the SHA-256 hash of the public key
    unsigned char sha256_result[SHA256_DIGEST_LENGTH];

    // Calculate the RIPEMD160 hash of the SHA-256 hash
    std::vector ripemd160_result(RIPEMD160_DIGEST_LENGTH);

    while (true) {
        // Create a 32-byte private key with 32 zeros followed by random bytes
        std::vector private_key_bytes(32, 0);

        // Generate random bytes for the remaining part of the private key
        std::vector random_bytes(max_bytes);
        if (RAND_bytes(random_bytes.data(), random_bytes.size()) != 1) {
            std::cerr << "Error generating random bytes." << std::endl;
            BN_free(limit_int);
            EC_KEY_free(ec_key);
            return 1;
        }

        // Append the random bytes to the private key
        std::copy(random_bytes.begin(), random_bytes.end(), private_key_bytes.begin() + 32 - max_bytes);

        // Create a BIGNUM from the private key bytes
        BIGNUM* bn_private_key = BN_bin2bn(private_key_bytes.data(), private_key_bytes.size(), NULL);

        // Set the private key in the EC_KEY object
        EC_KEY_set_private_key(ec_key, bn_private_key);

        // Compute the public key from the private key
        EC_POINT* public_key_point = EC_POINT_new(EC_KEY_get0_group(ec_key));
        EC_POINT_mul(EC_KEY_get0_group(ec_key), public_key_point, bn_private_key, NULL, NULL, NULL);

        // Convert the public key point to binary representation (compressed)
        size_t public_key_length = EC_POINT_point2oct(EC_KEY_get0_group(ec_key), public_key_point, POINT_CONVERSION_COMPRESSED, NULL, 0, NULL);
        std::vector public_key_bytes(public_key_length);
        EC_POINT_point2oct(EC_KEY_get0_group(ec_key), public_key_point, POINT_CONVERSION_COMPRESSED, public_key_bytes.data(), public_key_length, NULL);

        SHA256(public_key_bytes.data(), public_key_bytes.size(), sha256_result);
        ripemd160_result = calculateRIPEMD160(std::vector(sha256_result, sha256_result + SHA256_DIGEST_LENGTH));

        // Convert the calculated RIPEMD160 hash to a hexadecimal string
        std::string calculated_hash160_hex = bytesToHex(ripemd160_result);

        // Display the generated public key hash (Hash160) and private key
        std::string message = "\r\033[01;33m[+] Public Key Hash (Hash 160): " + calculated_hash160_hex;
        std::cout << message << "\e[?25l";
        std::cout.flush();

        // Check if the generated public key hash matches the target
        if (calculated_hash160_hex == target_hash160_hex) {
            // Get the current time
            std::time_t currentTime;
            std::time(¤tTime);
            std::tm tmStruct = *std::localtime(¤tTime);

            // Format the current time into a human-readable string
            std::stringstream timeStringStream;
            timeStringStream << std::put_time(&tmStruct, "%Y-%m-%d %H:%M:%S");
            std::string formattedTime = timeStringStream.str();

            std::cout << "\n\033[32m[+] PUZZLE SOLVED: " << formattedTime << "\033[0m" << std::endl;
            std::cout << "\r\033[32m[+] Target Public Key Hash (Hash160) found! Private Key: " << bytesToHex(private_key_bytes) << std::endl;

            // Append the private key information to a file if it matches
            std::ofstream file("KEYFOUNDKEYFOUND.txt", std::ios::app);
            if (file.is_open()) {
                file << "\nPUZZLE SOLVED " << formattedTime;
                file << "\nPrivate Key (hex): " << bytesToHex(private_key_bytes);
                file << "\n--------------------------------------------------------------------------------------------------------------------------------------------";
                file.close();
            }

            break;
        }
    }

    // Free the EC_KEY and BIGNUM objects
    BN_free(limit_int);
    EC_KEY_free(ec_key);

    return 0;
}


  • Bytea HASH160 Search by NoMachine
  • Sat Oct 21 10:39:23 2023
  • Puzzle: 15
  • Public Key Hash (Hash 160): fe7c45126731f7384640b0b0045fd40bac72e2a2
  • PUZZLE SOLVED: 2023-10-21 10:39:24
  • Target Public Key Hash (Hash160) found! Private Key: 00000000000000000000000000000000000000000000000000000000000068f3



It will solve Puzzle 15 for second on HASH 160 as target,


Compile
Code:
g++ -o puzzle puzzle.cpp -lssl -lcrypto -m64 -mssse3 -O3

Code:
./puzzle

p.s.
The Kangaroo Twins algorithm can be incorporated into the same based script for target_public_key_hex .  Grin
full member
Activity: 1162
Merit: 237
Shooters Shoot...

"G-SPOT"

Good luck with that, I think that's the million dollar question every man asks at least once in his life, "where is the G-spot". Why do I feel we are talking about vagina instead of curve. 😅
You can check my thread on project development, you will find ground breaking ultimate hack scripts. Look for point torsion script, maybe that's what you are looking for.

“Ground breaking” 😁
copper member
Activity: 1330
Merit: 899
🖤😏

"G-SPOT"

Good luck with that, I think that's the million dollar question every man asks at least once in his life, "where is the G-spot". Why do I feel we are talking about vagina instead of curve. 😅
You can check my thread on project development, you will find ground breaking ultimate hack scripts. Look for point torsion script, maybe that's what you are looking for.
newbie
Activity: 3
Merit: 0
sorry about the quotes, I will be here more often to learn. I have a very slow machine with 2 cores. Even 15 is slow for me. My goal is to get a script that is fast for the slowest machine , just like how fast the derivation of double and add function for public key
hero member
Activity: 862
Merit: 662
I just added an update to explain my script since it has no commenting and strange variable names.

Hi, Welcome!! It is nice to see more developers in this posts.

You don't need to quote all the previous text just to reply a single line, just quote those parts that are interesting.

BTW as digaran said before puzzle 15 in 1 minute is very slow. But i remember when i start to code for this I also start with such low speed, so as a starting  point that is OK.

Any doubt just ask.

newbie
Activity: 3
Merit: 0
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

Code:
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.😉
I just added an update to explain my script since it has no commenting and strange variable names.
copper member
Activity: 1330
Merit: 899
🖤😏
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

Code:
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.😉
newbie
Activity: 3
Merit: 0
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;

Code:
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()


member
Activity: 499
Merit: 38
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
Code:
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++
copper member
Activity: 1330
Merit: 899
🖤😏
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;wap

You still hope that someone will tell you precise method before they grab the prize for themselves ?  Grin
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 :
Code:
0xcdf15ce5b341762d
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.
member
Activity: 499
Merit: 38
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;wap

You still hope that someone will tell you precise method before they grab the prize for themselves ?  Grin
copper member
Activity: 1330
Merit: 899
🖤😏
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.🤣
member
Activity: 499
Merit: 38
If you mean by “stride” jumps of 2-2 like 2,4,6.........

Nope....
About CUDA Programming
https://www.math.wsu.edu/math/kcooper/CUDA/c09Shuffle.php
https://nanxiao.gitbooks.io/cuda-little-book/content/posts/grid-stride-loops.html


How do you imagine that he can achieve 1,200 MKey/s per card if he doesn't hack CUDA itself ?
member
Activity: 239
Merit: 53
New ideas will be criticized and then admired.
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? Smiley

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.
jr. member
Activity: 149
Merit: 7

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.
jr. member
Activity: 56
Merit: 1

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
Jump to: