Advertisement
Guest User

Generate a BTC address via Python 3 + openssl

a guest
Mar 3rd, 2013
5,331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.11 KB | None | 0 0
  1. #!/usr/bin/env python
  2. import ctypes
  3. import hashlib
  4. from base58 import encode as base58_encode
  5.  
  6. ################################################################################
  7. ################################################################################
  8. ssl_library = ctypes.cdll.LoadLibrary('libssl.so')
  9.  
  10. def gen_ecdsa_pair():
  11.     NID_secp160k1 = 708
  12.     NID_secp256k1 = 714
  13.     k = ssl_library.EC_KEY_new_by_curve_name(NID_secp256k1)
  14.  
  15.     if ssl_library.EC_KEY_generate_key(k) != 1:
  16.         raise Exception("internal error?")
  17.  
  18.     bignum_private_key = ssl_library.EC_KEY_get0_private_key(k)
  19.     size = (ssl_library.BN_num_bits(bignum_private_key)+7)//8
  20.     #print("Key size is {} bytes".format(size))
  21.     storage = ctypes.create_string_buffer(size)
  22.     ssl_library.BN_bn2bin(bignum_private_key, storage)
  23.     private_key = storage.raw
  24.  
  25.     size = ssl_library.i2o_ECPublicKey(k, 0)
  26.     #print("Pubkey size is {} bytes".format(size))
  27.     storage = ctypes.create_string_buffer(size)
  28.     ssl_library.i2o_ECPublicKey(k, ctypes.byref(ctypes.pointer(storage)))
  29.     public_key = storage.raw
  30.  
  31.     ssl_library.EC_KEY_free(k)
  32.     return public_key, private_key
  33.  
  34. def ecdsa_get_coordinates(public_key):
  35.     x = bytes(public_key[1:33])
  36.     y = bytes(public_key[33:65])
  37.     return x, y
  38.  
  39. def generate_address(public_key):
  40.     assert isinstance(public_key, bytes)
  41.  
  42.     x, y = ecdsa_get_coordinates(public_key)
  43.    
  44.     s = b'\x04' + x + y
  45.     #print('0x04 + x + y:', ''.join(['{:02X}'.format(i) for i in s]))
  46.  
  47.     hasher = hashlib.sha256()
  48.     hasher.update(s)
  49.     r = hasher.digest()
  50.     #print('SHA256(0x04 + x + y):', ''.join(['{:02X}'.format(i) for i in r]))
  51.  
  52.     hasher = hashlib.new('ripemd160')
  53.     hasher.update(r)
  54.     r = hasher.digest()
  55.     #print('RIPEMD160(SHA256(0x04 + x + y)):', ''.join(['{:02X}'.format(i) for i in r]))
  56.  
  57.     # Since '1' is a zero byte, it won't be present in the output address.
  58.     return '1' + base58_check(r, version=0)
  59.  
  60. def base58_check(src, version=0):
  61.     src = bytes([version]) + src
  62.     hasher = hashlib.sha256()
  63.     hasher.update(src)
  64.     r = hasher.digest()
  65.     #print('SHA256(0x00 + r):', ''.join(['{:02X}'.format(i) for i in r]))
  66.  
  67.     hasher = hashlib.sha256()
  68.     hasher.update(r)
  69.     r = hasher.digest()
  70.     #print('SHA256(SHA256(0x00 + r)):', ''.join(['{:02X}'.format(i) for i in r]))
  71.  
  72.     checksum = r[:4]
  73.     s = src + checksum
  74.     #print('src + checksum:', ''.join(['{:02X}'.format(i) for i in s]))
  75.  
  76.     return base58_encode(int.from_bytes(s, 'big'))
  77.  
  78. def test():
  79.     public_key, private_key = gen_ecdsa_pair()
  80.  
  81.     hex_private_key = ''.join(["{:02x}".format(i) for i in private_key])
  82.     assert len(hex_private_key) == 64
  83.  
  84.     print("ECDSA private key (random number / secret exponent) = {}".format(hex_private_key))
  85.     print("ECDSA public key = {}".format(''.join(['{:02x}'.format(i) for i in public_key])))
  86.     print("Bitcoin private key (Base58Check) = {}".format(base58_check(private_key, version=128)))
  87.  
  88.     addr = generate_address(public_key)
  89.     print("Bitcoin Address: {} (length={})".format(addr, len(addr)))
  90.  
  91. if __name__ == "__main__":
  92.     test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement