diff options
author | Marvin Borner | 2019-06-17 18:00:27 +0200 |
---|---|---|
committer | Marvin Borner | 2019-06-17 18:00:27 +0200 |
commit | 6d6c5c322572dafa783070060df7f7a9b9ba16cd (patch) | |
tree | a24480c25679c3669d0db2b4c6cd4d0c012fbf12 | |
parent | fa777f1ad9a3872a1ff1d2a164eaa19f5e3f6ceb (diff) |
Added visualization and explanations
-rw-r--r-- | main.py | 88 |
1 files changed, 73 insertions, 15 deletions
@@ -1,4 +1,5 @@ #!/usr/bin/python +import copy from constants import round_constants from constants import sbox @@ -12,13 +13,13 @@ def hex_to_matrix(hex_array): :param hex_array: Array of 16 hex chars :return: 4x4 matrix representation """ - matrix = [] + hex_matrix = [] for i in range(16): if i % matrix_size == 0: - matrix.append([hex_array[i]]) + hex_matrix.append([hex_array[i]]) else: - matrix[int(i / matrix_size)].append(hex_array[i]) - return matrix + hex_matrix[int(i / matrix_size)].append(hex_array[i]) + return hex_matrix def int_to_hex_string(number): @@ -27,7 +28,10 @@ def int_to_hex_string(number): :param number: Number to convert as base-10 integer :return: string of hex representation """ - return "%0.2X" % number + if type(number) == int: + return "%0.2X" % number + else: + return str(number) def text_to_hex(text): @@ -52,7 +56,7 @@ def key_expansion(key_matrix): round_keys = [key_matrix] round_key = key_matrix[:] for r in range(0, 10): - new_key = round_key.copy() + new_key = copy.deepcopy(round_key) last = round_key[3] new_key[3] = round_last(new_key[3], r) new_key[0] = xor_matrix(new_key[0], new_key[3]) @@ -94,17 +98,53 @@ def encrypt(text, passphrase): text_matrix = hex_to_matrix(text_to_hex(text)) round_keys = key_expansion(key_matrix) merged_matrix = xor_matrices(key_matrix, text_matrix) - # 9 intermediate rounds for 128 Bit key size + + print("XORing\n{0}\nwith {1}".format(matrix(text_matrix, text), matrix(key_matrix, passphrase))) + print("Result: ↘\n{0}".format(matrix(merged_matrix))) + print("---\nExpanded key {0}\nto".format(matrix(key_matrix, passphrase))) + print("{0}\n[Keys 2..9]\n{1}".format( + matrix(round_keys[1], "Key 1"), + matrix(round_keys[10], "Key 10") + )) + + # 9 intermediate rounds (+1 round without mixing) for 128 Bit key size for r in range(10): - confused_matrix = confusion(merged_matrix) - diffused_matrix = diffusion(confused_matrix) + confused_matrix = confusion(copy.deepcopy(merged_matrix)) + diffused_matrix = diffusion(copy.deepcopy(confused_matrix)) + print("---\nConfused (sbox, SubBytes)\n{0}\nto\n{1}".format( + matrix(merged_matrix, "Result matrix of previous round " + str(r)), + matrix(confused_matrix, "Confused matrix of round " + str(r + 1)) + )) + print("---\nDiffused (ShiftRows)\n'Confused matrix of round {0}'\nto\n{1}".format( + r + 1, + matrix(diffused_matrix, "Diffused matrix of round " + str(r + 1)) + )) + if r == 9: merged_matrix = xor_matrices(diffused_matrix, round_keys[r + 1]) + print("---\nMerged (XOR)\n'Diffused matrix of round {0}' with\n{1}\nto {2}".format( + r + 1, + matrix(round_keys[r + 1], "Round key"), + matrix(merged_matrix, "Final matrix") + )) else: mixed_matrix = mix_columns(diffused_matrix) merged_matrix = xor_matrices(mixed_matrix, round_keys[r + 1]) + print("---\nMixed columns (MixColumns) of\n'Diffused matrix of round {0}' to\n{1}".format( + r + 1, + matrix(merged_matrix, "Mixed matrix of round " + str(r + 1)) + )) + print("---\nMerged (XOR)\n'Mixed matrix of round {0}' with\n{1}\nto {2}".format( + r + 1, + matrix(round_keys[r + 1], "Round key"), + matrix(merged_matrix, "Final matrix of round " + str(r + 1)) + )) flat_matrix = [int_to_hex_string(item) for sublist in merged_matrix for item in sublist] - return " ".join(flat_matrix) + print("=> Result:\n{0}\n'Flattened' → {1}\n'Joined' → {2}".format( + matrix([list(reversed(element)) for element in list(zip(*reversed(copy.deepcopy(merged_matrix))))], "Rotated"), + flat_matrix, + " ".join(flat_matrix) + )) def confusion(merged_matrix): @@ -113,7 +153,7 @@ def confusion(merged_matrix): :param merged_matrix: Merged matrix of key and text :return: New "confused" matrix """ - merged_matrix = merged_matrix.copy() + merged_matrix = copy.deepcopy(merged_matrix) for i in range(matrix_size): for j in range(matrix_size): merged_matrix[i][j] = sbox[merged_matrix[i][j]] @@ -126,6 +166,7 @@ def diffusion(merged_matrix): :param merged_matrix: Merged matrix of key and text :return: New "diffused" matrix """ + merged_matrix = copy.deepcopy(merged_matrix) # Rotate matrix CCW merged_matrix = [list(element) for element in list(zip(*reversed(merged_matrix)))] # Shift matrix @@ -142,7 +183,7 @@ def mix_columns(merged_matrix): :param merged_matrix: Merged matrix of key and text :return: New "mixed" matrix """ - merged_matrix = merged_matrix.copy() + merged_matrix = copy.deepcopy(merged_matrix) magic = lambda x: (((x << 1) ^ 0x1B) & 0xFF) if (x & 0x80) else (x << 1) for i in range(4): a = merged_matrix[i] @@ -162,7 +203,7 @@ def xor_matrix(first, second): :param second: Second matrix :return: XORed (first) matrix """ - first = first.copy() + first = copy.deepcopy(first) for i in range(4): first[i] = first[i] ^ second[i] return first @@ -175,10 +216,27 @@ def xor_matrices(first, second): :param second: Second matrix :return: XORed (first) matrix """ - first = first.copy() + first = copy.deepcopy(first) for i in range(len(first)): first[i] = xor_matrix(first[i], second[i]) return first -print(encrypt("Two One Nine Two", "Thats my Kung Fu")) +def matrix(matrix_array, string=""): + """ + Visualizes matrix arrays + :param matrix_array: 2x2 matrix array + :param string: Note of the array + :return: Printable string representation + """ + new_array = [list(reversed(element)) for element in list(zip(*reversed(copy.deepcopy(matrix_array))))] + for i in range(len(new_array)): + new_array[i].insert(0, "\t|") + output = "" + if string != "": + output += "'{0}' ↘\n".format(string) + output += " |\n".join([" ".join([int_to_hex_string(cell) for cell in row]) for row in new_array]) + " |" + return output + + +encrypt("ATTACK AT DAWN!", "SOME 128 BIT KEY") |