def recover_dsa_priv(): y = '84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4'+\ 'abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004'+\ 'e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed'+\ '1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07b'+\ 'bb283e6633451e535c45513b2d33c99ea17' y = long(y, 16) h = 0xd2d0714f014a9784047eaeccf956520045c45265 r = 548099063082341131477253921760299949438196259240 s = 857042759984254168557880549501802188789837994940 m = 'For those that envy a MC it can be hazardous to your health\n'+\ 'So be friendly, a matter of life and death, just like a etch-a-sketch\n' x_sha1 = '0954edd5e0afe5542a4adf012611a91912a3ec16' #print hashlib.sha1(m).hexdigest() params = dsa.P, dsa.Q, dsa.G # we know k is between 0 and 2^16 for k in xrange(2**16): x = dsa.recover_priv_from_k(params, k, m, (r,s)) if x_sha1 == hashlib.sha1(binascii.hexlify(dsa._tohex(x))).hexdigest(): print "Found x == %d" % x return print "Could not find x"
def recover_dsa_nonce_repeated(params=(dsa.P, dsa.Q, dsa.G)): p, q, g = params # read messages f = open('44.txt','r') lines = f.readlines() f.close() y = '2d026f4bf30195ede3a088da85e398ef869611d0f68f07'+\ '13d51c9c1a3a26c95105d915e2d8cdf26d056b86b8a7b8'+\ '5519b1c23cc3ecdc6062650462e3063bd179c2a6581519'+\ 'f674a61f1d89a1fff27171ebc1b93d4dc57bceb7ae2430'+\ 'f98a6a4d83d8279ee65d71c1203d2c96d65ebbf7cce9d3'+\ '2971c3de5084cce04a2e147821' y = long(y, 16) x_sha1 = 'ca8f6f7c66fa362d40760d135b763eb8527d3d52' # r = g^{k} mod p mod q # s = k ^ -1 * (H(m) + x*r) mod q # repeated k means that r is the same # s1 - s2 = k ^ -1 * (H(m1) - H(m2)) mod q # so k = (H(m1) - H(m2))/(s1 - s2) mod q # search for a repeated r r_dict = {} for i in range(0, len(lines), 4): msg = lines[i][5:].strip('\n') s = lines[i+1][2:].strip() r = lines[i+2][2:].strip() h = lines[i+3][2:].strip() if r in r_dict: print "Found repeated r =", r # we found a repeat, so calculate k h1 = long(h, 16) s1 = long(s) s2, h2 = r_dict[r] h2 = long(h2, 16) s2 = long(s2) numerator = (h1 - h2) % q denominator = (s1 - s2) % q denom_inv = dsa.invmod(denominator, q) assert denom_inv k = (numerator * denom_inv) % q print "Found k: %d" % k r2 = dsa.modexp(g, k, p) % q print "Checking k ... ", long(r)==r2 # calculate x, the private key x = dsa.recover_priv_from_k(params, k, msg, (long(r),long(s))) if x_sha1 == hashlib.sha1(binascii.hexlify(dsa._tohex(x))).hexdigest(): print "Found x == %d" % x return else: print "Could not find correct x" r_dict[r] = (s, h) return "Could not find a repeated use of k"