Guest User

Untitled

a guest
Dec 15th, 2017
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.44 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # Joric/bitcoin-dev, june 2012, public domain
  3.  
  4. import hashlib
  5. import ctypes
  6. import ctypes.util
  7. import sys
  8.  
  9. ssl = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('ssl') or 'libeay32')
  10.  
  11. def check_result (val, func, args):
  12. if val == 0: raise ValueError
  13. else: return ctypes.c_void_p (val)
  14.  
  15. ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p
  16. ssl.EC_KEY_new_by_curve_name.errcheck = check_result
  17.  
  18. class KEY:
  19. def __init__(self):
  20. NID_secp256k1 = 714
  21. self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1)
  22. self.compressed = False
  23. self.POINT_CONVERSION_COMPRESSED = 2
  24. self.POINT_CONVERSION_UNCOMPRESSED = 4
  25.  
  26. def __del__(self):
  27. if ssl:
  28. ssl.EC_KEY_free(self.k)
  29. self.k = None
  30.  
  31. def generate(self, secret=None):
  32. if secret:
  33. self.prikey = secret
  34. priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new())
  35. group = ssl.EC_KEY_get0_group(self.k)
  36. pub_key = ssl.EC_POINT_new(group)
  37. ctx = ssl.BN_CTX_new()
  38. ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx)
  39. ssl.EC_KEY_set_private_key(self.k, priv_key)
  40. ssl.EC_KEY_set_public_key(self.k, pub_key)
  41. ssl.EC_POINT_free(pub_key)
  42. ssl.BN_CTX_free(ctx)
  43. return self.k
  44. else:
  45. return ssl.EC_KEY_generate_key(self.k)
  46.  
  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.  
  53. def get_secret(self):
  54. bn = ssl.EC_KEY_get0_private_key(self.k);
  55. bytes = (ssl.BN_num_bits(bn) + 7) / 8
  56. mb = ctypes.create_string_buffer(bytes)
  57. n = ssl.BN_bn2bin(bn, mb);
  58. return mb.raw.rjust(32, chr(0))
  59.  
  60. def set_compressed(self, compressed):
  61. self.compressed = compressed
  62. if compressed:
  63. form = self.POINT_CONVERSION_COMPRESSED
  64. else:
  65. form = self.POINT_CONVERSION_UNCOMPRESSED
  66. ssl.EC_KEY_set_conv_form(self.k, form)
  67.  
  68. def dhash(s):
  69. return hashlib.sha256(hashlib.sha256(s).digest()).digest()
  70.  
  71. def rhash(s):
  72. h1 = hashlib.new('ripemd160')
  73. h1.update(hashlib.sha256(s).digest())
  74. return h1.digest()
  75.  
  76. b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  77.  
  78. def base58_encode(n):
  79. l = []
  80. while n > 0:
  81. n, r = divmod(n, 58)
  82. l.insert(0,(b58_digits[r]))
  83. return ''.join(l)
  84.  
  85. def base58_decode(s):
  86. n = 0
  87. for ch in s:
  88. n *= 58
  89. digit = b58_digits.index(ch)
  90. n += digit
  91. return n
  92.  
  93. def base58_encode_padded(s):
  94. res = base58_encode(int('0x' + s.encode('hex'), 16))
  95. pad = 0
  96. for c in s:
  97. if c == chr(0):
  98. pad += 1
  99. else:
  100. break
  101. return b58_digits[0] * pad + res
  102.  
  103. def base58_decode_padded(s):
  104. pad = 0
  105. for c in s:
  106. if c == b58_digits[0]:
  107. pad += 1
  108. else:
  109. break
  110. h = '%x' % base58_decode(s)
  111. if len(h) % 2:
  112. h = '0' + h
  113. res = h.decode('hex')
  114. return chr(0) * pad + res
  115.  
  116. def base58_check_encode(s, version=0):
  117. vs = chr(version) + s
  118. check = dhash(vs)[:4]
  119. return base58_encode_padded(vs + check)
  120.  
  121. def base58_check_decode(s, version=0):
  122. k = base58_decode_padded(s)
  123. v0, data, check0 = k[0], k[1:-4], k[-4:]
  124. check1 = dhash(v0 + data)[:4]
  125. if check0 != check1:
  126. raise BaseException('checksum error')
  127. if version != ord(v0):
  128. raise BaseException('version mismatch')
  129. return data
  130.  
  131. def gen_eckey(passphrase=None, secret=None, pkey=None, compressed=False, rounds=1, version=0):
  132. k = KEY()
  133. if passphrase:
  134. secret = passphrase.encode('utf8')
  135. for i in xrange(rounds):
  136. secret = hashlib.sha256(secret).digest()
  137. if pkey:
  138. secret = base58_check_decode(pkey, 128+version)
  139. compressed = len(secret) == 33
  140. secret = secret[0:32]
  141. k.generate(secret)
  142. k.set_compressed(compressed)
  143. return k
  144.  
  145. def get_addr(k,version=0):
  146. pubkey = k.get_pubkey()
  147. secret = k.get_secret()
  148. hash160 = rhash(pubkey)
  149. addr = base58_check_encode(hash160,version)
  150. payload = secret
  151. if k.compressed:
  152. payload = secret + chr(1)
  153. pkey = base58_check_encode(payload, 128+version)
  154. return addr, pkey
  155.  
  156. def reencode(pkey,version=0):
  157. payload = base58_check_decode(pkey,128+version)
  158. secret = payload[:-1]
  159. payload = secret + chr(1)
  160. pkey = base58_check_encode(payload, 128+version)
  161. print get_addr(gen_eckey(pkey))
  162.  
  163. def test(otherversion):
  164. # random compressed
  165. print get_addr(gen_eckey(compressed=True,version=otherversion),version=otherversion)
  166.  
  167. # uncomment these to create addresses via a different method
  168. # random uncompressed
  169. #print get_addr(gen_eckey())
  170. # by secret
  171. #print get_addr(gen_eckey(secret=('%064x' % 0xdeadbabe).decode('hex')))
  172. # by passphrase
  173. #print get_addr(gen_eckey(passphrase='Satoshi Nakamoto'))
  174. # by private key
  175. #print get_addr(gen_eckey(pkey='5K1HkbYffstTZDuV4riUWMbAMkQh57b8798uoy9pXYUDYeUHe7F'))
  176. #print get_addr(gen_eckey(pkey='L3ATL5R9Exe1ubuAnHVgNgTKZEUKkDvWYAWkLUCyyvzzxRjtgyFe'))
  177.  
  178. # uncomment this to reencode the private keys created by early versions of this script
  179. #reencode(sys.argv[1])
  180.  
  181. if __name__ == '__main__':
  182. import optparse
  183. parser = optparse.OptionParser(usage="%prog [options]")
  184. parser.add_option("--otherversion", dest="otherversion", default=0,
  185. help="Generate address with different version number")
  186. (options, args) = parser.parse_args()
  187.  
  188. test(int(options.otherversion))
Add Comment
Please, Sign In to add comment