Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 19.66 KB | None | 0 0
  1. import codecs
  2. import itertools
  3. import os
  4. import binascii
  5. import random
  6.  
  7.  
  8. def to_bits(s):
  9.     result = []
  10.     for c in s:
  11.         bits = bin(ord(c))[2:]
  12.         bits = '00000000'[len(bits):] + bits
  13.         result.extend([int(b) for b in bits])
  14.     return result
  15.  
  16.  
  17. def from_bits(bits):
  18.     chars = []
  19.     length = int(len(bits) / 8)
  20.     for b in range(length):
  21.         byte = bits[b * 8:(b + 1) * 8]
  22.         chars.append(chr(int(''.join([str(bit) for bit in byte]), 2)))
  23.     return ''.join(chars)
  24.  
  25.  
  26. def chunks(array, chunk_size):
  27.     for i in range(0, len(array), chunk_size):
  28.         yield array[i:i + chunk_size]
  29.  
  30.  
  31. def xor(a, b):
  32.     block = []
  33.     for i in range(len(a)):
  34.         block.append(int(bool(a[i]) ^ bool(b[i])))
  35.     return block
  36.  
  37.  
  38. def int_to_bits(value, width=32):
  39.     bits = list("{0:b}".format(value).zfill(width))
  40.     bits = [int(i) for i in bits]
  41.     return bits
  42.  
  43.  
  44. def word_to_int(word):
  45.     value = 0
  46.     exp = 1
  47.     for i in range(0, 8):
  48.         if word[i] == 1:
  49.             value += exp
  50.         exp *= 2
  51.     return value
  52.  
  53.  
  54. def halve(block):
  55.     size = int(len(block))
  56.     half = int(size / 2)
  57.     return [block[0:half], block[half: size]]
  58.  
  59.  
  60. class Blowfish:
  61.  
  62.     def generate_IV(self):
  63.         bits = []
  64.         bytes = os.urandom(8)
  65.         for i in range(0, len(bytes)):
  66.             bits += int_to_bits(bytes[i], 8)
  67.         self.IV = bits
  68.  
  69.     def set_IV(self, source):
  70.         bits = to_bits(source)
  71.         if len(bits) < 64:
  72.             bits += int_to_bits((64 - len(bits)) * [0])
  73.         if len(bits) > 64:
  74.             bits = bits[0:64]
  75.         self.IV = bits
  76.  
  77.     def set_key(self):
  78.         key = self.key
  79.  
  80.         # Stretch the key
  81.         while len(key) < 576:
  82.             key = key + self.key
  83.         key = to_bits(key)
  84.  
  85.         # XOR the subkeys with stretched key
  86.         for i in range(0, 18):
  87.             self.subkeys[i] = word_to_int(xor(int_to_bits(self.subkeys[i]), key[i * 32: (i + 1) * 32]))
  88.  
  89.         # Zero initial vector
  90.         current_block = int_to_bits(0) + int_to_bits(0)
  91.  
  92.         # Rearranging p-values(subkeys)
  93.         for i in range(0, 18, 2):
  94.             current_block = self.encrypt_block(current_block)
  95.             self.subkeys[i] = word_to_int(halve(current_block)[0])
  96.             self.subkeys[i + 1] = word_to_int(halve(current_block)[1])
  97.  
  98.         # Rearranging S-boxes
  99.         for i in range(0, 4):
  100.             for j in range(0, 256, 2):
  101.                 current_block = self.encrypt_block(current_block)
  102.                 self.s_boxes[i][j] = word_to_int(halve(current_block)[0])
  103.                 self.s_boxes[i][j + 1] = word_to_int(halve(current_block)[0])
  104.  
  105.     def set_blocks(self, source):
  106.         bits = to_bits(self.plaintext)
  107.         blocks = list(chunks(bits, 64))
  108.         print(len(blocks[-1]))
  109.         if len(blocks[-1]) < 64:
  110.             blocks[-1] += (64 - len(blocks[-1]))*[0]
  111.         return blocks
  112.  
  113.     def __init__(self, key, string):
  114.  
  115.         self.s_boxes = [s0, s1, s2, s3]
  116.         self.subkeys = p
  117.         self.key = key
  118.         self.IV = None
  119.  
  120.         self.plaintext = string
  121.         self.ciphertext = None
  122.         self.cipher_blocks = []
  123.         self.blocks = []
  124.         self.blocks = self.set_blocks(self.plaintext)
  125.         self.set_key()
  126.  
  127.         encrypted_block = self.encrypt_block(self.blocks[0])
  128.         encrypted_block = self.encrypt_block(self.blocks[0])
  129.  
  130.     def encrypt(self, pt, IV = None):
  131.         if not IV:
  132.             self.generate_IV()
  133.         else:
  134.             self.set_IV(IV)
  135.         self.plaintext = pt
  136.         self.cipher_blocks = []
  137.         self.blocks = self.set_blocks(self.plaintext)
  138.  
  139.  
  140.         current_block = self.encrypt_block(xor(self.blocks[0], self.IV))
  141.         self.cipher_blocks.append(current_block)
  142.  
  143.         for i in range(1, len(self.blocks)):
  144.             current_block = self.encrypt_block(xor(self.blocks[i], current_block))
  145.             self.cipher_blocks.append(current_block)
  146.  
  147.         return "".join([from_bits(x) for x in self.cipher_blocks])
  148.  
  149.     def decrypt(self, ct, IV = None):
  150.         if IV:
  151.             self.set_IV(IV)
  152.         self.ciphertext = ct
  153.         self.cipher_blocks = []
  154.         self.blocks = []
  155.         self.cipher_blocks = self.set_blocks(self.ciphertext)
  156.  
  157.         for i in range(len(self.cipher_blocks) - 1, 0, -1):
  158.             current_block = self.decrypt_block(self.cipher_blocks[i])
  159.             current_block = xor(current_block, self.cipher_blocks[i - 1])
  160.             self.blocks.append(current_block)
  161.  
  162.         current_block = self.decrypt_block(self.cipher_blocks[0])
  163.         current_block = xor(current_block, self.IV)
  164.         self.blocks.append(current_block)
  165.         self.blocks.reverse()
  166.         return ""
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement