Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
skedarve
on 30/07/2025, 15:47:36 UTC
import cupy as cp
import numpy as np
import time
from Crypto.Hash import RIPEMD160, SHA256
from ecdsa import SECP256k1, SigningKey
import concurrent.futures

TARGET_HASH160 = bytes.fromhex("f6f5431d25bbf7b12e8add9af5e3475c44a0a5b8")
TARGET_PREFIX = TARGET_HASH160[:3]
THREADS = 256
BATCH_SIZE = 2**24

sha256_kernel = cp.RawKernel(r'''
extern "C" __global__
void sha256_partial(const unsigned long long* privkeys, unsigned char* out_prefixes, unsigned char* matches, int N) {
    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    if (idx >= N) return;
    unsigned long long key = privkeys[idx];
    unsigned char data[8];
    #pragma unroll
    for (int i = 0; i < 8; ++i)
        data[7 - i] = (key >> (i * Cool) & 0xFF;
    unsigned int h[8] = {
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
        0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
    };
    unsigned int k[4] = {
        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
    };
    unsigned int w[64] = {0};
    #pragma unroll
    for (int i = 0; i < 8; ++i)
        w = ((unsigned int)data) << 24;
    unsigned int a = h[0], b = h[1], c = h[2], d = h[3];
    unsigned int e = h[4], f = h[5], g = h[6], hh = h[7];
    for (int i = 0; i < 4; ++i) {
        unsigned int S1 = __funnelshift_r(e, e, 6) ^ __funnelshift_r(e, e, 11) ^ __funnelshift_r(e, e, 25);
        unsigned int ch = (e & f) ^ (~e & g);
        unsigned int temp1 = hh + S1 + ch + k + w;
        unsigned int S0 = __funnelshift_r(a, a, 2) ^ __funnelshift_r(a, a, 13) ^ __funnelshift_r(a, a, 22);
        unsigned int maj = (a & b) ^ (a & c) ^ (b & c);
        unsigned int temp2 = S0 + maj;
        hh = g;
        g = f;
        f = e;
        e = d + temp1;
        d = c;
        c = b;
        b = a;
        a = temp1 + temp2;
    }
    h[0] += a;
    unsigned char b0 = (h[0] >> 24) & 0xFF;
    unsigned char b1 = (h[0] >> 16) & 0xFF;
    unsigned char b2 = (h[0] >> Cool & 0xFF;
    out_prefixes[idx * 3 + 0] = b0;
    out_prefixes[idx * 3 + 1] = b1;
    out_prefixes[idx * 3 + 2] = b2;
    if (b0 == 0xf6 && b1 == 0xf5 && b2 == 0x43)
        matches[idx] = 1;
    else
        matches[idx] = 0;
}
''', 'sha256_partial')

def hash160(pubkey_bytes):
    sha = SHA256.new(pubkey_bytes).digest()
    h160 = RIPEMD160.new(sha).digest()
    return h160

def verify_candidate(candidate):
    pubkey = compressed_public_key_from_privkey(candidate)
    h160 = hash160(pubkey)
    if h160 == TARGET_HASH160:
        return candidate, pubkey.hex(), h160.hex()
    return None

def compressed_public_key_from_privkey(privkey_int):
    priv_bytes = int(privkey_int).to_bytes(32, 'big')
    sk = SigningKey.from_string(priv_bytes, curve=SECP256k1)
    vk = sk.get_verifying_key()
    x = vk.pubkey.point.x()
    prefix = b'\x03' if (vk.pubkey.point.y() & 1) else b'\x02'
    return prefix + x.to_bytes(32, 'big')

print("🔁 Starting search with GPU prefilter (3 bytes)...")

try:
    total_keys = 0
    total_candidates = 0
    while True:
        t0 = time.time()
        privkeys = cp.random.randint(0, 2**64, size=BATCH_SIZE, dtype=cp.uint64)
        out = cp.zeros((BATCH_SIZE * 3,), dtype=cp.uint8)
        matches = cp.zeros(BATCH_SIZE, dtype=cp.uint8)
        blocks = (BATCH_SIZE + THREADS - 1) // THREADS
        sha256_kernel((blocks,), (THREADS,), (privkeys, out, matches, BATCH_SIZE))
        matches_cpu = matches.get()
        privkeys_cpu = privkeys.get()
        candidates = [privkeys_cpu for i in range(BATCH_SIZE) if matches_cpu == 1]
        total_keys += BATCH_SIZE
        total_candidates += len(candidates)
        with concurrent.futures.ProcessPoolExecutor(max_workers=8) as executor:
            futures = [executor.submit(verify_candidate, c) for c in candidates]
            for future in concurrent.futures.as_completed(futures):
                result = future.result()
                if result is not None:
                    candidate, pub_hex, h160_hex = result
                    print(f"\n🎯 MATCH found! Private key: {hex(candidate)}")
                    print(f"    PublicKey: {pub_hex}")
                    print(f"    Hash160: {h160_hex}")
                    exit()
        elapsed = time.time() - t0
        print(f"🔹 Processed: {BATCH_SIZE} | Candidates: {len(candidates)} | Speed: {int(BATCH_SIZE / elapsed):,} keys/s")
except KeyboardInterrupt:
    print("⛔ Process interrupted.")