skip420

Der_sig

Jan 21st, 2022 (edited)
1,285
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # python3
  2. # note: it's very possible to change z1 and z2 and yet still keep the Sig as is. and will provide a different outcome.........
  3. # under careful observation.. .many are unknown/known to be flipped.| be wary on line 20 to 26 on flip-flop
  4.  
  5. import hashlib
  6.  
  7. p  = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
  8.  
  9. z1 = 0x75c991a64fa69368d1988c2ad6f885b17b8a69868763852b2c86aacc6b4745e8
  10. z2 = 0x5e3f128174bd4f0cd503ec82004467cc605265c950cae88ca9f247419bee5610
  11.  
  12. # r1 and s1 are contained in this ECDSA signature encoded in DER (openssl default).
  13. der_sig1 = "3044022035e4dd6e4d56638eee57fddf6af2d9f8a1cd8ae35d8e304b175f8c5ec0d80f6f022024e0255335dc10284b3df9feadd1edc2bfb0540c03d1dbc09d65a84179f3b3a701"
  14.  
  15. # the same thing with the above line.
  16. der_sig2 = "3044022035e4dd6e4d56638eee57fddf6af2d9f8a1cd8ae35d8e304b175f8c5ec0d80f6f02202b1c3c17b3d13a8e6c9ad6a75743feb2040dff9d741e53c7c5564baba7a09acb01"
  17.  
  18. params = {'p':p,'sig1':der_sig1,'sig2':der_sig2,'z1':z1,'z2':z2}
  19.  
  20. def hexify (s, flip=False):
  21.     if flip:
  22.         return s[::-1].encode ('hex')
  23.     else:
  24.         return s.encode ('hex')
  25.  
  26. def unhexify (s, flip=False):
  27.     if flip:
  28.         return s.decode ('hex')[::-1]
  29.     else:
  30.         return s.decode ('hex')
  31.  
  32. def inttohexstr(i):
  33.     tmpstr = hex(i)
  34.     hexstr = tmpstr.replace('0x','').replace('L','').zfill(64)
  35.     return hexstr
  36.  
  37. b58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  38.  
  39. def dhash(s):
  40.     return hashlib.sha256(hashlib.sha256(s).digest()).digest()
  41.  
  42. def rhash(s):
  43.     h1 = hashlib.new('ripemd160')
  44.     h1.update(hashlib.sha256(s).digest())
  45.     return h1.digest()
  46.  
  47. def base58_encode(n):
  48.     l = []
  49.     while n > 0:
  50.         n, r = divmod(n, 58)
  51.         l.insert(0,(b58_digits[r]))
  52.     return ''.join(l)
  53.  
  54. def base58_encode_padded(s):
  55.     res = base58_encode(int('0x' + s.encode('hex'), 16))
  56.     pad = 0
  57.     for c in s:
  58.         if c == chr(0):
  59.             pad += 1
  60.         else:
  61.             break
  62.     return b58_digits[0] * pad + res
  63.  
  64. def base58_check_encode(s, version=0):
  65.     vs = chr(version) + s
  66.     check = dhash(vs)[:4]
  67.     return base58_encode_padded(vs + check)
  68.  
  69. def get_der_field(i,binary):
  70.         if (ord(binary[i]) == 02):
  71.                 length = binary[i+1]
  72.                 end = i + ord(length) + 2
  73.                 string = binary[i+2:end]
  74.                 return string
  75.         else:
  76.                 return None
  77.  
  78. # Here we decode a DER encoded string separating r and s
  79. def der_decode(hexstring):
  80.         binary = unhexify(hexstring)
  81.         full_length = ord(binary[1])
  82.         if ((full_length + 3) == len(binary)):
  83.                 r = get_der_field(2,binary)
  84.                 s = get_der_field(len(r)+4,binary)
  85.                 return r,s
  86.         else:
  87.                 return None
  88.  
  89. def show_results(privkeys):
  90.         print "Posible Candidates..."
  91.         for privkey in privkeys:
  92.                 hexprivkey = inttohexstr(privkey)
  93.             print "intPrivkey = %d"  % privkey
  94.             print "hexPrivkey = %s" % hexprivkey
  95.             print "bitcoin Privkey (WIF) = %s" % base58_check_encode(hexprivkey.decode('hex'),version=128)
  96.             print "bitcoin Privkey (WIF compressed) = %s" % base58_check_encode((hexprivkey + "01").decode('hex'),version=128)
  97.  
  98.  
  99. def show_params(params):
  100.     for param in params:
  101.         try:
  102.             print "%s: %s" % (param,inttohexstr(params[param]))
  103.         except:
  104.             print "%s: %s" % (param,params[param])
  105.  
  106. def inverse_mult(a,b,p):
  107.     y =  (a * pow(b,p-2,p))  #(pow(a, b) modulo p) where p should be a prime number
  108.     return y
  109.  
  110. # Here is the wrock!
  111. def derivate_privkey(p,r,s1,s2,z1,z2):
  112.  
  113.     privkeys = []
  114.  
  115.     privkeys.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(s1-s2)),p) % int(p)))
  116.     privkeys.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(s1+s2)),p) % int(p)))
  117.     privkeys.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(-s1-s2)),p) % int(p)))
  118.     privkeys.append((inverse_mult(((z1*s2) - (z2*s1)),(r*(-s1+s2)),p) % int(p)))
  119.  
  120.     privkeys.append((inverse_mult(((z1*s2) + (z2*s1)),(r*(s1-s2)),p) % int(p)))
  121.         privkeys.append((inverse_mult(((z1*s2) + (z2*s1)),(r*(s1+s2)),p) % int(p)))
  122.         privkeys.append((inverse_mult(((z1*s2) + (z2*s1)),(r*(-s1-s2)),p) % int(p)))
  123.         privkeys.append((inverse_mult(((z1*s2) + (z2*s1)),(r*(-s1+s2)),p) % int(p)))
  124.  
  125.     return privkeys
  126.  
  127. def process_signatures(params):
  128.  
  129.     p = params['p']
  130.     sig1 = params['sig1']
  131.     sig2 = params['sig2']
  132.     z1 = params['z1']
  133.     z2 = params['z2']
  134.  
  135.     tmp_r1,tmp_s1 = der_decode(sig1) # Here we extract r and s from the signature encoded in DER.
  136.     tmp_r2,tmp_s2 = der_decode(sig2) # Idem.
  137.  
  138.     # the key of ECDSA are the integer numbers thats why we convert hexa from to them.
  139.     r1 = int(tmp_r1.encode('hex'),16)
  140.     r2 = int(tmp_r2.encode('hex'),16)
  141.     s1 = int(tmp_s1.encode('hex'),16)
  142.     s2 = int(tmp_s2.encode('hex'),16)
  143.  
  144.     if (r1 == r2): # If r1 and r2 are equal the two signatures are weak and we can recover the private key.
  145.         if (s1 != s2): # This: (s1-s2)>0 should be complied in order be able to compute the private key.
  146.             privkey = derivate_privkey(p,r1,s1,s2,z1,z2)
  147.             return privkey
  148.         else:
  149.             raise Exception("Privkey not computable: s1 and s2 are equal.")
  150.     else:
  151.         raise Exception("Privkey not computable: r1 and r2 are not equal.")
  152.  
  153. def main():
  154.     show_params(params)
  155.     privkey = process_signatures(params)
  156.     if len(privkey)>0:
  157.         show_results(privkey)
  158.  
  159. if __name__ == "__main__":
  160.     main()
  161.  
RAW Paste Data Copied