Advertisement
Guest User

Untitled

a guest
Sep 21st, 2017
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.98 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. import pbp #Get access to encrypt and decrypt functions
  4. from Crypto.Util import number #For modular multiplicative inverse
  5. import math
  6. #Had to use "sudo apt-get install python-dev" to be able to upgrade pycrypto with "sudo pip install pycrypto --upgrade"
  7.  
  8. MODULI_FILE = 'moduli.hex' #'test.hex' #
  9. CIPHER_FILE = '1.2.4_ciphertext.enc.asc'
  10. PRIMES_FILE = 'primes.txt'
  11. OUTPUT_FILE = 'sol_1.2.4.txt'
  12. e = 65537 #Public exponent
  13.  
  14. #In python long types should have infinite precision besides memory limits
  15. #Get RSA moduli (N = p * q, p and q are prime factors)
  16. with open(MODULI_FILE,'r') as mod_f:
  17. RSA_mods = mod_f.read()
  18. RSA_mods = RSA_mods.strip()
  19. RSA_mods = RSA_mods.split('\n')
  20.  
  21. RSA_ints = []
  22. #Convert array of hex moduli to ints (might be "long")
  23. for i in range(len(RSA_mods)):
  24. RSA_ints.append(int(RSA_mods[i],16))
  25.  
  26. #Get cipher text
  27. with open(CIPHER_FILE, 'r') as ciph_f:
  28. ciph = ciph_f.read()
  29.  
  30.  
  31. #Compute pairwise GCDs of RSA keys
  32. #Multiplies the first two entries in a vector
  33. def prod(a):
  34. p = 1
  35. for i in range(len(a)):
  36. p = p * a[i]
  37. return p
  38.  
  39.  
  40. #Product tree: using method from https//:facthacks.cr.yp.to/product.html
  41. #Takes in vector of integers to multiply together (will be the RSA moduli)
  42. def producttree(X):
  43. result= [X]
  44. while len(X) > 1:
  45. X = [prod(X[i*2:(i+1)*2]) for i in range ((len(X)+1)/2)]
  46. result.append(X)
  47. return result
  48.  
  49. def product(X):
  50. if len(X) == 0: return 1
  51. while len(X) > 1:
  52. X = [prod(X[i*2:(i+1)*2]) for i in range((len(X) + 1)/2)]
  53. return X[0]
  54.  
  55. #Remainder tree: using method from https//:facthacks.cr.yp.to/remainder.html
  56. #def remainderusingproducttree(n,T):
  57. # result = [n]
  58. # for t in reversed(T):
  59. # #Floor function on i/2 implied for ints
  60. # #print T[len(T)-10: len(T)-1] #Errors?
  61. # result = [result[(i/2)]%t[i] for i in range(len(t))]
  62.  
  63. # return result
  64.  
  65. #Computes n mod X[i] for i in range(len(X))
  66. #def remainders(n,X):
  67. # return remainderusingproducttree(n,producttree(X))
  68.  
  69. #Not defined for python 2 it seems
  70. def gcd(a, b):
  71. #Check that a > b
  72. if(a < b):
  73. c = a
  74. a = b
  75. b = c
  76. while( b > 0):
  77. c = a%b
  78. a = b
  79. b = c
  80. return a
  81.  
  82. def batchgcd_faster(X):
  83. prods = producttree(X)
  84. R = prods.pop()
  85. while prods:
  86. X = prods.pop()
  87. R = [R[int(math.floor(i/2))] % X[i]**2 for i in range(len(X))]
  88. return [gcd(r/n,n) for r,n in zip(R,X)]
  89.  
  90. #Actual call over RSA moduli, need to take gcd(product of keys mod (Ni^2)/Ni,Ni) for
  91. #all keys Ni
  92.  
  93. #final_prod = product(RSA_ints)
  94. #RSA_squared = []
  95. #for i in range(len(RSA_ints)):
  96. # RSA_squared.append(RSA_ints[i]**2)
  97. #RSA_rem = remainders(final_prod, RSA_squared)
  98. #del RSA_squared
  99. pq = []
  100. RSA_gcd = batchgcd_faster(RSA_ints)
  101.  
  102. for i in range(len(RSA_ints)):
  103. #Find gcd of results from remainder tree and product tree
  104. #RSA_rem[i] = gcd(RSA_rem[i]/RSA_ints[i], RSA_ints[i])
  105. #Looking through remainder tree results for gcds that resulted in non-1 values (no
  106. #factors matched) as well as values that that don't match the RSA key (both factors
  107. #matched) and appending to a final list of keys and one of their factors
  108. if(RSA_gcd[i] != 1 and RSA_gcd[i] != RSA_ints[i]):
  109. #Factor RSA keys with common factors by dividing and save the two factors for
  110. #easily finding Totient function to decrypt
  111. #Broken keys will be of form [p,q,i] where p is found shared factor, q is the
  112. # other factor found bu dividing the key by the found factor p, and i is the
  113. #number of the broken key in the original
  114. pq.append([RSA_gcd[i], RSA_ints[i] / RSA_gcd[i], i])
  115.  
  116. with open(PRIMES_FILE,'w') as prime_f:
  117. for i in range(len(pq)):
  118. prime_f.write(str(pq[i]) + '\n')
  119.  
  120. #Decrypt cipher using RSA keys
  121. #Find private key, not sure if I need to include k, not for now
  122. # m^(k*fi(n) + 1) = m (mod n) whfiere e*d = k*fi(n) + 1, d = (k*fi(n) + 1)/e
  123. #(q-1)*(p-1) = fi(N) = fi(q)*(p)
  124. #Assume k = 1
  125. #number.inverse(e,p*q-1) finds d such that e*(p*q-1) = 1 (mod b)
  126. with open(OUTPUT_FILE,'w') as output:
  127. #output = open("sol_1.2.4.txt", 'w')
  128. d = [] #Broken keys
  129. for i in range(len(pq)):
  130. #d = ((broken_keys[i][0]-1)*(broken_keys[i][1]-1) + 1)/e
  131. d.append(number.inverse(e, (pq[i][0]-1)*(pq[i][1]-1)))
  132. #Output plaintext to file, outputting all possibilities and will check for
  133. #For clue manually, then output the correct plaintext to solution
  134. tup = (long(pq[i][0]*pq[i][1]), long(e), long(d[i]))
  135. RSA_key = RSA.construct(tup)
  136. try:
  137. plain = pbp.decrypt(RSA_key,cipher)
  138. print plain
  139. output.write(plain)
  140. except ValueError:
  141. pass
  142. #output.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement