Skip to content

About

GPU engine for secp256k1 key search with checkpointing, a Go controller and a live telemetry dashboard

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Matrix-Search

CI

Matrix-Search scans a range of secp256k1 private keys on NVIDIA GPUs, looking for the key that belongs to a given compressed public key. It is built around the Bitcoin puzzle ranges. A CUDA engine scans one chunk of keys per run. A Go pool server splits the target range into chunks, hands them to GPU workers over WebSocket, keeps progress in SQLite so a restart loses no work, checks every reported key, and serves a web dashboard. A Go miner runs one engine process per GPU and reports speed and results back to the server.

Architecture

  Browser                  Pool server (Go)                     GPU host (Go + CUDA)
 +----------------+ HTTP  +----------------------------+  WS   +-----------------------------+
 | dashboard.html |------>| /api/stats   /api/config   |<----->| pool-miner                  |
 | polls every    |       | /api/terminate             | /mine |   one connection per GPU    |
 | 1.5 s          |       | chunk queue, key check     |       |   runs per chunk:           |
 +----------------+       | state.db (SQLite)          |       |   kangaroo <start> <end>    |
                          | current_target.json        |       |            <pubkey> <gpu>   |
                          +----------------------------+       +-----------------------------+
  • CUDA engine (kangaroo.cu, secp256k1_math.cuh): scans [start, end] on one GPU and prints SPD:<keys checked> while it runs and HIT:<private key> if it finds the key.
  • Pool server (cmd/pool-server): holds the current target, cuts it into chunks of 10^10 keys, assigns them to miners, records progress and found keys, and serves the dashboard and its JSON API.
  • Miner (cmd/pool-miner): detects GPUs with nvidia-smi -L, opens one WebSocket connection per GPU, runs the engine for each chunk it receives and forwards speed and the result.
  • Dashboard (dashboard.html): deploys and stops targets, shows pool speed, connected workers, progress, estimated time remaining, the server log and found keys.

Features

  • secp256k1 arithmetic on the GPU: 256-bit field operations with the fast reduction for p = 2^256 - 2^32 - 977, Jacobian point doubling and mixed addition.
  • One scalar multiplication per thread, then one point addition per key. The match test compares X with x * Z^2, so no modular inversion runs in the inner loop.
  • Distributed work over WebSocket, with one worker per GPU on each host.
  • Checkpointing in SQLite: a restarted server resumes the range, and chunks that were not finished are assigned again.
  • Server-side check of every reported key against the target public key before it is stored.
  • Dashboard presets for the unsolved puzzles #135, #140, #145, #150, #155 and #160 (also listed in puzzles_unsolved.txt).

Requirements

  • NVIDIA GPU and the CUDA Toolkit (nvcc) to build and run the engine. On Windows, nvcc also needs the MSVC compiler. The author builds with CUDA 13.1 on Windows.
  • Go 1.25 or newer for the server and the miner.
  • nvidia-smi on the miner's PATH to start one worker per GPU. Without it the miner starts one worker on device 0.

The pool server does not need a GPU.

Build

git clone https://github.com/Hitice/Matrix-Search.git
cd Matrix-Search

# CUDA engine: Linux
nvcc -O3 -o kangaroo kangaroo.cu
# CUDA engine: Windows (Developer Command Prompt with MSVC)
nvcc -O3 -o kangaroo.exe kangaroo.cu

# Pool server and miner
go build -o pool-server ./cmd/pool-server
go build -o pool-miner ./cmd/pool-miner

Add -arch=sm_XX to the nvcc command to build for your GPU's compute capability.

Run

Start the server from the repository root. It reads dashboard.html and writes state.db, current_target.json and hit.txt in its working directory.

./pool-server

Open http://localhost:8080, pick a preset or type a target, and click Start search. A target can also be deployed through the API:

curl -X POST http://localhost:8080/api/config -d '{
  "target_address": "1LHtnpd8nU5VHEMkG2TMYYNUjjLc992bps",
  "target_public_key": "030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b",
  "range_start": "20000000",
  "range_end": "3fffffff"
}'

That target is puzzle #30, which is already solved (private key 0x3d94cd64). Its range holds 2^29 keys, a single chunk, which makes it a quick end-to-end test.

Start a miner on each GPU host, next to the engine binary:

./pool-miner -pool ws://<server-host>:8080/mine -wallet rig01

Each GPU connects as rig01_GPU0, rig01_GPU1, and so on. The engine can also run on its own:

./kangaroo 20000000 3fffffff 030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b 0

Flags

Binary Flag Default Meaning
pool-server -addr :8080 Listen address for the dashboard, the API and /mine
pool-miner -pool ws://localhost:8080/mine Pool server WebSocket URL
pool-miner -wallet AnonMiner Worker name shown on the server
pool-miner -engine ./kangaroo (./kangaroo.exe on Windows) Path to the CUDA engine

HTTP API

Method Path Description
GET /api/stats Target, pool speed (keys/s), connected workers, keys scanned, last 300 log lines, last 20 found keys
POST /api/config Validate and deploy a target (target_address, target_public_key, range_start, range_end); returns 400 with the reason when invalid
POST /api/terminate Stop the current target
POST /api/clear_logs Clear the server log buffer
GET /mine WebSocket endpoint for miners

Miner protocol

The server sends {"cmd":"IDLE"} while there is nothing to assign, or {"cmd":"WORK","start":"<hex>","end":"<hex>","pubkey":"<hex>"}. While the engine runs, the miner sends {"event":"PROGRESS","speed":<keys/s>} about every two seconds. It closes the chunk with exactly one of {"event":"DONE"}, {"event":"HIT","priv":"<hex>"} or {"event":"FAILED","msg":"..."}.

How checkpointing works

Progress is stored per target public key and range in state.db:

  • search_progress keeps the cursor, which is the first key of the next chunk to cut, and the number of keys in chunks that miners reported as fully scanned. The dashboard progress bar and time estimate come from that count.
  • chunks holds every chunk that was cut but not finished. A chunk is assigned while a miner works on it. If the miner reports FAILED, reports a key that does not match, or disconnects, the chunk goes back to pending. On startup the server moves every assigned chunk back to pending, because no miner from the previous run is still working on it.
  • Pending chunks are handed out before new chunks are cut, so no key of the range is skipped.
  • A chunk leaves the table when the miner reports DONE (its keys are added to the scanned count) or a verified HIT.
  • The target stops on its own when a verified key is found, or when the cursor has passed the end of the range and no chunk is left in the table.

Deploying the same public key and range again resumes where it stopped. A different range for the same key is tracked separately.

Limitations

  • The search is a sequential scan, so the time grows linearly with the size of the range. Despite the file name, kangaroo.cu does not implement Pollard's kangaroo. For the unsolved puzzles the dashboard shows the estimate as an order of magnitude, for example "at least 10^24 years" for puzzle #135 at 155 M keys/s.
  • The server has no authentication. Anyone who can reach it can deploy or stop targets and read found keys from /api/stats, and the WebSocket endpoint does not check the Origin header. Run it on a trusted network, bind it to localhost with -addr 127.0.0.1:8080, or put it behind a reverse proxy that authenticates.
  • Stopping a target takes effect at the next chunk boundary: miners finish their current chunk first.
  • The speed reported by the engine is approximate, since thread 0 prints the shared counter while other threads of the same launch may still be running.

Screenshots

Dashboard

The dashboard with the puzzle #30 target from current_target.json.example loaded and no miner connected. Speed and keys scanned fill in once a miner with a GPU joins.

Project layout

Path Contents
kangaroo.cu Engine entry point, search kernel and host loop
secp256k1_math.cuh Field and point arithmetic for the GPU
cmd/pool-server/ Pool server: HTTP API, WebSocket hub, SQLite checkpoint (store.go), key check (secp256k1.go) and tests
cmd/pool-miner/ Miner: GPU detection, engine runner, WebSocket client
dashboard.html Single-file web dashboard served by the pool server
current_target.json.example Example target (puzzle #30)
puzzles_unsolved.txt Ranges, addresses and public keys of the puzzles in the dashboard presets

Disclaimer

This project is for research and education. The puzzle addresses are a public challenge. Use the tool only on keys you are entitled to search for.

About

GPU engine for secp256k1 key search with checkpointing, a Go controller and a live telemetry dashboard

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages