Skip to content

Instantly share code, notes, and snippets.

@Nikolaj-K
Last active April 3, 2025 18:08
Show Gist options
  • Save Nikolaj-K/b0bfd92a838733f5066091c8f7de5a23 to your computer and use it in GitHub Desktop.
Save Nikolaj-K/b0bfd92a838733f5066091c8f7de5a23 to your computer and use it in GitHub Desktop.
A private key brute forcing routine
"""
Script for the video discussed in
https://youtu.be/2ewwFC0FzE4
Script to bruteforce search for the private key given a public key.
Efficient python and C 99 algos to for the SECP256k1 log at:
https://github.com/Telariust
See also the programs in
https://privatekeys.pw/
For some ground truth keys, see:
https://github.com/trezor/trezor-core/blob/master/tests/test_trezor.crypto.curve.secp256k1.py
For the 31k bitcoin wallet:
https://bitinfocharts.com/top-100-richest-bitcoin-addresses.html
and in particular:
http://blockchain.com/btc/address/12ib7dApVFvg82TXKycWBNpN8kFyiAN1dr
which exposes the public key e.g. in the 9k bitcoin outgoing transaction here:
https://www.blockchain.com/de/btc/tx/064bc02f12cee52c0642bdb5f04e4a3a1e3600ed004c3e3c27ffa34ecd7056f8
Don't write me emails asking how to install python or something of the sort.
If you ask me something, use an adult sentence structure and attire.
Disclaimer: Due to potential bugs, don't use functions from this script for anything of value!
"""
from binascii import b2a_hex
from ecdsa import SigningKey, SECP256k1
from random import randint
MAX_SECRET = SECP256k1.order - 1
ALL_SECRETS = range(1, MAX_SECRET)
KNOWN_PUBKS = dict( # Note: on-chain keys have a 04 prefix, see https://youtu.be/LYN3h5DjeXw
first = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
fifth = "2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4d8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6",
satoshi_31k = "d6597d465408e6e11264c116dd98b539740e802dc756d7eb88741696e20dfe7d3588695d2e7ad23cbf0aa056d42afada63036d66a1d9b97070dd6bc0c87ceb0d",
)
class Config:
LOG_INTERVAL = 20000 # How often to print
TARGET_PUBK = KNOWN_PUBKS["satoshi_31k"]
SECRETS = ALL_SECRETS
#SECRETS = (randint(1, MAX_SECRET) for _ in ALL_SECRETS)
def _secret_to_pubk(secret): # See https://youtu.be/RZzB-vPFYmo
point = SigningKey.from_secret_exponent(secret, curve=SECP256k1) # A class from ecdsa
return b2a_hex(point.verifying_key.to_string()).decode('ascii') # A base 16 as string
def _match(secret, pubk):
return _secret_to_pubk(secret) == pubk # Note: Assumes all lower cases
# Validate the functions above
assert _match(1, KNOWN_PUBKS["first"])
assert _match(5, KNOWN_PUBKS["fifth"])
#assert _pubk_to_address("04" + KNOWN_PUBKS["satoshi_31k"]) == "12ib7dApVFvg82TXKycWBNpN8kFyiAN1dr" # _pubk_to_address from previous video
if __name__=="__main__":
print(f"Trying {MAX_SECRET} secrets.\n")
for idx, secret in enumerate(Config.SECRETS):
if idx % Config.LOG_INTERVAL == 0:
print(f"Trying {idx}'th secret ...")
if _match(secret, Config.TARGET_PUBK):
exit(f"Satoshi's private key found: {secret}")
@Bv56jg
Copy link

Bv56jg commented Jun 11, 2024

12tkqA9xSoowkzoERHMWNKsTey55YEBqkv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment