Bitcoin Forum
May 25, 2024, 09:57:12 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 ... 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 [252] 253 254 255 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 188319 times)
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 08, 2024, 12:25:45 PM
 #5021

Experiments with your python codes on rust language


You have here my full Puzzle sctipt in Rust:
https://bitcointalk.org/index.php?topic=1306983.msg63539973#msg63539973
It's very fast. Same as C++
But when you put Puzzle 66 and above as a test, everything is slow. Without a public key, I can only scratch my head.

ahahah soo hilarious.

Try test with custom script address build then, it's faster.
private key > Compresssed public key > custom script > address format.

i try that method it's faster enough.

I would like someone to make a Pollard's kangaroo for SECPK1 in Rust. Maybe it could work faster, Rust programs also optimize quite well, sometimes better than C. Enforces thread-safety of all code and data, even in 3rd party libraries.
It has incredible possibilities for compiling. I was able to run this on an ARM processor as well on Amd Zen 2, 3 and 4

 on almost everything.....on potatoe  Grin

https://doc.rust-lang.org/rustc/platform-support.html


It's a pity that I don't have more time to deal with this.
kTimesG
Jr. Member
*
Offline Offline

Activity: 56
Merit: 6


View Profile
May 08, 2024, 01:18:48 PM
Last edit: May 08, 2024, 01:36:40 PM by kTimesG
 #5022

Result
0x1A96CA8D8 | 82762283.93 keys/s
Generated number (decimal): 7137437912


single thread, M2 Proc.
Here's the ultimate private key cracking tool.
Code:
int main() {
   const uint64_t minRange = 0x100000000;
   const uint64_t maxRange = 0x1ffffffff;
   const uint64_t magic_number = 0x1a96ca8d8 - minRange;
   uint64_t max = maxRange - minRange + 1;      // range size
   uint64_t speed;
   uint64_t count = 0;

   struct timespec start, ticks;
   clock_gettime(CLOCK_MONOTONIC, &start);

   while (max--) {
        if (count == magic_number) {
            printf("Generated number: %16llx\n", count + minRange);
//            break;
        }

        ++count;
    }

    clock_gettime(CLOCK_MONOTONIC, &ticks);
    uint64_t ns = (ticks.tv_sec - start.tv_sec) * 1000000000ULL + ticks.tv_nsec - start.tv_nsec;
    // avoid 64-bit overflow
    speed = count * 1000000ULL / (ns / 1000);
    printf("Ops: %llu speed: %llu ops/s\n", count, speed);

    return 0;
}


Generated number:        1a96ca8d8
Ops: 4294967296 speed: 3099732241 ops/s


Apple M1, single thread.

I would like someone to make a Pollard's kangaroo for SECPK1 in Rust. Maybe it could work faster, Rust programs also optimize quite well, sometimes better than C. Enforces thread-safety of all code and data, even in 3rd party libraries.
It has incredible possibilities for compiling. I was able to run this on an ARM processor as well on Amd Zen 2, 3 and 4

We're bounded by secp256k1 field operations, it can't work faster than what a CPU is capable of. I made a kangaroo in plain C, and the bottleneck is the EC point addition, I can't squeeze out more than 852.000 affine point additions per second (the only speed up would be some assembler code). If someone finds a magical way to find an scale-invariant hash of a Jacobian point it would run 10x faster though. Otherwise we're stuck with having to compute a modular inverse at every kangaroo jump, and no programming language can save you from this limitation.
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 08, 2024, 01:52:55 PM
Last edit: May 08, 2024, 04:00:01 PM by nomachine
 #5023

I can't squeeze out more than 852.000 affine point additions per second


I have 249457 hops per second in python  converting this script with cpython into .so

Code:
import time
import os
import sys
import random
import secp256k1 as ice
import gmpy2

if os.name == 'nt':
    os.system('cls')
else:
    os.system('clear')
t = time.ctime()
sys.stdout.write(f"\033[?25l")
sys.stdout.write(f"\033[01;33m[+] Kangaroo: {t}\n")
sys.stdout.flush()

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 = gmpy2.mpz(x)
        self.y = gmpy2.mpz(y)

PG = Point(Gx, Gy)
Z = Point(0, 0)  # zero-point, infinite in real x, y - plane

def add(P, Q, p=modulo):
    if P == Z:
        return Q
    elif Q == Z:
        return P
    elif P.x == Q.x and (P.y != Q.y or P.y == 0):
        return Z
    elif P.x == Q.x:
        m = (3 * P.x * P.x) * gmpy2.invert(2 * P.y, p) % p
    else:
        m = (Q.y - P.y) * gmpy2.invert(Q.x - P.x, p) % p
  
    x = (m * m - P.x - Q.x) % p
    y = (m * (P.x - x) - P.y) % p
    return Point(x, y)

def mul2(P, p=modulo):
    if P == Z:
        return Z
    m = gmpy2.f_mod(3 * P.x * P.x * gmpy2.invert(2 * P.y, p), p)
    x = gmpy2.f_mod(m * m - 2 * P.x, p)
    y = gmpy2.f_mod(m * (P.x - x) - P.y, p)
    return Point(x, y)

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), p)

def X2Y(X, y_parity, p=modulo):
    X_cubed = gmpy2.powmod(X, 3, p)
    X_squared = gmpy2.powmod(X, 2, p)
    tmp = gmpy2.f_mod(X_cubed + 7, p)
    Y = gmpy2.powmod(tmp, gmpy2.f_div(gmpy2.add(p, 1), 4), p)
    if y_parity == 1:
        Y = gmpy2.f_mod(-Y, p)
    return Y


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)))
        HEX = "%064x" % abs(Ak[sol_kt] - Bk[sol_kw])
        dec = int(HEX, 16)
        wifc = ice.btc_pvk_to_wif(HEX)
        wifu = ice.btc_pvk_to_wif(HEX, False)
        caddr = ice.privatekey_to_address(0, True, dec)
        uaddr = ice.privatekey_to_address(0, False, dec)
        total_time = time.time() - starttime
        print('\n[+] total time: %.2f sec' % (total_time))
        t = time.ctime()
        print(f"\033[32m[+] PUZZLE SOLVED: {t} \033[0m")
        print(f"\033[32m[+] Private key (wif) Compressed : {wifc} \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(f"\nRandom seed: {seed}")
            file.write("\nPrivate Key (decimal): " + str(dec))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write("\nPrivate key (wif) Compressed : " + wifc)
            file.write("\nPrivate key (wif) Uncompressed: " + wifu)
            file.write("\nBitcoin address Compressed: " + caddr)
            file.write("\nBitcoin address Uncompressed: " + uaddr)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------------\n"
            )
        file.close()
        return True
    else:
        return False

def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    if P.x % DP_rarity == 0:
        A.append(gmpy2.mpz(P.x))
        Ak.append(gmpy2.mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Generate a list of powers of two for faster access

def generate_powers_of_two(hop_modulo):
    return [gmpy2.mpz(1 << pw) for pw in range(hop_modulo)]

def search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two):
    solved = False
    t = [gmpy2.mpz(lower_range_limit + gmpy2.mpz(random.randint(0, upper_range_limit - lower_range_limit))) for _ in range(Nt)]
    T = [mulk(ti) for ti in t]
    dt = [gmpy2.mpz(0) for _ in range(Nt)]
    w = [gmpy2.mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nw)]
    W = [add(W0, mulk(wk)) for wk in w]
    dw = [gmpy2.mpz(0) for _ in range(Nw)]
    print('[+] tame and wild herds are prepared')
    Hops, Hops_old = 0, 0
    t0 = time.time()  
    while not solved:
        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: break
            t[k] += dt[k]
            T[k] = add(P[int(pw)], T[k])
        if solved: break
        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: break
            w[k] += dw[k]
            W[k] = add(P[int(pw)], W[k])
        if solved: break
        t1 = time.time()
        if (t1 - t0) > 5:
            print('\r[+] Hops: %.0f h/s' % ((Hops - Hops_old) / (t1 - t0)), end='', flush=True)
            t0 = t1
            Hops_old = Hops
    print('[+] Hops:', Hops)
    return 'sol. time: %.2f sec' % (time.time() - starttime)

puzzles = [\
    ('0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69',32),\
    ('03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4',40),\
    ('025e466e97ed0e7910d3d90ceb0332df48ddf67d456b9e7303b50a3d89de357336',44),\
    ('026ecabd2d22fdb737be21975ce9a694e108eb94f3649c586cc7461c8abf5da71a',45),\
    ('03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6',50),\
    ('0230210c23b1a047bc9bdbb13448e67deddc108946de6de639bcc75d47c0216b1b',65),\
    ('03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852',130)]

puzzle = 40
for elem in puzzles:
    s, n = elem
    if puzzle == n: break

kangaroo_power = 4
DP_rarity = 1 << int(((puzzle -  2*kangaroo_power)/2 - 2))
hop_modulo = ((puzzle - 1) // 2) + kangaroo_power
Nt = Nw = 2**kangaroo_power

X = gmpy2.mpz(s[2:66], 16)
Y = X2Y(X, gmpy2.mpz(s[:2]) - 2)

W0 = Point(X,Y)
starttime = oldtime = time.time()
search_range = 2**(puzzle-1)

lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1

print(f"[+] [Puzzle]: {puzzle}")
print(f"[+] [Lower range limit]: {lower_range_limit}")
print(f"[+] [Upper range limit]: {upper_range_limit}")

# Precompute powers of two for faster access
powers_of_two = generate_powers_of_two(hop_modulo)

# Initialize variables
T, t, dt = [], [], []
W, w, dw = [], [], []

#Random seed Config
seed = os.urandom(9)
print(f"[+] [Random seed]: {seed}")
random.seed(seed)

Hops = 0
N_tests = 1

P = [PG]
for k in range(255): P.append(mul2(P[k]))  
print('[+] P-table prepared')

for k in range(N_tests):
    solved = False
    search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two)

print('[+] Average time to solve: %.2f sec' % ((time.time()-starttime)/N_tests))

It normally goes to 207301 h/s

Imagine this in Rust, how fast would it go? Grin


u128
const uint64_t
uint64 in C & u128 in Rust not work for Puzzle 130 (try to deal with dinosaur numbers)

BigUint/BIGINT from SSL works or GMP can be used Wink
kTimesG
Jr. Member
*
Offline Offline

Activity: 56
Merit: 6


View Profile
May 08, 2024, 03:57:47 PM
 #5024

I can't squeeze out more than 852.000 affine point additions per second

I have 249457 hops per second in python  converting this script with cpython into .so

Imagine this in Rust, how fast would it go? Grin
No idea, but I can tell you how fast it would go in C using the GMP routines, as I benchmarked a lot of tweaks and misc. formulas.

Close to 690k jumps /s, in-place point addition, no reallocs - this with using lowest level mpn_* routines (assembler optimized).
Around 638k jumps/s with the mpz_* routines.

Compare this to using the routines in libsecp256k1 field_impl.h and same formula steps:
affine + affine: 852k jumps/s (1 inversion, 2 multiplications, 1 squaring)

libsecp256k1 jacobian + affine addition -> jacobian result:
7.5M jumps/s (8M 3S) - removed safety checks since no point is the infinity and neither can be the result)
But... non-deterministic, I struggled for weeks to find a way to use a J point represented in multiple different ways to produce a stable hash, even a single one bit 50% probability hash as a base for deterministic jump). Seems we can only compare two J points for equality or non-equality, comparison result can vary its sign due to Z scaling.

It doesn't matter what Rust compiles down to, it can never ever generate machine code that runs faster than what the lowest level assembler routines can handle.

So we either need lots of threads (GPU) or some special hardware to speed things up. Sad
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 08, 2024, 04:03:33 PM
Last edit: May 08, 2024, 04:27:26 PM by nomachine
 #5025

The problem is what are you going to use for the dinosaur numbers above Puzzle 128. I wrote above additionally. These test scripts will not work configured like this with Puzzle 130.

This will work whatever number you insert - use gmp.h
Code:
#include <iostream>
#include <gmp.h>
#include <gmpxx.h>
#include <cstdlib>
#include <ctime>
#include <iomanip>

int main() {
    mpz_class min_range("18446744073709551615");
    mpz_class max_range("36893488147419103231");
    mpz_class counter = 0;
    mpz_class dec;
    gmp_randstate_t state;

    gmp_randinit_default(state);
    std::time_t start_time = std::time(nullptr);
    double total_time = 0;

    mpz_t range;
    mpz_sub(range, max_range.get_mpz_t(), min_range.get_mpz_t());

    while (true) {
        mpz_urandomm(dec.get_mpz_t(), state, range);
        mpz_add(dec.get_mpz_t(), dec.get_mpz_t(), min_range.get_mpz_t());
        counter++;

        std::time_t current_time = std::time(nullptr);
        double elapsed_time = difftime(current_time, start_time);

        if (elapsed_time > total_time) {
            std::cout << "Total " << counter << " numbers in " << elapsed_time << " seconds: " << std::setprecision(0) << std::fixed << counter / elapsed_time << " numbers/s" << std::endl;
            total_time = elapsed_time;
        }

    }

    gmp_randclear(state);
    mpz_clear(range);
    return 0;
}
kTimesG
Jr. Member
*
Offline Offline

Activity: 56
Merit: 6


View Profile
May 08, 2024, 04:51:16 PM
 #5026

The problem is what are you going to use for the dinosaur numbers above Puzzle 128. I wrote above additionally.
Irrelevant. EC field (x, y) is always 256-bit, so this is the size of the operands always even for private key 0x1. Scalar (private key) size does not matter, beyond the initial multiplication. Jump points are precomputed, so we only have additions. The larger keyspace is only problematic due to its size, it doesn't affect the speed itself. Finding a 30-bit or 256-bit solution runs at the same speed. Actually, you don't even need to have any knowledge of the group size itself, just of the interval size.

What we need is algorithms breakthrough, or lots of coordinated "potatoes" and patience.
k3ntINA
Newbie
*
Offline Offline

Activity: 18
Merit: 0


View Profile
May 08, 2024, 07:23:09 PM
 #5027


Why are you nervous?
All the keys are merged together, there is no space between the keys, and it becomes a key with a length of 561 characters like this:
137815314CE01D3202483A7B1460293068F3C9361764F3080D5749FD2C551BA5342DE40F556E52D C2A041FA5EE5340326E6AC3875D916CE817E2551E3D94CD647D4 FE747B862A62E1A96CA8D834A65911D4AED211709DE820A7C1757756A9322382FACD04B5F8303E9 E9AE4933D6153869ACC5B2A221C58D8F6BD3B27C591E02B35A358F 122FCA143C052EC18388D5446CD610B53CBAADE6D7CE3B9B174176B015F4D22BD43C2E935475070 A1A009D4EFAE164CB9E3C180788E47E326C236FB6D5AD1F436ABE1F9B6 7E1149D18B63AC4FFDF1EB25C90795D61C2C675B852189A217496CBB87CAB44FFC07A1825367BBE 13C96A3742F64906363D541EB611ABEE7CCE5EFDACCF6808F7051F27B09 112D41A838B13505B26867
  It is interesting that the number of characters in hex mode by adjusting the distance between the characters of numbers (550) is only 11 away from the length of the key.
Now this one key with the length of 561 is placed inside the spiral circle and we have magic order in setting the distance of all characters (one by one) on 550.
did you understand?

https://www.talkimg.com/images/2024/05/05/roBa2.gif
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 09, 2024, 07:53:19 AM
Last edit: May 09, 2024, 02:28:30 PM by nomachine
 #5028

Here is Rust puzzle script that will work from 1-256bit :

main.rs
Code:
use bitcoin::address::Address;
use bitcoin::key::PrivateKey;
use bitcoin::network::Network;
use chrono::Local;
use clap::{App, Arg};
use hex;
use num::bigint::BigInt;
use num::traits::One;

use num_cpus;
use rand::Rng;
use std::fs::File;
use std::io::{self, Write};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc};
use std::convert::TryInto;
use threadpool::ThreadPool;

