Pages:
Author

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

member
Activity: 165
Merit: 26
  • [Hops: 229969 h/s] [00:00:01]
  • total time: 1.47 sec
  • KANGAROO: Sun Jul 14 16:01:53 2024 PUZZLE SOLVED
  • Private key (hex) : 000000000000000000000000000000000000000000000000000000e9ae4933d6
  • Hops: 335150
  • Average time to solve: 1.47 sec

I can bet that you can make a .so file that works 20 times faster point_addition &  point_doubling than this. Grin
I bet that no matter how well you think an .so file based on this algorithm runs, it will never reach even 1 million jumps/s.

Let's idealize this a little to prove my statement, and still be grounded in reality check.

We have one processor, let's pretend it runs at 5 Ghz. Let's pretend it solely does point addition, and ignore any other overhead like having to read or write data to system memory, having to propagate carries, etc etc

A single point addition according to your program requires:

m = (y1 - y2) / (x1 - x2)
x3 = m**2 - x1 - x2
y3 = m(x2 - x3) - y2

So, 1 inverse, 2 multiplications, 1 squaring, 6 additions, all mod P, on 256-bit numbers.

Let's assume one single 64-bit basic operation (add, multiply) takes one cycle (hint: it doesn't).

1 addition mod P ~= 4 or 8 adds = 4 cycles
1 squaring mod P = 16 multiplications for product, 8 + 2 more muls for reduce, and 41 adds
1 multiplication mod P = 42 multiplications + 41 additions
1 inverse = a shitload of cycles, let's simplify to ~30 multiplications mod P

Total estimate for a single point addition:
1 inv = 30 mul
30 mul + 2 mul + 1 sqr + 6 add =
1344 64-bit muls + 1312 adds + 26 mul + 41 adds + 48 adds

~= 2771 cycles

5 Ghz / 2771 = 1.804.402 operations / s

And this is a very very idealistic upper bound, without considering ANY of the additional real-life instructions needed to run an point addition.

On what planet do you think that sticking to this algorithm can run at "20x speed"?
member
Activity: 499
Merit: 38
I'm wondering if going from GMP to iceland's package, would offer some speed up.


Here you go, all mathematics go through Iceland's package:


Code:
import time, random
import secp256k1 as ice

modulo = ice.N
Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
PG = Gx, Gy
Z = ice.Zero

def to_bytes(point):
    x_bytes = point[0].to_bytes(32, byteorder='big')
    y_bytes = point[1].to_bytes(32, byteorder='big')
    return b'\x04' + x_bytes + y_bytes

def from_bytes(point_bytes):
    x = int.from_bytes(point_bytes[1:33], byteorder='big')
    y = int.from_bytes(point_bytes[33:65], byteorder='big')
    return x, y

def add(P, Q, p=modulo):
    if P == Z: return Q
    if Q == Z: return P
    Px, Py = P; Qx, Qy = Q
    if Px == Qx and (Py != Qy or Py == 0): return Z
    P_bytes = to_bytes(P)
    Q_bytes = to_bytes(Q)
    result_bytes = ice.point_addition(P_bytes, Q_bytes)
    result = from_bytes(result_bytes)    
    return result

def mul2(P, p=modulo):
    if P == Z: return Z
    P_bytes = to_bytes(P)
    result_bytes = ice.point_doubling(P_bytes)
    result = from_bytes(result_bytes)  
    return result

def mulk(k, P=PG, p=modulo):
    result = Z
    addend = P
    while k > 0:
        if k & 1: result = add(result, addend, p)
        addend = mul2(addend, p)
        k >>= 1
    return result

def X2Y(X, y_parity, p=modulo):
    X_hex = '%064x' % X
    is_even = (y_parity == 0)
    Y_bytes = ice.get_x_to_y(X_hex, is_even)
    Y = int.from_bytes(Y_bytes, byteorder='big')
    if Y >= p:
        Y = p - Y
    return Y

def comparator(P, Pindex, DP_rarity, t, W, w, T):
    if P[0] % DP_rarity == 0:
        T.append(P[0])
        t.append(Pindex)
        common_elements = set(T).intersection(W)
        if common_elements:
            match = common_elements.pop()
            tT = t[T.index(match)]
            wW = w[W.index(match)]
            HEX = '%064x' % abs(tT - wW)
            dec = int(HEX, 16)
            total_time = time.time() - starttime
            print(f"\n[+] total time: {total_time:.2f} sec")
            print_status(time.ctime(), 'PUZZLE SOLVED')
            print(f"\033[32m[+] Private key (hex) : {HEX} \033[0m")
            log_solution(total_time, dec, HEX)
            return True
    return False

def search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper, lower):
    t = [lower + random.randint(0, upper - lower) for _ in range(Nt)]
    T = [mulk(ti) for ti in t]
    w = [random.randint(0, upper - lower) for _ in range(Nw)]
    W = [add(W0, mulk(wi)) for wi in w]
    Hops, Hops_old = 0, 0
    t0 = time.time()
    solved = False
    while not solved:
        for k in range(Nt + Nw):
            Hops += 1
            if k < Nt:
                pw = T[k][0] % hop_modulo
                solved = comparator(T[k], t[k], DP_rarity, T, t, W, w)
                if solved: break
                t[k] += 1 << pw
                T[k] = add(P[pw], T[k])
            else:
                k -= Nw
                pw = W[k][0] % hop_modulo
                solved = comparator(W[k], w[k], DP_rarity, W, w, T, t)
                if solved: break
                w[k] += 1 << pw
                W[k] = add(P[pw], W[k])
        t1 = time.time()
        elapsed_time = t1 - starttime
        if (t1 - t0) > 1:
            hops_per_second = (Hops - Hops_old) / (t1 - t0)
            hours, rem = divmod(elapsed_time, 3600)
            minutes, seconds = divmod(rem, 60)
            elapsed_time_str = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
            print(f'[+] [Hops: {hops_per_second:.0f} h/s] [{elapsed_time_str}]', end='\r', flush=True)
            t0 = t1
            Hops_old = Hops
    print('\r[+] Hops:', Hops)
    print('[+] Average time to solve: %.2f sec' % ((time.time() - starttime)))

def print_status(t, message):
    print(f"\033[?25l\033[01;33m[+]\033[32m KANGAROO: \033[01;33m{t}\033[0m {message}")

def print_puzzle_info(puzzle, lower, upper, X, Y):
    print(f"[+] [Puzzle]: {puzzle}")
    print(f"[+] [Lower range limit]: {hex(lower)}")
    print(f"[+] [Upper range limit]: {hex(upper)}")
    print(f"[+] [EC Point Coordinate X]: {hex(X)}")
    print(f"[+] [EC Point Coordinate Y]: {hex(Y)}")

def log_solution(total_time, dec, HEX):
    t = time.ctime()
    dash_line = '-' * 140
    with open("KEYFOUNDKEYFOUND.txt", "a") as file:
        file.write(f"\n{dash_line}")
        file.write("\n\nSOLVED " + t)
        file.write(f"\nTotal Time: {total_time:.2f} sec")
        file.write("\nPrivate Key (decimal): " + str(dec))
        file.write("\nPrivate Key (hex): " + HEX)
        file.write(f"\n{dash_line}")

t = time.ctime()
print_status(t, "")

puzzle = 40
compressed_public_key = "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4"
kangaroo_power = 5
lower = 2 ** (puzzle - 1)
upper = (2 ** puzzle) - 1

DP_rarity = 1 << ((puzzle - 2 * kangaroo_power) // 2 - 2)
hop_modulo = (puzzle - 1) // 2 + kangaroo_power

Nt = 2 ** kangaroo_power
Nw = 2 ** kangaroo_power

if len(compressed_public_key) == 66:
    X = int(compressed_public_key[2:66], 16)
    y_parity = int(compressed_public_key[:2]) - 2
    Y = X2Y(X, y_parity)
else:
    print("[error] pubkey len(66/130) invalid!")

W0 = (X, Y)
starttime = time.time()
print_puzzle_info(puzzle, lower, upper, X, Y)

t, W, w, T = [], [], [], []

random.seed()

P = [PG]
for k in range(255):
    P.append(mul2(P[k]))

solved = search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper, lower)

  • KANGAROO: Sun Jul 14 16:01:51 2024
  • [Puzzle]: 40
  • [Lower range limit]: 0x8000000000
  • [Upper range limit]: 0xffffffffff
  • [EC Point Coordinate X]: 0xa2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4
  • [EC Point Coordinate Y]: 0x7ba1a987013e78aef5295bf842749bdf97e25336a82458bbaba8c00d16a79ea7
  • [Hops: 229969 h/s] [00:00:01]
  • total time: 1.47 sec
  • KANGAROO: Sun Jul 14 16:01:53 2024 PUZZLE SOLVED
  • Private key (hex) : 000000000000000000000000000000000000000000000000000000e9ae4933d6
  • Hops: 335150
  • Average time to solve: 1.47 sec

I can bet that you can make a .so file that works 20 times faster point_addition &  point_doubling than this. Grin
newbie
Activity: 22
Merit: 1
Hello everyone! I found the key to puzzle 66, but now I have another problem: how to withdraw the funds so that no one can intercept them with a bot? Please repost this message so the creator sees it! Maybe someone can tweet this so that the owners of large pools can respond, whether they can add the transaction to the next block when it is found, without broadcasting it to the network?
Pls, HELP ME!!!!!
newbie
Activity: 1
Merit: 0
Guys, here's a new puzzle challenge from the channel https://www.youtube.com/watch?v=LkejrZuQadg, this challenge consists of locating the private key of the address 19L9vivFCPJnAVDsjZ76mF2ZiTLKFUXEpV which is in the same range as puzzle 66, but with a dot , according to the creator, next Friday, he will request a transfer, the objective would be to export the public key on the blockchain and test whether it would be possible for someone to intercept the transfer before it is completed through the RBF, thus removing doubts whether The same thing could happen with puzzle 66, so whoever has the BOTs being heated could do this test with this key. hahahaha.

Anyway, you already know the day, you just need to be more agile than the process on the blockchain, according to the creator, he will place the transaction at the lowest possible rate, precisely to understand if it would be possible for someone to intercept this transaction and withdraw before him, good luck.

Creator:
https://www.youtube.com/watch?v=LkejrZuQadg

Address: 19L9vivFCPJnAVDsjZ76mF2ZiTLKFUXEpV
Range: 20000000000000000:3ffffffffffffffff

That's cool , i'm waiting for this
newbie
Activity: 23
Merit: 0
Guys, here's a new puzzle challenge from the channel https://www.youtube.com/watch?v=LkejrZuQadg, this challenge consists of locating the private key of the address 19L9vivFCPJnAVDsjZ76mF2ZiTLKFUXEpV which is in the same range as puzzle 66, but with a dot , according to the creator, next Friday, he will request a transfer, the objective would be to export the public key on the blockchain and test whether it would be possible for someone to intercept the transfer before it is completed through the RBF, thus removing doubts whether The same thing could happen with puzzle 66, so whoever has the BOTs being heated could do this test with this key. hahahaha.

Anyway, you already know the day, you just need to be more agile than the process on the blockchain, according to the creator, he will place the transaction at the lowest possible rate, precisely to understand if it would be possible for someone to intercept this transaction and withdraw before him, good luck.

Creator:
https://www.youtube.com/watch?v=LkejrZuQadg

Address: 19L9vivFCPJnAVDsjZ76mF2ZiTLKFUXEpV
Range: 20000000000000000:3ffffffffffffffff
member
Activity: 499
Merit: 38
You can easily get 11M hops/s on single-core CPU

Do a single inverse (10-20x speedup).
Use carry-free representation (1-2x speedup).
Dump GMP, it does generic arithmetic, not specialized to our needs (> 75% speedup).


I only know how to do this with OpenSSL's BIGNUM and functions like BN_add, BN_sub, BN_mul, BN_mod, etc., for arithmetic operations. But I don't believe that the speed will be that high. Maybe 5M hops/s on single-core CPU.

member
Activity: 165
Merit: 26
You can easily get 11M hops/s on single-core CPU

Do a single inverse (10-20x speedup).
Use carry-free representation (1-2x speedup).
Dump GMP, it does generic arithmetic, not specialized to our needs (> 75% speedup).

With GMP, using MPN (lowest level possible) calls, and naive point addition like the one above, I never topped 700 K/s. In plain C.

Likely it would be even faster than 11-12 M/s with careful choices so that all data resides in CPU cache and the core is strongly assigned (no context switch).

But IMO it's just an exercise. The cost per kangaroo jump, in watts, is not worth it even if the speed would be triple or whatever. You might also get a fried CPU. Serve with potatoes and ketchup.
member
Activity: 499
Merit: 38
I'm wondering if going from GMP to iceland's package, would offer some speed up.


https://github.com/iceland2k14/kangaroo.git
from here?


# time python3 kangaroo.py -p 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 -keyspace 8000000000:ffffffffff
  • Starting CPU Kangaroo.... Please Wait     Version [ 15112021 ]
  • Search Mode: Range search Continuous in the given range
  • Working on Pubkey: 04a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d47ba1a987013e7 8aef5295bf842749bdf97e25336a82458bbaba8c00d16a79ea7
  • Using  [Number of CPU Threads: 11] [DP size: 10] [MaxStep: 2]
  • Scanning Range           0x8000000000 : 0x100007fffffffff
  • [3074.58 TeraKeys/s][Kang 11264][Count 2^28.20/2^29.07][Elapsed 08s][Dead 2][RAM 29.6MB/45.1MB] 
============== KEYFOUND ==============
Kangaroo FOUND PrivateKey : 0x000000000000000000000000000000000000000000000000000000e9ae4933d6
======================================
  • Program Finished

real   0m8.687s
user   1m31.744s
sys   0m0.095s

It has not been updated for a long time.

No, I meant using his secp256k1 library, integrating it into another kangaroo python script. I haven't really looked at his kangaroo library.

I understand, it's not a bad idea to try. I tried to see what was in his  kangaroo .so file from

https://dogbolt.org/


Best result is from Retargetable Decompiler(RetDec)

the decompiled output contains low-level assembly instructions and it's challenging to fully reconstruct high-level source code from compiled binaries, but you can see roughly what the program accesses and how.

I think he packaged the code with Cython a Python compiler.
full member
Activity: 1162
Merit: 237
Shooters Shoot...
I'm wondering if going from GMP to iceland's package, would offer some speed up.


https://github.com/iceland2k14/kangaroo.git
from here?


# time python3 kangaroo.py -p 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 -keyspace 8000000000:ffffffffff
  • Starting CPU Kangaroo.... Please Wait     Version [ 15112021 ]
  • Search Mode: Range search Continuous in the given range
  • Working on Pubkey: 04a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d47ba1a987013e7 8aef5295bf842749bdf97e25336a82458bbaba8c00d16a79ea7
  • Using  [Number of CPU Threads: 11] [DP size: 10] [MaxStep: 2]
  • Scanning Range           0x8000000000 : 0x100007fffffffff
  • [3074.58 TeraKeys/s][Kang 11264][Count 2^28.20/2^29.07][Elapsed 08s][Dead 2][RAM 29.6MB/45.1MB] 
============== KEYFOUND ==============
Kangaroo FOUND PrivateKey : 0x000000000000000000000000000000000000000000000000000000e9ae4933d6
======================================
  • Program Finished

real   0m8.687s
user   1m31.744s
sys   0m0.095s

It has not been updated for a long time.

No, I meant using his secp256k1 library, integrating it into another kangaroo python script. I haven't really looked at his kangaroo library.
member
Activity: 499
Merit: 38
I'm wondering if going from GMP to iceland's package, would offer some speed up.


https://github.com/iceland2k14/kangaroo.git
from here?


# time python3 kangaroo.py -p 03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 -keyspace 8000000000:ffffffffff
  • Starting CPU Kangaroo.... Please Wait     Version [ 15112021 ]
  • Search Mode: Range search Continuous in the given range
  • Working on Pubkey: 04a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d47ba1a987013e7 8aef5295bf842749bdf97e25336a82458bbaba8c00d16a79ea7
  • Using  [Number of CPU Threads: 11] [DP size: 10] [MaxStep: 2]
  • Scanning Range           0x8000000000 : 0x100007fffffffff
  • [3074.58 TeraKeys/s][Kang 11264][Count 2^28.20/2^29.07][Elapsed 08s][Dead 2][RAM 29.6MB/45.1MB] 
============== KEYFOUND ==============
Kangaroo FOUND PrivateKey : 0x000000000000000000000000000000000000000000000000000000e9ae4933d6
======================================
  • Program Finished

real   0m8.687s
user   1m31.744s
sys   0m0.095s

It has not been updated for a long time.
jr. member
Activity: 42
Merit: 0
So some how i got side tracked by this kangaroo thing cause i thought i saw a way to make it better. look.

  • KANGAROO: Fri Jul 12 23:59:50 2024
  • [Puzzle]: 40
  • [Lower range limit]: 549755813888
  • [Upper range limit]: 1099511627775
  • [X]: 73698089885969865917178217585365130397293864653143545863290470632977971667156
  • [Y]: 55920112788027504860697624221258924004816541552996850637631037640326076931751
  • P-table prepared
  • Hops: 472063.55 h/s
  • PUZZLE SOLVED: Fri Jul 12 23:59:56 2024
  • Private key (dec): 1003651412950
  • Hops: 2970544
  • Average time to solve: 6.33 sec
Same here... I love small simple scripts like these.
I start to get lost when I see a script that has over 1000 lines of code.
newbie
Activity: 7
Merit: 1
So some how i got side tracked by this kangaroo thing cause i thought i saw a way to make it better. look.

  • KANGAROO: Fri Jul 12 23:59:50 2024
  • [Puzzle]: 40
  • [Lower range limit]: 549755813888
  • [Upper range limit]: 1099511627775
  • [X]: 73698089885969865917178217585365130397293864653143545863290470632977971667156
  • [Y]: 55920112788027504860697624221258924004816541552996850637631037640326076931751
  • P-table prepared
  • Hops: 472063.55 h/s
  • PUZZLE SOLVED: Fri Jul 12 23:59:56 2024
  • Private key (dec): 1003651412950
  • Hops: 2970544
  • Average time to solve: 6.33 sec
full member
Activity: 1162
Merit: 237
Shooters Shoot...
hi there wandering,

what kind of code you have to do this speed next to his code, tweaked it,
got it for sharing ready, thanks for sharing,
i got the 640000 whatever it said with the original.,
so would be nice to have a faster one..

I have almost the same speed regardless of whether I use Python, Rust, or C++, as long
as it's based on a script from here


https://fe57.org/forum/thread.php?board=4&thema=1#1


This is because I have exactly the same GMP library and the same formulas everywhere.

Ole, FE57, oldie but goodie!  I believe it's sprinkled in the python script as well.  But this was one of the first Python scripts that I remember seeing put out for the public. Many worked on it.

https://github.com/Telariust/pollard-kangaroo

I'm wondering if going from GMP to iceland's package, would offer some speed up.
member
Activity: 499
Merit: 38
hi there wandering,

what kind of code you have to do this speed next to his code, tweaked it,
got it for sharing ready, thanks for sharing,
i got the 640000 whatever it said with the original.,
so would be nice to have a faster one..

I have almost the same speed regardless of whether I use Python, Rust, or C++, as long
as it's based on a script from here


https://fe57.org/forum/thread.php?board=4&thema=1#1


This is because I have exactly the same GMP library and the same formulas everywhere.
full member
Activity: 431
Merit: 105
hi there wandering,

what kind of code you have to do this speed next to his code, tweaked it,
got it for sharing ready, thanks for sharing,
i got the 640000 whatever it said with the original.,
so would be nice to have a faster one..
full member
Activity: 1162
Merit: 237
Shooters Shoot...
Have fun with your kangaroo!


  • KANGAROO: Sat Jul 13 02:26:56 2024
  • [Puzzle]: 40
  • [Lower range limit]: 549755813888
  • [Upper range limit]: 1099511627775
  • [X]: 73698089885969865917178217585365130397293864653143545863290470632977971667156
  • [Y]: 55920112788027504860697624221258924004816541552996850637631037640326076931751
  • P-table prepared
  • Hops: 423183 h/s
  • PUZZLE SOLVED: Sat Jul 13 02:27:00 2024
  • Private key (dec): 1003651412950
  • Hops: 1366627
  • Average time to solve: 3 sec


More than 420K hops per second on a single core.
Kangaroo power value is crucial in determining the efficiency for solving puzzle. It affects the balance between the number of "tame" and "wild" kangaroos and the size of the steps they take. Finding the optimal value can require manually calibration based on the specific puzzle number.

Thanks to 57fe for idea  Wink

Single core, Python script:

Code:
[  0d 00:00:03s ; 386.9K j/s; 1.2Mj 78.6%; dp/kgr=5.0;  0d 00:00:00s ]
[prvkey#40] 0x000000000000000000000000000000000000000000000000000000e9ae4933d6
[i] [2^39.0|-------------------------------------------------K----------|2^40.0]
[i] 386.1K j/s; 1.5Mj of 1.5Mj 100.6%; DP T+W=6+5=11; dp/kgr=5.5
[runtime]  0d 00:00:03s

And it could be faster with some tweaks.
member
Activity: 499
Merit: 38
Have fun with your kangaroo!

I am still on Earth.   Grin

I don't even have a GPU card right now. Here is Kangaroo C++ in one single file:

kangaroo.cpp
Code:
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;

typedef array Point;

const mpz_class modulo("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
const mpz_class Gx("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16);
const mpz_class Gy("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 16);
const Point PG = {Gx, Gy};
const Point Z = {0, 0};

auto starttime = chrono::high_resolution_clock::now();

Point add(const Point& P, const Point& Q, const mpz_class& p = modulo) {
    if (P == Z) return Q;
    if (Q == Z) return P;
    const mpz_class& Px = P[0];
    const mpz_class& Py = P[1];
    const mpz_class& Qx = Q[0];
    const mpz_class& Qy = Q[1];
    if (Px == Qx && (Py != Qy || Py == 0)) return Z;
    mpz_class m, num, denom, inv;
    if (Px == Qx) {
        num = 3 * Px * Px;
        denom = 2 * Py;
    } else {
        num = Qy - Py;
        denom = Qx - Px;
    }
    mpz_invert(inv.get_mpz_t(), denom.get_mpz_t(), p.get_mpz_t());
    m = (num * inv) % p;
    mpz_class x = (m * m - Px - Qx) % p;
    if (x < 0) x += p;
    mpz_class y = (m * (Px - x) - Py) % p;
    if (y < 0) y += p;
    return {x, y};
}


Point mul(const mpz_class& k, const Point& P = PG, const mpz_class& p = modulo) {
    Point R = Z;
    Point current = P;
    mpz_class k_copy = k;
    while (k_copy > 0) {
        if (k_copy % 2 == 1) {
            R = add(R, current, p);
        }
        current = add(current, current, p);
        k_copy >>= 1;
    }
    return R;
}

mpz_class X2Y(const mpz_class& X, int y_parity, const mpz_class& p = modulo) {
    mpz_class X_cubed = (X * X * X) % p;
    mpz_class tmp = (X_cubed + mpz_class(7)) % p;
    mpz_class Y;
    mpz_class exp = (p + mpz_class(1)) / mpz_class(4);
    mpz_powm(Y.get_mpz_t(), tmp.get_mpz_t(), exp.get_mpz_t(), p.get_mpz_t());
    if ((Y % 2) != y_parity) {
        Y = p - Y;
    }
    return Y;
}

bool comparator(const Point& P, const mpz_class& Pindex, const mpz_class& DP_rarity,
                std::vector& T, std::vector& t, const std::vector& W,
                const std::vector& w) {
    if (P[0] % DP_rarity == 0) {
        T.push_back(P);
        t.push_back(Pindex);
        std::set T_set;
        for (const auto& tp : T) T_set.insert(tp[0]);
        for (const auto& match : W) {
            auto it = find(T.begin(), T.end(), match);
            if (it != T.end()) {
                int index = distance(T.begin(), it);
                mpz_class tP = t[index];
                mpz_class wP = w[distance(W.begin(), find(W.begin(), W.end(), match))];
                mpz_class dec = abs(tP - wP);
                auto end = chrono::system_clock::now();
                time_t end_time = chrono::system_clock::to_time_t(end);
                cout << "\n\033[01;33m[+]\033[32m PUZZLE SOLVED: \033[32m" << ctime(&end_time)
                     << "\r";
                cout << "\r\033[01;33m[+]\033[32m Private key (dec): \033[32m" << dec << "\033[0m"
                     << endl;
                ofstream file("KEYFOUNDKEYFOUND.txt", ios::app);
                file << "\n" << string(140, '-') << endl;
                file << "SOLVED " << ctime(&end_time);
                file << "Private Key (decimal): " << dec << endl;
                file << "Private Key (hex): " << dec.get_str(16) << endl;
                file << string(140, '-') << endl;
                file.close();
                return true;
            }
        }
    }
    return false;
}

vector generate_powers_of_two(int hop_modulo) {
    vector powers(hop_modulo);
    for (int pw = 0; pw < hop_modulo; ++pw) {
        powers[pw] = mpz_class(1) << pw;
    }
    return powers;
}

string search(const vector& P, const Point& W0, const mpz_class& DP_rarity, int Nw, int Nt, int hop_modulo,
              const mpz_class& upper_range_limit, const mpz_class& lower_range_limit, const vector& powers_of_two) {
    vector T(Nt, Z), W(Nw, Z);
    vector t(Nt), w(Nw);

    gmp_randclass rand(gmp_randinit_default);

    for (int k = 0; k < Nt; ++k) {
        t[k] = lower_range_limit + rand.get_z_range(upper_range_limit - lower_range_limit);
        T[k] = mul(t[k]);
    }

    for (int k = 0; k < Nw; ++k) {
        w[k] = rand.get_z_range(upper_range_limit - lower_range_limit);
        W[k] = add(W0, mul(w[k]));
    }

    long long Hops = 0, Hops_old = 0;
    auto t0 = chrono::high_resolution_clock::now();
    vector memo(hop_modulo);

    for (int pw = 0; pw < hop_modulo; ++pw) {
        memo[pw] = powers_of_two[pw];
    }

    bool solved = false;
    while (!solved) {
        for (int k = 0; k < (Nt + Nw); ++k) {
            ++Hops;
            if (k < Nt) {
                mpz_class pw = T[k][0] % hop_modulo;
                solved = comparator(T[k], t[k], DP_rarity, T, t, W, w);
                if (solved) break;
                t[k] += memo[pw.get_ui()];
                T[k] = add(P[pw.get_ui()], T[k], modulo);
            } else {
                int n = k - Nw;
                mpz_class pw = W[n][0] % hop_modulo;
                solved = comparator(W[n], w[n], DP_rarity, W, w, T, t);
                if (solved) break;
                w[n] += memo[pw.get_ui()];
                W[n] = add(P[pw.get_ui()], W[n], modulo);
            }
        }

        auto t1 = chrono::high_resolution_clock::now();
        double elapsed_seconds = chrono::duration_cast>(t1 - t0).count();
        if (elapsed_seconds > 2.0) {
            cout << "\r[+] Hops: " << ((Hops - Hops_old) / elapsed_seconds) << " h/s" << "\r";
            cout << flush;
            t0 = t1;
            Hops_old = Hops;
        }
    }

    cout << "\r[+] Hops: " << Hops << endl;
    auto end = chrono::high_resolution_clock::now();
    double elapsed_seconds = chrono::duration_cast>(end - starttime).count();
    return "\r[+] Solution time: " + to_string(elapsed_seconds) + " sec";
}

int main() {
    int puzzle = 40;
    string compressed_public_key =
    "03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4";
    int kangaroo_power = 5;
    mpz_class lower_range_limit = mpz_class(1) << (puzzle - 1);
    mpz_class upper_range_limit = (mpz_class(1) << puzzle) - 1;

    mpz_class DP_rarity = mpz_class(1) << ((puzzle - 2 * kangaroo_power) / 2 - 2);
    int hop_modulo = ((puzzle - 1) / 2) + kangaroo_power;

    int Nt = 1 << kangaroo_power;
    int Nw = 1 << kangaroo_power;

    vector powers_of_two = generate_powers_of_two(hop_modulo);

    mpz_class X, Y;
    if (compressed_public_key.length() == 66) {
        X = mpz_class(compressed_public_key.substr(2), 16);
        Y = X2Y(X, stoi(compressed_public_key.substr(0, 2)) - 2);
    } else {
        cout << "[error] pubkey len(66/130) invalid!" << endl;
        return 1;
    }

    Point W0 = {X, Y};
    auto starttime = chrono::high_resolution_clock::now();
    time_t currentTime = time(nullptr);
    cout << "\r\033[01;33m[+]\033[32m KANGAROO: \033[01;33m" << ctime(¤tTime) << "\033[0m" << "\r";
    cout << "[+] [Puzzle]: " << puzzle << endl;
    cout << "[+] [Lower range limit]: " << lower_range_limit << endl;
    cout << "[+] [Upper range limit]: " << upper_range_limit << endl;
    cout << "[+] [X]: " << X << endl;
    cout << "[+] [Y]: " << Y << endl;

    vector P = {PG};
    P.reserve(256);
    for (int k = 0; k < 255; ++k) {
        P.push_back(add(P[k], P[k]));
    }
    cout << "[+] P-table prepared" << endl;

    unsigned long seed = static_cast(time(nullptr));
    gmp_randclass rand(gmp_randinit_default);
    rand.seed(seed);

    search(P, W0, DP_rarity, Nw, Nt, hop_modulo, upper_range_limit, lower_range_limit, powers_of_two);

    cout << "\r[+] Average time to solve: " << chrono::duration_cast(chrono::high_resolution_clock::now() - starttime).count() << " sec" << endl;

    return 0;
}

Build command:
Code:
g++ -o kangaroo kangaroo.cpp -m64 -march=native -mtune=native -mssse3 -Wall -Wextra -ftree-vectorize -flto -O3 -funroll-loops -lgmp -lgmpxx 

#./kangaroo

  • KANGAROO: Sat Jul 13 18:30:32 2024
  • [Puzzle]: 40
  • [Lower range limit]: 549755813888
  • [Upper range limit]: 1099511627775
  • [X]: 73698089885969865917178217585365130397293864653143545863290470632977971667156
  • [Y]: 55920112788027504860697624221258924004816541552996850637631037640326076931751
  • P-table prepared
  • Hops: 456661 h/s
  • PUZZLE SOLVED: Sat Jul 13 18:30:35 2024
  • Private key (dec): 1003651412950
  • Hops: 1366627
  • Average time to solve: 2 sec

More than 450K hops per second on a single core.
Kangaroo power value is crucial in determining the efficiency for solving puzzle. It affects the balance between the number of "tame" and "wild" kangaroos and the size of the steps they take. Finding the optimal value can require manually calibration based on the specific puzzle number.

Thanks to 57fe for idea  Wink
member
Activity: 165
Merit: 26
So 2 days ago I was convinced I had it, today i feel further away than ever. What I've been doing is converting some features to binary and carefully engineering matrices that convert them into quantum states. I've identified a pattern in the data that is very hard to express. At first I thought this pattern I have been trying to zero in on was the puzzle, but the more I work the more convinced I become that what I am looking at is not the pattern of the puzzle. In Bitcoin, the one-way nature of elliptic curve point multiplication on the secp256k1 curve ensures that while a private key can easily generate a public key and address, reversing the process to derive the private key from the public key or address is computationally infeasible due to the hardness of the Elliptic Curve Discrete Logarithm Problem. Except I think there is leakage, in the data. It's just hidden really, really well. Anyway the search continues. Have fun with your kangaroo!
Tho let the wildest Kangaroos into the realm of quantum entanglement and free them of collision harmfulness. A wild mutation out of nowhere will emerge at once from the multiverse of Schrodinger cats, as the living proof of certainty of uncertainty. Make Heisenberg proud and escape us of the hardness of ECDLP's secret hidden patterns. Let's embrace that Public Key is just a mind construct, such like time, out of our control. Don't try to break it, let's dance gracefully around it and forget it even exists.

And if ECDLP dares to fight, summon all qubits from all realities to join the GBB (Great Bits Battle). Take control over the full quantum state and derive all the keys at once in a single Matrix Transition, for your Desired Outcome. Show'em who the boss is. Make your own reality!

Meow.
newbie
Activity: 7
Merit: 1
So 2 days ago I was convinced I had it, today i feel further away than ever. What I've been doing is converting some features to binary and carefully engineering matrices that convert them into quantum states. I've identified a pattern in the data that is very hard to express. At first I thought this pattern I have been trying to zero in on was the puzzle, but the more I work the more convinced I become that what I am looking at is not the pattern of the puzzle. In Bitcoin, the one-way nature of elliptic curve point multiplication on the secp256k1 curve ensures that while a private key can easily generate a public key and address, reversing the process to derive the private key from the public key or address is computationally infeasible due to the hardness of the Elliptic Curve Discrete Logarithm Problem. Except I think there is leakage, in the data. It's just hidden really, really well. Anyway the search continues. Have fun with your kangaroo!
member
Activity: 194
Merit: 14

Yes, I read about it here on the forum! thanks for the answer! But there was a message on this branch with a division by 2. and there was an answer to it, but I don't remember which one and on which page these messages are also I don't remember. But the question is, if it were possible to divide public keys by 2? would it make it easier to find the private key? what I remember seems to be the answer to that message was "if we could divide the public key by 2, then finding the private key would be easy, and it seems to have given the formula", if I was wrong, please correct me!

I suspect and breath a bad digaran breath here...

He told you and explained indirectly that it doesn't help find the original private key. You'll just be in a infinite loop with unknown keys that cannot be found. So you'll endup having trying to find some random private keys the same way as finding the orginal key if you decide to divide or even multiple.


Yes you can divide any key by 2, 3 or even 9999999999999999999999 but it doesn't make any sense, because the key won't really be divideded according to our needs because of floats

EDIT: I might have understood your point. YES you could divide the key by 2 since you have 50 % 50 % that its even or odd and if you're lucky enough if the original private key ends with 2, 4, 8 or 10 (even numbers) yes you could divide and cut a little bit of its length and size but then what? What's next? The new key is still big as hell to be found and searched. And if you try to keep dividing the divided keys by 2 you will definitely f*ck up with a key and divide a key that ends with a odd number ( 1 , 3 , 5 , 7 , 9 ) and then good morning u will end with a random key on the curve that is totally unknown.

It doesn't help.
Pages:
Jump to: