Skip to content

Instantly share code, notes, and snippets.

@tirinox
Created April 15, 2019 10:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save tirinox/c058dfc6dd160c0cb4d95f69053104db to your computer and use it in GitHub Desktop.
Save tirinox/c058dfc6dd160c0cb4d95f69053104db to your computer and use it in GitHub Desktop.
import hashlib
import ecdsa
import os
from binascii import hexlify
from base58 import b58encode
# Installation:
# pip install base58 ecdsa
# Use that service to make sure that this generator works well:
# 1. navigate to https://bitcoinpaperwallet.com/bitcoinpaperwallet/generate-wallet.html#
# 2. Press "Skip"
# 3. Press "Enter my own key, ..."
# 4. Enter generated private key
# 5. Press "Apply"
# 6. Make sure that everything matches! PROFIT!
def random_secret_exponent(curve_order):
while True:
bytes = os.urandom(32)
random_hex = hexlify(bytes)
random_int = int(random_hex, 16)
if random_int >= 1 and random_int < curve_order:
return random_int
def generate_private_key():
curve = ecdsa.curves.SECP256k1
se = random_secret_exponent(curve.order)
from_secret_exponent = ecdsa.keys.SigningKey.from_secret_exponent
return from_secret_exponent(se, curve, hashlib.sha256).to_string()
def get_public_key_uncompressed(private_key_bytes):
k = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1)
return b'\04' + k.get_verifying_key().to_string() # 0x04 = uncompressed key prefix
def get_bitcoin_address(public_key_bytes, prefix=b'\x00'):
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(hashlib.sha256(public_key_bytes).digest())
r = prefix + ripemd160.digest()
checksum = hashlib.sha256(hashlib.sha256(r).digest()).digest()[0:4]
return b58encode(r + checksum)
def main():
# private_key = generate_private_key()
# or:
private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1).to_string()
public_key = get_public_key_uncompressed(private_key)
address = get_bitcoin_address(public_key)
print(f'private key: {hexlify(private_key)}')
print(f'public key uncompressed: {hexlify(public_key)}')
print(f'btc address: {address}')
if __name__ == '__main__':
main()
@micro84
Copy link

micro84 commented Feb 21, 2023

hello can you help,
need to fix the script, the script generates crooked addresses and private.
example :
Bitcoin address : 2NofGJaFRBZyCn9xzWJuXqvWom9s8jJT
Private Key WIF : fBW9pucaNjpi4ZUvaei4HfSH5Yx5PJJJinsKMmDWgTtdT1
Thanks

import os
import hashlib
import binascii

if os.path.exists('done.txt'):
    os.remove('done.txt')

#(be sure to replace the path with your own location of the Address.txt file)
address_file = open('Address.txt', 'r')
addresses = address_file.readlines()
address_file.close()

#(be sure to replace the path with your own location of the done.txt file)
done_file = open("done.txt", "a+")

#the main loop to generate and compare the addresses
generated_counter = 0
coincidence_counter = 0

while True:

    #generate a random 32-byte private key
    hex_private_key = os.urandom(32).hex()
    private_key_bytes = binascii.unhexlify(hex_private_key)

    #add the prefix "80" to the private key
    sha256_a = hashlib.sha256(private_key_bytes).hexdigest()
    ripemd160_a = hashlib.new("ripemd160")
    ripemd160_a.update(binascii.unhexlify(sha256_a))

    #create the mainnet public address from the private key
    hex_public_key = ripemd160_a.hexdigest()
    public_key_bytes = binascii.unhexlify(hex_public_key)
    sha256_b = hashlib.sha256(public_key_bytes).hexdigest()
    sha256_c = hashlib.sha256(binascii.unhexlify(sha256_b)).hexdigest()

    #add the prefix "00" to the public key
    ripemd160_b = hashlib.new("ripemd160")
    ripemd160_b.update(binascii.unhexlify(sha256_c))
    hex_checksum = ripemd160_b.hexdigest()

    #add the six checksum bytes to the end of the public key
    bitcoin_address = "00" + hex_public_key + hex_checksum[:6]

    #convert the public key from hex to Base58
    decimal_bitcoin_address = int(bitcoin_address, 16)
    alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
    base58_bitcoin_address = ''

    while decimal_bitcoin_address > 0:
        remainder = decimal_bitcoin_address % 58
        decimal_bitcoin_address //= 58
        base58_bitcoin_address = alphabet[remainder] + base58_bitcoin_address

    #add the prefix "80" to the private key again
    formatted_private_key = "80" + hex_private_key

    #create the WIF (Wallet Import Format) from the private key
    decimal_formatted_private_key = int(formatted_private_key, 16)
    base58_formatted_private_key = ''

    while decimal_formatted_private_key > 0:
        remainder = decimal_formatted_private_key % 58
        decimal_formatted_private_key //= 58
        base58_formatted_private_key = alphabet[remainder] + base58_formatted_private_key

    #add the suffix "01" to the WIF
    wif = base58_formatted_private_key + "1"

    #compare the generated address to the given addresses
    if base58_bitcoin_address in addresses:
        coincidence_counter += 1
        done_file.write("{}. Address Coincidence: {}\n"
                         "Bitcoin address :  {}\n"
                         "Private Key WIF : {}\n"
                         "-----------------------------------------------------------------------------------------------\n"
                         .format(coincidence_counter, base58_bitcoin_address, base58_bitcoin_address, wif))
    generated_counter += 1

    #print the progress
    print("==============================")
    print("Generated - {:<7}   |  Coincidence - {}".format(generated_counter, coincidence_counter))
    print("==============================")
    print("Bitcoin address :  {}".format(base58_bitcoin_address))
    print("Private Key WIF : {}".format(wif))
    print("-----------------------------------------------------------------------------------------------")

done

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