Advertisement
Guest User

DES

a guest
May 19th, 2019
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.29 KB | None | 0 0
  1. import textwrap
  2. BLOCK_SIZE_BYTE = 8
  3. BLOCK_SIZE = 64
  4. NUM_OF_ROUNDS = 16
  5.  
  6.  
  7. # Msg functions
  8. # Function to add symbols to opened text
  9. def pkcsf7(text):
  10.     if len(text) % BLOCK_SIZE_BYTE == 0:
  11.         return text
  12.     add_text = BLOCK_SIZE_BYTE - len(text) % BLOCK_SIZE_BYTE
  13.     added_text = text + (add_text * chr(add_text))
  14.     return added_text
  15.  
  16.  
  17. def unpad(text):
  18.     pattern = text[-1]
  19.     length = ord(pattern)
  20.     # check if the bytes to be removed are all the same pattern
  21.     if text.endswith(pattern * length):
  22.         return text[:-length]
  23.     else:
  24.         return text
  25.  
  26.  
  27. # Divides text on blocks
  28. def text_by_blocks(text):
  29.     blocks = []
  30.     while text:
  31.         blocks.append(text[:BLOCK_SIZE])
  32.         text = text[BLOCK_SIZE:]
  33.     return blocks
  34.  
  35.  
  36. # Recreate the string from the bit array
  37. def bit_array_to_string(array):
  38.     res = ''.join([chr(int(y, 2)) for y in [''.join([str(x) for x in _bytes]) for _bytes in nsplit(array, 8)]])
  39.     return res
  40.  
  41.  
  42. # Split a list into sublists of size "n"
  43. def nsplit(s, n):
  44.     return [s[k:k+n] for k in range(0, len(s), n)]
  45.  
  46.  
  47. # Transform string to bin_arr
  48. def to_bin_arr(text):
  49.     bin_arr = ''
  50.     for i in text:
  51.         ascii_sym = ord(i)
  52.         bin_arr += (bin(ascii_sym)[2:]).zfill(8)
  53.     return bin_arr
  54.  
  55.  
  56. def spliHalf(binarybits):
  57.     return binarybits[:32], binarybits[32:]
  58.  
  59.  
  60. # Transpose matrix
  61. def transpose(block, matrix):
  62.     transpose_block = ''
  63.     for i in matrix:
  64.         transpose_block += block[int(i)-1]
  65.     return transpose_block
  66.  
  67.  
  68. # Key functions
  69. def split_in_half(key):
  70.     left_side, right_side = key[:28], key[28:]
  71.     return left_side, right_side
  72.  
  73.  
  74. def circular_left_shift(half_key, num_of_bits):
  75.     shifted_key = half_key[num_of_bits:] + half_key[:num_of_bits]
  76.     return shifted_key
  77.  
  78.  
  79. def round_keys(key56):
  80.     round_keys_arr = []
  81.     for i in range(NUM_OF_ROUNDS):
  82.         left_side, right_side = split_in_half(key56)
  83.         shifted_left = circular_left_shift(left_side, round_shifts[i])
  84.         shifted_right = circular_left_shift(right_side, round_shifts[i])
  85.         round_key = transpose(shifted_left + shifted_right, PC2)
  86.         round_keys_arr.append(round_key)
  87.         left_side = shifted_left
  88.         right_side = shifted_right
  89.     return round_keys_arr
  90.  
  91.  
  92. def XOR(bits1, bits2):
  93.     xor_result = ""
  94.     for index in range(len(bits1)):
  95.         if bits1[index] == bits2[index]:
  96.             xor_result += '0'
  97.         else:
  98.             xor_result += '1'
  99.     return xor_result
  100.  
  101.  
  102. def split_in_6bits(XOR_48bits):
  103.     """split 48 bits into 6 bits each """
  104.     list_of_6bits = textwrap.wrap(XOR_48bits, 6)
  105.     return list_of_6bits
  106.  
  107.  
  108. # Below are some supportive function used for smooth the process
  109.  
  110. def get_first_and_last_bit(bits6):
  111.     """Return first and last bit from a binary string"""
  112.     twobits = bits6[0] + bits6[-1]
  113.     return twobits
  114.  
  115.  
  116. def get_middle_four_bit(bits6):
  117.     """Return first and last bit from a binary string"""
  118.     fourbits = bits6[1:5]
  119.     return fourbits
  120.  
  121.  
  122. def binary_to_decimal(binarybits):
  123.     """ Convert binary bits to decimal"""
  124.     # helps during list access
  125.     decimal = int(binarybits, 2)
  126.     return decimal
  127.  
  128.  
  129. def decimal_to_binary(decimal):
  130.     """ Convert decimal to binary bits"""
  131.     binary4bits = bin(decimal)[2:].zfill(4)
  132.     return binary4bits
  133.  
  134.  
  135. def sbox_lookup(sboxcount, first_last, middle4):
  136.     """ take three parameter and access the Sbox accordingly and return the value"""
  137.     d_first_last = binary_to_decimal(first_last)
  138.     d_middle = binary_to_decimal(middle4)
  139.  
  140.     sbox_value = SBOX[sboxcount][d_first_last][d_middle]
  141.     return decimal_to_binary(sbox_value)
  142.  
  143.  
  144. def functionF(pre32bits, key48bits):
  145.  
  146.     """This is main function to perform function F """
  147.     result = ""
  148.     expanded_left_half = transpose(pre32bits, EXPANSION_TABLE)
  149.     xor_value = XOR(expanded_left_half, key48bits)
  150.     bits6list = split_in_6bits(xor_value)
  151.     for sboxcount, bits6 in enumerate(bits6list):
  152.         first_last = get_first_and_last_bit(bits6)
  153.         middle4 = get_middle_four_bit(bits6)
  154.         sboxval = sbox_lookup(sboxcount, first_last, middle4)
  155.         result += sboxval
  156.     final32bits = transpose(result, PERMUTATION_TABLE)
  157.     return final32bits
  158.  
  159.  
  160. # Transpose matrix
  161. INITIAL_PERMUTATION_TABLE = ['58 ', '50 ', '42 ', '34 ', '26 ', '18 ', '10 ', '2',
  162.                              '60 ', '52 ', '44 ', '36 ', '28 ', '20 ', '12 ', '4',
  163.                              '62 ', '54 ', '46 ', '38 ', '30 ', '22 ', '14 ', '6',
  164.                              '64 ', '56 ', '48 ', '40 ', '32 ', '24 ', '16 ', '8',
  165.                              '57 ', '49 ', '41 ', '33 ', '25 ', '17 ', '9 ', '1',
  166.                              '59 ', '51 ', '43 ', '35 ', '27 ', '19 ', '11 ', '3',
  167.                              '61 ', '53 ', '45 ', '37 ', '29 ', '21 ', '13 ', '5',
  168.                              '63 ', '55 ', '47 ', '39 ', '31 ', '23 ', '15 ', '7']
  169.  
  170. PC1 = [57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
  171.        63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4]
  172.  
  173. round_shifts = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
  174.  
  175. PC2 = [14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41,
  176.        52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32]
  177.  
  178. EXPANSION_TABLE = [32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16,
  179.                    17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1]
  180.  
  181. SBOX = [
  182.     # Box-1
  183.     [
  184.         [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
  185.         [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
  186.         [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
  187.         [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]
  188.     ],
  189.     # Box-2
  190.  
  191.     [
  192.         [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
  193.         [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
  194.         [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
  195.         [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]
  196.     ],
  197.  
  198.     # Box-3
  199.  
  200.     [
  201.         [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
  202.         [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
  203.         [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
  204.         [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]
  205.  
  206.     ],
  207.  
  208.     # Box-4
  209.     [
  210.         [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
  211.         [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
  212.         [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
  213.         [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]
  214.     ],
  215.  
  216.     # Box-5
  217.     [
  218.         [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
  219.         [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
  220.         [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
  221.         [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]
  222.     ],
  223.     # Box-6
  224.  
  225.     [
  226.         [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
  227.         [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
  228.         [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
  229.         [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]
  230.  
  231.     ],
  232.     # Box-7
  233.     [
  234.         [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
  235.         [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
  236.         [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
  237.         [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]
  238.     ],
  239.     # Box-8
  240.  
  241.     [
  242.         [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
  243.         [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
  244.         [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
  245.         [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]
  246.     ]
  247.  
  248. ]
  249.  
  250. PERMUTATION_TABLE = [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
  251.                         2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25]
  252.  
  253. INVERSE_PERMUTATION_TABLE = ['40 ', '8 ', '48 ', '16 ', '56 ', '24 ', '64 ', '32',
  254.                              '39 ', '7 ', '47 ', '15 ', '55 ', '23 ', '63 ', '31',
  255.                              '38 ', '6 ', '46 ', '14 ', '54 ', '22 ', '62 ', '30',
  256.                              '37 ', '5 ', '45 ', '13 ', '53 ', '21 ', '61 ', '29',
  257.                              '36 ', '4 ', '44 ', '12 ', '52 ', '20 ', '60 ', '28',
  258.                              '35 ', '3 ', '43 ', '11 ', '51 ', '19 ', '59 ', '27',
  259.                              '34 ', '2 ', '42 ', '10 ', '50 ', '18 ', '58 ', '26',
  260.                              '33 ', '1 ', '41 ', '9 ', '49 ', '17 ', '57 ', '25']
  261.  
  262. # main
  263. opened_text = "column = int(''.join([str(x) for x in block[1:][:-1]]),2) #Column is the 2,3,4,5th bitsr"
  264. print("opened text is:", opened_text)
  265.  
  266. padded_msg = pkcsf7(opened_text)
  267. print('Opened text with added symbols:', padded_msg)
  268.  
  269. padded_bin = to_bin_arr(padded_msg)
  270. print('Binary array of padded msg: ', padded_bin)
  271.  
  272. key = '01234567'
  273. print("key is: ", key)
  274.  
  275. bin_key_64 = to_bin_arr(key)
  276. print('Key binary 64 bit:', bin_key_64)
  277.  
  278. key_56bits = transpose(bin_key_64, PC1)
  279. print('Key 56 bits: ', key_56bits)
  280.  
  281. left_side, right_side = split_in_half(key_56bits)
  282. print('Split the 56 bits key into two equal half: ', left_side, right_side)
  283.  
  284. roundkeys = round_keys(key_56bits)
  285. print('Round Keys: ', roundkeys)
  286.  
  287.  
  288. def decrypt_encrypt(whattodo, text, keys):
  289.     text = text_by_blocks(text)
  290.     transp_block_of_msg = []
  291.     for b in text:
  292.         transp_block_of_msg.append(transpose(b, INITIAL_PERMUTATION_TABLE))
  293.     cipher = ''
  294.     for p_plaintext in transp_block_of_msg:
  295.         L, R = spliHalf(p_plaintext)
  296.         for round in range(NUM_OF_ROUNDS):
  297.             if whattodo == 'E':
  298.                 newR = XOR(L, functionF(R, keys[round]))
  299.             else:
  300.                 newR = XOR(L, functionF(R, keys[15 - round]))
  301.             newL = R
  302.             R = newR
  303.             L = newL
  304.         cipher += transpose(R+L, INVERSE_PERMUTATION_TABLE)
  305.     return cipher
  306.  
  307.  
  308. encrypt = decrypt_encrypt('E', padded_bin, roundkeys)
  309. decrypt = decrypt_encrypt('D', encrypt, roundkeys)
  310. print('cipher =', bit_array_to_string(encrypt))
  311. print('decryption = ', unpad(bit_array_to_string(decrypt)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement