Generate Bitcoin keys offline. No wallet. No network. No trust.
When you use an exchange or an online wallet, someone else holds your private keys. If they get hacked, go bankrupt, or decide to freeze your account, your Bitcoin is gone. This has happened repeatedly throughout Bitcoin's history.
The Bitcoin community has a saying: "not your keys, not your coins." If you don't personally control the private key, you don't truly own the Bitcoin.
But generating keys on a computer connected to the internet is also risky. Malware, keyloggers, clipboard hijackers, and compromised software can steal your private key the moment it's created — before you even know it exists.
The safest approach is simple: generate your key on a computer that has never been and will never be connected to the internet. That way, even if the machine had malware, it would have no way to send your key to an attacker.
That's what this tool is for.
Use any computer that is disconnected from the internet. An old laptop with Wi-Fi disabled works well. A Raspberry Pi is another good option. The key requirement: no network connection, ever, while the machine has access to your private key.
Download the binary on a separate, internet-connected computer. Verify the checksum. Copy it to a USB drive. Plug the USB drive into the air-gapped machine.
Open a terminal and run btc-keygen generate. The tool
prints two things:
bc1q)
— this is like a bank account number. You give it to people so
they can send you Bitcoin. It's safe to share publicly.K or L) — WIF stands for "Wallet Import
Format." It's your private key encoded in a way that any Bitcoin wallet
can read. Think of it as the password to your Bitcoin. Anyone who has
this string can spend your funds. Keep it absolutely secret.Write both the address and the private key on paper, or stamp them into metal. Do not save them to a file. The tool does not save anything — once you close the terminal, the key exists only where you wrote it down.
Put the paper or metal in a safe, a safety deposit box, or another secure location. This is your "cold storage." To receive Bitcoin, give someone the address. To spend it later, you'll import the private key into a wallet.
To receive Bitcoin, share your address (the
bc1q... string) with the person or service sending you funds.
You can share it by text message, email, or any other channel — the
address is public information and cannot be used to steal your Bitcoin.
You can check whether Bitcoin has arrived at your address using any public block explorer (for example, search your address on mempool.space or blockchair.com). You do not need your private key to check your balance — only to spend.
When you want to spend the Bitcoin stored at your address, you need to import your WIF private key into a wallet application. Here is how that works with common wallets:
K or L.Some wallets offer two options:
This tool was designed as if every run could protect someone's life savings. Here is what's under the hood, in plain language:
For the full technical threat model, security assumptions, and dependency analysis, see the design documentation in the repository.
Pre-built binaries are available for every major platform. Each binary is a single file with no dependencies — download it, verify the checksum, and run it.
SHA256SUMS.txt file from the release and compare it against
the binary you downloaded. This ensures the file hasn't been tampered
with.
Download the latest release from GitHub
# Download
curl -LO https://github.com/aguimaraes/btc-keygen/releases/download/v0.0.3/btc-keygen-linux-x86_64
# Verify checksum
sha256sum btc-keygen-linux-x86_64
# Make executable and run
chmod +x btc-keygen-linux-x86_64
./btc-keygen-linux-x86_64 generate
# Download
curl -LO https://github.com/aguimaraes/btc-keygen/releases/download/v0.0.3/btc-keygen-linux-aarch64
# Verify checksum
sha256sum btc-keygen-linux-aarch64
# Make executable and run
chmod +x btc-keygen-linux-aarch64
./btc-keygen-linux-aarch64 generate
# Download
curl -LO https://github.com/aguimaraes/btc-keygen/releases/download/v0.0.3/btc-keygen-macos-aarch64
# Verify checksum
shasum -a 256 btc-keygen-macos-aarch64
# Make executable and run
chmod +x btc-keygen-macos-aarch64
./btc-keygen-macos-aarch64 generate
macOS may show a Gatekeeper warning. To bypass:
xattr -d com.apple.quarantine btc-keygen-macos-aarch64
# Download
curl -LO https://github.com/aguimaraes/btc-keygen/releases/download/v0.0.3/btc-keygen-macos-x86_64
# Verify checksum
shasum -a 256 btc-keygen-macos-x86_64
# Make executable and run
chmod +x btc-keygen-macos-x86_64
./btc-keygen-macos-x86_64 generate
# Download btc-keygen-windows-x86_64.exe from the release page
# Verify checksum (PowerShell)
Get-FileHash btc-keygen-windows-x86_64.exe -Algorithm SHA256
# Run
.\btc-keygen-windows-x86_64.exe generate
Requires Rust and a C compiler (gcc, clang, or MSVC).
git clone https://github.com/aguimaraes/btc-keygen.git
cd btc-keygen
cargo build --release
./target/release/btc-keygen generate
Pre-built binaries are not provided for BSD. Build from source using the instructions above. The tool compiles and runs correctly on FreeBSD, OpenBSD, and NetBSD.
$ btc-keygen generate
address: bc1q...
wif: K...
This prints the Bitcoin address and the WIF private key. That's all you need to receive and later spend Bitcoin.
$ btc-keygen generate --hex
address: bc1q...
wif: K...
private_key_hex: ab12cd...
$ btc-keygen generate --pubkey
address: bc1q...
wif: K...
pubkey_hex: 02ab12cd...
$ btc-keygen generate --json
{"address":"bc1q...","wif":"K..."}
$ btc-keygen generate --hex --pubkey --json
bc1q (native SegWit).K or L. Keep it secret.
See Using your keys for how to use
it.No. Every run generates a completely new, random keypair. There is no way to recreate a previous key. Write it down the first time.
Any Bitcoin sent to that address is permanently inaccessible. There is no recovery mechanism. This is by design — if anyone could recover your key, so could an attacker.
Hardware wallets are a good option. This tool is an alternative for people who prefer not to trust a hardware device manufactured by a third party, or who want a simple, verifiable way to generate a single key for long-term storage.
Mnemonic phrases are useful for HD wallets that generate many addresses. This tool intentionally generates a single standalone key. It's simpler, easier to audit, and sufficient for cold storage of a single address. BIP39 support may be considered in a future version.
No. This is a key generator. It creates a keypair and exits. It cannot send Bitcoin, check balances, or interact with the Bitcoin network in any way. To spend Bitcoin, you'll need to import the private key into a wallet application. See Using your address and private key for step-by-step instructions.
btc-keygen is also available as a Rust library. If you are building software that needs to generate Bitcoin keys, you can use it as a dependency instead of shelling out to the binary.
cargo add btc-keygen
The library exposes four functions and one type:
| Function | Input | Output |
|---|---|---|
generate() |
— | Result<PrivateKey, Error> |
encode_wif(&key) |
&PrivateKey |
String — starts with K or L |
derive_pubkey(&key) |
&PrivateKey |
[u8; 33] — compressed public key |
derive_address(&pubkey) |
&[u8; 33] |
String — Bech32 address (bc1q...) |
use btc_keygen;
fn main() -> Result<(), btc_keygen::Error> {
// 1. Generate a private key from OS randomness
let key = btc_keygen::generate()?;
// 2. Encode as WIF (for wallet import)
let wif = btc_keygen::encode_wif(&key);
// 3. Derive the compressed public key
let pubkey = btc_keygen::derive_pubkey(&key);
// 4. Derive the Bitcoin address
let address = btc_keygen::derive_address(&pubkey);
println!("Address: {address}");
println!("WIF: {wif}");
Ok(())
}
PrivateKey automatically zeroizes its bytes when dropped
— you do not need to clear it manually.
Full API documentation is available on docs.rs.