Commit a7752fb6 authored by Almouhannad Hafez's avatar Almouhannad Hafez

Implement encrypt, decrypt, perform_round

parent eb75bf88
...@@ -24,150 +24,40 @@ ...@@ -24,150 +24,40 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 2,
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"9\n" "key:\n",
] " 00011100000101001110011110000000100100001000101011\n",
} "original text:\n",
], " Almouhannad.Hafez\n",
"source": [ "original text in binary:\n",
"sdes = SDES()\n", " 010000010110110001101101011011110111010101101000011000010110111001101110011000010110010000101110010010000110000101100110011001010111101000000000\n",
"print(sdes.key_length)" "encrypted:\n",
] " 000100001010000110100001100010010000111110100100111001011101001101010000111001011101111110001010110011010100101001110000110101001111100100110011\n",
}, "decrypted:\n",
{ " Almouhannad.Hafez\n"
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"168\n",
"Almouhannad.Hafez + 1\n",
"True\n"
]
}
],
"source": [
"original_text = \"Almouhannad.Hafez + 1\"\n",
"bin = sdes.text_to_binary(original_text)\n",
"print(len(bin))\n",
"text = sdes.binary_to_text(bin)\n",
"print(text)\n",
"print(text == original_text)\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['010000010110',\n",
" '110001101101',\n",
" '011011110111',\n",
" '010101101000',\n",
" '011000010110',\n",
" '111001101110',\n",
" '011000010110',\n",
" '010000101110',\n",
" '010010000110',\n",
" '000101100110',\n",
" '011001010111',\n",
" '101000100000',\n",
" '001010110010',\n",
" '000000110001']"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sdes.get_blocks(original_text)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"12434356\n"
]
}
],
"source": [
"print(sdes.E(\"123456\"))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"010\n"
]
}
],
"source": [
"print(sdes.apply_S(\"1101\", 2))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"011100100\n"
] ]
} }
], ],
"source": [ "source": [
"sdes = SDES(\n",
" key_length = 50,\n",
" rounds_count = 100\n",
")\n",
"key = sdes.generate_random_key()\n", "key = sdes.generate_random_key()\n",
"print(key)\n", "print(f\"key:\\n {key}\")\n",
"##OK" "text = \"Almouhannad.Hafez\"\n",
] "print(f\"original text:\\n {text}\")\n",
}, "print(f\"original text in binary:\\n {sdes.text_to_binary(text)}\")\n",
{ "enc = sdes.encrypt(text, key)\n",
"cell_type": "code", "print(f\"encrypted:\\n {enc}\")\n",
"execution_count": 31, "dec = sdes.decrypt(enc, key)\n",
"metadata": {}, "print(f\"decrypted:\\n {dec}\")\n"
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"000001111010\n"
]
}
],
"source": [
"block = \"111111000001\"\n",
"processed_block = sdes.process_block(key, 0, block)\n",
"print (processed_block)\n",
"##OK"
] ]
} }
], ],
......
...@@ -150,35 +150,68 @@ class SDES: ...@@ -150,35 +150,68 @@ class SDES:
return text return text
def get_blocks(self, plain_text: str) -> list[str]: def get_blocks(self, input: str) -> list[str]:
""" """
Convert plain text into a list of binary strings, each with length of self.block_size Convert input into a list of binary strings, each with length of self.block_size
Parameters: Parameters:
plain_text (str): Text to be converted input (str): Input to be converted into blocks
Returns: Returns:
blocks (list[str]): Binary blocks of the original text blocks (list[str]): Binary blocks of the original input
""" """
# Type checking # Type checking
if not isinstance(plain_text, str): if not isinstance(input, str):
raise TypeError(f"'plain_text' must be str, got {type(plain_text).__name__}") raise TypeError(f"'input' must be str, got {type(input).__name__}")
# Validation rules # Validation rules
if len(plain_text) == 0: if len(input) == 0:
raise ValueError("'plain_text' must not be empty") raise ValueError("'input' must not be empty")
binary_text = self.text_to_binary(plain_text)
blocks = [] blocks = []
blocks = [binary_text[i:i+self.block_size] for i in range(0, len(binary_text), self.block_size)] blocks = [input[i:i+self.block_size] for i in range(0, len(input), self.block_size)]
return blocks return blocks
############################################################################################### ###############################################################################################
def process_block(self, key: str, round_number: int, old_block: str) -> str: def encrypt(self, plain_text: str, key: str) -> str:
binary_text = self.text_to_binary(plain_text)
output = binary_text
for i in range(self.rounds_count):
output = self.perform_round(i, key, output, 'enc')
return output
def decrypt(self, binary_encrypted_input: str, key: str) -> str:
output = binary_encrypted_input
for i in range(self.rounds_count):
output = self.perform_round(i, key, output, 'dec')
decrypted_plain_text = self.binary_to_text(output)
return decrypted_plain_text
def perform_round (self, round_number: int, key: int, input: str, mode: str) -> str:
blocks = self.get_blocks(input)
if mode == 'dec':
round_number_inv = (self.rounds_count - round_number - 1) % self.rounds_count
round_key = self.get_round_key(key, round_number_inv)
else:
round_key = self.get_round_key(key, round_number)
output = ''
for i in range(len(blocks)):
blocks[i] = self.process_block(round_key, blocks[i])
if round_number == self.rounds_count -1:
block = blocks[i]
blocks[i] = ''
blocks[i] += block[self.block_size//2 : self.block_size]
blocks[i] += block[0:self.block_size//2]
output += blocks[i]
return output
def process_block(self, round_key: str, old_block: str) -> str:
L_old, R_old = old_block[0:self.block_size//2] , old_block[self.block_size//2 : self.block_size] L_old, R_old = old_block[0:self.block_size//2] , old_block[self.block_size//2 : self.block_size]
L_new = R_old L_new = R_old
round_key = self.get_round_key(key, round_number)
R_new = self.f(round_key, R_old) R_new = self.f(round_key, R_old)
R_new = self.binary_strings_xor(R_new, L_old) R_new = self.binary_strings_xor(R_new, L_old)
new_block = '' new_block = ''
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment