Files
CS454-HW1/DES.py
2024-10-07 21:53:56 -07:00

296 lines
9.4 KiB
Python

# Miguel Muniz
# CS454
import argparse
#Constants/permutations
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,
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
]
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, 52, 31, 37, 47, 55, 30, 40,
51, 45, 33, 48, 44, 49, 39, 56,
34, 53, 46, 42, 50, 36, 29, 32
]
IP = [
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
]
P = [
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
]
FP = [
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
]
E = [
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, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
]
#S-Boxes
sbox = [[[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
[0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
[4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]],
[[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
[3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
[0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]],
[[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
[1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]],
[[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
[13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
[3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]],
[[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
[4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]],
[[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
[9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
[4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]],
[[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
[1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
[6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]],
[[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
[1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
[7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
[2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]]
LEFT_SHIFT = [
1, 1, 2, 2, 2, 2, 2, 2,
1, 2, 2, 2, 2, 2, 2, 1
]
subkeys_left = []
subkeys_right = []
subkeys = []
left_half_f = []
right_half_f = []
data_block = ""
def hex_to_binary(hex):
return bin(int(hex, 16))[2:].zfill(64)
def binary_to_hex(binary):
return hex(int(binary, 2))[2:].zfill(16)
def DES_Encrypt(data_block, key):
data_block = hex_to_binary(data_block)
key = hex_to_binary(key)
#print ("binary key:", key)
key = permute(key, PC1)
#print ("permutated key:", key)
# generate 16 subkeys
left_key = key[:28]
right_key = key[28:]
subkeys_left.append(left_key)
subkeys_right.append(right_key)
# left shift
for i in range(16):
left_key = left_key[LEFT_SHIFT[i]:] + left_key[:LEFT_SHIFT[i]]
right_key = right_key[LEFT_SHIFT[i]:] + right_key[:LEFT_SHIFT[i]]
subkeys_left.append(left_key)
subkeys_right.append(right_key)
# print ("left key:",left_key)
# print ("right key:",right_key)
subkeys.append(permute(left_key + right_key, PC2))
# Initial Permutation
data_block = permute(data_block, IP)
#print ("Initial Permutation:", data_block)
# Split data_block into left and right halves
left_half = data_block[:32]
right_half = data_block[32:]
# left_half_f.append(left_half)
# right_half_f.append(right_half)
# print ("left half:", left_half)
# print ("right half:", right_half)
# 16 rounds of DES
for i in range(16):
# Expansion
expanded_right = permute(right_half, E)
#print ("expanded right half:", expanded_right)
# XOR with subkey
xor_result = int(''.join(expanded_right), 2) ^ int(''.join(subkeys[i]), 2)
xor_result = bin(xor_result)[2:].zfill(48)
#print ("XOR result:", xor_result)
# S-Box substitution
sbox_result = ""
for j in range(8):
row = int(xor_result[j*6] + xor_result[j*6 + 5], 2)
col = int(xor_result[j*6 + 1:j*6 + 5], 2)
sbox_result += bin(sbox[j][row][col])[2:].zfill(4)
#print ("S-Box result:", sbox_result)
# Permutation
permuted_result = permute(sbox_result, P)
#print ("Permutated result:", permuted_result)
# XOR with left half
xor_result = int(''.join(permuted_result), 2) ^ int(''.join(left_half), 2)
xor_result = bin(xor_result)[2:].zfill(32)
#print ("XOR result:", xor_result)
# Swap left and right halves
left_half = right_half
right_half = xor_result
left_half_f.append(left_half)
right_half_f.append(right_half)
print ("left half:", left_half)
print ("right half:", right_half)
# Final permutation
data_block = permute(right_half + left_half, FP)
data_block = str(data_block).replace("[","").replace("]","").replace(",","").replace(" ","").replace("'","")
#print ("Final Permutation:", data_block)
data_block = binary_to_hex(data_block)
print ("Encrypted:", data_block)
def permute(data_block, permutation):
return [data_block[i - 1] for i in permutation]
def DES_Decrypt(data_block, key):
pass
def parse_variables(file_path):
variables = {}
try:
with open(file_path, 'r') as file:
for line in file:
# Remove any extra spaces and ignore empty lines
line = line.strip()
if ':' in line and line:
key, value = line.split(':', 1)
variables[key.strip()] = value.strip()
except FileNotFoundError:
print(f"Error: The file {file_path} was not found.")
return variables
def output_file(output_file, data_block):
with open(output_file, 'w') as file:
# write all the sub keys to the file remove brackets quotations and commas
for i in range(17):
file.write(f"C{i}=")
file.write(str(subkeys_left[i]).replace("[","").replace("]","").replace(",","").replace(" ","").replace("'",""))
file.write("\n")
file.write(f"D{i}=")
file.write(str(subkeys_right[i]).replace("[","").replace("]","").replace(",","").replace(" ","").replace("'",""))
file.write("\n")
file.write("\n")
for i in range(16):
file.write(f"K{i+1}=")
file.write(str(subkeys[i]).replace("[","").replace("]","").replace(",","").replace(" ","").replace("'",""))
file.write("\n")
for i in range(17):
file.write(f"L{i}=")
file.write(str(left_half_f).replace("[","").replace("]","").replace(",","").replace(" ","").replace("'",""))
file.write("\n")
file.write(f"R{i}=")
file.write(str(right_half_f).replace("[","").replace("]","").replace(",","").replace(" ","").replace("'",""))
file.write("\n")
file.write(data_block)
def main():
# Set up command-line argument parsing
parser = argparse.ArgumentParser(description='Parse variables for encryption or decryption.')
parser.add_argument('input_file', type=str, help='Path to the text file containing the variables.')
parser.add_argument('output_file', type=str, help='Path to the text file containing the output.')
# Parse the arguments
args = parser.parse_args()
# Parse the file and retrieve variables
variables = parse_variables(args.input_file)
# Get data_block and key from the parsed variables
data_block = variables.get('data_block', '')
key = variables.get('key', '')
operation = variables.get('operation','')
# Print the variables
print(f"Data Block: {data_block}")
print(f"Key: {key}")
print(f"Operation: {operation}")
if operation == 'encryption' :
DES_Encrypt(data_block, key)
else :
DES_Decrypt(data_block, key)
# path to output file
output_file(args.output_file, data_block)
if __name__ == "__main__":
main()