bitcoin address generator (address.py)


SUBMITTED BY: Guest

DATE: Nov. 10, 2013, 5:02 p.m.

FORMAT: Text only

SIZE: 6.1 kB

HITS: 890

  1. # Joric/bitcoin-dev, june 2012, public domain
  2. import hashlib
  3. import ctypes
  4. import ctypes.util
  5. ssl = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('ssl') or 'libeay32')
  6. def check_result (val, func, args):
  7. if val == 0: raise ValueError
  8. else: return ctypes.c_void_p (val)
  9. ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
  10. ssl.EC_KEY_new_by_curve_name.errcheck = check_result
  11. class KEY:
  12. def __init__(self):
  13. NID_secp256k1 = 714
  14. self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
  15. self.compressed = False
  16. self.POINT_CONVERSION_COMPRESSED = 2
  17. self.POINT_CONVERSION_UNCOMPRESSED = 4
  18. def __del__(self):
  19. if ssl:
  20. ssl.EC_KEY_free(self.k)
  21. self.k = None
  22. def generate(self, secret=None):
  23. if secret:
  24. priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new())
  25. group = ssl.EC_KEY_get0_group(self.k)
  26. pub_key = ssl.EC_POINT_new(group)
  27. ctx = ssl.BN_CTX_new()
  28. ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx)
  29. ssl.EC_KEY_set_private_key(self.k, priv_key)
  30. ssl.EC_KEY_set_public_key(self.k, pub_key)
  31. ssl.EC_POINT_free(pub_key)
  32. ssl.BN_CTX_free(ctx)
  33. return self.k
  34. else:
  35. return ssl.EC_KEY_generate_key(self.k)
  36. def set_privkey(self, key):
  37. self.mb = ctypes.create_string_buffer(key)
  38. ssl.d2i_ECPrivateKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key))
  39. def set_pubkey(self, key):
  40. self.mb = ctypes.create_string_buffer(key)
  41. ssl.o2i_ECPublicKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key))
  42. def get_privkey(self):
  43. size = ssl.i2d_ECPrivateKey(self.k, 0)
  44. mb_pri = ctypes.create_string_buffer(size)
  45. ssl.i2d_ECPrivateKey(self.k, ctypes.byref(ctypes.pointer(mb_pri)))
  46. return mb_pri.raw
  47. def get_pubkey(self):
  48. size = ssl.i2o_ECPublicKey(self.k, 0)
  49. mb = ctypes.create_string_buffer(size)
  50. ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb)))
  51. return mb.raw
  52. def get_secret(self):
  53. bn = ssl.EC_KEY_get0_private_key(self.k);
  54. bytes = (ssl.BN_num_bits(bn) + 7) / 8
  55. mb = ctypes.create_string_buffer(bytes)
  56. n = ssl.BN_bn2bin(bn, mb);
  57. return mb.raw.rjust(32, chr(0))
  58. def set_compressed(self, compressed):
  59. self.compressed = compressed
  60. if compressed:
  61. form = self.POINT_CONVERSION_COMPRESSED
  62. else:
  63. form = self.POINT_CONVERSION_UNCOMPRESSED
  64. ssl.EC_KEY_set_conv_form(self.k, form)
  65. def dhash(s):
  66. return hashlib.sha256(hashlib.sha256(s).digest()).digest()
  67. def rhash(s):
  68. h1 = hashlib.new('ripemd160')
  69. h1.update(hashlib.sha256(s).digest())
  70. return h1.digest()
  71. b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  72. def base58_encode(n):
  73. l = []
  74. while n > 0:
  75. n, r = divmod(n, 58)
  76. l.insert(0,(b58_digits[r]))
  77. return ''.join(l)
  78. def base58_decode(s):
  79. n = 0
  80. for ch in s:
  81. n *= 58
  82. digit = b58_digits.index(ch)
  83. n += digit
  84. return n
  85. def base58_encode_padded(s):
  86. res = base58_encode(int('0x' + s.encode('hex'), 16))
  87. pad = 0
  88. for c in s:
  89. if c == chr(0):
  90. pad += 1
  91. else:
  92. break
  93. return b58_digits[0] * pad + res
  94. def base58_decode_padded(s):
  95. pad = 0
  96. for c in s:
  97. if c == b58_digits[0]:
  98. pad += 1
  99. else:
  100. break
  101. h = '%x' % base58_decode(s)
  102. if len(h) % 2:
  103. h = '0' + h
  104. res = h.decode('hex')
  105. return chr(0) * pad + res
  106. def base58_check_encode(s, version=0):
  107. vs = chr(version) + s
  108. check = dhash(vs)[:4]
  109. return base58_encode_padded(vs + check)
  110. def base58_check_decode(s, version=0):
  111. k = base58_decode_padded(s)
  112. v0, data, check0 = k[0], k[1:-4], k[-4:]
  113. check1 = dhash(v0 + data)[:4]
  114. if check0 != check1:
  115. raise BaseException('checksum error')
  116. if version != ord(v0):
  117. raise BaseException('version mismatch')
  118. return data
  119. def gen_eckey(passphrase=None, secret=None, pkey=None, compressed=False, rounds=1):
  120. k = KEY()
  121. if passphrase:
  122. secret = passphrase.encode('utf8')
  123. for i in xrange(rounds):
  124. secret = hashlib.sha256(secret).digest()
  125. if pkey:
  126. secret = base58_check_decode(pkey, 128)
  127. compressed = len(secret) == 33
  128. secret = secret[0:32]
  129. k.generate(secret)
  130. k.set_compressed(compressed)
  131. return k
  132. def get_addr(k):
  133. pubkey = k.get_pubkey()
  134. secret = k.get_secret()
  135. hash160 = rhash(pubkey)
  136. addr = base58_check_encode(hash160)
  137. payload = secret
  138. if k.compressed:
  139. payload = secret + chr(1)
  140. pkey = base58_check_encode(payload, 128)
  141. return addr, pkey
  142. def test():
  143. # random uncompressed
  144. print get_addr(gen_eckey())
  145. # random compressed
  146. print get_addr(gen_eckey(compressed=True))
  147. # by secret
  148. print get_addr(gen_eckey(secret=('%064x' % 0xdeadbabe).decode('hex')))
  149. # by passphrase
  150. print get_addr(gen_eckey(passphrase='Satoshi Nakamoto'))
  151. # by private key, uncompressed
  152. print get_addr(gen_eckey(pkey='5K1HkbYffstTZDuV4riUWMbAMkQh57b8798uoy9pXYUDYeUHe7F'))
  153. # by private key, compressed
  154. print get_addr(gen_eckey(pkey='L3ATL5R9Exe1ubuAnHVgNgTKZEUKkDvWYAWkLUCyyvzzxRjtgyFe'))
  155. if __name__ == '__main__':
  156. test()

comments powered by Disqus