Advertisement
Guest User

Untitled

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