Skip to content

Instantly share code, notes, and snippets.

@jujum4n
Last active June 7, 2022 06:01
Show Gist options
  • Select an option

  • Save jujum4n/1ba13e18f9b32665d24f to your computer and use it in GitHub Desktop.

Select an option

Save jujum4n/1ba13e18f9b32665d24f to your computer and use it in GitHub Desktop.
Python Bitcoin Keypair Generator
# By: Justin Chase
# Description: Based heavily on PYBITCOINTOOLS - https://github.com/vbuterin/pybitcointools By: vbuterin
# Version: 0.01
import sys, re
import binascii
import os
import hashlib
import random
import time
import ssl
# Elliptic curve parameters (secp256k1)
P = 2**256 - 2**32 - 977
N = 115792089237316195423570985008687907852837564279074904382605163141518161494337
A = 0
B = 7
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
G = (Gx, Gy)
if sys.version_info.major == 2:
string_types = (str, unicode)
string_or_bytes_types = string_types
int_types = (int, float, long)
# Base switching
code_strings = {
2: '01',
10: '0123456789',
16: '0123456789abcdef',
32: 'abcdefghijklmnopqrstuvwxyz234567',
58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
256: ''.join([chr(x) for x in range(256)])
}
def bin_dbl_sha256(s):
bytes_to_hash = from_string_to_bytes(s)
return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest()
def lpad(msg, symbol, length):
if len(msg) >= length:
return msg
return symbol * (length - len(msg)) + msg
def get_code_string(base):
if base in code_strings:
return code_strings[base]
else:
raise ValueError("Invalid base!")
def changebase(string, frm, to, minlen=0):
if frm == to:
return lpad(string, get_code_string(frm)[0], minlen)
return encode(decode(string, frm), to, minlen)
def bin_to_b58check(inp, magicbyte=0):
inp_fmtd = chr(int(magicbyte)) + inp
leadingzbytes = len(re.match('^\x00*', inp_fmtd).group(0))
checksum = bin_dbl_sha256(inp_fmtd)[:4]
return '1' * leadingzbytes + changebase(inp_fmtd + checksum, 256, 58)
def bytes_to_hex_string(b):
return b.encode('hex')
def safe_from_hex(s):
return s.decode('hex')
def from_int_representation_to_bytes(a):
return str(a)
def from_int_to_byte(a):
return chr(a)
def from_byte_to_int(a):
return ord(a)
def from_bytes_to_string(s):
return s
def from_string_to_bytes(a):
return a
def safe_hexlify(a):
return binascii.hexlify(a)
def encode(val, base, minlen=0):
base, minlen = int(base), int(minlen)
code_string = get_code_string(base)
result = ""
while val > 0:
result = code_string[val % base] + result
val //= base
return code_string[0] * max(minlen - len(result), 0) + result
def decode(string, base):
base = int(base)
code_string = get_code_string(base)
result = 0
if base == 16:
string = string.lower()
while len(string) > 0:
result *= base
result += code_string.find(string[0])
string = string[1:]
return result
def random_string(x):
return os.urandom(x)
def encode_pubkey(pub, formt):
if not isinstance(pub, (tuple, list)):
pub = decode_pubkey(pub)
if formt == 'decimal':
return pub
elif formt == 'bin':
return b'\x04' + encode(pub[0], 256, 32) + encode(pub[1], 256, 32)
elif formt == 'bin_compressed':
return from_int_to_byte(2 + (pub[1] % 2)) + encode(pub[0], 256, 32)
elif formt == 'hex':
return '04' + encode(pub[0], 16, 64) + encode(pub[1], 16, 64)
elif formt == 'hex_compressed':
return '0' + str(2 + (pub[1] % 2)) + encode(pub[0], 16, 64)
elif formt == 'bin_electrum':
return encode(pub[0], 256, 32) + encode(pub[1], 256, 32)
elif formt == 'hex_electrum':
return encode(pub[0], 16, 64) + encode(pub[1], 16, 64)
else:
raise Exception("Invalid format!")
def nurandom_key(userentropy):
entropy = random_string(256) \
+ str(random.randrange(2 ** 256)) \
+ str(int(time.time() * 1000000)) \
+ str(userentropy) \
+ random_string(256)
return nusha256(entropy)
def bin_sha256(string):
binary_data = string if isinstance(string, bytes) else bytes(string, 'utf-8')
return hashlib.sha256(binary_data).digest()
def nusha256(string):
return bytes_to_hex_string(bin_sha256(string))
def b58check_to_bin(inp):
leadingzbytes = len(re.match('^1*', inp).group(0))
data = b'\x00' * leadingzbytes + changebase(inp, 58, 256)
assert bin_dbl_sha256(data[:-4])[:4] == data[-4:]
return data[1:-4]
def get_version_byte(inp):
leadingzbytes = len(re.match('^1*', inp).group(0))
data = b'\x00' * leadingzbytes + changebase(inp, 58, 256)
assert bin_dbl_sha256(data[:-4])[:4] == data[-4:]
return ord(data[0])
def hex_to_b58check(inp, magicbyte=0):
return bin_to_b58check(binascii.unhexlify(inp), magicbyte)
def b58check_to_hex(inp):
return safe_hexlify(b58check_to_bin(inp))
def bin_hash160(string):
intermed = hashlib.sha256(string).digest()
try:
digest = hashlib.new('ripemd160', intermed).digest()
except:
digest = ssl.RIPEMD160(intermed).digest()
return digest
def pubkey_to_address(pubkey, magicbyte=0):
if isinstance(pubkey, (list, tuple)):
pubkey = encode_pubkey(pubkey, 'bin')
if len(pubkey) in [66, 130]:
return bin_to_b58check(
bin_hash160(binascii.unhexlify(pubkey)), magicbyte)
return bin_to_b58check(bin_hash160(pubkey), magicbyte)
pubtoaddr = pubkey_to_address
def privkey_to_address(priv, magicbyte=0):
return pubkey_to_address(privkey_to_pubkey(priv), magicbyte)
privtoaddr = privkey_to_address
def from_jacobian(p):
z = inv(p[2], P)
return ((p[0] * z**2) % P, (p[1] * z**3) % P)
def jacobian_double(p):
if not p[1]:
return (0, 0, 0)
ysq = (p[1] ** 2) % P
S = (4 * p[0] * ysq) % P
M = (3 * p[0] ** 2 + A * p[2] ** 4) % P
nx = (M**2 - 2 * S) % P
ny = (M * (S - nx) - 8 * ysq ** 2) % P
nz = (2 * p[1] * p[2]) % P
return (nx, ny, nz)
def jacobian_add(p, q):
if not p[1]:
return q
if not q[1]:
return p
U1 = (p[0] * q[2] ** 2) % P
U2 = (q[0] * p[2] ** 2) % P
S1 = (p[1] * q[2] ** 3) % P
S2 = (q[1] * p[2] ** 3) % P
if U1 == U2:
if S1 != S2:
return (0, 0, 1)
return jacobian_double(p)
H = U2 - U1
R = S2 - S1
H2 = (H * H) % P
H3 = (H * H2) % P
U1H2 = (U1 * H2) % P
nx = (R ** 2 - H3 - 2 * U1H2) % P
ny = (R * (U1H2 - nx) - S1 * H3) % P
nz = H * p[2] * q[2]
return (nx, ny, nz)
def jacobian_multiply(a, n):
if a[1] == 0 or n == 0:
return (0, 0, 1)
if n == 1:
return a
if n < 0 or n >= N:
return jacobian_multiply(a, n % N)
if (n % 2) == 0:
return jacobian_double(jacobian_multiply(a, n//2))
if (n % 2) == 1:
return jacobian_add(jacobian_double(jacobian_multiply(a, n//2)), a)
def to_jacobian(p):
o = (p[0], p[1], 1)
return o
def fast_multiply(a, n):
return from_jacobian(jacobian_multiply(to_jacobian(a), n))
def privkey_to_pubkey(privkey):
f = get_privkey_format(privkey)
privkey = decode_privkey(privkey, f)
if privkey >= N:
raise Exception("Invalid privkey")
if f in ['bin', 'bin_compressed', 'hex', 'hex_compressed', 'decimal']:
return encode_pubkey(fast_multiply(G, privkey), f)
else:
return encode_pubkey(fast_multiply(G, privkey), f.replace('wif', 'hex'))
def decode_privkey(priv,formt=None):
if not formt: formt = get_privkey_format(priv)
if formt == 'decimal': return priv
elif formt == 'bin': return decode(priv, 256)
elif formt == 'bin_compressed': return decode(priv[:32], 256)
elif formt == 'hex': return decode(priv, 16)
elif formt == 'hex_compressed': return decode(priv[:64], 16)
elif formt == 'wif': return decode(b58check_to_bin(priv),256)
elif formt == 'wif_compressed':
return decode(b58check_to_bin(priv)[:32],256)
else: raise Exception("WIF does not represent privkey")
def get_privkey_format(priv):
if isinstance(priv, int_types): return 'decimal'
elif len(priv) == 32: return 'bin'
elif len(priv) == 33: return 'bin_compressed'
elif len(priv) == 64: return 'hex'
elif len(priv) == 66: return 'hex_compressed'
else:
bin_p = b58check_to_bin(priv)
if len(bin_p) == 32: return 'wif'
elif len(bin_p) == 33: return 'wif_compressed'
else: raise Exception("WIF does not represent privkey")
def inv(a, n):
if a == 0:
return 0
lm, hm = 1, 0
low, high = a % n, n
while low > 1:
r = high//low
nm, new = hm-lm*r, high-low*r
lm, low, hm, high = nm, new, lm, low
return lm % n
def change_curve(p, n, a, b, gx, gy):
global P, N, A, B, Gx, Gy, G
P, N, A, B, Gx, Gy = p, n, a, b, gx, gy
G = (Gx, Gy)
def getBitcoinKeyPair(userentropy):
PAIR = []
rand_key = nurandom_key(userentropy)
payment_address = privkey_to_address(rand_key)
payment_address = str(payment_address)
PAIR.append(payment_address)
PAIR.append(hexstrtowif(rand_key))
return PAIR
def hexstrtowif(hex_str):
numpriv = int(hex_str, 16)
t='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
step1 = '80'+hex(numpriv)[2:].strip('L').zfill(64)
step2 = hashlib.sha256(binascii.unhexlify(step1)).hexdigest()
step3 = hashlib.sha256(binascii.unhexlify(step2)).hexdigest()
step4 = int(step1 + step3[:8] , 16)
return ''.join([t[step4/(58**l)%58] for l in range(100)])[::-1].lstrip('1')
def example_usage():
#Entropy from Form input
userentropy = str('source of user entropy 12803hasipokdjm;l12@#$EFDS')
#Generate a new Keypair using Users Entropy
keyPair = getBitcoinKeyPair(userentropy)
print 'Public: ' + keyPair[0]
print 'Private: ' + keyPair[1]
print 'Wif: ' + hexstrtowif(keyPair[1])
@henryjvr
Copy link

henryjvr commented Jun 7, 2022

the term"conda" is not recognize as a name of a cmdlet can you please help

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