fn main() {
    // Print the current time when the script starts
    let current_time = Local::now();
    print!("\x1b[2J\x1b[1;1H");
    println!(
        "\x1b[38;5;226m[+] Puzzle search\n[+] Script started at:{}",
        current_time.format("%Y-%m-%d %H:%M:%S")
    );
    let matches = App::new("Puzzle Solver")
        .version("1.0")
        .arg(
            Arg::with_name("puzzle")
                .short('p')
                .long("puzzle")
                .value_name("PUZZLE")
                .help("Sets the puzzle number")
                .required(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("address")
                .short('a')
                .long("address")
                .value_name("ADDRESS")
                .help("Sets the target address")
                .required(true)
                .takes_value(true),
        )
        .get_matches();

    let puzzle_str = matches.value_of("puzzle").unwrap();
    let puzzle: u128 = puzzle_str.parse().expect("Failed to parse puzzle number");
    let target_address = Arc::new(matches
        .value_of("address")
        .expect("Target address is required")
        .to_string());

    let range_start: BigInt = num::pow(BigInt::from(2), (puzzle - 1) as usize);
    let range_end: BigInt = num::pow(BigInt::from(2), puzzle as usize) - BigInt::one();

    let num_threads = num_cpus::get() as usize; // Convert to usize

    println!(
        "[+] concurrency:{}\n[+] puzzle:{}\n[+] from:{} to:{}\n[+] target:{}",
        num_threads, puzzle, range_start, range_end, target_address
    );

    let found_flag = Arc::new(AtomicBool::new(false));
    let pool = ThreadPool::new(num_threads.try_into().unwrap()); // Convert to usize

    // Handling termination signals
    let found_flag_clone = found_flag.clone();
    ctrlc::set_handler(move || {
        found_flag_clone.store(true, Ordering::Relaxed);
        std::process::exit(0); // Terminate the program
    })
    .expect("Error setting Ctrl-C handler");

    for _ in 0..num_threads {
        let target_address = Arc::clone(&target_address);
        let range_start_clone = range_start.clone();
        let range_end_clone = range_end.clone();
        let found_flag = found_flag.clone();
        let pool_clone = pool.clone();
        pool.execute(move || {
            random_lookfor(&range_start_clone, &range_end_clone, &target_address, &found_flag, &pool_clone);
        });
    }

    pool.join();
}

fn random_lookfor(
    range_start: &BigInt,
    range_end: &BigInt,
    target_address: &Arc<String>,
    found_flag: &Arc<AtomicBool>,
    _pool: &ThreadPool,
) {
    let mut rng = rand::thread_rng();
    let secp = bitcoin::secp256k1::Secp256k1::new();

    loop {
        let key: BigInt = rng.gen_range(range_start.clone()..range_end.clone());
        let private_key_hex = format!("{:0>64x}", key);
        let private_key_bytes =
            hex::decode(&private_key_hex).expect("Failed to decode private key hex");

        let private_key = PrivateKey {
            compressed: true,
            network: Network::Bitcoin,
            inner: bitcoin::secp256k1::SecretKey::from_slice(&private_key_bytes)
                .expect("Failed to create secret key from slice"),
        };

        let public_key = private_key.public_key(&secp);
        let address = Address::p2pkh(&public_key, Network::Bitcoin).to_string();
        print!("[+] key:{}\r", key);
        io::stdout().flush().unwrap();

        // Check if a match has been found by another thread
        if found_flag.load(Ordering::Relaxed) {
            break;
        }

        if address == **target_address {
            let current_time = Local::now();
            let line_of_dashes = "-".repeat(80);
            println!(
                "\n[+] {}\n[+] KEY FOUND! {}\n[+] decimal: {} \n[+] private key: {} \n[+] public key: {} \n[+] address: {}\n[+] {}",
                line_of_dashes,
                current_time.format("%Y-%m-%d %H:%M:%S"),
                key,
                private_key,
                public_key,
                address,
                line_of_dashes
            );

            // Set the flag to true to signal other threads to exit
            found_flag.store(true, Ordering::Relaxed);

            if let Ok(mut file) = File::create("KEYFOUNDKEYFOUND.txt") {
                let line_of_dashes = "-".repeat(130);
                writeln!(
                    &mut file,
                    "\n{}\nKEY FOUND! {}\ndecimal: {} \nprivate key: {} \npublic key: {} \naddress: {}\n{}",
                    line_of_dashes,
                    current_time.format("%Y-%m-%d %H:%M:%S"),
                    key,
                    private_key,
                    public_key,
                    address,
                    line_of_dashes
                )
                .expect("Failed to write to file");
            } else {
                eprintln!("Error: Failed to create or write to KEYFOUNDKEYFOUND.txt");
            }
            io::stdout().flush().unwrap();
            break;
        }
    }
}

Cargo.toml
Code:
[package]
name = "puzzle"
version = "0.1.0"
edition = "2021"

[dependencies]
num = "0.4.1"
num-traits = "0.2"
num-bigint = { version = "0.4.4", features = ["rand"] }
threadpool = "1.8.0"
bitcoin_hashes = "0.14.0"             
bitcoin = "0.31.2"
hex = "0.4.3"
rand = "0.8.5"
secp256k1 = "0.29.0"
num_cpus = "1.16.0"
chrono = "0.4.38"
clap = "3.0"
ctrlc = "3.4.4"


Build program
Code:
RUSTFLAGS="-C target-feature=+ssse3" cargo build --release --target=x86_64-unknown-linux-gnu


Usage example
Code:
./puzzle -p 20 -a 1HsMJxNiV7TLxmoF6uJNkydxPFDog4NQum
./puzzle -p 30 -a 1LHtnpd8nU5VHEMkG2TMYYNUjjLc992bps
./puzzle -p 66 -a 13zb1hQbWVsc2S7ZTZnP2G4undNNpdh5so
./puzzle -p 130 -a 1Fo65aKq8s8iquMt6weF1rku1moWVEd5Ua

 Wink
giovanimarks
Newbie
*
Offline Offline

Activity: 4
Merit: 0


View Profile
May 10, 2024, 05:42:31 AM
 #5029

The Bitcoin puzzle transaction involving multiple addresses generated by a formula with corresponding private key values has intrigued many. The challenge to decipher the formula behind these addresses, with the prize of approximately 32 BTC, remains unsolved, inviting the Bitcoin community's collective efforts and ingenuity to crack it.
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 10, 2024, 05:54:46 AM
 #5030

The Bitcoin puzzle transaction involving multiple addresses generated by a formula with corresponding private key values has intrigued many. The challenge to decipher the formula behind these addresses, with the prize of approximately 32 BTC, remains unsolved, inviting the Bitcoin community's collective efforts and ingenuity to crack it.

Oh, sure! Because nothing screams "fun weekend activity" like trying to crack a cryptographic puzzle for a chance at some digital gold. Who needs Netflix when you can spend hours staring at strings of alphanumeric characters, hoping they form a magical circle that summons the secrets of the universe? It's like a high-stakes Sudoku, except instead of filling in numbers, you're filling in existential dread. But hey, at least you might end up with enough Bitcoin to buy a small tropical island, right? Totally worth it!  Grin
citb0in
Hero Member
*****
Offline Offline

Activity: 686
Merit: 709


Bitcoin g33k


View Profile
May 10, 2024, 06:06:27 AM
 #5031

The Bitcoin puzzle transaction involving multiple addresses generated by a formula with corresponding private key values has intrigued many. The challenge to decipher the formula behind these addresses, with the prize of approximately 32 BTC, remains unsolved, inviting the Bitcoin community's collective efforts and ingenuity to crack it.

uninteresting output of  ChatGPT caused by non-sens input. Actually totally pointless and a waste of time. But somehow you have to keep your fake double-triple-four accounts on their toes, don't you?

  _      _   _       __  _          _  _   __
 |_) |  / \|/   (_  / \ | \  / |_ |_) (_ 
 |_) |_ \_/ \_ |\   __) \_/ |_ \/  |_ | \ __)
--> citb0in Solo-Mining Group <--- low stake of only 0.001 BTC. We regularly rent about 5 PH/s hash power and direct it to SoloCK pool. Wanna know more? Read through the link and JOIN NOW
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 10, 2024, 06:14:28 AM
 #5032

Keeping those Digaran fake accounts on their toes is practically a full-time gig now.  Grin
citb0in
Hero Member
*****
Offline Offline

Activity: 686
Merit: 709


Bitcoin g33k


View Profile
May 10, 2024, 06:15:46 AM
Merited by nomachine (1)
 #5033

quote author=nomachine link=topic=1306983.msg64056686#msg64056686 date=1715321668]
Keeping those Digaran fake accounts on their toes is practically a full-time gig now.  Grin
[/quote]

absolutely true. Unfortunately he is not alone abusing this forum by such techniques but I am not allowed to post detailed info.

  _      _   _       __  _          _  _   __
 |_) |  / \|/   (_  / \ | \  / |_ |_) (_ 
 |_) |_ \_/ \_ |\   __) \_/ |_ \/  |_ | \ __)
--> citb0in Solo-Mining Group <--- low stake of only 0.001 BTC. We regularly rent about 5 PH/s hash power and direct it to SoloCK pool. Wanna know more? Read through the link and JOIN NOW
Tepan
Jr. Member
*
Offline Offline

Activity: 45
Merit: 1


View Profile
May 10, 2024, 07:58:55 AM
 #5034

I can't squeeze out more than 852.000 affine point additions per second


I have 249457 hops per second in python  converting this script with cpython into .so

Code:
import time
import os
import sys
import random
import secp256k1 as ice
import gmpy2

if os.name == 'nt':
    os.system('cls')
else:
    os.system('clear')
t = time.ctime()
sys.stdout.write(f"\033[?25l")
sys.stdout.write(f"\033[01;33m[+] Kangaroo: {t}\n")
sys.stdout.flush()

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 = gmpy2.mpz(x)
        self.y = gmpy2.mpz(y)

PG = Point(Gx, Gy)
Z = Point(0, 0)  # zero-point, infinite in real x, y - plane

def add(P, Q, p=modulo):
    if P == Z:
        return Q
    elif Q == Z:
        return P
    elif P.x == Q.x and (P.y != Q.y or P.y == 0):
        return Z
    elif P.x == Q.x:
        m = (3 * P.x * P.x) * gmpy2.invert(2 * P.y, p) % p
    else:
        m = (Q.y - P.y) * gmpy2.invert(Q.x - P.x, p) % p
  
    x = (m * m - P.x - Q.x) % p
    y = (m * (P.x - x) - P.y) % p
    return Point(x, y)

def mul2(P, p=modulo):
    if P == Z:
        return Z
    m = gmpy2.f_mod(3 * P.x * P.x * gmpy2.invert(2 * P.y, p), p)
    x = gmpy2.f_mod(m * m - 2 * P.x, p)
    y = gmpy2.f_mod(m * (P.x - x) - P.y, p)
    return Point(x, y)

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), p)

def X2Y(X, y_parity, p=modulo):
    X_cubed = gmpy2.powmod(X, 3, p)
    X_squared = gmpy2.powmod(X, 2, p)
    tmp = gmpy2.f_mod(X_cubed + 7, p)
    Y = gmpy2.powmod(tmp, gmpy2.f_div(gmpy2.add(p, 1), 4), p)
    if y_parity == 1:
        Y = gmpy2.f_mod(-Y, p)
    return Y


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)))
        HEX = "%064x" % abs(Ak[sol_kt] - Bk[sol_kw])
        dec = int(HEX, 16)
        wifc = ice.btc_pvk_to_wif(HEX)
        wifu = ice.btc_pvk_to_wif(HEX, False)
        caddr = ice.privatekey_to_address(0, True, dec)
        uaddr = ice.privatekey_to_address(0, False, dec)
        total_time = time.time() - starttime
        print('\n[+] total time: %.2f sec' % (total_time))
        t = time.ctime()
        print(f"\033[32m[+] PUZZLE SOLVED: {t} \033[0m")
        print(f"\033[32m[+] Private key (wif) Compressed : {wifc} \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(f"\nRandom seed: {seed}")
            file.write("\nPrivate Key (decimal): " + str(dec))
            file.write("\nPrivate Key (hex): " + HEX)
            file.write("\nPrivate key (wif) Compressed : " + wifc)
            file.write("\nPrivate key (wif) Uncompressed: " + wifu)
            file.write("\nBitcoin address Compressed: " + caddr)
            file.write("\nBitcoin address Uncompressed: " + uaddr)
            file.write(
                "\n-------------------------------------------------------------------------------------------------------------------------------------------\n"
            )
        file.close()
        return True
    else:
        return False

def check(P, Pindex, DP_rarity, A, Ak, B, Bk):
    if P.x % DP_rarity == 0:
        A.append(gmpy2.mpz(P.x))
        Ak.append(gmpy2.mpz(Pindex))
        return comparator(A, Ak, B, Bk)
    else:
        return False

# Generate a list of powers of two for faster access

def generate_powers_of_two(hop_modulo):
    return [gmpy2.mpz(1 << pw) for pw in range(hop_modulo)]

def search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two):
    solved = False
    t = [gmpy2.mpz(lower_range_limit + gmpy2.mpz(random.randint(0, upper_range_limit - lower_range_limit))) for _ in range(Nt)]
    T = [mulk(ti) for ti in t]
    dt = [gmpy2.mpz(0) for _ in range(Nt)]
    w = [gmpy2.mpz(random.randint(0, upper_range_limit - lower_range_limit)) for _ in range(Nw)]
    W = [add(W0, mulk(wk)) for wk in w]
    dw = [gmpy2.mpz(0) for _ in range(Nw)]
    print('[+] tame and wild herds are prepared')
    Hops, Hops_old = 0, 0
    t0 = time.time()  
    while not solved:
        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: break
            t[k] += dt[k]
            T[k] = add(P[int(pw)], T[k])
        if solved: break
        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: break
            w[k] += dw[k]
            W[k] = add(P[int(pw)], W[k])
        if solved: break
        t1 = time.time()
        if (t1 - t0) > 5:
            print('\r[+] Hops: %.0f h/s' % ((Hops - Hops_old) / (t1 - t0)), end='', flush=True)
            t0 = t1
            Hops_old = Hops
    print('[+] Hops:', Hops)
    return 'sol. time: %.2f sec' % (time.time() - starttime)

puzzles = [\
    ('0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69',32),\
    ('03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4',40),\
    ('025e466e97ed0e7910d3d90ceb0332df48ddf67d456b9e7303b50a3d89de357336',44),\
    ('026ecabd2d22fdb737be21975ce9a694e108eb94f3649c586cc7461c8abf5da71a',45),\
    ('03f46f41027bbf44fafd6b059091b900dad41e6845b2241dc3254c7cdd3c5a16c6',50),\
    ('0230210c23b1a047bc9bdbb13448e67deddc108946de6de639bcc75d47c0216b1b',65),\
    ('03633cbe3ec02b9401c5effa144c5b4d22f87940259634858fc7e59b1c09937852',130)]

puzzle = 40
for elem in puzzles:
    s, n = elem
    if puzzle == n: break

kangaroo_power = 4
DP_rarity = 1 << int(((puzzle -  2*kangaroo_power)/2 - 2))
hop_modulo = ((puzzle - 1) // 2) + kangaroo_power
Nt = Nw = 2**kangaroo_power

X = gmpy2.mpz(s[2:66], 16)
Y = X2Y(X, gmpy2.mpz(s[:2]) - 2)

W0 = Point(X,Y)
starttime = oldtime = time.time()
search_range = 2**(puzzle-1)

lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2 ** puzzle) - 1

print(f"[+] [Puzzle]: {puzzle}")
print(f"[+] [Lower range limit]: {lower_range_limit}")
print(f"[+] [Upper range limit]: {upper_range_limit}")

# Precompute powers of two for faster access
powers_of_two = generate_powers_of_two(hop_modulo)

# Initialize variables
T, t, dt = [], [], []
W, w, dw = [], [], []

#Random seed Config
seed = os.urandom(9)
print(f"[+] [Random seed]: {seed}")
random.seed(seed)

Hops = 0
N_tests = 1

P = [PG]
for k in range(255): P.append(mul2(P[k]))  
print('[+] P-table prepared')

for k in range(N_tests):
    solved = False
    search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two)

print('[+] Average time to solve: %.2f sec' % ((time.time()-starttime)/N_tests))

It normally goes to 207301 h/s

Imagine this in Rust, how fast would it go? Grin


u128
const uint64_t
uint64 in C & u128 in Rust not work for Puzzle 130 (try to deal with dinosaur numbers)

BigUint/BIGINT from SSL works or GMP can be used Wink

okay good information here, i'll learn that for P#130, thankyou.
maylabel
Newbie
*
Offline Offline

Activity: 19
Merit: 0


View Profile
May 10, 2024, 08:38:01 AM
 #5035

share with us sir


I can share puzzle search app in Rust. I'm sick of code in Python. Grin

main.rs
Code:
extern crate bitcoin;
extern crate rand;
extern crate reqwest;
extern crate secp256k1;
extern crate num_cpus;
extern crate thousands;
extern crate threadpool;
extern crate chrono;

use bitcoin::network::Network;
use bitcoin::address::Address;
use bitcoin::key::PrivateKey;
use rand::Rng;
use std::env;
use std::fs::File;
use std::io::Write;
use std::sync::{Arc, Mutex};
use threadpool::ThreadPool;
use chrono::Local;

const TARGET: &str = "1QCbW9HWnwQWiQqVo5exhAnmfqKRrCRsvW";

fn main() {
    // Print the current time when the script starts
    let current_time = Local::now();
    println!("[+] Puzzle search\n[+] Script started at: {}", current_time);

    let args: Vec<String> = env::args().collect();
    let num_threads = if args.len() < 2 {
        num_cpus::get() as u32
    } else {
        args[1].parse().expect("Failed to parse number of threads")
    };

    let begin: u128 = 16383;
    let end: u128 = 32767;

    println!(
        "[+] concurrency:{}\n[+] from:{} to:{}\n[+] target:{}",
        num_threads,
        begin,
        end,
        TARGET
    );

    let found_flag = Arc::new(Mutex::new(false));
    let pool = ThreadPool::new(num_threads.try_into().unwrap());

    for _ in 0..num_threads {
        let pool = pool.clone();
        let found_flag = found_flag.clone();
        pool.execute(move || {
            let mut rng = rand::thread_rng();
            random_lookfor(rng.gen_range(begin..end), end, found_flag);
        });
    }

    pool.join();
}

fn random_lookfor(begin: u128, end: u128, found_flag: Arc<Mutex<bool>>) {
    let secp = bitcoin::secp256k1::Secp256k1::new();

    loop {
        let value: u128 = rand::thread_rng().gen_range(begin..end);
        let private_key_hex = format!("{:0>64x}", value);
        let private_key_bytes = hex::decode(&private_key_hex).expect("Failed to decode private key hex");

        let private_key: PrivateKey = PrivateKey {
            compressed: true,
            network: Network::Bitcoin,
            inner: bitcoin::secp256k1::SecretKey::from_slice(&private_key_bytes).unwrap(),
        };

        let public_key = private_key.public_key(&secp);
        let address = Address::p2pkh(&public_key, Network::Bitcoin).to_string();
        print!(
            "\r[+] WIF: {}",
            private_key
        );

        // Check if a match has been found by another thread
        let mut found_flag = found_flag.lock().unwrap();
        if *found_flag {
            break;
        }

        if address == TARGET {
            let current_time = Local::now();
            let line_of_dashes = "-".repeat(80);
            println!(
                "\n[+] {}\n[+] KEY FOUND! {}\n[+] decimal: {} \n[+] private key: {} \n[+] public key: {} \n[+] address: {}\n[+] {}",
                line_of_dashes,
                current_time,
                value,
                private_key,
                public_key,
                address,
                line_of_dashes         
            );

            // Set the flag to true to signal other threads to exit
            *found_flag = true;

            if let Ok(mut file) = File::create("KEYFOUNDKEYFOUND.txt") {
                let line_of_dashes = "-".repeat(130);
                writeln!(
                    &mut file,
                "\n{}\nKEY FOUND! {}\ndecimal: {} \nprivate key: {} \npublic key: {} \naddress: {}\n{}",
                line_of_dashes,
                current_time,
                value,
                private_key,
                public_key,
                address,
                line_of_dashes     
                )
                .expect("Failed to write to file");
            } else {
                eprintln!("Error: Failed to create or write to KEYFOUNDKEYFOUND.txt");
            }
            break;
        }
    }
}

Cargo.toml
Code:
[package]
name = "puzzle"
version = "0.1.0"
edition = "2021"

[dependencies]
threadpool = "1.8.0"
bitcoin_hashes = "0.13.0"                
bitcoin = "0.31.1"
hex = "0.4.3"
rand = "0.8.5"
reqwest = "0.11.23"
secp256k1 = "0.28.1"
num_cpus = "1.16.0"
thousands = "0.2.0"
chrono = "0.4"

  • --------------------------------------------------------------------------------
  • KEY FOUND!
  • decimal: 26867
  • private key: KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFY5iMZbuRxj
  • public key: 02fea58ffcf49566f6e9e9350cf5bca2861312f422966e8db16094beb14dc3df2c
  • address: 1QCbW9HWnwQWiQqVo5exhAnmfqKRrCRsvW
  • --------------------------------------------------------------------------------

Install Rust:
Code:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Configure Rust Environment:
Code:
source $HOME/.cargo/env

Code:
export PATH="$HOME/.cargo/bin:$PATH"

Create a Puzzle Rust Project:
Code:
cargo new puzzle

copy/paste above main.rs & Cargo.toml

Code:
cd  puzzle

Build program
Code:
cargo build --release

Start
Code:
cargo run

or directly as a bin application
Code:
./target/release/puzzle

p.s.
You can remove :      
Code:
        print!(
            "\r[+] WIF: {}",
            private_key
        );

for more speed....

I have similar levels of performance in Rust and C. But much less bugs in Rust  Wink

I love python but blows my memory in no time (cpu). And I have been fight with eclipse all my life.
Doesn't matter how many thread I cant run more than 3 hours bc my memory goes to 100%.

Can you tell me if rust has the same memory issue?

thx
maylabel
Newbie
*
Offline Offline

Activity: 19
Merit: 0


View Profile
May 10, 2024, 08:55:07 AM
 #5036

The Bitcoin puzzle transaction involving multiple addresses generated by a formula with corresponding private key values has intrigued many. The challenge to decipher the formula behind these addresses, with the prize of approximately 32 BTC, remains unsolved, inviting the Bitcoin community's collective efforts and ingenuity to crack it.

Oh, sure! Because nothing screams "fun weekend activity" like trying to crack a cryptographic puzzle for a chance at some digital gold. Who needs Netflix when you can spend hours staring at strings of alphanumeric characters, hoping they form a magical circle that summons the secrets of the universe? It's like a high-stakes Sudoku, except instead of filling in numbers, you're filling in existential dread. But hey, at least you might end up with enough Bitcoin to buy a small tropical island, right? Totally worth it!  Grin

 Cheesy Cheesy Cheesy Cheesy dying by reading that

I had the (dis)pleasure to cross with these puzzles recently, together with k4 of kryptos.
(why Im doing this to myself?lol)

And now I'm surrounding by papers and notes... my broken casio too.

I read so much about the BTC calculation is give me headaches, literally I went to walk an hour to give me a break




nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 10, 2024, 10:33:07 AM
Last edit: May 10, 2024, 11:11:35 AM by nomachine
 #5037

I love python but blows my memory in no time (cpu). And I have been fight with eclipse all my life.
Doesn't matter how many thread I cant run more than 3 hours bc my memory goes to 100%.

Can you tell me if rust has the same memory issue?

thx

This is the puzzle script from this post :
https://bitcointalk.org/index.php?topic=1306983.msg64052077#msg64052077

https://i.ibb.co/xz2p58j/2024-05-10-12-29.png

It consumes all 12 cores I have. It works rock solid like this for days.
But this is a special machine just for these things. I don't use it for anything else.
maylabel
Newbie
*
Offline Offline

Activity: 19
Merit: 0


View Profile
May 10, 2024, 11:09:29 AM
 #5038

I love python but blows my memory in no time (cpu). And I have been fight with eclipse all my life.
Doesn't matter how many thread I cant run more than 3 hours bc my memory goes to 100%.

Can you tell me if rust has the same memory issue?

thx

This is the puzzle script from this post :
https://bitcointalk.org/index.php?topic=1306983.msg64052077#msg64052077

https://i.ibb.co/xz2p58j/2024-05-10-12-29.png

It consumes all 12 cores I have. It works rock solid like this for days.
But this is a special machine just for these things. I don't use it for anything else.

Wow, you have solid 8x more memory and 3x more cores than I, kudos for you Kiss

I can't just dedicated my cpu for that; I still need to teach tho....
So to compensate I'm using statistics to reduce the range... not perfect but I already cut in half (i believe)

I will try to run your code (even if I never used rust before)

Thx anyways! Wink
k3ntINA
Newbie
*
Offline Offline

Activity: 18
Merit: 0


View Profile
May 10, 2024, 04:22:32 PM
 #5039

It is very surprising that two of my posts were deleted and these two posts were deleted because they were off topic.
there was nothing from the magic circle and nothing obscure, just a simple new arrangement of private keys in hex and decimal format that showed the relationship between the keys.
There are things in this thread that everyone knows are off topic, but they are not deleted. But this arrangement, which is not something special and is a special category, cannot be sent. They delete it
What is the reason?
No problem, I will upload a full video of these on YouTube in an hour.
 It is proven to everyone that consecutive keys from a wallet can be leaked and have bugs.
Now why don't I open a number? I do not have the knowledge of mathematics and programming or the knowledge that is needed to make this connection meaningful.
That's why I couldn't reach the keys, but there are definitely those who, by looking at the numbers, can discover things that the others failed to discover.
Bugs and cracks always appear somewhere and from where no one thought of it, and sometimes they are very simple and very unexpected.
nomachine
Member
**
Offline Offline

Activity: 277
Merit: 12


View Profile
May 10, 2024, 05:19:56 PM
 #5040

No problem, I will upload a full video of these on YouTube in an hour.
Bugs and cracks always appear somewhere and from where no one thought of it, and sometimes they are very simple and very unexpected.

Oh, it sounds like we're invited for a thrilling YouTube premiere! Who knew the drama of consecutive keys from a wallet could be so riveting? And here I was, thinking that bugs and cracks only appeared in poorly written software and manuals. Who knows what secrets lie hidden in the labyrinth of ones and zeros? Only time will tell, my friend, only time will tell. But hey, you've got a keen eye for the unexpected - who knows, maybe your next video will uncover the secret of the universe hidden in the digits of pi.  Wink
Pages: « 1 ... 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 [252] 253 254 255 »
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!