Bitcoin Forum
April 27, 2026, 07:43:11 AM *
News: Latest Bitcoin Core release: 30.2 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 4 5 6 7 8 9 10 11 [12] 13 14 15 16 17 18 19 20 21 22 23 24 »  All
  Print  
Author Topic: Solving ECDLP with Kangaroos: Part 1 + 2 + RCKangaroo  (Read 17902 times)
This is a self-moderated topic. If you do not want to be moderated by the person who started this topic, create a new topic. (27 posts by 5+ users deleted.)
Akito S. M. Hosana
Jr. Member
*
Offline Offline

Activity: 420
Merit: 8


View Profile
March 08, 2025, 05:10:07 PM
 #221

How many rtx 4090 gpu needed to solve puzzle 135 using your software?

Around 2,500 RTX 4090 GPUs would take approximately two months to solve the puzzle. For Puzzle 140, you would need to be Elon Musk and have over 10,000 GPUs.
farou9
Newbie
*
Offline Offline

Activity: 89
Merit: 0


View Profile
March 18, 2025, 04:35:18 PM
 #222

how much time does it take to break 107 bit key using rckangaroo ?
kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 248


View Profile
March 18, 2025, 11:18:58 PM
 #223

how much time does it take to break 107 bit key using rckangaroo ?

It is well known that bit keys are a bit tough. Usually a single bit takes some effort, depending on how much of a hammer you use to crack it open. It also depends on your body constitution and any known medical conditions. Some people take them slow, others jump right on it with full force.

So 107 bits might take somewhere between one Planck time unit and some infinite amount of time well beyond after the last proton in the Universe decays.

Off the grid, training pigeons to broadcast signed messages.
farou9
Newbie
*
Offline Offline

Activity: 89
Merit: 0


View Profile
March 19, 2025, 02:08:09 PM
 #224

how much time does it take to break 107 bit key using rckangaroo ?

It is well known that bit keys are a bit tough. Usually a single bit takes some effort, depending on how much of a hammer you use to crack it open. It also depends on your body constitution and any known medical conditions. Some people take them slow, others jump right on it with full force.

So 107 bits might take somewhere between one Planck time unit and some infinite amount of time well beyond after the last proton in the Universe decays.

so my question is , let say we have 2^27 points stored in a file and we guarantee that one of theme's scalar is between 1 and 2^107 , what is the fastest approach we can take to solve it?
kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 248


View Profile
March 19, 2025, 04:58:39 PM
 #225

how much time does it take to break 107 bit key using rckangaroo ?

It is well known that bit keys are a bit tough. Usually a single bit takes some effort, depending on how much of a hammer you use to crack it open. It also depends on your body constitution and any known medical conditions. Some people take them slow, others jump right on it with full force.

So 107 bits might take somewhere between one Planck time unit and some infinite amount of time well beyond after the last proton in the Universe decays.

so my question is , let say we have 2^27 points stored in a file and we guarantee that one of theme's scalar is between 1 and 2^107 , what is the fastest approach we can take to solve it?


Easy-peasy. You need one tame kangaroo and 2^27 types of wild kangaroos. They all walk one step at a time until you have a tame-wildX collision or a wildX/wildX collision (same type of wild). Basically that's running 2^27 Kangaroo instances at once.

If some point indeed has a scalar less than 2^107 then the shenanigan stops after around 2^54 steps or so. But it may not, because we only used one wild kangaroo for every problem. What to do? Create a new wild kangaroo for each type and start over. This will, again take more or less than 2^54 steps.

By that time you'll have jumped some good 2^(27 + 54) * numberOfRestarts steps, that's 2^80 jumps at least. Equivalent of Puzzle 160. Multiply that by the number of restarts.

Or simply start off 2^27 Kangaroo instances. Set and forget, until one yields something. It may not. Who's to know.  Huh Grin

Off the grid, training pigeons to broadcast signed messages.
vaccar73
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
March 26, 2025, 07:19:47 AM
 #226

hi RetiredCoder, thank you for sharing your hard work with us, I am new to this, so I do not really understand much of what is mentioned here.

Have you posted any pictures of your hardware setup anywhere ?


Anyway I tested puzzle 85, I have two of the 3060M Frankenstein Cards in my desktop


Code:
C:\rck>RCKangaroo.exe -dp 16 -range 84 -start 1000000000000000000000 -pubkey 0329c4574a4fd8c810b7e42a4b398882b381bcd85e40c6883712912d167c83e73a
********************************************************************************
*                    RCKangaroo v3.0  (c) 2024 RetiredCoder                    *
********************************************************************************

This software is free and open-source: https://github.com/RetiredC
It demonstrates fast GPU implementation of SOTA Kangaroo method for solving ECDLP
Windows version
CUDA devices: 2, CUDA driver/runtime: 12.8/12.8
GPU 0: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 1, L2 size: 3072 KB
GPU 1: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 3, L2 size: 3072 KB
Total GPUs for work: 2

MAIN MODE

Solving public key
X: 29C4574A4FD8C810B7E42A4B398882B381BCD85E40C6883712912D167C83E73A
Y: 0E02C3AFD79913AB0961C95F12498F36A72FFA35C93AF27CEE30010FA6B51C53
Offset: 0000000000000000000000000000000000000000001000000000000000000000

Solving point: Range 84 bits, DP 16, start...
SOTA method, estimated ops: 2^42.202, RAM for DPs: 3.062 GB. DP and GPU overheads not included!
Estimated DPs per kangaroo: 39.253.
GPU 0: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPU 1: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPUs started...
MAIN: Speed: 3037 MKeys/s, Err: 0, DPs: 449K/77175K, Time: 0d:00h:00m/0d:00h:27m
MAIN: Speed: 3326 MKeys/s, Err: 0, DPs: 974K/77175K, Time: 0d:00h:00m/0d:00h:25m
MAIN: Speed: 3318 MKeys/s, Err: 0, DPs: 1484K/77175K, Time: 0d:00h:00m/0d:00h:25m

MAIN: Speed: 3244 MKeys/s, Err: 0, DPs: 109584K/77175K, Time: 0d:00h:36m/0d:00h:25m
MAIN: Speed: 3244 MKeys/s, Err: 0, DPs: 110079K/77175K, Time: 0d:00h:36m/0d:00h:25m
Stopping work ...
Point solved, K: 1.648 (with DP and GPU overheads)


PRIVATE KEY: 00000000000000000000000000000000000000000011720C4F018D51B8CEBBA8


C:\rck>
Cricktor
Legendary
*
Offline Offline

Activity: 1470
Merit: 3907



View Profile
March 26, 2025, 07:51:29 PM
 #227

Have you posted any pictures of your hardware setup anywhere ?

Are you too lazy to look for yourself in RetiredCoder's post history? Just invest a little bit of time yourself, instead of asking to be spoon-fed, how tiresome!

Quick overview: https://ninjastic.space/search?author=RetiredCoder  ---  Look, Ma, I can read!

███████████████████████████
███████▄████████████▄██████
████████▄████████▄████████
███▀█████▀▄███▄▀█████▀███
█████▀█▀▄██▀▀▀██▄▀█▀█████
███████▄███████████▄███████
███████████████████████████
███████▀███████████▀███████
████▄██▄▀██▄▄▄██▀▄██▄████
████▄████▄▀███▀▄████▄████
██▄███▀▀█▀██████▀█▀███▄███
██▀█▀████████████████▀█▀███
███████████████████████████
.
.Duelbits PREDICT..
█████████████████████████
█████████████████████████
███████████▀▀░░░░▀▀██████
██████████░░▄████▄░░████
█████████░░████████░░████
█████████░░████████░░████
█████████▄▀██████▀▄████
████████▀▀░░░▀▀▀▀░░▄█████
██████▀░░░░██▄▄▄▄████████
████▀░░░░▄███████████████
█████▄▄█████████████████
█████████████████████████
█████████████████████████
.
.WHERE EVERYTHING IS A MARKET..
█████
██
██







██
██
██████
Will Bitcoin hit $200,000
before January 1st 2027?

    No @1.15         Yes @6.00    
█████
██
██







██
██
██████

  CHECK MORE > 
vaccar73
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
March 31, 2025, 08:58:28 PM
 #228

Have you posted any pictures of your hardware setup anywhere ?

Are you too lazy to look for yourself in RetiredCoder's post history? Just invest a little bit of time yourself, instead of asking to be spoon-fed, how tiresome!

Quick overview: https://ninjastic.space/search?author=RetiredCoder  ---  Look, Ma, I can read!

why are you cluttering this thread with your useless pompous comments, stop hijacking peoples threads

OP asked to post speed results of different cards, so I did, it was my first post ever on this forum, and I purposely
 joined so that I can post my results and try to contribute some data to this thread, and then you reply to it with your snotty comment, what is wrong with you, get over yourself, you are not that important


Just because I showed interest in his hardware setup of 400 gpus, does not mean I want to be spoon fed, I was just wanting to see what a 400 gpu setup looks like.

I did look threw his post history and did not see pictures, maybe he posted them some where else, did you happen do consider that?


mjojo
Newbie
*
Online Online

Activity: 87
Merit: 0


View Profile
April 01, 2025, 07:01:45 AM
 #229

Have you posted any pictures of your hardware setup anywhere ?

Are you too lazy to look for yourself in RetiredCoder's post history? Just invest a little bit of time yourself, instead of asking to be spoon-fed, how tiresome!

Quick overview: https://ninjastic.space/search?author=RetiredCoder  ---  Look, Ma, I can read!

why are you cluttering this thread with your useless pompous comments, stop hijacking peoples threads

OP asked to post speed results of different cards, so I did, it was my first post ever on this forum, and I purposely
 joined so that I can post my results and try to contribute some data to this thread, and then you reply to it with your snotty comment, what is wrong with you, get over yourself, you are not that important


Just because I showed interest in his hardware setup of 400 gpus, does not mean I want to be spoon fed, I was just wanting to see what a 400 gpu setup looks like.

I did look threw his post history and did not see pictures, maybe he posted them some where else, did you happen do consider that?



I just wonder RC when he said use more than 400 gpus for solving P130, what kind of single motherboard can accept that all gpus for running RCkang?? I never see that even for mining rig when ETH in POW. so I just make conclusion (disclaimer maybe its wrong) he split the range of P130 and his 400 gpus in several rig. make illustration for explaining  the range is 200 and number gpus is 80 then split to 4 range (1 - 50, 50 - 100, 100 -150, 150 - 200) and each range use 20 gpus for running RCkang.
vaccar73
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
April 01, 2025, 07:36:46 PM
 #230

So I did another puzzle 84 test with 5 RTX 3060m Frankenstein cards, and 1 RTX 2070 card

It solved it in 10 minutes

It seem the MKeys/s goes down over time for some reason.

Any suggestions on what command parameters I should use for puzzle 135 with this current Gpu setup, I am not sure what the dp and tames parameters do exactly.

Would it be better to split up the 135 range ?

I hopes it is OK that I am asking questions, like I said before I am new to this.



Code:
C:\rck>RCKangaroo.exe -dp 16 -range 84 -start 1000000000000000000000 -pubkey 0329c4574a4fd8c810b7e42a4b398882b381bcd85e40c6883712912d167c83e73a
********************************************************************************
*                    RCKangaroo v3.0  (c) 2024 RetiredCoder                    *
********************************************************************************

This software is free and open-source: https://github.com/RetiredC
It demonstrates fast GPU implementation of SOTA Kangaroo method for solving ECDLP
Windows version
CUDA devices: 6, CUDA driver/runtime: 12.8/12.8
GPU 0: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 3, L2 size: 3072 KB
GPU 1: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 4, L2 size: 3072 KB
GPU 2: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 5, L2 size: 3072 KB
GPU 3: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 6, L2 size: 3072 KB
GPU 4: NVIDIA GeForce RTX 3060 Laptop GPU, 6.00 GB, 30 CUs, cap 8.6, PCI 8, L2 size: 3072 KB
GPU 5: NVIDIA GeForce RTX 2070, 8.00 GB, 36 CUs, cap 7.5, PCI 9, L2 size: 4096 KB
Total GPUs for work: 6

MAIN MODE

Solving public key
X: 29C4574A4FD8C810B7E42A4B398882B381BCD85E40C6883712912D167C83E73A
Y: 0E02C3AFD79913AB0961C95F12498F36A72FFA35C93AF27CEE30010FA6B51C53
Offset: 0000000000000000000000000000000000000000001000000000000000000000

Solving point: Range 84 bits, DP 16, start...
SOTA method, estimated ops: 2^42.202, RAM for DPs: 3.062 GB. DP and GPU overheads not included!
Estimated DPs per kangaroo: 12.662.
GPU 0: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPU 1: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPU 2: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPU 3: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPU 4: allocated 2899 MB, 983040 kangaroos. OldGpuMode: Yes
GPU 5: allocated 3477 MB, 1179648 kangaroos. OldGpuMode: Yes
GPUs started...
MAIN: Speed: 8204 MKeys/s, Err: 0, DPs: 1202K/77175K, Time: 0d:00h:00m/0d:00h:10m
MAIN: Speed: 10167 MKeys/s, Err: 0, DPs: 2774K/77175K, Time: 0d:00h:00m/0d:00h:08m
MAIN: Speed: 10142 MKeys/s, Err: 0, DPs: 4346K/77175K, Time: 0d:00h:00m/0d:00h:08m
MAIN: Speed: 10133 MKeys/s, Err: 0, DPs: 5872K/77175K, Time: 0d:00h:00m/0d:00h:08m
...
MAIN: Speed: 9439 MKeys/s, Err: 0, DPs: 92661K/77175K, Time: 0d:00h:10m/0d:00h:08m
MAIN: Speed: 9432 MKeys/s, Err: 0, DPs: 94099K/77175K, Time: 0d:00h:10m/0d:00h:08m
MAIN: Speed: 9440 MKeys/s, Err: 0, DPs: 95549K/77175K, Time: 0d:00h:10m/0d:00h:08m
Stopping work ...
Point solved, K: 1.432 (with DP and GPU overheads)


PRIVATE KEY: 00000000000000000000000000000000000000000011720C4F018D51B8CEBBA8


C:\rck>
kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 248


View Profile
April 02, 2025, 10:43:55 AM
 #231

It seem the MKeys/s goes down over time for some reason.

Yeah, I really wonder why as well. I think it has to do with some basic laws of physics, like... things heat up, and heat = energy, so you're losing more energy on disipating heat rather than on jumping RC kangaroos.

Any suggestions on what command parameters I should use for puzzle 135 with this current Gpu setup, I am not sure what the dp and tames parameters do exactly.

Would it be better to split up the 135 range ?

I hopes it is OK that I am asking questions, like I said before I am new to this.

I suggest you don't, since this a demo program. You will waste your time, you need a fully distributed software system, not an .exe Frankly, all of your questions are kinda stupid. Computing power is a commodity that can be bought, and you are asking people to show pictures of their oil drilling setup just because they drove a car. Or setup of their solar power grid just because they can light up their TV.

Off the grid, training pigeons to broadcast signed messages.
Dontbeatool2
Newbie
*
Offline Offline

Activity: 5
Merit: 0


View Profile
April 02, 2025, 04:20:57 PM
Last edit: April 04, 2025, 09:39:07 PM by Mr. Big
 #232

Hi all,

Here is my research about using kangaroo methods to solve ECDLP, Part 1.
Open source:  https://github.com/RetiredC/Kang-1

This software demonstrates various ways to solve the ECDLP using Kangaroos.
The required number of operations is approximately K * sqrt(range), where K is a coefficient that depends on the method used.
This software demonstrates four methods:

1 - Classic. The simplest method. There are two groups of kangaroos: tame and wild.
As soon as a collision between any tame and wild kangaroos happens, the ECDLP is solved.
In practice, K is approximately 2.10 for this method.

2 - 3-way. A more advanced method. There are three groups of kangaroos: tame, wild1, and wild2.
As soon as a collision happens between any two types of kangaroos, the ECDLP is solved.
In practice, K is approximately 1.60 for this method.

3 - Mirror. This method uses two groups of kangaroos and the symmetry of the elliptic curve to improve K.
Another trick is to reduce the range for wild kangaroos.
In practice, K is approximately 1.30 for this method.
The main issue with this method is that the kangaroos loop continuously.

4 - SOTA. This method uses three groups of kangaroos and the symmetry of the elliptic curve.
In practice, K is approximately 1.15 for this method. The main issue is the same as in the Mirror method.
I couldn’t find any papers about this method, so let's assume that I invented it Smiley

Important note: this software handles kangaroo looping in a very simple way.
This method is bad for large ranges higher than 100 bits.
Next part will demonstrate a good way to handle loops.

PS. Please don't post any stupid messages here, I will remove them.


Hello.
I find it difficult to understand C or C++ language in math operations.

Instead, I develop algorithms with the Fastecdsa Library in Python. I then switch to C or C++ for performance and then use it with GPU performance.

When I tried to read your article, I tried to understand what the value of K is based on. If I see this rule of 4 algorithm you mentioned (such as Fastecdsa or Sagemath in Python), I can join your conversation more.

Just wanted to point out. I am following your topic.

Thank you very much.

import threading
from hashlib import sha256
from ecdsa import SECP256k1, ellipticcurve
from binascii import unhexlify
import random

# Elliptic Curve Parameters
curve = SECP256k1.curve
G = SECP256k1.generator
order = SECP256k1.order

# Puzzle 135 Compressed Public Key
pubkey_hex = '02145d2611c823a396ef6712ce0f712f09b9b4f3135e3e0aa3230fb9b6d08d1e16'
pubkey_bytes = unhexlify(pubkey_hex)

def decompress_pubkey(pubkey_bytes):
    prefix = pubkey_bytes[0]
    x = int.from_bytes(pubkey_bytes[1:], 'big')
    alpha = (x ** 3 + 7) % curve.p()
    beta = pow(alpha, (curve.p() + 1) // 4, curve.p())
    y = beta if (beta % 2 == 0 and prefix == 2) or (beta % 2 == 1 and prefix == 3) else curve.p() - beta
    return ellipticcurve.Point(curve, x, y)

P_target = decompress_pubkey(pubkey_bytes)

# Puzzle 135 Range
lower_bound = int("4000000000000000000000000000000000", 16)
upper_bound = int("7fffffffffffffffffffffffffffffffff", 16)

# Generate fixed step table
def generate_step_table(n=64):
    random.seed(42)
    return [random.randint(1 << 16, 1 << 20) for _ in range(n)]

# Step function using point hash
def step_function(P, table):
    h = int(sha256(P.x().to_bytes(32, 'big') + P.y().to_bytes(32, 'big')).hexdigest(), 16)
    idx = h % len(table)
    s = table[idx]
    return s, s * G

# Walk logic
def kangaroo_walk(start_scalar, start_point, table, max_iters=500000):
    X = start_point
    a = start_scalar
    visited = {}

    for _ in range(max_iters):
        s, sG = step_function(X, table)
        X = X + sG
        a = (a + s) % order

        if (X.x() & ((1 << 20) - 1)) == 0:
            key = (X.x(), X.y())
            if key in visited:
                return visited[key], a, key
            visited[key] = a

    return None, a, None

# Threaded worker
def kangaroo_thread(thread_id, table):
    secret_scalar = random.randint(lower_bound, upper_bound)
    wild_point = secret_scalar * G
    _, wild_a, wild_key = kangaroo_walk(0, wild_point, table)

    tame_point = upper_bound * G
    _, tame_a, tame_key = kangaroo_walk(upper_bound, tame_point, table)

    if tame_key and wild_key and tame_key == wild_key:
        recovered = (tame_a - wild_a) % order
        if recovered == secret_scalar:
            print(f"[Thread {thread_id}] SUCCESS: Recovered key {hex(recovered)} matches {hex(secret_scalar)}")
        else:
            print(f"[Thread {thread_id}] Collision found but recovery failed.")
    else:
        print(f"[Thread {thread_id}] No collision found in this walk.")

# Main launcher
def run_kangaroo_threads(num_threads=10):
    step_table = generate_step_table()
    threads = []

    for i in range(num_threads):
        t = threading.Thread(target=kangaroo_thread, args=(i, step_table))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

# Run all
if __name__ == "__main__":
    run_kangaroo_threads(10)
This was closest I came with python hope it helps still raw.



Hi all,

Here is my research about using kangaroo methods to solve ECDLP, Part 1.
Open source:  https://github.com/RetiredC/Kang-1

This software demonstrates various ways to solve the ECDLP using Kangaroos.
The required number of operations is approximately K * sqrt(range), where K is a coefficient that depends on the method used.
This software demonstrates four methods:

1 - Classic. The simplest method. There are two groups of kangaroos: tame and wild.
As soon as a collision between any tame and wild kangaroos happens, the ECDLP is solved.
In practice, K is approximately 2.10 for this method.

2 - 3-way. A more advanced method. There are three groups of kangaroos: tame, wild1, and wild2.
As soon as a collision happens between any two types of kangaroos, the ECDLP is solved.
In practice, K is approximately 1.60 for this method.

3 - Mirror. This method uses two groups of kangaroos and the symmetry of the elliptic curve to improve K.
Another trick is to reduce the range for wild kangaroos.
In practice, K is approximately 1.30 for this method.
The main issue with this method is that the kangaroos loop continuously.

4 - SOTA. This method uses three groups of kangaroos and the symmetry of the elliptic curve.
In practice, K is approximately 1.15 for this method. The main issue is the same as in the Mirror method.
I couldn’t find any papers about this method, so let's assume that I invented it Smiley

Important note: this software handles kangaroo looping in a very simple way.
This method is bad for large ranges higher than 100 bits.
Next part will demonstrate a good way to handle loops.

PS. Please don't post any stupid messages here, I will remove them.


Hello.
I find it difficult to understand C or C++ language in math operations.

Instead, I develop algorithms with the Fastecdsa Library in Python. I then switch to C or C++ for performance and then use it with GPU performance.

When I tried to read your article, I tried to understand what the value of K is based on. If I see this rule of 4 algorithm you mentioned (such as Fastecdsa or Sagemath in Python), I can join your conversation more.

Just wanted to point out. I am following your topic.

Thank you very much.


sorry posted wrong script previously this is raw script with the new methods:
import threading
import multiprocessing
import hashlib
import cupy as cp
from ecdsa import SECP256k1, ellipticcurve
from binascii import unhexlify
import os

# === CONFIGURATION ===
NUM_THREADS = 10
BATCH_SIZE = 1_000_000
LOG_DIR = "./logs"
MATCH_LOG = os.path.join(LOG_DIR, "135match.txt")
PROGRESS_LOG = os.path.join(LOG_DIR, "kangaroo_progress.log")

# === ECDSA SETUP ===
curve = SECP256k1.curve
G = SECP256k1.generator
order = SECP256k1.order

# Puzzle 135 compressed public key
pubkey_hex = '02145d2611c823a396ef6712ce0f712f09b9b4f3135e3e0aa3230fb9b6d08d1e16'
pubkey_bytes = unhexlify(pubkey_hex)

def decompress_pubkey(pubkey_bytes):
    prefix = pubkey_bytes[0]
    x = int.from_bytes(pubkey_bytes[1:], 'big')
    alpha = (x ** 3 + 7) % curve.p()
    beta = pow(alpha, (curve.p() + 1) // 4, curve.p())
    y = beta if (beta % 2 == 0 and prefix == 2) or (beta % 2 == 1 and prefix == 3) else curve.p() - beta
    return ellipticcurve.Point(curve, x, y)

P_target = decompress_pubkey(pubkey_bytes)

# Puzzle 135 keyspace
lower_bound = int("4000000000000000000000000000000000", 16)
upper_bound = int("7fffffffffffffffffffffffffffffffff", 16)
keyspace = upper_bound - lower_bound

# === LOGGING SETUP ===
os.makedirs(LOG_DIR, exist_ok=True)
log_lock = threading.Lock()

def log_progress(message):
    with log_lock:
        with open(PROGRESS_LOG, "a") as f:
            f.write(message + "\n")
        print(message)

def log_match(scalar_hex):
    with log_lock:
        with open(MATCH_LOG, "a") as f:
            f.write(scalar_hex + "\n")
        print(f"[MATCH FOUND] {scalar_hex}")

# === STEP TABLE ===
def generate_step_table(n=256):
    cp.random.seed(42)
    return cp.array(cp.random.randint(1 << 12, 1 << 20, size=(n, 3), dtype=cp.uint64))

def step_function_3jump(P, table):
    h = int(hashlib.sha256(P.x().to_bytes(32, 'big') + P.y().to_bytes(32, 'big')).hexdigest(), 16)
    idx = h % table.shape[0]
    steps = table[idx]
    s1, s2, s3 = int(steps[0]), int(steps[1]), int(steps[2])
    total = s1 + s2 + s3
    return total, s1 * G + s2 * G + s3 * G

# === KANGAROO WALK ===
def kangaroo_walk(start_scalar, start_point, table, max_iters=500000):
    X = start_point
    a = start_scalar
    visited = {}

    for _ in range(max_iters):
        s, sG = step_function_3jump(X, table)
        X = X + sG
        a = (a + s) % order
        if (X.x() & ((1 << 20) - 1)) == 0:
            key = (X.x(), X.y())
            if key in visited:
                return visited[key], a, key
            visited[key] = a
    return None, a, None

# === WORKER FUNCTION ===
def kangaroo_worker(proc_id, start_base, step_table):
    threads = []

    def thread_func(thread_id, thread_offset):
        batch_start = start_base + thread_offset * BATCH_SIZE
        batch_end = min(batch_start + BATCH_SIZE, upper_bound)
        secret_scalar = batch_start
        wild_point = secret_scalar * G
        _, wild_a, wild_key = kangaroo_walk(0, wild_point, step_table)

        tame_point = upper_bound * G
        _, tame_a, tame_key = kangaroo_walk(upper_bound, tame_point, step_table)

        if tame_key and wild_key and tame_key == wild_key:
            recovered = (tame_a - wild_a) % order
            if recovered == secret_scalar:
                log_match(hex(recovered))
            else:
                log_progress(f"[Proc {proc_id}][Thread {thread_id}] Collision mismatch.")
        else:
            log_progress(f"[Proc {proc_id}][Thread {thread_id}] Range {hex(batch_start)} - {hex(batch_end)} completed with no match.")

    for i in range(NUM_THREADS):
        t = threading.Thread(target=thread_func, args=(i, i))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()

# === MULTIPROCESS CONTROL ===
def launch_processes(total_batches=5):
    step_table = generate_step_table()
    processes = []

    for i in range(total_batches):
        start = lower_bound + i * NUM_THREADS * BATCH_SIZE
        if start >= upper_bound:
            break
        p = multiprocessing.Process(target=kangaroo_worker, args=(i, start, step_table))
        p.start()
        processes.append(p)

    for p in processes:
        p.join()

# === START ===
if __name__ == "__main__":
    launch_processes(total_batches=5)



Hi all,

Here is my research about using kangaroo methods to solve ECDLP, Part 1.
Open source:  https://github.com/RetiredC/Kang-1

This software demonstrates various ways to solve the ECDLP using Kangaroos.
The required number of operations is approximately K * sqrt(range), where K is a coefficient that depends on the method used.
This software demonstrates four methods:

1 - Classic. The simplest method. There are two groups of kangaroos: tame and wild.
As soon as a collision between any tame and wild kangaroos happens, the ECDLP is solved.
In practice, K is approximately 2.10 for this method.

2 - 3-way. A more advanced method. There are three groups of kangaroos: tame, wild1, and wild2.
As soon as a collision happens between any two types of kangaroos, the ECDLP is solved.
In practice, K is approximately 1.60 for this method.

3 - Mirror. This method uses two groups of kangaroos and the symmetry of the elliptic curve to improve K.
Another trick is to reduce the range for wild kangaroos.
In practice, K is approximately 1.30 for this method.
The main issue with this method is that the kangaroos loop continuously.

4 - SOTA. This method uses three groups of kangaroos and the symmetry of the elliptic curve.
In practice, K is approximately 1.15 for this method. The main issue is the same as in the Mirror method.
I couldn’t find any papers about this method, so let's assume that I invented it Smiley

Important note: this software handles kangaroo looping in a very simple way.
This method is bad for large ranges higher than 100 bits.
Next part will demonstrate a good way to handle loops.

PS. Please don't post any stupid messages here, I will remove them.


Hello.
I find it difficult to understand C or C++ language in math operations.

Instead, I develop algorithms with the Fastecdsa Library in Python. I then switch to C or C++ for performance and then use it with GPU performance.

When I tried to read your article, I tried to understand what the value of K is based on. If I see this rule of 4 algorithm you mentioned (such as Fastecdsa or Sagemath in Python), I can join your conversation more.

Just wanted to point out. I am following your topic.

Thank you very much.


Here is my best shot at nailing Sota+ It is still raw but if it helps:
import threading
import multiprocessing
import hashlib
import cupy as cp
from ecdsa import SECP256k1, ellipticcurve
from binascii import unhexlify
import os

# === CONFIGURATION ===
NUM_THREADS = 10
BATCH_SIZE = 1_000_000
LOG_DIR = "./logs"
MATCH_LOG = os.path.join(LOG_DIR, "135match.txt")
PROGRESS_LOG = os.path.join(LOG_DIR, "kangaroo_progress.log")
USE_SOTA_PLUS = True  # Toggle SOTA+ mode

# === ECDSA SETUP ===
curve = SECP256k1.curve
G = SECP256k1.generator
order = SECP256k1.order
p = curve.p()

pubkey_hex = '02145d2611c823a396ef6712ce0f712f09b9b4f3135e3e0aa3230fb9b6d08d1e16'
pubkey_bytes = unhexlify(pubkey_hex)

def decompress_pubkey(pubkey_bytes):
    prefix = pubkey_bytes[0]
    x = int.from_bytes(pubkey_bytes[1:], 'big')
    alpha = (x ** 3 + 7) % p
    beta = pow(alpha, (p + 1) // 4, p)
    y = beta if (beta % 2 == 0 and prefix == 2) or (beta % 2 == 1 and prefix == 3) else p - beta
    return ellipticcurve.Point(curve, x, y)

P_target = decompress_pubkey(pubkey_bytes)

lower_bound = int("4000000000000000000000000000000000", 16)
upper_bound = int("7fffffffffffffffffffffffffffffffff", 16)
keyspace = upper_bound - lower_bound

# === LOGGING ===
os.makedirs(LOG_DIR, exist_ok=True)
log_lock = threading.Lock()

def log_progress(message):
    with log_lock:
        with open(PROGRESS_LOG, "a") as f:
            f.write(message + "\n")
        print(message)

def log_match(scalar_hex):
    with log_lock:
        with open(MATCH_LOG, "a") as f:
            f.write(scalar_hex + "\n")
        print(f"[MATCH FOUND] {scalar_hex}")

# === STEP TABLE ===
def generate_step_table(n=256):
    cp.random.seed(42)
    return cp.array(cp.random.randint(1 << 12, 1 << 20, size=(n, 3), dtype=cp.uint64))

def step_function_sota(P, table):
    h = int(hashlib.sha256(P.x().to_bytes(32, 'big') + P.y().to_bytes(32, 'big')).hexdigest(), 16)
    idx = h % table.shape[0]
    steps = table[idx]
    s1, s2, s3 = int(steps[0]), int(steps[1]), int(steps[2])
    total = s1 + s2 + s3
    direction = h & 1  # 50/50 split for forward/inverse

    jump = s1 * G + s2 * G + s3 * G
    if USE_SOTA_PLUS and direction == 1:
        jump = ellipticcurve.Point(curve, jump.x(), (-jump.y()) % p)
        total = -total % order
    return total, jump

# === WALK ===
def kangaroo_walk(start_scalar, start_point, table, max_iters=500000):
    X = start_point
    a = start_scalar
    visited = {}

    for _ in range(max_iters):
        s, sG = step_function_sota(X, table)
        X = X + sG
        a = (a + s) % order
        if (X.x() & ((1 << 20) - 1)) == 0:
            key = (X.x(), X.y())
            if key in visited:
                return visited[key], a, key
            visited[key] = a
    return None, a, None

# === THREAD WORKER ===
def kangaroo_worker(proc_id, start_base, step_table):
    threads = []

    def thread_func(thread_id, thread_offset):
        batch_start = start_base + thread_offset * BATCH_SIZE
        batch_end = min(batch_start + BATCH_SIZE, upper_bound)
        secret_scalar = batch_start
        wild_point = secret_scalar * G
        _, wild_a, wild_key = kangaroo_walk(0, wild_point, step_table)

        tame_point = upper_bound * G
        _, tame_a, tame_key = kangaroo_walk(upper_bound, tame_point, step_table)

        if tame_key and wild_key and tame_key == wild_key:
            recovered = (tame_a - wild_a) % order
            if recovered == secret_scalar:
                log_match(hex(recovered))
            else:
                log_progress(f"[Proc {proc_id}][Thread {thread_id}] Collision mismatch.")
        else:
            log_progress(f"[Proc {proc_id}][Thread {thread_id}] Range {hex(batch_start)} - {hex(batch_end)} complete.")

    for i in range(NUM_THREADS):
        t = threading.Thread(target=thread_func, args=(i, i))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()

# === MULTIPROCESS CONTROL ===
def launch_processes(total_batches=5):
    step_table = generate_step_table()
    processes = []

    for i in range(total_batches):
        start = lower_bound + i * NUM_THREADS * BATCH_SIZE
        if start >= upper_bound:
            break
        p = multiprocessing.Process(target=kangaroo_worker, args=(i, start, step_table))
        p.start()
        processes.append(p)

    for p in processes:
        p.join()

# === START ===
if __name__ == "__main__":
    launch_processes(total_batches=5)
vaccar73
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
April 03, 2025, 03:03:03 AM
Last edit: April 03, 2025, 04:41:15 AM by vaccar73
 #233

It seem the MKeys/s goes down over time for some reason.

Yeah, I really wonder why as well. I think it has to do with some basic laws of physics, like... things heat up, and heat = energy, so you're losing more energy on disipating heat rather than on jumping RC kangaroos.

Any suggestions on what command parameters I should use for puzzle 135 with this current Gpu setup, I am not sure what the dp and tames parameters do exactly.

Would it be better to split up the 135 range ?

I hopes it is OK that I am asking questions, like I said before I am new to this.

I suggest you don't, since this a demo program. You will waste your time, you need a fully distributed software system, not an .exe Frankly, all of your questions are kinda stupid. Computing power is a commodity that can be bought, and you are asking people to show pictures of their oil drilling setup just because they drove a car. Or setup of their solar power grid just because they can light up their TV.


Frankly, all of your assumptions are kinda stupid

The 3060m uses lower wattage and runs pretty cool, plus i got a good cooling system, the rtx 2070 runs pretty hot though

Using other programs like bitcrack, keyhuntcuda, vanitygen, etc, etc I did not see mkey rate drop after hours and hours of runtime

I think it has more to do with memory being used up, so I think you are wrong about the heating issue.

Yes I understand that gpus can be rented by minute, hour, day, week, month, I have already did that and tested rckangaroo with 8 4090 gpus, but I saw a post from OP which made me think he was using his own gpus

Quote
Exactly. I'm a retired coder, a good one, so I do it for fun mostly when I have time and interest, and it becomes boring after a month of managing a network of GPUs.

He could certainly afford to use his own gpus with his winnings, so it is not a far stretch to think he has some type of hardware setup. For me building the rig and seeing how fast you can get it running is part of the fun.

So you are saying he has no hardware rigs setup at all, you seem to know everything, but I have seen OP saying you were wrong about a lot of things in this thread alone, almost every one of your posts.

I do not see myself wasting time, I am doing this for a hobby, for fun and most importantly to learn. How many puzzles did you solve with your super secret software that no one has seen? If you have not solved any then maybe you have wasted a lot more time then me.

I think some of the people on this forum just like to be rude to new comers to discourage people from trying to solve puzzles, the less people that are doing them, the better their chances are to solving it, maybe you are one of those people, not sure.






kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 248


View Profile
April 03, 2025, 08:07:10 AM
 #234

It seem the MKeys/s goes down over time for some reason.

Yeah, I really wonder why as well. I think it has to do with some basic laws of physics, like... things heat up, and heat = energy, so you're losing more energy on disipating heat rather than on jumping RC kangaroos.

Any suggestions on what command parameters I should use for puzzle 135 with this current Gpu setup, I am not sure what the dp and tames parameters do exactly.

Would it be better to split up the 135 range ?

I hopes it is OK that I am asking questions, like I said before I am new to this.

I suggest you don't, since this a demo program. You will waste your time, you need a fully distributed software system, not an .exe Frankly, all of your questions are kinda stupid. Computing power is a commodity that can be bought, and you are asking people to show pictures of their oil drilling setup just because they drove a car. Or setup of their solar power grid just because they can light up their TV.


Frankly, all of your assumptions are kinda stupid

The 3060m uses lower wattage and runs pretty cool, plus i got a good cooling system, the rtx 2070 runs pretty hot though

Using other programs like bitcrack, keyhuntcuda, vanitygen, etc, etc I did not see mkey rate drop after hours and hours of runtime

I think it has more to do with memory being used up, so I think you are wrong about the heating issue.

Yes I understand that gpus can be rented by minute, hour, day, week, month, I have already did that and tested rckangaroo with 8 4090 gpus, but I saw a post from OP which made me think he was using his own gpus

Quote
Exactly. I'm a retired coder, a good one, so I do it for fun mostly when I have time and interest, and it becomes boring after a month of managing a network of GPUs.

He could certainly afford to use his own gpus with his winnings, so it is not a far stretch to think he has some type of hardware setup. For me building the rig and seeing how fast you can get it running is part of the fun.

So you are saying he has no hardware rigs setup at all, you seem to know everything, but I have seen OP saying you were wrong about a lot of things in this thread alone, almost every one of your posts.

I do not see myself wasting time, I am doing this for a hobby, for fun and most importantly to learn. How many puzzles did you solve with your super secret software that no one has seen? If you have not solved any then maybe you have wasted a lot more time then me.

I think some of the people on this forum just like to be rude to new comers to discourage people from trying to solve puzzles, the less people that are doing them, the better their chances are to solving it, maybe you are one of those people, not sure.

My assumptions are based on what I'm seeing you put out Smiley

If you want to use an unoptimized PROOF OF CONCEPT software that has no networking built in, and that requires 1000 top-end GPUs to solve Puzzle 135 in ~1 year, and better yet, by splitting it into ranges (probably because you found out there is no networking built in), that's your problem, not mine.

I only gave you a suggestion: don't do it. Every time you split, you increase your running time by 41%. Two splits? Double your time.

So maybe first learn, and then throw yourself into a witch hunt.

Off the grid, training pigeons to broadcast signed messages.
vaccar73
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
April 03, 2025, 08:29:26 AM
Last edit: April 03, 2025, 08:46:35 AM by vaccar73
 #235


I only gave you a suggestion: don't do it. Every time you split, you increase your running time by 41%. Two splits? Double your time.

So maybe first learn, and then throw yourself into a witch hunt.

no, you were rude and said that my questions are stupid, and made some other snarky comments about solar panels, and oil drilling

you could not just answer a question without trying to belittle me, the question was not even directed to you

I am trying to learn, that is why I ask questions, is that OK with you ? Do I have your permission to ask questions on this forum ?

You want to be rude to me I will give it right back, you may know a lot more about this stuff then I do, but the fact is you have not solved a puzzle yet, and you probably never will.

Maybe you need to LEARN how to be a little bit more humble, get over you technical arrogance, and work on your decorum.

Cricktor
Legendary
*
Offline Offline

Activity: 1470
Merit: 3907



View Profile
April 04, 2025, 12:16:09 AM
Merited by ABCbits (2), Mia Chloe (1)
 #236

@Dontbeatool2
If you post the wrong script then why don't you edit your post with the wrong script and replace it with the correct one?

And please, post code in [code]...[/code] tags, not only for better readability but mainly for the reason that the forum code may gobble up certain character sequences in your code because they may be interpreted as bbcode or sometimes smileys (you know that e.g. [i] isn't that uncommon in code, guess what happens if that were in your code snippets posted like you did).

Additionally you violate forum rule #32 (see here for rules to avoid possible trouble).


Every time you split, you increase your running time by 41%. Two splits? Double your time.
I'm not soo deep in the technicalities of the method using Kangaroos. Do you (or anybody else) mind explaining in more or less short words why there's such a significant penalty by splitting the range? I struggle a bit at the moment to wrap my head around for an explanation.

If that's is so, than splitting the range to distribute work to multiple GPUs seems not the time and energy efficient way. What's the more efficient work load distribution method? Distributing the number of Kangaroos over multiple GPUs all working on the same range? How to sync efficiently?

My apologies, I'm probably too much of only an interested bystander whose brain has been (partially?) fried by too much of let's say sub-par thought-out ideas and brain-dead chit-chat in the mega threads
Bitcoin puzzle transaction ~32 BTC prize to who solves it
== Bitcoin challenge transaction: ~1000 BTC total bounty to solvers! ==UPDATED==


~~~
You may have a point. Questions should always be possible. It's sometimes easier to bark than to wiggle the tail or be constructive, call it whatever you want. Questions are sometimes or more often misinterpreted as stupid or lazyness or whatever, highly depends on the question and its perception by others which is also highly subjective. It happens that others react harsh, me included, when newbies step in and "do their thing" (no pun intended, everybody here once was a newbie).

It's good to point that out, helps to reflect if ones own response is actually appropriate.

███████████████████████████
███████▄████████████▄██████
████████▄████████▄████████
███▀█████▀▄███▄▀█████▀███
█████▀█▀▄██▀▀▀██▄▀█▀█████
███████▄███████████▄███████
███████████████████████████
███████▀███████████▀███████
████▄██▄▀██▄▄▄██▀▄██▄████
████▄████▄▀███▀▄████▄████
██▄███▀▀█▀██████▀█▀███▄███
██▀█▀████████████████▀█▀███
███████████████████████████
.
.Duelbits PREDICT..
█████████████████████████
█████████████████████████
███████████▀▀░░░░▀▀██████
██████████░░▄████▄░░████
█████████░░████████░░████
█████████░░████████░░████
█████████▄▀██████▀▄████
████████▀▀░░░▀▀▀▀░░▄█████
██████▀░░░░██▄▄▄▄████████
████▀░░░░▄███████████████
█████▄▄█████████████████
█████████████████████████
█████████████████████████
.
.WHERE EVERYTHING IS A MARKET..
█████
██
██







██
██
██████
Will Bitcoin hit $200,000
before January 1st 2027?

    No @1.15         Yes @6.00    
█████
██
██







██
██
██████

  CHECK MORE > 
kTimesG
Full Member
***
Offline Offline

Activity: 812
Merit: 248


View Profile
April 04, 2025, 11:40:10 AM
Merited by Cricktor (1)
 #237

I'm not soo deep in the technicalities of the method using Kangaroos. Do you (or anybody else) mind explaining in more or less short words why there's such a significant penalty by splitting the range? I struggle a bit at the moment to wrap my head around for an explanation.

If that's is so, than splitting the range to distribute work to multiple GPUs seems not the time and energy efficient way. What's the more efficient work load distribution method? Distributing the number of Kangaroos over multiple GPUs all working on the same range? How to sync efficiently?

Because if you need c*sqrt(n) steps to solve for an n-interval, you need sqrt(2)*c*sqrt(n) to solve for two n/2-intervals. That's an 41% increase in the time to solve, for every halving. It's actually the most efficient way to intentionally increase the necessary number of steps - splitting a problem in two halves until there's nothing more to split Smiley

It's basically moving an sqrt(n) complexity problem towards an (n) complexity problem (brute-force).

Off the grid, training pigeons to broadcast signed messages.
vaccar73
Newbie
*
Offline Offline

Activity: 7
Merit: 0


View Profile
April 04, 2025, 08:40:17 PM
Last edit: April 04, 2025, 08:55:50 PM by vaccar73
 #238

you need a fully distributed software system, not an .exe

I actually am/been working on something likes this that uses c# and utilizes cpu to run on my computers that do not have a good Nvidia gpu, it is more a brute force method.

I also want to make something that will utilize Nvida cuda to use with a mining rig that I have been putting together. I know mining is not lucrative, I am only building it for puzzles and maybe some AI stuff in the future

The c++ code is a bit harder for me to understand, so I have been testing and looking at other cuda applications that do this, like rckangaroo, vanitygen bitcrack and stuff like that, trying to learn the best methods of going about it.

I do not think I will be renting gpus from Simplepod anymore, I just don't have the money for it at this point, I want to utilize the hardware I already have and try not to spend too much on this.

You may have a point. Questions should always be possible. It's sometimes easier to bark than to wiggle the tail or be constructive, call it whatever you want. Questions are sometimes or more often misinterpreted as stupid or lazyness or whatever, highly depends on the question and its perception by others which is also highly subjective. It happens that others react harsh, me included, when newbies step in and "do their thing" (no pun intended, everybody here once was a newbie).

It's good to point that out, helps to reflect if ones own response is actually appropriate.

Anyway this will be my last post here on the forum, I feel kind of bad that my questions have caused RetiredCoder's thread to go off topic, I did not intend to derail this thread, so I will find some where else to go if I need to ask questions.
Cricktor
Legendary
*
Offline Offline

Activity: 1470
Merit: 3907



View Profile
April 04, 2025, 09:43:26 PM
 #239

I also want to make something that will utilize Nvida cuda to use with a mining rig that I have been putting together. I know mining is not lucrative, I am only building it for puzzles and maybe some AI stuff in the future

Take into account that remaining puzzles still need massive numbers of GPUs to find a solution in a competitive time. I don't think there's a shortcut to this. Your own GPUs aren't for free: you either had or have to buy them and they need energy while they "crunch numbers".

This isn't meant as discouragemant.


Anyway this will be my last post here on the forum, I feel kind of bad that my questions have caused RetiredCoder's thread to go off topic, I did not intend to derail this thread, so I will find some where else to go if I need to ask questions.
That's your decision. You need a thicker skin here.


~~~
Oops, well, that's almost embarrassing.  Shocked  Apparently I didn't see the forest with all the trees around me... thanks!

███████████████████████████
███████▄████████████▄██████
████████▄████████▄████████
███▀█████▀▄███▄▀█████▀███
█████▀█▀▄██▀▀▀██▄▀█▀█████
███████▄███████████▄███████
███████████████████████████
███████▀███████████▀███████
████▄██▄▀██▄▄▄██▀▄██▄████
████▄████▄▀███▀▄████▄████
██▄███▀▀█▀██████▀█▀███▄███
██▀█▀████████████████▀█▀███
███████████████████████████
.
.Duelbits PREDICT..
█████████████████████████
█████████████████████████
███████████▀▀░░░░▀▀██████
██████████░░▄████▄░░████
█████████░░████████░░████
█████████░░████████░░████
█████████▄▀██████▀▄████
████████▀▀░░░▀▀▀▀░░▄█████
██████▀░░░░██▄▄▄▄████████
████▀░░░░▄███████████████
█████▄▄█████████████████
█████████████████████████
█████████████████████████
.
.WHERE EVERYTHING IS A MARKET..
█████
██
██







██
██
██████
Will Bitcoin hit $200,000
before January 1st 2027?

    No @1.15         Yes @6.00    
█████
██
██







██
██
██████

  CHECK MORE > 
JackMazzoni
Jr. Member
*
Offline Offline

Activity: 207
Merit: 7


View Profile
April 13, 2025, 06:58:33 AM
 #240

How to install/compile on windows?

Need Wallet Recovery? PM ME. 100% SAFE
Pages: « 1 2 3 4 5 6 7 8 9 10 11 [12] 13 14 15 16 17 18 19 20 21 22 23 24 »  All
  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!