Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import hashlib
- import argparse
- def xor_list(char_list, key_int_list):
- output = [chr(ord(char) ^ key_int) for char, key_int in zip(char_list, key_int_list)]
- return output
- def split_by_period(str_or_list_in, period):
- splitsection_indices = range(0, len(str_or_list_in), period)
- output = [str_or_list_in[start: start + period] for start in splitsection_indices]
- return output
- class FeistelCipher:
- def __init__(self, unencrypted_text = "", password_in = "", encrypted_text = ""):
- def get_double_sha_key_list(password):
- def get_sha256(string_in):
- hash_object = hashlib.sha256(string_in.encode())
- return str(hash_object.hexdigest())
- first_hash = get_sha256(password)
- second_hash = get_sha256(first_hash)
- all_key_ints = split_by_period(first_hash+second_hash, period = 2)
- # interpret as hexadecimals and convert to integer
- all_key_hexs = [int(str("0x"+all_key_int),0) for all_key_int in all_key_ints]
- # keylenghts = (1/2)*blocklength. 8-byte blocks ==> key_length = 4
- key_list = split_by_period(all_key_hexs, period = 4)
- return key_list
- self.key_list = get_double_sha_key_list(password_in)
- self.encrypted = encrypted_text
- self.unencrypted = unencrypted_text
- self.decrypted = []
- def block_splitting_routine(self, word, keys, round_function):
- L = [word[0:int(len(word)/2)]]
- R = [word[int(len(word)/2):len(word)]]
- for key in keys:
- L_new, R_new = round_function(R[-1], L[-1], key)
- L.append(L_new)
- R.append(R_new)
- return list(L[-1] + R[-1])
- def encrypt(self):
- def next_round(R_in, L_in, key):
- R_out = L_in
- L_out = xor_list(R_in, key)
- return (L_out, R_out)
- encrypted_blocklist = []
- for unencrypted_block in split_by_period(self.unencrypted,8):
- encrypted_blocklist.append(self.block_splitting_routine(unencrypted_block,
- self.key_list,
- next_round))
- self.encrypted = "".join(["".join(_) for _ in encrypted_blocklist])
- print(self.encrypted)
- return self.encrypted
- def decrypt(self):
- def previous_round(R_in, L_in, key):
- L_out = R_in
- R_out = xor_list(L_in, key)
- return (L_out, R_out)
- decrypted_blocklist = []
- for encrypted_block in split_by_period(self.encrypted,8):
- decrypted_blocklist.append(self.block_splitting_routine(encrypted_block,
- reversed(self.key_list),
- previous_round))
- self.decrypted = "".join(["".join(_) for _ in decrypted_blocklist])
- print(self.decrypted)
- return self.decrypted
- def arg_handler():
- parser = argparse.ArgumentParser()
- parser.add_argument('password', type=str,
- help='password used for key-generation')
- parser.add_argument('text', type=str,
- help='insert text to be de- or encrypted.')
- parser.add_argument("-e", "--encrypt", action='store_true',
- help='encrypt text')
- parser.add_argument("-d", "--decrypt", action='store_true',
- help='decrypt text')
- args = parser.parse_args()
- text = str(args.text)
- password = str(args.password)
- return text, password
- if __name__ == "__main__":
- text, password = arg_handler()
- unencrypted, encrypted = "",""
- CipherObject = FeistelCipher(password_in = password)
- if args.encrypt:
- CipherObject.unencrypted = text
- CipherObject.encrypt()
- if args.decrypt:
- CipherObject.encrypted = text
- CipherObject.decrypt()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement