The practical keyhunt guide
From installing it, through the mode choice that costs people weeks without them noticing, to how not to lose the prize if you ever actually find one. Gathered from what is scattered across forum threads, and checked against the source rather than repeated.
1. Installing
keyhunt is built with Linux in mind. On Windows, use WSL — a native build is a long slog. macOS works, but there is no GPU acceleration, so treat it as practice rather than production.
sudo apt update sudo apt install -y git build-essential libssl-dev libgmp-dev git clone https://github.com/albertobsd/keyhunt cd keyhunt make # check the build ./keyhunt --help | head
libssl-dev and libgmp-dev are only needed for the legacy build, but installing them now saves you getting stuck later.
2. Can this tool be trusted?
Once it is installed, the thought arrives on its own. “This is a program that finds private keys. If I actually find one, what stops it quietly mailing the key somewhere?” That is a fair suspicion. A program that computes private keys is structurally in a position to steal them. And “it’s open source” is not an answer — open source that nobody reads is just code.
So it got checked. keyhunt is a C/C++ tool by albertobsd, and keyhunt.cpp is the body of the executable. Open that file and:
- There is not one networking header.
sys/socket.h,netinet/in.h,curl/curl.h— none of them. The include list is stdio, stdlib, pthread and its own crypto library. - There are no socket, connect or recv calls. Grep for anything resembling an address or a URL and the only hit is a comment on line 471, which turns out to be a link explaining random number generation.
- A found key is appended to
KEYFOUNDKEYFOUND.txt. A local file.
Don’t take my word for it. From the repository root:
# (1) does the executable's own source include networking headers? # expected output: nothing grep -nE '#include <(sys/socket|netinet/in|arpa/inet|curl/curl)' keyhunt.cpp # (2) are there socket calls or URLs in it? # expected output: one comment on line 471 (a link about randomness) grep -nE '\b(socket|connect|recv|getaddrinfo|curl)\b|https?://' keyhunt.cpp # (3) which files anywhere in the repo include a networking header? # expected output: two — bsgsd.cpp and base58/base58.c grep -rln 'sys/socket\.h\|netinet/in\.h\|arpa/inet\.h\|curl/curl\.h' . # (4) does base58.c actually use any networking function? # expected output: nothing grep -nE 'htonl|ntohl|socket' base58/base58.c
Check (3) returns two files. That is the most important part of this whole exercise, so here it is in full rather than glossed over:
bsgsd.cpp— there are real sockets in it. But this is a server daemon that offers BSGS over the network, a separate program built for exactly that purpose and documented inBSGSD.mdin the repo. What matters is that a plainmakedoes not build it. You have to typemake bsgsdon purpose. If you don’t, the program does not exist on your machine.base58/base58.c— includesarpa/inet.hand then uses nothing from it. It is leftover from Luke Dashjr’s libbase58 (MIT), which pulled it in for byte-order macros. Rungrep -nE 'htonl|ntohl|socket' base58/base58.cand you get an empty result.
- Never run a binary somebody else compiled. Everything above is a statement about the source, not about an exe posted in a Telegram group. Nearly every real incident happens right here. Build from source with
make. - Run it with outbound traffic blocked. If you are not going to read all the code, this is the surest move. Cut that process off at the firewall and malice has nowhere to go.
- Actually watch it. While it runs,
lsof -i -a -p $(pgrep keyhunt)should show no open sockets. Or, more thoroughly,sudo tcpdump -i any host not 127.0.0.1. - Don’t run it on the computer you touch wallets with. Keeping the search machine separate is stronger than any code audit.
One more thing: the worry is aimed slightly off target. For keyhunt to steal your key, you first have to find something — and if you work out the odds, that does not happen. The real danger is not the tool. It is the moment you move the coins, which gets its own section below.
3. Picking a mode — most people get this wrong
keyhunt has several modes, and what you know about the target decides which one. Get it backwards and the program runs along happily without a word of complaint, finding nothing, forever. This is the most common way to waste time here.
| What you have | Mode | Cost |
|---|---|---|
An address only (1PWo3Je…) | -m address | O(2ⁿ) |
A public key (02…/03…) | -m bsgs | O(2^(n/2)) |
| A HASH160 (20 bytes of hex) | -m rmd160 | O(2ⁿ) |
If you want to know what BSGS and Kangaroo actually do
For a sense of the gap: over a 71-bit range, an address brute force is 2⁷⁰ operations, while BSGS with a known public key is 2³⁵. A factor of 34 billion. That is why #140, #145, #150, #155, #160, whose public keys are exposed, are more realistic targets than much lower-numbered puzzles.
The command builder makes this call for you from the puzzle number alone.
4. Make your first run a solved puzzle
Start on an unsolved puzzle and you cannot even tell whether your tooling works. Run one whose answer is known first, and check that it finds it within seconds.
echo "1EeAxcprB2PpCnr34VfZdFrkUWuxyiNEFv" > 40.txt ./keyhunt -m address -f 40.txt -b 40 -l compress -t 8 -q -s 5 # KEY FOUND should appear within seconds. # If it doesn't, the mode or the -b value is wrong.
-b 40 is the crucial part. It means “search the 40-bit range only”. Leave it out and it starts working through all 2²⁵⁶, which never ends.
5. Running a real target
echo "1PWo3JeB9jrGwfHDNpdGK54CRas7fsVzXU" > 71.txt ./keyhunt -m address -f 71.txt -b 71 -l compress -t 16 -R -q -s 10
-t 16— match your physical core count. Using every hyperthread sometimes makes it slower.-R— jump around the range at random. Reduces overlap when you run several machines.-s 10— print the rate every 10 seconds. Put that number into the calculator.-k— BSGS mode only. Trades RAM for speed, and simply dies if there isn’t enough. Start at 4 and work up.
Honestly: going after an unsolved puzzle on a CPU is pointless. Sixteen threads on #71 comes to millions of years. To do this seriously you need a GPU (BitCrack, VanitySearch, Kangaroo), and one card is not enough either. keyhunt is CPU-based — use it to learn and to verify, and look at GPU tools for the real thing.
6. If you find one — moving it without losing it
This is the most important section in this guide. Finding one is hard, but people have found one and then had it taken from them.
Moving coins off a puzzle address means signing a transaction, and a signature carries the public key with it. The moment that transaction appears in the public mempool, a watching bot reads the public key. And everyone knows a puzzle key sits inside a narrow range — with the public key and the range, Pollard’s Kangaroo recovers the private key in seconds.
If that sounds like Bitcoin as a whole is broken
Take #66: the range is 2⁶⁶, so Kangaroo needs around 2³³ operations — about ten seconds on a GPU. The bot then builds a transaction spending the same coins to its own address at a higher fee, and yours gets pushed out. That is exactly what happened to #66 and #69 in September 2024.
- Disabling RBF — setting nSequence to final achieves nothing. Modern nodes default to full-RBF, and a miner has every reason to take the more valuable transaction.
- Paying a huge fee — the bot is bidding for the entire prize, so it can always outbid you.
- Being fast — the bot is faster than a person.
It is easy to think a transaction accelerator would solve this. But ViaBTC, BTC.com and most accelerators take a TXID as input. Having a TXID means you have already broadcast, and at that point it is over. An accelerator pushes a stuck transaction along; it does not prevent exposure.
What you need is somewhere that accepts the signed raw hex itself, not a TXID. Only such a service can handle a transaction the world has not seen yet.
Private submission, concretely
The one route currently open to an ordinary person without a separate agreement is MARA Slipstream. Since August 2026 it has been open to the public, with no application and no special client. Submit the signed raw transaction and it stays out of the public mempool, sitting in their queue alone until MARA mines a block. There is no extra charge — you pay the normal network fee.
- Prepare the destination address first. A fresh address from a hardware wallet is good. No key is needed for this step, so get it done before you find anything.
- Build and sign the transaction offline.
bitcoin-cli signrawtransactionwithkeyis enough. The machine should be disconnected, and what comes out is a single signed hex string. - Submit that hex to Slipstream. Do not paste it anywhere else — a block explorer’s “broadcast” box, a wallet’s broadcast button, an accelerator: all of them go to the public mempool.
- Wait. This is what the method costs you. See the table.
| Until MARA mines a block | Wait |
|---|---|
| On average | 3.5 hours |
| Half of the time, within | 2.5 hours |
| Nine times in ten | 8.2 hours |
| Ninety-nine times in a hundred | 16.3 hours |
There are several ways to submit. You can paste it into the Slipstream web page directly, or use something like Outofband, which relays PSBTs and raw transactions to Slipstream for you. This site’s own withdrawal tool will send it the moment you paste it in — and it takes transactions signed on a Keystone or Coldcard as they come.
MARA’s pool holds about 4.7% of the hashrate (Hashrate Index, May 2026), which works out to a block every 213 minutes on average. It is a Poisson process, so the spread is wide — be prepared to wait a day. Nothing is exposed anywhere while you wait, so do not get nervous and switch to a public broadcast. That is the most common way this fails.
Submitting to Slipstream means showing MARA the transaction first. There is no technical mechanism stopping them from pulling the public key out, running Kangaroo, recovering the key and sending the coins to themselves. You are betting on a listed company’s reputation instead of on an anonymous bot’s restraint. The risk did not vanish.
For a large amount, then, talking to a pool directly and in advance is better. Real solutions have been handled this way, by agreeing a substantial cut of the fee. The arithmetic is that giving up part of the prize beats losing all of it.
It sounds plausible and it does not help at all. A node’s job is to propagate transactions. The instant you feed sendrawtransaction to your own node it goes out to your peers, and one to three seconds later the whole network has it. Your node is not a private channel. It is an on-ramp to the public mempool.
Running a node is worth it for different reasons — you can sign offline instead of pasting a private key into somebody else’s website, and you don’t hand your IP and wallet details to a third-party service. Both are good reasons. Neither is about RBF theft.
For reference — not every puzzle is at risk
Once the public key is out, the time Kangaroo needs scales with the square root of the range. So the higher the number, the safer a public broadcast becomes — the bot simply cannot finish the computation inside one block.
| Puzzle | Recovery time once exposed | Public broadcast |
|---|---|---|
| #66 | 6 seconds | certain loss |
| #71 | 34 seconds | certain loss |
| #80 | 13 minutes | dangerous |
| #100 | 9 days | safe in practice |
| #120 | 26 years | safe |
Based on one GPU at a billion operations per second. A bot running a hundred cards is a hundred times faster, which pushes the boundary up to roughly #95. #71, the one people are working on now, sits squarely in the middle — private submission is not optional there. At the other end, #140 and above already have their public keys exposed and would take months for anyone to recompute, so this particular risk barely applies.
- Rehearse before you find anything. Run the exact same procedure once using the published key of a puzzle that is already solved. The balance is zero so there is nothing to lose, and you avoid doing this for the first time when it counts.
- Don’t send a small amount to “check” the balance. That exposes the public key on the spot. Look the address up on a block explorer instead.
- Keep watching for a few blocks after it confirms. A chain reorganisation would reopen the window against a key that is now exposed. It is unlikely, but for a large amount it is a risk worth watching.
7. Before you join a pool
Since going it alone does not add up, joining a pool is an option. btcpuzzle.info runs a “solo pool” — you get assigned a range, and whoever finds it keeps the whole prize. The client is on GitHub, a CUDA program forking VanitySearch with a pool communication module bolted on.
Reading through that source, here is what holds:
- On the default settings, no key goes to the server.
save_key=false,telegram_share=falseandapi_share=falseare the defaults, and in that state a found key is printed to your local console and nowhere else. - The path that does store on the server is properly locked. Both
save_keyanduntrusted_computerhave to be on and the encryption has to succeed before anything is sent — and the encryption uses your own RSA public key. The operator cannot read it either. - Telegram and webhooks are plaintext. Turn
telegram_share=trueon and leaveuntrusted_computeroff, and a found private key travels in the clear through Telegram’s servers. If you want the notification but not the exposure, turn both on. - Encryption failure falls back to plaintext. If RSA key loading goes wrong it logs the error and sends in the clear anyway. After configuring it, verify with a test output that encryption is genuinely applied.
- The operator knows exactly which ranges have been exhausted. That is structural and unavoidable, but go in knowing it is valuable information.
The pool itself is reasonably designed. What you have to know for yourself is what gets exposed when you change a default.
8. What not to do
- Pointing this at an address that isn’t a puzzle. That is not searching, it is attempted theft. And it will not work anyway — look at the numbers on the scale page.
- Paying for a “key database” or a recovery service. All of them are scams. Without exception.
- Typing a seed phrase into some website. A site offering to check your balance is not checking anything; it is collecting.
- Burning electricity while ignoring expected value. Put your electricity price into the calculator. On most setups the power costs more than the prize.
- Running somebody else’s compiled binary. Especially on the computer you touch wallets with. Build from source.