diff --git a/main.py b/main.py index 462dc75ee11e52a20a1c728c712ae2868f47ffe7..ac6268daa7e0f4aa0a9d11039def542261e2af99 100644 --- a/main.py +++ b/main.py @@ -4,27 +4,56 @@ Authors : Rayyan BELHI, Dario GENGA Date : 2022 """ -def modulo(a, b): # a mod b = res + +# Return a mod b +def modulo(a, b): res = 0 tmp = 0 - if (a < b): + if a < b: res = a - elif (a > b): + elif a > b: tmp = a // b res = a - (b*tmp) else: res = 0 return res -def add_mod(a,b): # (a+b) mod 16 (=2^4) // p.3 + +# Return (a+b) mod 16 +def add_mod(a, b): + if type(a) == str: + a = int(a, 2) + + if type(b) == str: + b = int(b, 2) + tmp = a + b - res = modulo(tmp, 16) - return res + res = modulo(tmp, 2**4) + return format(res, '04b') + + +# Return (a*b) mod 17 +def mul_mod(a, b): + if type(a) == str: + a = int(a, 2) + + if type(b) == str: + b = int(b, 2) + + # If we have a nibble of 0000, then this corresponds to 16 (base 10) that is congruent to -1 modulo 17 + if a == 0: + a = 16 + if b == 0: + b = 16 -def mul_mod(a,b): # (a*b) mod 17 // p.3 tmp = a * b - res = modulo(tmp, 17) - return res + res = modulo(tmp, 2**4 + 1) + # Because we work with nibbles and 2^4 + 1 = 17, if we obtain 16 as result this will correspond to 10000 in binary. + # This value can't be stored in a nibble, so we must exclude it + if res == 2**4: + res = 0 + + return format(res, '04b') def xor(a,b):#a XOR b = str(binaire) @@ -62,38 +91,99 @@ def xor(a,b):#a XOR b = str(binaire) i += 1 return res -def create_key_tables(): - pass - -def round(): - # 1. Multiply X1 and the first subkey Z1 - # 2. Add X2 and the second subkey Z2 - # 3. Add X3 and the third subkey Z3 - # 4. Multiply X4 and the fourth subkey Z4 +# Shift the 6 first bit of the key to the end +def shift_key(key): + bit_to_shift = key[0:6] + new_key = key[6:] + bit_to_shift + return new_key + + +# Create the table of the 28 subkeys used for the IDEA encryption +def create_subkeys_table(key): + subkeys = [] + nibble = '' + + while len(subkeys) < 28: + # Decompose the key into 8 nibbles + for bit in key: + nibble += bit + if len(nibble) >= 4 and len(subkeys) < 28: + subkeys.append(nibble) + nibble = '' + + # Shift the key for the next round + key = shift_key(key) + + return subkeys + + +# Encrypt the text with the key by using the IDEA algorithm +def encrypt(plaintext, key): + input_block = plaintext + subkeys = create_subkeys_table(key) + + current_round = 0 + total_rounds = 4 + + while current_round <= total_rounds: + # 1. Multiply X1 and the first subkey Z1 + res_1 = mul_mod(input_block[0:4], subkeys[0]) + # 2. Add X2 and the second subkey Z2 + res_2 = add_mod(input_block[4:8], subkeys[1]) + # 3. Add X3 and the third subkey Z3 + res_3 = add_mod(input_block[8:12], subkeys[2]) + # 4. Multiply X4 and the fourth subkey Z4 + res_4 = mul_mod(input_block[12:16], subkeys[3]) + + # Don't do the next steps if this is the final round + if current_round < total_rounds: + # 5. Bitwise XOR the results of steps 1 and 3 + res_5 = xor(res_1, res_3) + # 6. Bitwise XOR the results of steps 2 and 4 + res_6 = xor(res_2, res_4) + # 7. Multiply the result of step 5 and the fifth subkey Z5 + res_7 = mul_mod(res_5, subkeys[4]) + # 8. Add the results of step 6 and 7 + res_8 = add_mod(res_6, res_7) + # 9. Multiply the result of step 8 and the sixth subkey Z6 + res_9 = mul_mod(res_8, subkeys[5]) + # 10. Add the results of steps 7 and 9 + res_10 = add_mod(res_7, res_9) + # 11. Bitwise XOR the results of steps 1 and 9 + res_11 = xor(res_1, res_9) + # 12. Bitwise XOR the results of steps 3 and 9 + res_12 = xor(res_3, res_9) + # 13. Bitwise XOR the results of steps 2 and 10 + res_13 = xor(res_2, res_10) + # 14. Bitwise XOR the results of steps 4 and 10 + res_14 = xor(res_4, res_10) + # Create the input for the next round with the final results + # The results of the steps 12 and 13 are swapped + input_block = res_11 + res_13 + res_12 + res_14 + + current_round += 1 + subkeys = subkeys[6:] + + ciphertext = res_1 + res_2 + res_3 + res_4 + return ciphertext - # Don't do the next steps if this is the final round - # 5. Bitwise XOR the results of steps 1 and 3 - # 6. Bitwise XOR the results of steps 2 and 4 - # 7. Multiply the result of step 5 and the fifth subkey Z5 - # 8. Add the results of step 6 and 7 - # 9. Multiply the result of step 8 and the sisth subkey Z6 - # 10. Add the results of steps 7 and 9 - # 11. Bitwise XOR the results of steps 1 and 9 - # 12. Bitwise XOR the results of steps 3 and 9 - # 13. Bitwise XOR the results of steps 2 and 10 - # 14. Bitwise XOR the results of steps 4 and 10 - - pass +def main(): + plaintext = '1001110010101100' + key = '11011100011011110011111101011001' + expected_ciphertext = '1011101101001011' + ciphertext = encrypt(plaintext, key) -def main(): - plaintext = 1001110010101100 - key = 11011100011011110011111101011001 - expected_ciphertext = 1011101101001011 + print("The original message is : " + plaintext) + print("The key is : " + key) + print("The ciphertext obtained is : " + ciphertext) - print("hello world") + if ciphertext == expected_ciphertext: + print("The encryption has been successful !") + else: + print("An error has occurred during the encryption...") if __name__ == "__main__":