Search content
Sort by

Showing 20 of 23 results by Geshma
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 22/07/2025, 13:26:35 UTC
do you have code simulating the checksum prefix
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 13/07/2025, 05:45:58 UTC
use mara slipstream
Post
Topic
Board Bitcoin Discussion
Re: $500 puzzle
by
Geshma
on 01/07/2025, 23:35:49 UTC
this information can help alot:

Service Pack Version: A disc with Service Pack 3 (SP3) will have more files than one with SP2 or the original RTM (Release To Manufacturing) version, as service packs include numerous updates and bug fixes.

Edition: While the core files are similar, there might be slight differences between Windows XP Home, Professional, Media Center Edition, or Tablet PC Edition discs.

Language: Different language versions would naturally have different sets of language-specific files.
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 06/04/2025, 10:26:49 UTC
I have a BSGS that solves puzzle 60 in 3 seconds.
The problem is that we don't have public keys.  Grin
[/care to share the code , can it be modified to search for public key using hash10]
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 03/04/2025, 14:21:05 UTC
change the base key to 2A32ED54F2B4E35EE (Dec)
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 16/03/2025, 16:22:43 UTC
thank you.
@nomachine
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 15/03/2025, 16:53:30 UTC
care sharing the .cpp file
Post
Topic
Board Development & Technical Discussion
Re: I created smaller secp256k1 just for testing
by
Geshma
on 15/03/2025, 13:44:53 UTC
from ecdsa.ellipticcurve import Point
from ecdsa.curves import SECP256k1

# Secp256k1 parameters
curve = SECP256k1.curve
p = curve.p()
n = SECP256k1.order
G = SECP256k1.generator

# Endomorphism constants
beta = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee
lmbda = 0x5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72
beta2 = (beta * beta) % p
lmbda2 = (lmbda * lmbda) % n

def endomorphism(P, beta_val):
    """Apply x-coordinate endomorphism with given beta"""
    return Point(curve, (beta_val * P.x()) % p, P.y(), order=n)

def negate_point(P):
    """Negate point by flipping y-coordinate"""
    return Point(curve, P.x(), (-P.y()) % p, order=n)

def format_key(P):
    """Format point as uncompressed public key"""
    return f'04{P.x():064x}{P.y():064x}'

# Input private key
k = 5

# Base point
P = k * G

# Generate all 6 keys
keys = [
    # Original y group
    (P, k),
    (endomorphism(P, beta), (k * lmbda) % n),
    (endomorphism(P, beta2), (k * lmbda2) % n),
   
    # Negated y group
    (negate_point(P), (n - k) % n),
    (negate_point(endomorphism(P, beta)), (n - (k * lmbda)) % n),
    (negate_point(endomorphism(P, beta2)), (n - (k * lmbda2)) % n)
]

# Print results
print(f"Uncompressed public key: {format_key(P)}\n")

print("Three x values:")
print(f"x1 = {P.x()}")
print(f"x2 = {endomorphism(P, beta).x()}")
print(f"x3 = {endomorphism(P, beta2).x()}\n")

print("Two y values:")
print(f"y1 = {P.y()}")
print(f"y2 = {negate_point(P).y()}\n")

print("Six public keys with private keys:")
for i, (point, priv) in enumerate(keys, 1):
    print(f"Public key {i}: {format_key(point)} [Private key: {priv}]")
    print(f"  Validated: {point == priv * G}")

sum_y1 = sum(keys[1] for i in range(3))
sum_y2 = sum(keys[1] for i in range(3,6))

print(f"\nSum for y1: {sum_y1} (n = {n})")
print(f"Sum for y2: {sum_y2} (2n = {2*n})")
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 05/03/2025, 15:37:33 UTC
Don't use test on slipstream
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 04/03/2025, 07:48:35 UTC
care sharing the script
Post
Topic
Board Development & Technical Discussion
Re: Cyclone - fastest CPU Satoshi's puzzle solver (only CPU)
by
Geshma
on 26/02/2025, 16:49:19 UTC
puzzle: 67 730fc235 Possibilities : 13

Seed : 2113081982 KHex : 730fc235
Seed : 2179848786 KHex : 730fc235
Seed : 2620256395 KHex : 730fc235
Seed : 3559516538 KHex : 730fc235
Seed : 5559894373 KHex : 730fc235
Seed : 5960477113 KHex : 730fc235
Seed : 6204436682 KHex : 730fc235
Seed : 7016671995 KHex : 730fc235
Seed : 8305603871 KHex : 730fc235
Seed : 8560029709 KHex : 730fc235
Seed : 8633074902 KHex : 730fc235
Seed : 9737552820 KHex : 730fc235
Seed : 9997208084 KHex : 730fc235


seed integer (or "exit" to quit): 8560029709

Seed : 8560029709 KHex : 730fc235

Searching range: 730fc235000000000:730fc235fffffffff (2^36 keys)

================= WORK IN PROGRESS =================
Target Address: 1BY8GQbnueYofwSuFAT3USAhGjPrkxDdW9
CPU Threads   : 2
Mkeys/s       : 5.50
Total Checked : 35287381504
Elapsed Time  : 01:46:50
Range         : 730fc235000000000:730fc235fffffffff
Progress      : 51.3499 %
Progress Save : 21
================== FOUND MATCH! ==================
Private Key   : 00000000000000000000000000000000000000000000000730FC235C1942C1AE
Public Key    : 0212209F5EC514A1580A2937BD833979D933199FC230E204C6CDC58872B7D46F75
WIF           : KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qbP2K5cm35XKMND1X1KW
P2PKH Address : 1BY8GQbnueYofwSuFAT3USAhGjPrkxDdW9
Total Checked : 35315148800
Elapsed Time  : 01:46:54
Speed         : 5.5030 Mkeys/s

Success! Private key found with seed 8560029709.
Post
Topic
Board Development & Technical Discussion
Re: BSGS + Kangaroo Hybrid
by
Geshma
on 26/02/2025, 08:27:01 UTC
possible , but give and take time
Post
Topic
Board Development & Technical Discussion
Re: Ultra-Lightweight Database with Public Keys (for puzzle btc)
by
Geshma
on 24/02/2025, 09:46:40 UTC
What is Virtual Memory?
Virtual memory is a memory management technique that abstracts physical RAM, providing each process with a large, private address space. It works by:
Paging: Dividing memory into fixed-size pages (e.g., 4 KB on most systems).
Swapping: Moving inactive pages from RAM to a disk-based page file/swap space when RAM is full, and swapping them back when needed.
Translation: Using the Memory Management Unit (MMU) to map virtual addresses (used by programs) to physical addresses (in RAM or swapped to disk).
Key components:
Page File/Swap Space: Disk storage (e.g., pagefile.sys on Windows, /swap on Linux) for swapped pages.
Page Table: Tracks which pages are in RAM or on disk, managed by the OS.

in virtual address space. Physical RAM usage is capped at available RAM (e.g., 16 GB), with excess swapped to disk.

Implementation Details
Keep Original Code: Use the RAM-based SortedDict approach without SQLite or caching modifications (see code below).
Configure Swap Space:
Windows: Ensure the page file is set to "System Managed" or manually increased (e.g., 64 GB for puzzle 64) via System Properties > Advanced > Virtual Memory.
Linux/macOS: Increase swap space (e.g., sudo fallocate -l 64G /swapfile; sudo mkswap /swapfile; sudo swapon /swapfile).
Run as Is: The OS swaps excess SortedDict pages to disk when RAM fills, requiring no code changes beyond ensuring swap space exists.
Post
Topic
Board Development & Technical Discussion
Re: Ultra-Lightweight Database with Public Keys (for puzzle btc)
by
Geshma
on 24/02/2025, 08:16:49 UTC
  • BSGS with Two Grumpy Giants and a Baby: Mon Feb 24 08:04:32 2025
  • Creating babyTable...
  • Baby table saved
  • Loading baby table...
  • Baby table loaded successfully with 741383 entries
  • BSGS Search in progress with Two Grumpy Giants and a Baby
  • m=741455 step=612168 b=574622
  • Key found: 1003651412950
  • Time Spent : 4.15 seconds

number of steps have reduced drastically
Post
Topic
Board Development & Technical Discussion
Re: kangaroos per thread
by
Geshma
on 22/02/2025, 23:30:44 UTC
like 3 tames and 1 wild or 3 wild and 3 tames
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 07/02/2025, 23:49:57 UTC
its a bit mumbled up , wanted your perspective  , and not working also as intended , be gentle:

maybe speed up your Python.

What are you trying to do? It looks like you made some changes to the Python Kangaroo I posted 4 months ago that worked fine (sort of). What are the theoretical bases for your changes though? Some things to consider:

1. I stated several times the code is just for learning purposes. It has its own limitations and had some bugs as well, in edge-cases.
2. Python is very slow, even when using GMP.
3. Kangaroo with only 2 kang types takes longer to solve.
4. Kangaroo that doesn't take advantage of curve symmetry takes longer to solve.
5. Once you change jump tables, alpha, etc. you should really, really know what you're doing, and why. Point doublings (kang == jump_point) are not supported, for private reasons (that code was shrinked down from a larger implementation, I never need to bother with point doublings in any of my algorithms).

Thanks for the input and insight , kang == jump point , enlighten me please.


Code:
import time
import os
import sys
import random
import gmpy2
from math import log2, sqrt, log
from secrets import randbelow

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)

PG = (Gx, Gy)

def add(P, Q):
    Z = (0, 0)
    if P == Z:
        return Q
    if Q == Z:
        return P
   
    Px, Py = P
    Qx, Qy = Q

    if Px == Qx:
        if Py == Qy:
            # Use double formula
            inv_2Py = gmpy2.invert((Py << 1) % modulo, modulo)
            m = (3 * Px * Px * inv_2Py) % modulo
        else:
            return Z
    else:
        inv_diff_x = gmpy2.invert(Qx - Px, modulo)
        m = ((Qy - Py) * inv_diff_x) % modulo

    x = (m * m - Px - Qx) % modulo
    y = (m * (Px - x) - Py) % modulo
   
    return (x, y)

def mul(k, P=PG):
    R = (0, 0)
    while k:
        if k & 1:
            R = add(R, P)
        P = add(P, P)
        k >>= 1
    return R

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 generate_powers_of_two(hop_modulo):
    return [gmpy2.mpz(1 << pw) for pw in range(hop_modulo)]

def handle_solution(solution):
    HEX = "%064x" % abs(solution) 
    dec = int(HEX, 16)
    print(f"\n\033[32m[+] PUZZLE SOLVED \033[0m")
    print(f"\033[32m[+] Private key (dec): {dec} \033[0m")
    with open("KEYFOUNDKEYFOUND.txt", "a") as file:
        file.write("\n\nSOLVED " + t)
        file.write("\nPrivate Key (decimal): " + str(dec))
        file.write("\nPrivate Key (hex): " + HEX)
        file.write(f"\n{'-' * 100}\n")
    return True

def search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two):
    solved = False
    t_values = [lower_range_limit + randbelow(upper_range_limit - lower_range_limit) for _ in range(Nt)]
    T = [mul(ti) for ti in t_values]
    dt = [gmpy2.mpz(0) for _ in range(Nt)]
    w_values = [randbelow(upper_range_limit - lower_range_limit) for _ in range(Nw)]
    W = [add(W0, mul(wk)) for wk in w_values]
    dw = [gmpy2.mpz(0) for _ in range(Nw)]
    print('[+] Tame and wild herds prepared.')   
    Hops, Hops_old = 0, 0
    tame_dps = {}
    wild_dps = {}
    last_print_time = time.time()
    while not solved:
        for k in range(Nt):
            Hops += 1
            pw = int(T[k][0] % hop_modulo) 
            dt[k] = powers_of_two[pw]
            if T[k][0] % DP_rarity == 0:
                x = T[k][0]
                if x in wild_dps:
                    solution = wild_dps[x] - t_values[k]
                    solved = handle_solution(solution)
                    return solved
                tame_dps[x] = t_values[k]
            t_values[k] += dt[k]
            T[k] = add(P[pw], T[k])       
        for k in range(Nw):
            Hops += 1
            pw = int(W[k][0] % hop_modulo) 
            dw[k] = powers_of_two[pw]
            if W[k][0] % DP_rarity == 0: 
                x = W[k][0]
                if x in tame_dps:
                    solution = w_values[k] - tame_dps[x]
                    solved = handle_solution(solution)
                    return solved
                wild_dps[x] = w_values[k]
            w_values[k] += dw[k]
            W[k] = add(P[pw], W[k])

        current_time = time.time()
        elapsed_time = current_time - starttime
        if current_time - last_print_time >= 5:
            time_since_last = current_time - last_print_time
            hops_since_last = Hops - Hops_old
            hops_per_second = hops_since_last / time_since_last if time_since_last > 0 else 0
            last_print_time = current_time
            Hops_old = Hops           
            hours, rem = divmod(elapsed_time, 3600)
            minutes, seconds = divmod(rem, 60)
            elapsed_time_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
            hops = f'{log2(Hops):.2f}' if Hops > 0 else '0.00'
            print(f'[+] [Hops: 2^{hops} <-> {hops_per_second:.0f} h/s] [{elapsed_time_str}]', end='\r', flush=True)
   
    print('\r[+] Hops:', Hops)
    print('[+] Average time to solve: %.2f sec' % ((time.time()-starttime)))

# Configuration for the puzzle
puzzle = 40
compressed_public_key = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4"
kangaroo_power = puzzle // 5
lower_range_limit = 2 ** (puzzle - 1)
upper_range_limit = (2**puzzle) - 1
DP_rarity = 1 << ((puzzle - 1) // 2 - 2) // 2 + 2
hop_modulo = round(log(2**puzzle)+5)
Nt = Nw = 2**kangaroo_power
powers_of_two = generate_powers_of_two(hop_modulo)

if len(compressed_public_key) == 66:
    X = gmpy2.mpz(int(compressed_public_key[2:66], 16))
    Y = X2Y(X, int(compressed_public_key[:2]) - 2)
else:
    print("[error] Public key length invalid!")
    sys.exit(1)

W0 = (X,Y)
P = [PG]
for _ in range(puzzle ** 2):
    P.append(add(P[-1], P[-1]))
print('[+] P-table prepared')

# Start kangaroo search
starttime = time.time()
print(f"[+] Puzzle: {puzzle}")
print(f"[+] Lower range limit: {lower_range_limit}")
print(f"[+] Upper range limit: {upper_range_limit}")
print(f"[+] DP: 2^{int(log2(DP_rarity))}({DP_rarity:x})")
print(f"[+] Expected Hops: 2^{log2(2.13 * sqrt(1 << (puzzle-1))):.2f} ({int(2.13 * sqrt(1 << (puzzle-1)))})")

search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two)
print(f"[+] Total time: {time.time() - starttime:.2f} seconds")

  • Kangaroo: Fri Feb  7 22:00:56 2025
  • P-table prepared
  • Puzzle: 40
  • Lower range limit: 549755813888
  • Upper range limit: 1099511627775
  • DP: 2^10(400)
  • Expected Hops: 2^20.59 (1579299)
  • Tame and wild herds prepared.
  • [Hops: 2^20.43 <-> 282835 h/s] [00:00:05]
  • PUZZLE SOLVED
  • Private key (dec): 1003651412950
  • Total time: 5.59 seconds


You can also try my script for learning process.

But I won't give you false hope that this script can solve anything above 60 soon. It's simply beyond the reach of python's capabilities. Grin



[/quote] thanks [/quote]
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 07/02/2025, 17:27:57 UTC
its a bit mumbled up , wanted your perspective  , and not working also as intended , be gentle:

maybe speed up your Python.

What are you trying to do? It looks like you made some changes to the Python Kangaroo I posted 4 months ago that worked fine (sort of). What are the theoretical bases for your changes though? Some things to consider:

1. I stated several times the code is just for learning purposes. It has its own limitations and had some bugs as well, in edge-cases.
2. Python is very slow, even when using GMP.
3. Kangaroo with only 2 kang types takes longer to solve.
4. Kangaroo that doesn't take advantage of curve symmetry takes longer to solve.
5. Once you change jump tables, alpha, etc. you should really, really know what you're doing, and why. Point doublings (kang == jump_point) are not supported, for private reasons (that code was shrinked down from a larger implementation, I never need to bother with point doublings in any of my algorithms).

Thanks for the input and insight , kang == jump point , enlighten me please.
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 06/02/2025, 21:54:26 UTC
#67 You can solve puzzles using mathematical methods, only requiring 58 to the power of 7 Calculation.

Go get it!

its a bit mumbled up , wanted your perspective  , and not working also as intended , be gentle:

import os
import math
import time
import bisect
from gmpy2 import gmpy2

# --------------------------
# Field and Group Operations (unchanged)
# --------------------------

class S:  # Scalar field (secp256k1 order)
    N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
    gmp_N = gmpy2.mpz(N)

    @staticmethod
    def add(a, b):
        return gmpy2.mod(gmpy2.add(a, b), S.gmp_N)

    @staticmethod
    def sub(a, b):
        return gmpy2.mod(gmpy2.sub(a, b), S.gmp_N)

    @staticmethod
    def mul(a, b):
        return gmpy2.mod(gmpy2.mul(a, b), S.gmp_N)

class F:  # Prime field (secp256k1 field)
    P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
    gmp_P = gmpy2.mpz(P)
    gmp_P4 = gmpy2.mpz((P + 1) // 4)

    @staticmethod
    def add(a, b):
        return gmpy2.mod(gmpy2.add(a, b), F.gmp_P)

    @staticmethod
    def sub(a, b):
        return gmpy2.mod(gmpy2.sub(a, b), F.gmp_P)

    @staticmethod
    def mul(a, b):
        return gmpy2.mod(gmpy2.mul(a, b), F.gmp_P)

    @staticmethod
    def pow(b, e):
        return gmpy2.powmod(b, e, F.gmp_P)

    @staticmethod
    def sqrt(a):
        return gmpy2.powmod(a, F.gmp_P4, F.gmp_P)

    @staticmethod
    def inv(a):
        return gmpy2.invert(a, F.gmp_P)

# -----------------
# Point Operations (unchanged)
# -----------------

class Point:
    def __init__(self, x, y, parity=-1):
        self.x = x
        self.y = y if parity == -1 else self.calc_y(x, parity)

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y       

    @classmethod
    def uncompress(cls, s):
        parity, xh = int(s[:2], 16), s[2:]
        if parity not in [2, 3]:
            raise ValueError("Invalid parity byte")
        return Point(int(xh, 16), 0, parity % 2)

    @staticmethod
    def calc_y(x, parity):
        y_sq = F.add(F.pow(x, 3), 7)
        y = F.sqrt(y_sq)
        return y if (y % 2) == parity else F.P - y

class JPoint:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def affine(self):
        iz = F.inv(self.z)
        iz2 = F.mul(iz, iz)
        return Point(F.mul(self.x, iz2), F.mul(self.y, F.mul(iz, iz2)))

    def double(self):
        if self.y == 0:
            return JPoint(0, 0, 0)
       
        y2 = F.mul(self.y, self.y)
        s = F.mul(4 * self.x, y2)
        m = F.mul(3 * F.mul(self.x, self.x), F.mul(self.z, F.mul(self.z, self.z)))
       
        x = F.sub(F.mul(m, m), F.mul(2, s))
        y = F.sub(F.mul(m, F.sub(s, x)), F.mul(8, F.mul(y2, y2)))
        z = F.mul(2 * self.y, self.z)
        return JPoint(x, y, z)

    def add(self, q):
        if self.y == 0:
            return q
        if q.y == 0:
            return self

        z1z1 = F.mul(self.z, self.z)
        z2z2 = F.mul(q.z, q.z)
        u1 = F.mul(self.x, z2z2)
        u2 = F.mul(q.x, z1z1)
        s1 = F.mul(self.y, F.mul(q.z, z2z2))
        s2 = F.mul(q.y, F.mul(self.z, z1z1))

        if u1 == u2:
            return self.double() if s1 == s2 else JPoint(0, 0, 1)
           
        h = F.sub(u2, u1)
        r = F.sub(s2, s1)
        h2 = F.mul(h, h)
        h3 = F.mul(h, h2)
       
        x = F.sub(F.sub(F.mul(r, r), h3), F.mul(2, F.mul(u1, h2)))
        y = F.sub(F.mul(r, F.sub(F.mul(u1, h2), x)), F.mul(s1, h3))
        z = F.mul(h, F.mul(self.z, q.z))
        return JPoint(x, y, z)

    def mul(self, n):
        result = JPoint(0, 0, 1)
        current = self
       
        while n > 0:
            if n % 2 == 1:
                result = result.add(current)
            current = current.double()
            n //= 2
        return result

class Group:
    G = Point(
        0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
        0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
    )

    @staticmethod
    def mul(p: Point, k):
        return JPoint(p.x, p.y, 1).mul(k).affine()

    @staticmethod
    def add(p: Point, q: Point):
        if p.x == q.x:
            raise ValueError("Points with same x-coordinate")
        m = F.mul(F.sub(p.y, q.y), F.inv(F.sub(p.x, q.x)))
        x = F.sub(F.sub(F.mul(m, m), p.x), q.x)
        y = F.sub(F.mul(m, F.sub(p.x, x)), p.y)
        return Point(x, y)

# ------------------
# Enhanced Kangaroo Algorithm with Adjustments
# ------------------

class Kangaroo:
    def __init__(self, start, end, dp_bits=14, herd_size=1024):
        # 1. Initialize critical range parameters FIRST
        self.start = start
        self.end = end
        self.range = end - start + 1
        self.interval_size = self.range  # Key parameter
        self.max_intervals = 1  # Now properly defined

        # 2. Store target reference for herd initialization
        self.target = None  # Will be set in solve()

        # 3. Configure jumps and DPs
        self.dp_mask = (1 << dp_bits) - 1
        self.herd_size = herd_size

        self.tame_points = []  # Initialize tame_points here
        self.wild_points = []  # Initialize wild_points here

        # 4. Initialize jump parameters. This is the code change.
        self.base_alpha = self.herd_size * math.sqrt(self.range) / 2
        self.current_alpha = self.base_alpha
        self.adaptation_interval = 1000  # How often to adjust alpha
        self.jump_history = []  # To track jumps

        self._update_jump_table()  # Initialize jumps

    def _update_jump_table(self):
        """Generate geometrically increasing jumps"""
        self.jump_dists = []
        max_step = int(self.current_alpha)
        step = 1
        while len(self.jump_dists) < 12 and step <= max_step:
            self.jump_dists.append(step)
            step *= 4
        # Add final large step to prevent stagnation
        self.jump_dists.append(max_step)
        self.jump_points = [Group.mul(Group.G, d) for d in self.jump_dists]

    def _search_interval(self, interval):
        """Fixed initialization using stored target"""
        # Tame kangaroos spread through range
        step_size = self.range // self.herd_size
        tame = [Group.mul(Group.G, self.start + i*step_size)
               for i in range(self.herd_size)]
        t_dist = [self.start + i*step_size for i in range(self.herd_size)]
       
        # Wild kangaroos start from TARGET + offsets
        wild = [Group.add(self.target, Group.mul(Group.G, i))
               for i in range(self.herd_size)]
        w_dist = [i for i in range(self.herd_size)]
       
        return tame, t_dist, wild, w_dist

    def _adapt_jump_strategy(self):
        if len(self.jump_history) >= self.adaptation_interval:
            avg_jump = sum(self.jump_history[-self.adaptation_interval:]) / self.adaptation_interval
            if avg_jump < self.current_alpha / 4:
                self.current_alpha = max(self.base_alpha / 4, self.current_alpha * 0.9)
            else:
                self.current_alpha = min(self.base_alpha * 4, self.current_alpha * 1.1)
            self._update_jump_table()
            self.jump_history = []

    def _update_jump_table(self):
        self.jump_dists = []
        max_step = max(1, int(self.current_alpha))
        # Generate jumps optimized for small steps
        a, b = 1, 1
        while len(self.jump_dists) < 8 and a <= max_step:
            self.jump_dists.append(a)
            a, b = b, a + b
        # Fill remaining with 1s to ensure coverage
        while len(self.jump_dists) < 8:
            self.jump_dists.append(1)
        self.jump_points = [Group.mul(Group.G, d) for d in self.jump_dists]

    def _search_interval(self, interval):
        offset = self.start + interval * self.interval_size
        P = Group.mul(Group.G, offset)
        v = max(1, self.interval_size // self.herd_size)
       
        tame = []
        wild = []
        t_dist = []
        w_dist = []
        for i in range(self.herd_size):
            tame_pos = offset + i * v
            tame.append(Group.mul(Group.G, tame_pos))
            t_dist.append(tame_pos)
            wild_pos = (tame_pos + (self.range // 2)) % S.N  # Wild starts offset by half range
            wild.append(Group.mul(Group.G, wild_pos))
            w_dist.append(wild_pos)
        return tame, t_dist, wild, w_dist

    def solve(self, target):
        self.target = target  # Critical: store target reference
        try:
            for interval in range(self.max_intervals):  # Now works
                tame, t_dist, wild, w_dist = self._search_interval(interval)
                ops = 0
                start_time = time.time()
               
                while True:
                    # Process tame herd
                    for i in range(self.herd_size):
                        if (tame.x & self.dp_mask) == 0:
                            parity = tame.y % 2
                            entry = (tame.x, parity)
                            idx = bisect.bisect_left(self.tame_points, entry)
                            if idx < len(self.tame_points) and self.tame_points[idx][:2] == entry:
                                candidate = S.sub(t_dist, self.tame_points[idx][2])
                                if Group.mul(Group.G, candidate) == target:
                                    return candidate
                            bisect.insort(self.tame_points, (tame.x, parity, t_dist))
                       
                        j = tame.x % len(self.jump_dists)
                        tame = Group.add(tame, self.jump_points[j])
                        t_dist = S.add(t_dist, self.jump_dists[j])
                        self.jump_history.append(self.jump_dists[j])

                    # Process wild herd
                    for i in range(self.herd_size):
                        if (wild.x & self.dp_mask) == 0:
                            parity = wild.y % 2
                            entry = (wild.x, parity)
                            idx = bisect.bisect_left(self.wild_points, entry)
                            if idx < len(self.wild_points) and self.wild_points[idx][:2] == entry:
                                candidate = S.sub(w_dist, self.wild_points[idx][2])
                                if Group.mul(Group.G, candidate) == target:
                                    return candidate
                            bisect.insort(self.wild_points, (wild.x, parity, w_dist))
                       
                        j = wild.x % len(self.jump_dists)
                        wild = Group.add(wild, self.jump_points[j])
                        w_dist = S.add(w_dist, self.jump_dists[j])
                        self.jump_history.append(self.jump_dists[j])

                    ops += 2 * self.herd_size
                    self._adapt_jump_strategy()
                   
                    if time.time() - start_time > 2:
                        print(f"Interval {interval} | Ops: {ops:,} | Tame: {len(self.tame_points)} | Wild: {len(self.wild_points)}")
                        start_time = time.time()
       
        except KeyboardInterrupt:
            print("\nSearch halted by user")
            return None

# ----------
# Interface
# ----------

def run_puzzle(start, end, pubkey_hex):
    try:
        target = Point.uncompress(pubkey_hex)
        kang = Kangaroo(start, end)
       
        print(f"Searching range {hex(start)}-{hex(end)} ({(end-start+1):,} keys)")
        start_time = time.time()
        result = kang.solve(target)
       
        if result is not None:
            calc_point = Group.mul(Group.G, result)
            print(f"\nFound candidate: {hex(result)}")
            print(f"Target X:   {target.x:064x}")
            print(f"Calculated X: {calc_point.x:064x}")
            print(f"Y Parity Match: {calc_point.y%2 == target.y%2}")
            if calc_point.x == target.x:
                print("Full Verification:", calc_point.y == target.y)
            else:
                print("Warning: False positive detected")
        else:
            print("\nNo valid solution found")
       
        print(f"Time elapsed: {time.time()-start_time:.2f}s")
   
    except KeyboardInterrupt:
        print("\nOperation cancelled by user")

if __name__ == "__main__":
    run_puzzle(0x1000000, 0x1ffffff, "03057fbea3a2623382628dde556b2a0698e32428d3cd225f3bd034dca82dd7455a")
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 05/02/2025, 00:01:02 UTC
Therefore, due to the uniform distribution of hashes, it is less likely that we will find a prefix close to another one.

A probabilistic software using a previous prefix as a reference point, where you skip millions of keys and where a coincidence or collision is less likely, is not a waste of time as you suggest. Instead, it would be another probabilistic option. In this case, where sequential brute force is exponentially demanding, a probabilistic search suggests a better strategy.

I'm not preaching anything that's not in a 9th grade high school math book where I live.

Did you read the definition of a uniform distribution? It's a random oracle where anything can happen (with an equal chance of course, which is all I'm bragging about for the last 10 posts here), not something that will ever follow any kind of even-spaced value-to-slot allocations, no matter how you look at it, analyze it, or whatever you want to do with it. The "margin of error" when trying to predict anything about it is simply equal to keeping track of skipped key ranges, which is where everyone that attempts to use this "theory" will end up to, once they find that they either have too many or too few prefixes found.

Just because the probabilities are all equal, does not mean that you will end up with an equal amount of same values over some microscopic sample size (like any 2**66 sample out of comb(2**160, 2**66), or rather, out of (2**160) ** (2**66) possibilities, since any hash has an equal probability to occur).

It is exactly the same principle why, if you throw a coin 100 times, the chances to get a 50/50 is extremely unlikely, even if it has the highest chances. Or isn't a coin flip an uniform distribution of 50/50? Why wouldn't RIPEMD-160 be the same, if you scan some range, and only count how many times the first bit is 1, there's basically 0% chances to have anywhere near the same amount of hashes that start with a 0 (the difference will be a really really big number, not close to zero, and there's a 99.9% confidence for this really big difference to occur). Only when the number of flips (number of hashes) goes to infinity, will you ever have an exact ratio of 50% 0s (heads) and 50% 1s (tails). Up to that  point, the difference (in absolute value) will almost certainly increase further and further, perhaps at some times swapping whether the 0s or the 1s start to go ahead. It's all a probability race based on equal chances of possible occurrences.

Thanks for the lesson that 2 bytes can hold 65536 distinct values.

Bitcoin block 756951 has the lowest SHA256 hash to date: 0000000000000000000000005d6f06154c8685146aa7bc3dc9843876c9cefd0f. Generating a hash this low has the same likelihood as flipping a coin 97 times in a row and it landing on tails every time.
Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
Geshma
on 30/01/2025, 07:43:39 UTC
lol, I have no reason to lie.

I did not scan anything, well, recently. I found it on a rig that hasn't ran the 67 challenge in a while. I finally consolidated my list and spotted that one.

You can do what you will with the info. I was just informing you that there is an address closer.

Thank you for not giving me information = (Nothing).
If you wanted me to write this, I wrote it.

Now it's up to you to prove it's a LIE or TRUE.
You won't be the first or the last person to say you're closer than me. Wink

My MESSAGE to everyone ;

I really don't understand most of you.

You say you are doing it wrong?
I say prove it. Everyone says things they have memorized.
But you don't think there is a difference of opinion or that we are wrong.

Everyone has calculated how many 66-67 bit, 10 or 11 lengths there are. Nobody knows the right answer. Everyone says an average PROBABILITY result.

When I say something about PROBABILITY, I am declared the person who is doing it WRONG.

I know all of these, friends. But don't forget that there will be solutions.


------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhArAdMsz8Qy
Hash160: 739437bb3dd6d1983e66629c5f08c70e51db53af
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhFEzGfW5Jd5
Hash160: 739437bb3dd6d1983e66629c5f08c70e524f436c
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhBXaa9CSSoz
Hash160: 739437bb3dd6d1983e66629c5f08c70e51ed4234
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhBREEgoMzYo
Hash160: 739437bb3dd6d1983e66629c5f08c70e51ea5e87
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhGm5ehSbYxs
Hash160: 739437bb3dd6d1983e66629c5f08c70e527757d3
Hello Geshma I would like to ask you for the private key and public keys of the address listed below you posted it but didn't add the private keys and public keys please could you also post the private keys
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhArAdMsz8Qy
Hash160: 739437bb3dd6d1983e66629c5f08c70e51db53af
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhFEzGfW5Jd5
Hash160: 739437bb3dd6d1983e66629c5f08c70e524f436c
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhBXaa9CSSoz
Hash160: 739437bb3dd6d1983e66629c5f08c70e51ed4234
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhBREEgoMzYo
Hash160: 739437bb3dd6d1983e66629c5f08c70e51ea5e87
------------------------------------------------------------
Private Key:
Public Key:
Address: 1BY8GQbnueYofwSuFAT3USAhGm5ehSbYxs
Hash160: 739437bb3dd6d1983e66629c5f08c70e527757d3


currently no , but once i finalize with the code will post link to github , its a work in progress.