diff options
author | Marvin Borner | 2019-06-17 18:27:39 +0200 |
---|---|---|
committer | Marvin Borner | 2019-06-17 18:27:39 +0200 |
commit | f31866c0decfc10a164cc4c8d740e787422b6ddd (patch) | |
tree | bd7ebc43ad26589bd25715eae3a71d66074b9f25 | |
parent | f5d2986eec7dba025b6e81a5a83b5a91555fac72 (diff) |
Updated filenames to match README
-rw-r--r-- | encrypt.py | 192 | ||||
-rw-r--r-- | sources | 4 | ||||
-rw-r--r-- | visualizer.py (renamed from main.py) | 3 |
3 files changed, 194 insertions, 5 deletions
diff --git a/encrypt.py b/encrypt.py new file mode 100644 index 0000000..00d4778 --- /dev/null +++ b/encrypt.py @@ -0,0 +1,192 @@ +#!/usr/bin/python +import copy +import sys + +from constants import round_constants +from constants import sbox + +matrix_size = 4 + + +def hex_to_matrix(hex_array): + """ + Converts hex arrays to 4x4 matrices + :param hex_array: Array of 16 hex chars + :return: 4x4 matrix representation + """ + hex_matrix = [] + for i in range(16): + if i % matrix_size == 0: + hex_matrix.append([hex_array[i]]) + else: + hex_matrix[int(i / matrix_size)].append(hex_array[i]) + return hex_matrix + + +def int_to_hex_string(number): + """ + Converts an integer to it's regarding hex representation + :param number: Number to convert as base-10 integer + :return: string of hex representation + """ + if type(number) == int: + return "%0.2X" % number + else: + return str(number) + + +def text_to_hex(text): + """ + Converts text to a array-hex representation + :param text: String/ASCII/UNICODE text + :return: Array of hex chars + """ + hex_array = [] + for char in text: + hex_array.append(ord(char)) + hex_array = hex_array + [0x01] * (16 - len(hex_array)) + return hex_array + + +def key_expansion(key_matrix): + """ + Expands a single key matrix to 11 distinct ones + :param key_matrix: Matrix of master passphrase + :return: Array of 11 round keys + """ + round_keys = [key_matrix] + round_key = key_matrix[:] + for r in range(0, 10): + 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]) + new_key[1] = xor_matrix(new_key[1], new_key[0]) + new_key[2] = xor_matrix(new_key[2], new_key[1]) + new_key[3] = xor_matrix(last, new_key[2]) + round_key = new_key + round_keys += [new_key] + return round_keys + + +def round_last(round_key, r): + """ + Applies special actions for bottom row + :param round_key: Complete matrix round key + :param r: Round index + :return: Modified bottom row (last column) + """ + # Shift bottom row + last_column = round_key[1:] + round_key[:1] + + # Byte substitution (sbox uses hex representation as index) + for column in range(matrix_size): + last_column[column] = sbox[last_column[column]] + + # Adding round constant + last_column[0] = last_column[0] ^ round_constants[r] + return last_column + + +def encrypt(text, passphrase): + """ + Encrypts a text using a 128-Bit passphrase + :param text: Plain text + :param passphrase: 128-Bit passphrase (16 chars) + :return: Encrypted text as hex + """ + key_matrix = hex_to_matrix(text_to_hex(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 (+1 round without mixing) for 128 Bit key size + for r in range(10): + confused_matrix = confusion(copy.deepcopy(merged_matrix)) + diffused_matrix = diffusion(copy.deepcopy(confused_matrix)) + + if r == 9: + merged_matrix = xor_matrices(diffused_matrix, round_keys[r + 1]) + else: + mixed_matrix = mix_columns(diffused_matrix) + merged_matrix = xor_matrices(mixed_matrix, round_keys[r + 1]) + flat_matrix = [int_to_hex_string(item) for sublist in merged_matrix for item in sublist] + print(" ".join(flat_matrix)) + + +def confusion(merged_matrix): + """ + Applies confusion by running bytes through sbox (SubBytes) + :param merged_matrix: Merged matrix of key and text + :return: New "confused" matrix + """ + 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]] + return merged_matrix + + +def diffusion(merged_matrix): + """ + Shifts the merged matrix to the left (ShiftRows) + :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 + for i in range(matrix_size): + merged_matrix[i] = merged_matrix[i][-i:] + merged_matrix[i][:-i] + # Rotate matrix back (CW) + merged_matrix = [list(element)[::-1] for element in list(zip(*reversed(merged_matrix)))][::-1] + return merged_matrix + + +def mix_columns(merged_matrix): + """ + Mixes columns with AES MixColumns algorithm (MixColumns) + :param merged_matrix: Merged matrix of key and text + :return: New "mixed" matrix + """ + 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] + t = a[0] ^ a[1] ^ a[2] ^ a[3] + u = a[0] + a[0] ^= t ^ magic(a[0] ^ a[1]) + a[1] ^= t ^ magic(a[1] ^ a[2]) + a[2] ^= t ^ magic(a[2] ^ a[3]) + a[3] ^= t ^ magic(a[3] ^ u) + return merged_matrix + + +def xor_matrix(first, second): + """ + XORs 1-dimensional matrices + :param first: First matrix + :param second: Second matrix + :return: XORed (first) matrix + """ + first = copy.deepcopy(first) + for i in range(4): + first[i] = first[i] ^ second[i] + return first + + +def xor_matrices(first, second): + """ + XORs 2-dimensional matrices + :param first: First matrix + :param second: Second matrix + :return: XORed (first) matrix + """ + first = copy.deepcopy(first) + for i in range(len(first)): + first[i] = xor_matrix(first[i], second[i]) + return first + + +encrypt(sys.argv[1], sys.argv[2]) diff --git a/sources b/sources deleted file mode 100644 index d913ed8..0000000 --- a/sources +++ /dev/null @@ -1,4 +0,0 @@ -http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html -https://kavaliro.com/wp-content/uploads/2014/03/AES.pdf -https://en.wikipedia.org/wiki/Rijndael_S-box -http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf
\ No newline at end of file @@ -1,5 +1,6 @@ #!/usr/bin/python import copy +import sys from constants import round_constants from constants import sbox @@ -239,4 +240,4 @@ def matrix(matrix_array, string=""): return output -encrypt("ATTACK AT DAWN!", "SOME 128 BIT KEY") +encrypt(sys.argv[1], sys.argv[2]) |