fork(21) download
  1. import hashlib
  2.  
  3. p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
  4. #r = 0xd47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
  5. #s1 = 0x44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
  6. #s2 = 0x9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab
  7. z1 = 0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
  8. z2 = 0x17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc
  9.  
  10. # r1 and s1 are contained in this ECDSA signature encoded in DER (openssl default).
  11. der_sig1 = "30440220d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1022044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e01"
  12.  
  13. # the same thing with the above line.
  14. der_sig2 = "30440220d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad102209a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab01"
  15.  
  16. params = {'p':p,'sig1':der_sig1,'sig2':der_sig2,'z1':z1,'z2':z2}
  17.  
  18. def hexify (s, flip=False):
  19. if flip:
  20. return s[::-1].encode ('hex')
  21. else:
  22. return s.encode ('hex')
  23.  
  24. def unhexify (s, flip=False):
  25. if flip:
  26. return s.decode ('hex')[::-1]
  27. else:
  28. return s.decode ('hex')
  29.  
  30. def inttohexstr(i):
  31. tmpstr = "%s" % hex(i)
  32. hexstr = tmpstr.replace('0x','').replace('L','')
  33. return hexstr
  34.  
  35. b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  36.  
  37. def dhash(s):
  38. return hashlib.sha256(hashlib.sha256(s).digest()).digest()
  39.  
  40. def rhash(s):
  41. h1 = hashlib.new('ripemd160')
  42. h1.update(hashlib.sha256(s).digest())
  43. return h1.digest()
  44.  
  45. def base58_encode(n):
  46. l = []
  47. while n > 0:
  48. n, r = divmod(n, 58)
  49. l.insert(0,(b58_digits[r]))
  50. return ''.join(l)
  51.  
  52. def base58_encode_padded(s):
  53. res = base58_encode(int('0x' + s.encode('hex'), 16))
  54. pad = 0
  55. for c in s:
  56. if c == chr(0):
  57. pad += 1
  58. else:
  59. break
  60. return b58_digits[0] * pad + res
  61.  
  62. def base58_check_encode(s, version=0):
  63. vs = chr(version) + s
  64. check = dhash(vs)[:4]
  65. return base58_encode_padded(vs + check)
  66.  
  67. def get_der_field(i,binary):
  68. if (ord(binary[i]) == 02):
  69. length = binary[i+1]
  70. end = i + ord(length) + 2
  71. string = binary[i+2:end]
  72. return string
  73. else:
  74. return None
  75.  
  76. # Here we decode a DER encoded string separating r and s
  77. def der_decode(hexstring):
  78. binary = unhexify(hexstring)
  79. full_length = ord(binary[1])
  80. if ((full_length + 3) == len(binary)):
  81. r = get_der_field(2,binary)
  82. s = get_der_field(len(r)+4,binary)
  83. return r,s
  84. else:
  85. return None
  86.  
  87. def show_results(privkeys):
  88. print "Posible Candidates..."
  89. for privkey in privkeys:
  90. hexprivkey = inttohexstr(privkey)
  91. print "intPrivkey = %d" % privkey
  92. print "hexPrivkey = %s" % hexprivkey
  93. print "bitcoin Privkey (WIF) = %s" % base58_check_encode(hexprivkey.decode('hex'),version=128)
  94.  
  95. def show_params(params):
  96. for param in params:
  97. try:
  98. print "%s: %s" % (param,inttohexstr(params[param]))
  99. except:
  100. print "%s: %s" % (param,params[param])
  101.  
  102. # This is the same as (a/b mod p) but avoiding floating numbers since we are dealing with prime numbers and modulus
  103. # and beacuse this the python built in division isn't suitable for our needs,
  104. # it returns floating point numbers rounded and we don't want them.
  105. def inverse_mult(a,b,p):
  106. y = (a * pow(b,p-2,p)) #(pow(a, b) modulo p) where p should be a prime number
  107. return y
  108.  
  109. # Here is the wrock!
  110. def derivate_privkey(p,r,s1,s2,z1,z2):
  111.  
  112. privkey = []
  113.  
  114. privkey.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(s1-s2)),p) % int(p)))
  115. privkey.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(s1+s2)),p) % int(p)))
  116. privkey.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(-s1-s2)),p) % int(p)))
  117. privkey.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(-s1+s2)),p) % int(p)))
  118.  
  119. return privkey
  120.  
  121. def process_signatures(params):
  122.  
  123. p = params['p']
  124. sig1 = params['sig1']
  125. sig2 = params['sig2']
  126. z1 = params['z1']
  127. z2 = params['z2']
  128.  
  129. tmp_r1,tmp_s1 = der_decode(sig1) # Here we extract r and s from the signature encoded in DER.
  130. tmp_r2,tmp_s2 = der_decode(sig2) # Idem.
  131.  
  132. if (tmp_r1 == tmp_r2): # If r1 and r2 are equal the two signatures are weak and we can recover the private key.
  133.  
  134. if (tmp_s1 != tmp_s2): # This: (s1-s2)>0 should be complied in order be able to compute the private key.
  135.  
  136. # the key of ECDSA are the integer numbers thats why we convert hexa from to them.
  137. r1 = int(tmp_r1.encode('hex'),16)
  138. r2 = int(tmp_r2.encode('hex'),16)
  139. s1 = int(tmp_s1.encode('hex'),16)
  140. s2 = int(tmp_s2.encode('hex'),16)
  141.  
  142. privkey = derivate_privkey(p,r1,s1,s2,z1,z2)
  143. return privkey
  144.  
  145. else:
  146. raise Exception("Privkey not computable: s1 and s2 are equal.")
  147. else:
  148. raise Exception("Privkey not computable: r1 and r2 are not equal.")
  149.  
  150. def main():
  151. show_params(params)
  152. privkey = process_signatures(params)
  153. if len(privkey)>0:
  154. show_results(privkey)
  155.  
  156. if __name__ == "__main__":
  157. main()
Runtime error #stdin #stdout #stderr 0.03s 44680KB
stdin
0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
stdout
Standard output is empty
stderr
Traceback (most recent call last):
  File "<builtin>/app_main.py", line 75, in run_toplevel
  File "<string>", line 89
    for privkey in privkeys:
                           ^
IndentationError: unindent does not match any outer indentation level