Skip to content
Snippets Groups Projects
Commit 3c4648d0 authored by dario.genga's avatar dario.genga
Browse files

Add subkeys table creation and IDEA encryption

Improved the add_mod and mul_mod methods to supports
string parameters.
Fixed an error in the mul_mod method that wasn't
converting 0000 nibbles as 16 (base 10).
parent b7460eaf
Branches
No related tags found
No related merge requests found
......@@ -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__":
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment