Advertisement
Guest User

Untitled

a guest
Dec 17th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.94 KB | None | 0 0
  1. import random
  2.  
  3. NUM_BITS_SIZE_MESSAGE = 64
  4. NUM_WITNESSES = 100
  5.  
  6.  
  7. def keygen(b):
  8. fix = 2 ** (b // 2 - 1)
  9.  
  10. rnd = random.SystemRandom() #uses os.urandom() which is suitable for cryptography and is practical
  11. p = rnd.getrandbits(b // 2) | fix
  12. while miller_rabin_primality_testing(p, NUM_WITNESSES) == False:
  13. p = rnd.getrandbits(b // 2) | fix
  14. q = rnd.getrandbits(b // 2) | fix
  15. while miller_rabin_primality_testing(q, NUM_WITNESSES) == False:
  16. q = rnd.getrandbits(b // 2) | fix
  17. #At this point, we have two prime numbers (high probability)
  18. #finding e
  19. phi_n = (p - 1) * (q - 1)
  20. while True:
  21. e = rnd.randint(3, phi_n-1)
  22. res = xEuclid(e, phi_n)
  23. if res[0] == 1:
  24. break
  25. d = res[1] % phi_n
  26.  
  27. n = p * q
  28.  
  29. print n.bit_length()
  30. print p.bit_length()
  31. print q.bit_length()
  32.  
  33. return (n, p, q, e, d)
  34.  
  35.  
  36.  
  37. #FAZER CHECK DO TAMANHO DOS BITS DE N E SE FOR MENOR QUE 64 USAR 64 + random
  38. #usando os bits se calhar
  39. def cipher(msg, n, e):
  40. print("CIPHER")
  41. size_msg = len(msg)
  42. block_size = n.bit_length() #64 min?
  43. block_pick = block_size - 1 #64 min?
  44. #if block_size < 64:
  45. # block_size = 64
  46.  
  47. n_blocks = (size_msg + NUM_BITS_SIZE_MESSAGE) // block_pick
  48. noise_ammount = block_pick - ((size_msg + NUM_BITS_SIZE_MESSAGE) % block_pick)
  49.  
  50. #Check if we are going to need padding (block isnt complete)
  51. if noise_ammount != 0:
  52. n_blocks += 1
  53.  
  54. #ciphered = pow(convert_list_binary_to_int(msg), e, n) #maybe improve
  55. #bits = ciphered.bit_length()
  56.  
  57. list = []
  58. #print("Message to code ", ciphered)
  59. #print("Message to code as binary ", convert_int_to_binary_list(ciphered))
  60. #print("Message num bits ", ciphered.bit_length())
  61. #print("Size message ", ciphered.bit_length())
  62. print("Num blocks =", n_blocks)
  63. print("block size =", block_size)
  64.  
  65.  
  66.  
  67. #Size of message to send
  68. #Add values we know for sure are zeros
  69. for _ in range(NUM_BITS_SIZE_MESSAGE - size_msg.bit_length()):
  70. list.append(0)
  71. append_num_as_bin_to_list(size_msg, list)
  72.  
  73. print("List of", len(list), "bits containing size of message ", size_msg)
  74. print()
  75.  
  76. #Message itself
  77. for i in msg:
  78. list.append(i)
  79.  
  80. #append noise to make even blocks
  81. #Random noise
  82. if noise_ammount > 0:
  83. rnd = random.SystemRandom() #uses os.urandom() which is suitable for cryptography and is practical
  84. num = rnd.getrandbits(noise_ammount)
  85.  
  86. #Add values we know for sure are zeros
  87. for i in range(noise_ammount - num.bit_length()):
  88. list.append(0)
  89. append_num_as_bin_to_list(num, list)
  90.  
  91. new_list = [] #LOT OF ZEROS WRONG??
  92. for i in range(n_blocks):
  93. #print(list[block_size*i:block_size*(i+1)])
  94. num_to_cipher = convert_list_binary_to_int(list[block_pick * i:block_pick * (i + 1)])
  95. ciphered = pow(num_to_cipher, e, n) #maybe improve
  96.  
  97. #Add values we know for sure are zeros
  98. for i in range(block_size - ciphered.bit_length()):
  99. new_list.append(0)
  100. append_num_as_bin_to_list(ciphered, new_list)
  101.  
  102. print("Random noise ammount =", noise_ammount)
  103.  
  104. return new_list
  105.  
  106.  
  107. def decipher(msg, n, d):
  108. print("DECIPHER")
  109. size_msg = len(msg)
  110. block_pick = n.bit_length()
  111. block_size = block_pick-1
  112. #if block_size < 64:
  113. # block_size = 64
  114. n_blocks = size_msg // block_size
  115. print("Num blocks =", n_blocks)
  116. print("block size =", block_size)
  117. print("block pick =", block_pick)
  118.  
  119. firstblock = []
  120. #first block special
  121. num_to_decipher = convert_list_binary_to_int(msg[:block_pick])
  122. deciphered = pow(num_to_decipher, d, n) #maybe improve
  123.  
  124. #Add values we know for sure are zeros
  125. for i in range(block_size - deciphered.bit_length()):
  126. firstblock.append(0)
  127. append_num_as_bin_to_list(deciphered, firstblock)
  128.  
  129. #extract msg size
  130. size_msg = convert_list_binary_to_int(firstblock[:NUM_BITS_SIZE_MESSAGE])
  131. noise_ammount = n_blocks * block_size - size_msg - NUM_BITS_SIZE_MESSAGE
  132.  
  133. print("size of msg = ", size_msg)
  134. print("size of noise=", noise_ammount)
  135. if size_msg <= block_size-NUM_BITS_SIZE_MESSAGE:
  136. list = firstblock[NUM_BITS_SIZE_MESSAGE:NUM_BITS_SIZE_MESSAGE+size_msg]#LOT OF ZEROS WRONG??
  137. else:
  138. list = firstblock[NUM_BITS_SIZE_MESSAGE:]
  139. for i in range(1, n_blocks-1):
  140. num_to_decipher = convert_list_binary_to_int(msg[block_pick * i:block_pick * (i + 1)])
  141. deciphered = pow(num_to_decipher, d, n) #maybe improve
  142.  
  143. #Add values we know for sure are zeros
  144. for i in range(block_size - deciphered.bit_length()):
  145. list.append(0)
  146. append_num_as_bin_to_list(deciphered, list)
  147.  
  148. #Last block special as we can have noise
  149. num_to_decipher = convert_list_binary_to_int(msg[block_pick * (n_blocks-1):])
  150. deciphered = pow(num_to_decipher, d, n) #maybe improve
  151.  
  152. for _ in range(block_size - deciphered.bit_length()):
  153. list.append(0)
  154. auxlist = convert_int_to_binary_list(deciphered)
  155. for i in range(deciphered.bit_length()-noise_ammount):
  156. list.append(auxlist[i])
  157.  
  158. #list.append(meow[:block_size-noise_ammount])
  159.  
  160. print("size = ", len(list))
  161. return list
  162.  
  163. def append_num_as_bin_to_list(num, list):
  164. num_bit_length = num.bit_length()
  165.  
  166. #Check if a bit is 1 or 0 and append it stating at most significant
  167. for i in range(num_bit_length - 1, -1, -1):
  168. copy_num = num
  169. if copy_num & (2 ** i) == 0:
  170. list.append(0)
  171. else:
  172. list.append(1)
  173.  
  174. def convert_list_binary_to_int(list):
  175. result = 0
  176. for bit in list:
  177. result = (result << 1) | bit
  178. return result
  179.  
  180. def convert_int_to_binary_list(num):
  181. list = []
  182. while num != 0:
  183. list.append(num & 1)
  184. num >>= 1
  185. return(list[::-1])
  186.  
  187. #chheck this and comments
  188. def miller_rabin_primality_testing(n, k):
  189. if not (n & 1):
  190. return False
  191.  
  192. rnd = random.SystemRandom() #uses os.urandom() which is suitable for cryptography and is practical
  193.  
  194. if n < 2:
  195. return False
  196.  
  197. # Decompose (n - 1) to write it as (2 ** r) * d
  198. # While d is even, divide it by 2 and increase the exponent.
  199. d = n - 1
  200. r = 0
  201.  
  202. while not (d & 1):
  203. r += 1
  204. d >>= 1
  205.  
  206. witnesses = []
  207. a = 1
  208. # Test k witnesses.
  209. for _ in range(k):
  210. # Generate random integer a, where 3 <= a <= (n - 1)
  211. # a cant be pair
  212. while not (a & 1) or a in witnesses:
  213. a = rnd.randint(3, n - 1) #CONFIRMAR
  214. witnesses.append(a)
  215.  
  216. x = pow(a, d, n)
  217. if x == 1 or x == n - 1:
  218. continue
  219.  
  220. for _ in range(r - 1):
  221. x = pow(x, 2, n)
  222. if x == 1:
  223. return False
  224. if x == n - 1:
  225. break
  226. else:
  227. return False
  228. return True
  229.  
  230. def xEuclid(d, f):
  231. x1, x2, x3 = 1, 0, f
  232. y1, y2, y3 = 0, 1, d
  233. while True:
  234. if y3 == 0: return (x3, "no inverse")
  235. if y3 == 1: return (y3, y2)
  236. q = x3 // y3
  237. x1, x2, x3, y1, y2, y3 = y1, y2, y3, x1 - (q * y1), x2 - (q * y2), x3 - (q * y3)
  238.  
  239. """
  240. #cipher
  241. num_to_cipher = 548624
  242. num_to_cipher_bin = convert_int_to_binary_list(num_to_cipher)
  243. n = 119
  244. e = 5
  245. print("Ciphering", num_to_cipher, "with bin =", num_to_cipher_bin, "and n =", n, "and e =", e)
  246. res = cipher(num_to_cipher_bin, n, e)
  247. #print("Result =", res)
  248.  
  249.  
  250. #decipher
  251.  
  252. #num_to_decipher = 66
  253. #num_to_decipher_bin = convert_int_to_binary_list(num_to_decipher)
  254. #n = 119
  255. #
  256. #print("Deciphering", num_to_decipher, "with bin =", num_to_decipher_bin, "and
  257. #n =", n, "and d =", d)
  258. d = 77
  259. res = decipher(res, n, d)
  260. print("Result =", res)
  261. print()
  262. """
  263. if __name__ == "__main__":
  264. msg = convert_int_to_binary_list(9832423 ** 12121)
  265. keys = keygen(1000)
  266. #msg = [0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1]
  267. #msg = [0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1]
  268. cypheredmsg = cipher(msg, keys[0], keys[3])
  269.  
  270. decypheredmsg = decipher(cypheredmsg, keys[0], keys[4])
  271. print
  272. print len(msg)
  273. print msg == decypheredmsg
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement