Compare commits

...

4 Commits

Author SHA1 Message Date
Ondrej Hladuvka 588e6b2f87 hw4 2025-05-21 21:13:01 +03:00
Ondrej Hladuvka b8056c084c hw3 2025-05-21 21:12:35 +03:00
Ondrej Hladuvka e5d8cd6214 wh2 2025-05-21 21:12:09 +03:00
Ondrej Hladuvka a7a984c0d8 hw1 2025-05-21 21:11:43 +03:00
12 changed files with 2287 additions and 0 deletions

3
hw1/build.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
docker build -t jupyter .

BIN
hw1/hw1.pdf Normal file

Binary file not shown.

547
hw2/Homework 2.ipynb Normal file
View File

@ -0,0 +1,547 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "421d5e4d-1327-449b-8aae-16cb1c99cb60",
"metadata": {},
"source": [
"Ondřej Hladůvka \n",
"\n",
"If you want to run code in this notebook, you can find it here: https://git.hladu.xyz/hladu357/TalTech_crypt/src/branch/master/hw2"
]
},
{
"cell_type": "markdown",
"id": "0ed8045c-d080-4288-909a-9190433d6a09",
"metadata": {},
"source": [
"## Task 1 Confusion and diffusion\n",
"From the lectures, you learned about importance of confusion and diffusion principles for the block ciphers. Let us examine them in more details. Assume you need to analyse\n",
"properties of Vigenere cipher."
]
},
{
"cell_type": "markdown",
"id": "c8eedd35-16bd-433d-b161-b1e9c7a26c19",
"metadata": {},
"source": [
"1. Encrypt message THEWANDCHOOSESTHEWIZARD with key MAGIC."
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "47aba105-8f9d-40eb-a5ed-5f93bbe63b86",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ciphertext: FHKECZDIPQASKAVTECQBMRJ\n"
]
}
],
"source": [
"def vigenere_enc(pt : str, key : str):\n",
" pt_int = [ord(i) - ord('A') for i in pt]\n",
" key_int = [ord(i) - ord('A') for i in key]\n",
"\n",
" ct_int = [(char + key_int[idx % len(key_int)]) % 26 for idx, char in enumerate(pt_int)]\n",
" ct = [chr(i + ord('A')) for i in ct_int]\n",
" return ct\n",
"\n",
"pt = \"THEWANDCHOOSESTHEWIZARD\"\n",
"key = \"MAGIC\"\n",
"ct = vigenere_enc(pt, key)\n",
"\n",
"print(\"ciphertext: \", \"\".join(ct))"
]
},
{
"cell_type": "markdown",
"id": "60d515f1-5951-4743-8286-4b41018fabc4",
"metadata": {},
"source": [
"2. Suppose we change one letter (W becomes L) in the plaintext to get THEWANDCHOOSESTHE L IZARD.\n",
"How may letters of the ciphertext are changed? Is the diffusion property achieved?"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "3c55e9ad-dd9f-48ee-b4fe-064dacb0706a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Witch changed plaintext at index 17\n",
"New ciphertext is: FHKECZDIPQASKAVTERQBMRJ\n",
"character changes at index 17 C -> R\n",
"diffusion is not achieved, as the plaintext's change effects the ciphertext in structured way exploitable by cryptanalysis\n"
]
}
],
"source": [
"idx = 17\n",
"pt2 = pt[:idx] + \"L\" + pt[(idx + 1):]\n",
"ct2 = \"\".join(vigenere_enc(pt2, key))\n",
"\n",
"print(f\"Witch changed plaintext at index {idx}\")\n",
"print(f\"New ciphertext is: {ct2}\")\n",
"\n",
"for idx, (a, b) in enumerate(zip(ct, ct2)):\n",
" if (a != b):\n",
" print(f\"character changes at index {idx} {a} -> {b}\")\n",
"print(\"diffusion is not achieved, as the plaintext's change effects the ciphertext in structured way exploitable by cryptanalysis\")"
]
},
{
"cell_type": "markdown",
"id": "47b5e048-9f0a-4436-8294-fcba9fca489e",
"metadata": {},
"source": [
"3. Suppose we change one letter in key (G becomes N). How may letters of the ciphertext are changed?\n",
"Is confusion property achieved?"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "c89a36d4-6c24-4ca3-84c5-bafea87073c3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"it would change lower whole part n / k letters where n is length of plaintext and k is length of the key\n",
"floor(n / k) = floor(23 / 5) = 4\n",
"confusion is not achieved, as the key's effect on the ciphertext is structured and exploitable by cryptanalysis\n"
]
}
],
"source": [
"import math\n",
"print(\"it would change lower whole part n / k letters where n is length of plaintext and k is length of the key\")\n",
"n = len(pt)\n",
"k = len(key)\n",
"print(f\"floor(n / k) = floor({n} / {k}) = {math.floor(n/k)}\")\n",
"print(\"confusion is not achieved, as the key's effect on the ciphertext is structured and exploitable by cryptanalysis\")"
]
},
{
"cell_type": "markdown",
"id": "1b4e0abb-fbcb-4019-9c4d-c8486d7c3884",
"metadata": {},
"source": [
"## Task 2. Pseudorandom function \n",
"Let F {0, 1}\n",
"n × {0, 1}\n",
"n → {0, 1}\n",
"n\n",
"be a secure PRF. Do the following\n",
"functions satisfy definition of pseudo-random function?"
]
},
{
"cell_type": "markdown",
"id": "3dc36d9b-46b1-4222-bd16-19b68356dd6a",
"metadata": {},
"source": [
"1. F(k, m) = F(k, m) || 0^n, where 0^n is a zero string of length n"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "bd6cd25a-944c-4844-a82d-601c27a17a80",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Adversary with strategy that guesses its not oraculum if last n bits of the message are all zeros\n",
"can be wrong only if oraculum, was used (1/2 chance) and it generated last last n bits of the message all zeros (2^-n)\n",
"Chance of this is 2 to the power of minus (message length + 1)\n",
"With growing n, this function converges to 0 -> F' is not secure PRF\n",
"\n",
"\n",
"We can simulate this, assumming python random is close enough to random oraculum\n",
"For message 4 characters long, its only a 0.0625 chance\n",
"but only if random oracle is selected so times 0.5 -> 0.03125 chance\n",
"adverasry got response: [1, 1, 1, 1, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its False\n",
"\n",
"adverasry got response: [0, 1, 0, 0, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [0, 0, 1, 0, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [1, 1, 1, 0, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [0, 0, 0, 1, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [1, 1, 0, 0, 0, 1, 0, 0]\n",
"he guessed it is oraculum - its True\n",
"\n",
"we can meassure the prediction:\n",
"adversary passed 971 out of 1000 tests, which is 0.029 chance of failure\n"
]
}
],
"source": [
"# no efficient algorithm can distinguish (with significant advantage)\n",
"# between a function chosen randomly from the PRF family and a random oracle\n",
"import random\n",
"import string\n",
"msg_len = 4\n",
"\n",
"def prf1(input):\n",
" return [random.randint(0, 1) for _ in range(len(input))] + [0] * len(input)\n",
"\n",
"def challenger1(input):\n",
" if (random.choice([True, False])): # random oracle\n",
" return [random.randint(0, 1) for _ in range(len(input) * 2)], True\n",
" else: # tested function\n",
" return prf1(input), False\n",
"\n",
"words = [\"abcd\", \"efgh\", \"ijkl\", \"mnop\", \"qrst\", \"uvwx\"]\n",
"def adversary1(w, verbose=True):\n",
" response = challenger1(w)\n",
" if verbose: print(f\"adverasry got response: {response[0]}\")\n",
" \n",
" if all(x == 0 for x in response[0][len(w):]):\n",
" if verbose: print(f\"he guessed it is not oraculum - its {response[1] == False}\\n\")\n",
" return response[1] == False\n",
" else:\n",
" if verbose: print(f\"he guessed it is oraculum - its {response[1] == True}\\n\")\n",
" return response[1] == True\n",
"\n",
"\n",
"print(\"Adversary with strategy that guesses its not oraculum if last n bits of the message are all zeros\")\n",
"print(\"can be wrong only if oraculum, was used (1/2 chance) and it generated last last n bits of the message all zeros (2^-n)\")\n",
"print(\"Chance of this is 2 to the power of minus (message length + 1)\")\n",
"print(\"With growing n, this function converges to 0 -> F' is not secure PRF\\n\\n\")\n",
"\n",
"chance = pow(2,-msg_len)\n",
"print(f\"We can simulate this, assumming python random is close enough to random oraculum\")\n",
"print(f\"For message {msg_len} characters long, its only a {chance} chance\")\n",
"print(f\"but only if random oracle is selected so times 0.5 -> {chance/2} chance\")\n",
"\n",
"for w in words:\n",
" adversary1(w)\n",
"\n",
"tests = 1000\n",
"passed = 0\n",
"print(f\"we can meassure the prediction:\")\n",
"for i in range(0, tests):\n",
" msg = ''.join(random.choices(string.ascii_lowercase, k=msg_len))\n",
" passed += adversary1(msg, False)\n",
"\n",
"print(f\"adversary passed {passed} out of {tests} tests, which is {round(1 - (passed / tests),5)} chance of failure\")"
]
},
{
"cell_type": "markdown",
"id": "06d4358a-0216-457a-ab08-3662f1999b89",
"metadata": {},
"source": [
"2. F(k, mm) = F(k, m)F(k, m ⊕ 0^n), where 0^n is a zero string of length n"
]
},
{
"cell_type": "markdown",
"id": "f99e71fa-a4e2-4396-8072-9621b40700fc",
"metadata": {},
"source": [
"Since x ⊕ 0 = x, we can simplify\n",
"F' := F(k, mm) = F'(k, m)F'(k, m)\n",
"\n",
"With startegy: \n",
"choose message x\n",
"x = a^n (where n is power of 2)\n",
"\n",
"get message y \n",
"if message is repeating bit => adversary guess its not oraculum \n",
"y = F'(a^(n/2) || F'(a^(n/2)) = F'(a^(n/4)) || F'(a^(n/4)) || F'(a^(n/4)) || F'(a^(n/4)) = ... = F'(a)^n\n",
"\n",
"else => guess its oraculum\n",
"\n",
"Only way adversary could be wrong if oraculum generated n repeating bits, chance of this is 2^(-n) \n",
"With growing n, this function converges to 0 -> F' is not secure PRF"
]
},
{
"cell_type": "markdown",
"id": "fc89bafe-990c-4a05-9bd4-1c86075f4fcd",
"metadata": {},
"source": [
"3. F(k, mm) = F(k, 0m) ⊕ F(k, m1), where m, m∈ {0, 1}^(n1)"
]
},
{
"cell_type": "markdown",
"id": "7fccba29-9283-448a-83e5-0a9e1dca8864",
"metadata": {},
"source": [
"With startegy:\n",
"querying two messages x_1, x_2 \n",
"x_1 = 0^(n-1)||0^(n-1) \n",
"x_2 = 0^(n-1)||1^(n-1) \n",
" \n",
"get messages y_1, y_2 \n",
"\n",
"\n",
"if y_1 ⊕ y_2 == 0^n => adversary guess its not oraculum \n",
"y_1 ⊕ y_2 = (F(k,0||0^(n1)) ⊕ F(k,0^(n1)||1)) ⊕ (F(k,0||0^(n1)) ⊕ F(k,1^(n1||1)) \n",
"y_1 ⊕ y_2 = F(k,0||1^(n1)) ⊕ F(k,1^(n1||1) \n",
" \n",
"else => guess its oraculum \n",
" \n",
"chance of two random oraculum outputs being inverse (y_1 ⊕ y_2 == 0^n) is 2^(-n) \n",
"With growing n, this function converges to 0 -> F' is not secure PRF"
]
},
{
"cell_type": "markdown",
"id": "e62ff1ca-3ea5-4f08-9b2d-286966f45a7e",
"metadata": {},
"source": [
"## Task 3\n",
"Output feedback mode Consider the following permutation cipher instead of permuting plaintext letters to get ciphertext, you are first required to convert plaintext letters to binary form and next you\n",
"permute bits according to the key. Letter H becomes encrypted to T with key (5, 1, 2, 4, 3). Let us view it as\n",
"block cipher with block length 5 bits."
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "9ca5e5f2-19ae-4d1d-aad1-eecc6b9d07e3",
"metadata": {},
"outputs": [],
"source": [
"def perm_enc(pt: list[int], key: list[int]):\n",
" blocksize = 5\n",
" ct = [0] * blocksize\n",
" for idx in range(0, blocksize):\n",
" ct[idx] = pt[key[idx] - 1]\n",
" return ct\n",
"\n",
"def convert_str(pt: list[int]): # converts to list of binary blocks\n",
" bit_array = []\n",
" for char in pt:\n",
" bits = bin(ord(char) - ord('A'))[2:][-5:].zfill(5)\n",
" bit_array.append([int(bit) for bit in bits])\n",
" return bit_array\n",
"\n",
"def ofb(pt, key, iv, cipher):\n",
" ct = []\n",
" for block in pt:\n",
" iv = cipher(iv, key)\n",
" ct.append([x ^ y for (x,y) in zip(iv, block)]) # encrypted iv into block\n",
" return ct\n",
"\n",
"key = [5, 1, 2, 4, 3]"
]
},
{
"cell_type": "markdown",
"id": "95d3d5f0-26cc-4adf-ba2f-3e19aac52174",
"metadata": {},
"source": [
"1. Encrypt world DOG with key (4, 1, 3, 5, 2) using permutation cipher in OFB mode with iv = 01011. Leave\n",
"result as a binary string."
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "63f150c4-cefc-4288-9568-6c0ed4963d7b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"plaintext: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"ciphertext: [[1, 0, 0, 0, 0], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]]\n"
]
}
],
"source": [
"pt = convert_str(['D', 'O', 'G'])\n",
"key = [4, 1, 3, 5, 2]\n",
"iv = [0, 1, 0, 1, 1]\n",
"ct = ofb(pt, key, iv, perm_enc)\n",
"print(f\"plaintext: {pt}\")\n",
"print(f\"ciphertext: {ct}\")"
]
},
{
"cell_type": "markdown",
"id": "2e92ea0e-ccab-4eb7-bb0d-5f325fcd8e77",
"metadata": {},
"source": [
"2. Flip 5-th bit of received ciphertext (0 becomes 1 and vice versa). Now decrypt modified ciphertext. How\n",
"many bits in the plaintext get changed?"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "ae47fd93-809c-4e03-b565-3d1ebb8f4b42",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original ciphertext: [[1, 0, 0, 0, 0], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]]\n",
"modified ciphertext: [[1, 0, 0, 0, 1], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]]\n",
"original plaintext: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"modified plaintext: [[0, 0, 0, 1, 0], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"one bit also flipped -> no diffusion\n"
]
}
],
"source": [
"import copy\n",
"ct2 = copy.deepcopy(ct)\n",
"ct2[0][4] ^= 1\n",
"pt2 = ofb(ct2, key, iv, perm_enc)\n",
"\n",
"print(f\"original ciphertext: {ct}\")\n",
"print(f\"modified ciphertext: {ct2}\")\n",
"print(f\"original plaintext: {pt}\")\n",
"print(f\"modified plaintext: {pt2}\")\n",
"print(f\"one bit also flipped -> no diffusion\")"
]
},
{
"cell_type": "markdown",
"id": "dd8b801d-8bcc-49dc-8ad1-b0d54ce62959",
"metadata": {},
"source": [
"3. Flip the first bit of the IV iv = 11011, decrypt ciphertext from Step 1 with iv\n",
". How many bits in the\n",
"plaintext get changed?"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "a358aa91-7e8a-4ada-82f0-58fdb7aa30a9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original plaintext: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"modified plaintext: [[0, 1, 0, 1, 1], [0, 1, 1, 1, 1], [0, 0, 1, 0, 0]]\n",
"one bit per block also flipped\n"
]
}
],
"source": [
"iv[0] ^= 1\n",
"pt3 = ofb(ct, key, iv, perm_enc)\n",
"\n",
"print(f\"original plaintext: {pt}\")\n",
"print(f\"modified plaintext: {pt3}\")\n",
"print(f\"one bit per block also flipped\")"
]
},
{
"cell_type": "markdown",
"id": "fc3e1681-f07b-4546-bc30-688753fcbd53",
"metadata": {},
"source": [
"## Task 4\n",
"Consider the encryption of nblock message m = m1m2. . .m_n by some block cipher E in\n",
"CFB mode. Let use denote ciphertext produced by E as c = c1c2. . .cn. Show which information about\n",
"the plaintext can be extracted if we get a collision: ci = cj\n",
", where i ≠ j."
]
},
{
"cell_type": "markdown",
"id": "7134ee9b-fcc0-4d6e-a240-208707160694",
"metadata": {},
"source": [
"#### In OFB mode: \n",
"Ek(iv)^n := Ek( Ek( ... Ek(iv))) n times\n",
"ct_n = pt_n ⊕ Ek(iv)^n\n",
"\n",
"ct_i == ct_j implies => \n",
"Ek(iv)^i == Ek(iv)^j => \n",
"pt_i ⊕ pt_j == Ek(iv)^(i-1) ⊕ Ek(iv)^(j-1)"
]
},
{
"cell_type": "markdown",
"id": "7e65fe31-62e3-4c6c-a7a8-e29ee8dc9e57",
"metadata": {},
"source": [
"## Task 5\n",
"Show that Pigpen cipher defined below is not IND-OT-CPA secure (where adversary is allowed to\n",
"do only one query to the challenger in the IND-CPA game).\n",
"The pigpen cipher uses graphical symbols assigned according to a key in the diagram below1\n",
"(NOTE: Positions\n",
"of the letters in the diagrams are random and not known to adversary):"
]
},
{
"cell_type": "markdown",
"id": "296118e7-4df4-451f-8b27-9a317c04d362",
"metadata": {},
"source": [
"#### Indistinguishability under One-Time Chosen Plaintext Attack definition:\n",
"1. The challenger generates a secret key K\n",
"2. The adversary submits two distinct plaintexts Pt_0, Pt_1 of equal length to the challenger\n",
"3. The challenger selects a random bit b ∈ {0,1}, resulting in ciphertext Ct = Ek(M_b) being sent to the adversary\n",
"4. Based on the Ct, the adversary guess b ∈ {0,1} for the value of b\n",
"5. Scheme is not secure if no adversary has a non-negligible advantage in guessing over 1/2\n",
"\n",
"#### Adversary strategy:\n",
"We can expoit Pigpen cipher being monoalphabetic\n",
"Adversary will send one message with repeating characters and another with each character unique \n",
"M_0 := \"AA\" \n",
"M_1 := \"AB\" \n",
"\n",
"If Ct is some repeating characters => choose 0 \n",
"Else => choose 1 \n",
"\n",
"This strategy will work every time thanks to monoalphabeticity"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

5
hw2/run.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
docker run -p 8888:8888 \
-v "$(pwd)":/work \
jupyter

547
hw3/Homework 2.ipynb Normal file
View File

@ -0,0 +1,547 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "421d5e4d-1327-449b-8aae-16cb1c99cb60",
"metadata": {},
"source": [
"Ondřej Hladůvka \n",
"\n",
"If you want to run code in this notebook, you can find it here: https://git.hladu.xyz/hladu357/TalTech_crypt/src/branch/master/hw2"
]
},
{
"cell_type": "markdown",
"id": "0ed8045c-d080-4288-909a-9190433d6a09",
"metadata": {},
"source": [
"## Task 1 Confusion and diffusion\n",
"From the lectures, you learned about importance of confusion and diffusion principles for the block ciphers. Let us examine them in more details. Assume you need to analyse\n",
"properties of Vigenere cipher."
]
},
{
"cell_type": "markdown",
"id": "c8eedd35-16bd-433d-b161-b1e9c7a26c19",
"metadata": {},
"source": [
"1. Encrypt message THEWANDCHOOSESTHEWIZARD with key MAGIC."
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "47aba105-8f9d-40eb-a5ed-5f93bbe63b86",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ciphertext: FHKECZDIPQASKAVTECQBMRJ\n"
]
}
],
"source": [
"def vigenere_enc(pt : str, key : str):\n",
" pt_int = [ord(i) - ord('A') for i in pt]\n",
" key_int = [ord(i) - ord('A') for i in key]\n",
"\n",
" ct_int = [(char + key_int[idx % len(key_int)]) % 26 for idx, char in enumerate(pt_int)]\n",
" ct = [chr(i + ord('A')) for i in ct_int]\n",
" return ct\n",
"\n",
"pt = \"THEWANDCHOOSESTHEWIZARD\"\n",
"key = \"MAGIC\"\n",
"ct = vigenere_enc(pt, key)\n",
"\n",
"print(\"ciphertext: \", \"\".join(ct))"
]
},
{
"cell_type": "markdown",
"id": "60d515f1-5951-4743-8286-4b41018fabc4",
"metadata": {},
"source": [
"2. Suppose we change one letter (W becomes L) in the plaintext to get THEWANDCHOOSESTHE L IZARD.\n",
"How may letters of the ciphertext are changed? Is the diffusion property achieved?"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "3c55e9ad-dd9f-48ee-b4fe-064dacb0706a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Witch changed plaintext at index 17\n",
"New ciphertext is: FHKECZDIPQASKAVTERQBMRJ\n",
"character changes at index 17 C -> R\n",
"diffusion is not achieved, as the plaintext's change effects the ciphertext in structured way exploitable by cryptanalysis\n"
]
}
],
"source": [
"idx = 17\n",
"pt2 = pt[:idx] + \"L\" + pt[(idx + 1):]\n",
"ct2 = \"\".join(vigenere_enc(pt2, key))\n",
"\n",
"print(f\"Witch changed plaintext at index {idx}\")\n",
"print(f\"New ciphertext is: {ct2}\")\n",
"\n",
"for idx, (a, b) in enumerate(zip(ct, ct2)):\n",
" if (a != b):\n",
" print(f\"character changes at index {idx} {a} -> {b}\")\n",
"print(\"diffusion is not achieved, as the plaintext's change effects the ciphertext in structured way exploitable by cryptanalysis\")"
]
},
{
"cell_type": "markdown",
"id": "47b5e048-9f0a-4436-8294-fcba9fca489e",
"metadata": {},
"source": [
"3. Suppose we change one letter in key (G becomes N). How may letters of the ciphertext are changed?\n",
"Is confusion property achieved?"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "c89a36d4-6c24-4ca3-84c5-bafea87073c3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"it would change lower whole part n / k letters where n is length of plaintext and k is length of the key\n",
"floor(n / k) = floor(23 / 5) = 4\n",
"confusion is not achieved, as the key's effect on the ciphertext is structured and exploitable by cryptanalysis\n"
]
}
],
"source": [
"import math\n",
"print(\"it would change lower whole part n / k letters where n is length of plaintext and k is length of the key\")\n",
"n = len(pt)\n",
"k = len(key)\n",
"print(f\"floor(n / k) = floor({n} / {k}) = {math.floor(n/k)}\")\n",
"print(\"confusion is not achieved, as the key's effect on the ciphertext is structured and exploitable by cryptanalysis\")"
]
},
{
"cell_type": "markdown",
"id": "1b4e0abb-fbcb-4019-9c4d-c8486d7c3884",
"metadata": {},
"source": [
"## Task 2. Pseudorandom function \n",
"Let F {0, 1}\n",
"n × {0, 1}\n",
"n → {0, 1}\n",
"n\n",
"be a secure PRF. Do the following\n",
"functions satisfy definition of pseudo-random function?"
]
},
{
"cell_type": "markdown",
"id": "3dc36d9b-46b1-4222-bd16-19b68356dd6a",
"metadata": {},
"source": [
"1. F(k, m) = F(k, m) || 0^n, where 0^n is a zero string of length n"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "bd6cd25a-944c-4844-a82d-601c27a17a80",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Adversary with strategy that guesses its not oraculum if last n bits of the message are all zeros\n",
"can be wrong only if oraculum, was used (1/2 chance) and it generated last last n bits of the message all zeros (2^-n)\n",
"Chance of this is 2 to the power of minus (message length + 1)\n",
"With growing n, this function converges to 0 -> F' is not secure PRF\n",
"\n",
"\n",
"We can simulate this, assumming python random is close enough to random oraculum\n",
"For message 4 characters long, its only a 0.0625 chance\n",
"but only if random oracle is selected so times 0.5 -> 0.03125 chance\n",
"adverasry got response: [1, 1, 1, 1, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its False\n",
"\n",
"adverasry got response: [0, 1, 0, 0, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [0, 0, 1, 0, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [1, 1, 1, 0, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [0, 0, 0, 1, 0, 0, 0, 0]\n",
"he guessed it is not oraculum - its True\n",
"\n",
"adverasry got response: [1, 1, 0, 0, 0, 1, 0, 0]\n",
"he guessed it is oraculum - its True\n",
"\n",
"we can meassure the prediction:\n",
"adversary passed 971 out of 1000 tests, which is 0.029 chance of failure\n"
]
}
],
"source": [
"# no efficient algorithm can distinguish (with significant advantage)\n",
"# between a function chosen randomly from the PRF family and a random oracle\n",
"import random\n",
"import string\n",
"msg_len = 4\n",
"\n",
"def prf1(input):\n",
" return [random.randint(0, 1) for _ in range(len(input))] + [0] * len(input)\n",
"\n",
"def challenger1(input):\n",
" if (random.choice([True, False])): # random oracle\n",
" return [random.randint(0, 1) for _ in range(len(input) * 2)], True\n",
" else: # tested function\n",
" return prf1(input), False\n",
"\n",
"words = [\"abcd\", \"efgh\", \"ijkl\", \"mnop\", \"qrst\", \"uvwx\"]\n",
"def adversary1(w, verbose=True):\n",
" response = challenger1(w)\n",
" if verbose: print(f\"adverasry got response: {response[0]}\")\n",
" \n",
" if all(x == 0 for x in response[0][len(w):]):\n",
" if verbose: print(f\"he guessed it is not oraculum - its {response[1] == False}\\n\")\n",
" return response[1] == False\n",
" else:\n",
" if verbose: print(f\"he guessed it is oraculum - its {response[1] == True}\\n\")\n",
" return response[1] == True\n",
"\n",
"\n",
"print(\"Adversary with strategy that guesses its not oraculum if last n bits of the message are all zeros\")\n",
"print(\"can be wrong only if oraculum, was used (1/2 chance) and it generated last last n bits of the message all zeros (2^-n)\")\n",
"print(\"Chance of this is 2 to the power of minus (message length + 1)\")\n",
"print(\"With growing n, this function converges to 0 -> F' is not secure PRF\\n\\n\")\n",
"\n",
"chance = pow(2,-msg_len)\n",
"print(f\"We can simulate this, assumming python random is close enough to random oraculum\")\n",
"print(f\"For message {msg_len} characters long, its only a {chance} chance\")\n",
"print(f\"but only if random oracle is selected so times 0.5 -> {chance/2} chance\")\n",
"\n",
"for w in words:\n",
" adversary1(w)\n",
"\n",
"tests = 1000\n",
"passed = 0\n",
"print(f\"we can meassure the prediction:\")\n",
"for i in range(0, tests):\n",
" msg = ''.join(random.choices(string.ascii_lowercase, k=msg_len))\n",
" passed += adversary1(msg, False)\n",
"\n",
"print(f\"adversary passed {passed} out of {tests} tests, which is {round(1 - (passed / tests),5)} chance of failure\")"
]
},
{
"cell_type": "markdown",
"id": "06d4358a-0216-457a-ab08-3662f1999b89",
"metadata": {},
"source": [
"2. F(k, mm) = F(k, m)F(k, m ⊕ 0^n), where 0^n is a zero string of length n"
]
},
{
"cell_type": "markdown",
"id": "f99e71fa-a4e2-4396-8072-9621b40700fc",
"metadata": {},
"source": [
"Since x ⊕ 0 = x, we can simplify\n",
"F' := F(k, mm) = F'(k, m)F'(k, m)\n",
"\n",
"With startegy: \n",
"choose message x\n",
"x = a^n (where n is power of 2)\n",
"\n",
"get message y \n",
"if message is repeating bit => adversary guess its not oraculum \n",
"y = F'(a^(n/2) || F'(a^(n/2)) = F'(a^(n/4)) || F'(a^(n/4)) || F'(a^(n/4)) || F'(a^(n/4)) = ... = F'(a)^n\n",
"\n",
"else => guess its oraculum\n",
"\n",
"Only way adversary could be wrong if oraculum generated n repeating bits, chance of this is 2^(-n) \n",
"With growing n, this function converges to 0 -> F' is not secure PRF"
]
},
{
"cell_type": "markdown",
"id": "fc89bafe-990c-4a05-9bd4-1c86075f4fcd",
"metadata": {},
"source": [
"3. F(k, mm) = F(k, 0m) ⊕ F(k, m1), where m, m∈ {0, 1}^(n1)"
]
},
{
"cell_type": "markdown",
"id": "7fccba29-9283-448a-83e5-0a9e1dca8864",
"metadata": {},
"source": [
"With startegy:\n",
"querying two messages x_1, x_2 \n",
"x_1 = 0^(n-1)||0^(n-1) \n",
"x_2 = 0^(n-1)||1^(n-1) \n",
" \n",
"get messages y_1, y_2 \n",
"\n",
"\n",
"if y_1 ⊕ y_2 == 0^n => adversary guess its not oraculum \n",
"y_1 ⊕ y_2 = (F(k,0||0^(n1)) ⊕ F(k,0^(n1)||1)) ⊕ (F(k,0||0^(n1)) ⊕ F(k,1^(n1||1)) \n",
"y_1 ⊕ y_2 = F(k,0||1^(n1)) ⊕ F(k,1^(n1||1) \n",
" \n",
"else => guess its oraculum \n",
" \n",
"chance of two random oraculum outputs being inverse (y_1 ⊕ y_2 == 0^n) is 2^(-n) \n",
"With growing n, this function converges to 0 -> F' is not secure PRF"
]
},
{
"cell_type": "markdown",
"id": "e62ff1ca-3ea5-4f08-9b2d-286966f45a7e",
"metadata": {},
"source": [
"## Task 3\n",
"Output feedback mode Consider the following permutation cipher instead of permuting plaintext letters to get ciphertext, you are first required to convert plaintext letters to binary form and next you\n",
"permute bits according to the key. Letter H becomes encrypted to T with key (5, 1, 2, 4, 3). Let us view it as\n",
"block cipher with block length 5 bits."
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "9ca5e5f2-19ae-4d1d-aad1-eecc6b9d07e3",
"metadata": {},
"outputs": [],
"source": [
"def perm_enc(pt: list[int], key: list[int]):\n",
" blocksize = 5\n",
" ct = [0] * blocksize\n",
" for idx in range(0, blocksize):\n",
" ct[idx] = pt[key[idx] - 1]\n",
" return ct\n",
"\n",
"def convert_str(pt: list[int]): # converts to list of binary blocks\n",
" bit_array = []\n",
" for char in pt:\n",
" bits = bin(ord(char) - ord('A'))[2:][-5:].zfill(5)\n",
" bit_array.append([int(bit) for bit in bits])\n",
" return bit_array\n",
"\n",
"def ofb(pt, key, iv, cipher):\n",
" ct = []\n",
" for block in pt:\n",
" iv = cipher(iv, key)\n",
" ct.append([x ^ y for (x,y) in zip(iv, block)]) # encrypted iv into block\n",
" return ct\n",
"\n",
"key = [5, 1, 2, 4, 3]"
]
},
{
"cell_type": "markdown",
"id": "95d3d5f0-26cc-4adf-ba2f-3e19aac52174",
"metadata": {},
"source": [
"1. Encrypt world DOG with key (4, 1, 3, 5, 2) using permutation cipher in OFB mode with iv = 01011. Leave\n",
"result as a binary string."
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "63f150c4-cefc-4288-9568-6c0ed4963d7b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"plaintext: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"ciphertext: [[1, 0, 0, 0, 0], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]]\n"
]
}
],
"source": [
"pt = convert_str(['D', 'O', 'G'])\n",
"key = [4, 1, 3, 5, 2]\n",
"iv = [0, 1, 0, 1, 1]\n",
"ct = ofb(pt, key, iv, perm_enc)\n",
"print(f\"plaintext: {pt}\")\n",
"print(f\"ciphertext: {ct}\")"
]
},
{
"cell_type": "markdown",
"id": "2e92ea0e-ccab-4eb7-bb0d-5f325fcd8e77",
"metadata": {},
"source": [
"2. Flip 5-th bit of received ciphertext (0 becomes 1 and vice versa). Now decrypt modified ciphertext. How\n",
"many bits in the plaintext get changed?"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "ae47fd93-809c-4e03-b565-3d1ebb8f4b42",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original ciphertext: [[1, 0, 0, 0, 0], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]]\n",
"modified ciphertext: [[1, 0, 0, 0, 1], [1, 0, 1, 0, 0], [1, 1, 1, 1, 1]]\n",
"original plaintext: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"modified plaintext: [[0, 0, 0, 1, 0], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"one bit also flipped -> no diffusion\n"
]
}
],
"source": [
"import copy\n",
"ct2 = copy.deepcopy(ct)\n",
"ct2[0][4] ^= 1\n",
"pt2 = ofb(ct2, key, iv, perm_enc)\n",
"\n",
"print(f\"original ciphertext: {ct}\")\n",
"print(f\"modified ciphertext: {ct2}\")\n",
"print(f\"original plaintext: {pt}\")\n",
"print(f\"modified plaintext: {pt2}\")\n",
"print(f\"one bit also flipped -> no diffusion\")"
]
},
{
"cell_type": "markdown",
"id": "dd8b801d-8bcc-49dc-8ad1-b0d54ce62959",
"metadata": {},
"source": [
"3. Flip the first bit of the IV iv = 11011, decrypt ciphertext from Step 1 with iv\n",
". How many bits in the\n",
"plaintext get changed?"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "a358aa91-7e8a-4ada-82f0-58fdb7aa30a9",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"original plaintext: [[0, 0, 0, 1, 1], [0, 1, 1, 1, 0], [0, 0, 1, 1, 0]]\n",
"modified plaintext: [[0, 1, 0, 1, 1], [0, 1, 1, 1, 1], [0, 0, 1, 0, 0]]\n",
"one bit per block also flipped\n"
]
}
],
"source": [
"iv[0] ^= 1\n",
"pt3 = ofb(ct, key, iv, perm_enc)\n",
"\n",
"print(f\"original plaintext: {pt}\")\n",
"print(f\"modified plaintext: {pt3}\")\n",
"print(f\"one bit per block also flipped\")"
]
},
{
"cell_type": "markdown",
"id": "fc3e1681-f07b-4546-bc30-688753fcbd53",
"metadata": {},
"source": [
"## Task 4\n",
"Consider the encryption of nblock message m = m1m2. . .m_n by some block cipher E in\n",
"CFB mode. Let use denote ciphertext produced by E as c = c1c2. . .cn. Show which information about\n",
"the plaintext can be extracted if we get a collision: ci = cj\n",
", where i ≠ j."
]
},
{
"cell_type": "markdown",
"id": "7134ee9b-fcc0-4d6e-a240-208707160694",
"metadata": {},
"source": [
"#### In OFB mode: \n",
"Ek(iv)^n := Ek( Ek( ... Ek(iv))) n times\n",
"ct_n = pt_n ⊕ Ek(iv)^n\n",
"\n",
"ct_i == ct_j implies => \n",
"Ek(iv)^i == Ek(iv)^j => \n",
"pt_i ⊕ pt_j == Ek(iv)^(i-1) ⊕ Ek(iv)^(j-1)"
]
},
{
"cell_type": "markdown",
"id": "7e65fe31-62e3-4c6c-a7a8-e29ee8dc9e57",
"metadata": {},
"source": [
"## Task 5\n",
"Show that Pigpen cipher defined below is not IND-OT-CPA secure (where adversary is allowed to\n",
"do only one query to the challenger in the IND-CPA game).\n",
"The pigpen cipher uses graphical symbols assigned according to a key in the diagram below1\n",
"(NOTE: Positions\n",
"of the letters in the diagrams are random and not known to adversary):"
]
},
{
"cell_type": "markdown",
"id": "296118e7-4df4-451f-8b27-9a317c04d362",
"metadata": {},
"source": [
"#### Indistinguishability under One-Time Chosen Plaintext Attack definition:\n",
"1. The challenger generates a secret key K\n",
"2. The adversary submits two distinct plaintexts Pt_0, Pt_1 of equal length to the challenger\n",
"3. The challenger selects a random bit b ∈ {0,1}, resulting in ciphertext Ct = Ek(M_b) being sent to the adversary\n",
"4. Based on the Ct, the adversary guess b ∈ {0,1} for the value of b\n",
"5. Scheme is not secure if no adversary has a non-negligible advantage in guessing over 1/2\n",
"\n",
"#### Adversary strategy:\n",
"We can expoit Pigpen cipher being monoalphabetic\n",
"Adversary will send one message with repeating characters and another with each character unique \n",
"M_0 := \"AA\" \n",
"M_1 := \"AB\" \n",
"\n",
"If Ct is some repeating characters => choose 0 \n",
"Else => choose 1 \n",
"\n",
"This strategy will work every time thanks to monoalphabeticity"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

435
hw3/homework 3.ipynb Normal file
View File

@ -0,0 +1,435 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "04af88ae-4585-44f4-8a6b-e54ef1b369fc",
"metadata": {},
"source": [
"Ondřej Hladůvka"
]
},
{
"cell_type": "markdown",
"id": "81c9f10b-5df5-4187-9be5-913c536fdb27",
"metadata": {},
"source": [
"# Task 1\n",
"You are working in the company that uses RSA cryptosystem in their solutions.\n",
"You have been sent the following abstract for the scientific paper. Based on this, would your recommendation to your company and why? \n",
"<img src=\"Screenshot_11-Apr_12-46-16_5589.png\" width=\"400\" height=\"200\">"
]
},
{
"cell_type": "markdown",
"id": "19cec4fd-90ac-4255-9add-9a48879f5b89",
"metadata": {},
"source": [
"RSA key generation: \n",
"let $p,q$ be large primes \n",
"$n := p \\times q$ \n",
"let $e$ be integer $1 < e < \\text{Lcm}(\\varphi(p, q))$ \n",
"$d := e^{-1} \\pmod{\\varphi(n)}$ \n",
"\n",
"Private key := $(d, n)$ \n",
"Public key := $(e, n)$ \n",
"\n",
"------------------------------------\n",
"\n",
"It is correct that $\\varphi(n)$ for public $n$ is used to generate $d$ (using EEA), so attacker able to compute it could break an encryption.\n",
"\n",
"Another thing that attacker could do knowing $n$ and $\\varphi(n)$ is to compute primes $p, q$:\n",
"$$\n",
"\\varphi(n) = \\varphi(p \\times q) = (p-1)(q-1) = p \\times q - p - q + 1 = (n+1)-(p+q)\n",
"$$\n",
"$$\n",
"\\Rightarrow p+q = (n+1)-\\varphi(n)\n",
"\\,\\,\\,\\,\\, \\land \\,\\,\\,\\,\\,\n",
"p \\times q = n\n",
"$$\n",
"$$\n",
"\\Rightarrow p+q -(n+1)+\\varphi(n) = 0\n",
"\\,\\,\\,\\,\\, \\land \\,\\,\\,\\,\\,\n",
"p \\times q - n = 0\n",
"$$\n",
"this forms system of equations, \n",
"lets substitute $p := (n+1)-\\varphi(n) - q$:\n",
"$$\n",
"((n+1)-\\varphi(n) - q) \\times q - n = 0\n",
"$$\n",
"Solving for $q$:\n",
"$$\n",
"q = \\frac{n}{(n+1)-\\varphi(n)-q}\n",
"$$\n",
"$$\n",
"p = \\frac{n}{q} \\text{ (where } p \\text{ and } q \\text{ can be swapped)}\n",
"$$\n",
"\n",
"This proves that factorization of $n$ is trivial when $\\varphi(n)$ is known, thus computing $\\varphi(n)$ has to be at least as difficult as computing factorization of $n$\n",
"\n",
"And when we know primes $p$ and $q$, computing $\\varphi(n)$ is just $(p-1)(q-1)$ $\\Rightarrow$ computing $\\varphi(n)$ is as difficult as computing factorization of $n$ \n",
" \n",
"#### I would not make any change based on this arcicle, as RSA is based on diffclty of computing $\\varphi(n)$"
]
},
{
"cell_type": "markdown",
"id": "5748beac-4e59-4211-aa41-8175b332bef4",
"metadata": {},
"source": [
"# Task 2\n",
"Suppose you are given the following encryption scheme: \n",
"$KeyGen()$\n",
"1. Sample large prime number $p$\n",
"2. Compute modulus as $n := p^2$\n",
"3. Select $e$ to be integer such that \n",
"$Gcd(\\varphi(n), e) = 1 \n",
"\\,\\,\\,\\,\\, \\land \\,\\,\\,\\,\\,\n",
"2 < e < \\varphi(n)$\n",
"4. Calculate $d$ such that $e \\times d ≡ 1 \\, mod \\, \\varphi(n)$\n",
"5. Return private key $Sk := (d, n)$ and \n",
" public key $Pk = (e, n)$ \n",
"\n",
"$Enc(Pk, Pt)$\n",
"1. Compute ciphertext as $Ct = Pt^e \\, (mod \\,\\, n)$\n",
" \n",
"$Dec(Sk, Ct)$\n",
"1. Compute decryption as $Pt = Ct^d \\, (mod \\,\\, n)$\n",
"\n",
"provide an attack that shows that given encryption scheme is not secure with respect to the\n",
"IND-OT-CPA security definition."
]
},
{
"cell_type": "markdown",
"id": "3029803a-82e5-45a9-b5c9-a6373af60ee7",
"metadata": {},
"source": [
"#### Indistinguishability under One-Time Chosen Plaintext Attack:\n",
"1. Challenger generates a key $k$\n",
"1. Adversary submits two equal-length messages $m_0, m_1$\n",
"1. Challenger flips a random bit $b \\gets \\{0,1\\}$ and returns $Enc(k, m_b)$\n",
"1. Adversary guesses $b$ \n",
"The scheme is IND-OT-CPA secure if this advantage is negligible for all adversaries \n",
"-------------------------------------------\n",
"Knowing $n$ is square, adversary can calculate \n",
"$$\n",
"\\varphi(n) = n^2 - n\n",
"$$\n",
"there are $p^2$ total integers from $1$ to $p^2$ \n",
"out of these, the numbers that are not relatively prime to $p^2$ are the multiples of $p, 2p, 3p ... p^2$\n",
"and there are exactly $p$ such multiples. \n",
"\n",
"With $\\varphi(n)$ obtained, adversary can compute $d \\equiv e^{-1} (mod \\,\\, \\varphi(n))$ the same way challanger did. \n",
" \n",
"#### Attack\n",
"Adversary's strategy:\n",
"1. Adversary will sens two distinct messages $m_0, m_1$ and recieves compute $Ct$ and $Pk = (e, n)$\n",
"2. Computes $\\varphi(n) = n^2 - n$\n",
"3. Computes $d = e^{-1} \\, (mod \\,\\, \\varphi(n))$\n",
"4. Decrypts $Pt = Ct^d \\, (mod \\,\\, n)$\n",
"5. Comares $Pt$ against $m_0, m_1$ and select which plaintext was encrypted\n",
"\n",
"##### Adversary will win every time => scheme is not IND-OT-CPA secure"
]
},
{
"cell_type": "markdown",
"id": "b911e6e5-1a14-47d4-8322-4ee26318db8e",
"metadata": {},
"source": [
"# Task 3\n",
"#### Consider the ElGamal cryptosystem with a public key $h$ and a private key $x$ \n",
"\n",
"let cyclic group $G$ of order $q$, with generator $g$ and identity element $e$. And all operation on this group... \n",
"let message $m \\in G$ \n",
"public key $h := g^x$ \n",
"shared secret $s := h^y = (g^x)^y = g^{x \\times y}$ \n",
"$c_1 := g^y$ \n",
"$c_2 := m \\times s$"
]
},
{
"cell_type": "markdown",
"id": "f9d7ddb7-045e-434a-8af3-d3291a57e08c",
"metadata": {},
"source": [
"1. Assume that you are given a ciphertext $(c_1, c_2)$ encrypting an unknown message $m$. Show how you can generate a new ciphertext $(c_1', c_2')$ that encrypts the same $m$, but with different randomness $y'$ (without decrypting the ciphertext)"
]
},
{
"cell_type": "markdown",
"id": "d3202508-ecae-4fa8-af4f-b09b842f2bd3",
"metadata": {},
"source": [
"ElGamal decryption principle:\n",
"$$\n",
"s \\times c_1^{q-x} = g^{x \\times y} \\times {(g^y)}^{q-x} = g^{x \\times y} \\times g^{y(q-x)} = g^{x \\times y + y \\times q - x \\times y} = g^{y \\times q} = {(g^q)}^y = e^y = e\n",
"$$\n",
"$$\n",
"\\Rightarrow s^{-1} = c_1^{q-x}\n",
"$$\n",
"$$\n",
"m = c_2 \\times s^{-1} = m \\times s \\times s^{-1}\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "dc716837-53fb-4f8c-92d5-38ccdb49d317",
"metadata": {},
"source": [
"to get the same message from different ct\n",
"$$\n",
"m = c_2{'} \\times s^{-1}{'} = c_2{'} \\times ({c_1'})^{q-x}\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "28980583-2777-4a56-a4f4-9c251070eb80",
"metadata": {},
"source": [
"we can modify messages with any pair $k, l$ \n",
"$c_1{'} := c_1 \\times k$ \n",
"$c_2{'} := c_2 \\times l$\n",
"$$\n",
"m = c_2{'} \\times {(c_1{'})}^{q-x} = c_2 \\times l \\times {(c_1 \\times k)}^{q-x} = c_2 \\times l \\times {c_1}^{q-x} \\times {k}^{q-x}\n",
"$$\n",
"with relation $l \\times {k}^{q-x} = e$, but we dont know private exponent $x$\n"
]
},
{
"cell_type": "markdown",
"id": "c38e621f-392c-4b20-8102-8952c7fb2fc3",
"metadata": {},
"source": [
"this can be achived with $k := g^z$ for any choosen $z \\in G$\n",
"$$\n",
"c_1{'} = c_1 \\times g^z = g^y \\times g^z = g^{y+z}\n",
"$$ \n",
"$$\n",
"s{'} = c_1^{x} = {g}^{x(y+z)} = {g}^{xy+xz}\n",
"$$\n",
"$$\n",
"\\frac{c_2{'}}{c_2} = \\frac{m \\times s{'}}{m \\times s} = \\frac{s{'}}{s} = g^{xz} = \\frac{c_2 \\times l}{c_2} = l\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "71d98453-5695-4942-bee9-8441e95051b0",
"metadata": {},
"source": [
"2. Assume you are given ciphertext $c = (c1, c2)$ that you wants to decrypt, but you do not know corresponding private key $sk$. Suppose that you have a friend who provides you with the decryption of any other chosen ciphertext $c{'} \\not= c$ using private key $sk$. Show how can you decrypt $c$."
]
},
{
"cell_type": "markdown",
"id": "67b945b1-553a-405a-8daa-e797a3f9616f",
"metadata": {},
"source": [
"We can choose any $c'$ to decipher $m$\n",
"$$\n",
"\\frac{c_2}{c_2{'}} = \\frac{m \\times s}{m{'} \\times s} = \\frac{m}{m{'}}\n",
"$$\n",
"$$\n",
"\\Rightarrow m = m{'} \\times \\frac{c_2}{c_2{'}}\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "cd4f9b24-52d6-407d-a9e2-769b6dba6a54",
"metadata": {},
"source": [
"3. Assume you are given two ciphertexts $ct_1 = (c_{11}, c_{12})$ and $ct_2 = (c_{21}, c_{22})$ that correspond to some\n",
"plaintext messages (not known to you) $m_1$ and $m_2$. What information can you learn about $m_1$ and $m_2$, if you observe that $c_{11} = c_{21}$?"
]
},
{
"cell_type": "markdown",
"id": "b95d2854-1d8c-40f8-a69e-eb35f5d19ee8",
"metadata": {},
"source": [
"$$\n",
"1 = \\frac{c_{11}}{c_{12}} = \\frac{g^{y_1}}{g^{y_2}} = g^{y_1 - y_2}\n",
"$$\n",
"$$\n",
"\\Rightarrow y_1 = y_2\n",
"$$\n",
"$$\n",
"\\Rightarrow h^{y_1} = h^{y_2}\n",
"$$\n",
"$$\n",
"\\frac{c_{12}}{c_{22}} = \\frac{m_1 \\times h^{y_1}}{m_2 \\times h^{y_2}} = \\frac{m_1}{m_2}\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "44a536aa-8f2a-4234-a88e-ae020f560d94",
"metadata": {},
"source": [
"4. Bring an example of potential application of ElGamal encryption scheme, where homomorphic property is useful and another example, where it violates the desired security of the application. Justify your answer."
]
},
{
"cell_type": "markdown",
"id": "1a8ce5ba-477e-4be8-b6f1-697da610487a",
"metadata": {},
"source": [
"- Desired application could multiply messages from multiple senders and decrypt result to protect privacy of them but get the product of all \n",
"- Undesired applicatio would be for example online auction where adversary could manipulate offers"
]
},
{
"cell_type": "markdown",
"id": "a2238cd4-1944-4139-909c-ae984776d407",
"metadata": {},
"source": [
"# Task 4\n",
"You have intercepted two RSA ciphertexts $c_1 = 7$ and $c_2 = 16$ that correspond to the same plaintext a promo code for the video game. You know that those ciphertexts have been created using corresponding public keys $pk_1 = (e = 3, n = 57)$ and $pk_2 = (e = 5, n = 57)$. What is the promo code m from the intercepted ciphertext? \n",
"Note: for this attack, your task is not to find the private key!"
]
},
{
"cell_type": "markdown",
"id": "a8d3026a-1b29-4339-9548-d889871ad68e",
"metadata": {},
"source": [
"${\\lvert m^{3} \\rvert}_{57} \\equiv 7$ \n",
"${\\lvert m^{5} \\rvert}_{57} \\equiv 16$ "
]
},
{
"cell_type": "markdown",
"id": "e8358104-d161-4617-9f36-761e80cf6d63",
"metadata": {},
"source": [
"${\\lvert m^{3} \\rvert}_{57} \\equiv 16$ \n",
"${\\lvert 7 \\times m^{2} \\rvert}_{57} \\equiv 16$ \n",
"${\\lvert 7^{-1} \\times 7 \\times m^{2} \\rvert}_{57} \\equiv 16 \\times 7^{-1}$ \n",
"${\\lvert m^{2} \\rvert}_{57} \\equiv 43$ \n",
"${\\lvert \\sqrt{m} \\rvert}_{57} \\equiv \\{10, 28, 29, 47\\}$ "
]
},
{
"cell_type": "markdown",
"id": "82b4dbb3-218a-47a2-a623-8961451298cd",
"metadata": {},
"source": [
"${\\lvert {28}^{3} \\rvert}_{57} \\equiv 7$ \n",
"${\\lvert {28}^{5} \\rvert}_{57} \\equiv 16$ \n",
"$ m = 28$"
]
},
{
"cell_type": "markdown",
"id": "682d50fa-6ab4-4f8e-9c25-d11fea9f2b74",
"metadata": {},
"source": [
"# Task 5\n",
"Your company is building a product that heavily relies on\n",
"usage of cryptography. You receive the following list of security requirements for the system"
]
},
{
"cell_type": "markdown",
"id": "6fd52e32-8336-45a9-8f2b-ea7f741603e2",
"metadata": {},
"source": [
"1. System should ensure data confidentiality and integrity in transmission \n",
"**Scheme: TLS 1.3 with AES-256-GCM or ChaCha20-Poly1305 256-bit** \n",
" $\\to$ Both provide confidentiality and integrity in single pass \n",
" $\\to$ ChaCha20 is efficient in software and resistant to timing attacks \n",
" $\\to$ AES-256 ia accelerated on almost every CPU, AES-NI instructions mitigate side-channel risks \n",
" $\\to$ TLS 1.3 removes deprecated ciphers (RC4 etc..), but may not be supported on older platforms (typically embedded devices) \n",
" using TLS 1.2 and whitelisting only secure ciphers may be option too\n",
" \n",
"3. System should ensure data confidentiality and integrity at rest \n",
"**Scheme: AES-256-XTS with HMAC-SHA-256** \n",
" $\\to$ AES-256 is resistant to brute-force attacks (even with quantum computing, Grover's algorithm would require ~$2^128$ operations) \n",
" $\\to$ XTS Encrypts each sector independently to avoids performance penalties for random I/O operations, but keeps diffusion advantage of chaining modes \n",
" $\\to$ HMAC-SHA-256 ensures integrity and can be backupped separately to ensure backup wasnt tampered with\n",
" \n",
"3. System should enforce strong authentication mechanisms for users and services to ensure that only authorized entities can access the data \n",
"**Scheme for user authentication: pow password hashing + Ed25519** \n",
" $\\to$ Argon2id is designed to not be comutable on FPGA and can be configured (iterations, memory, parallelism) to match requrements\n",
" $\\to$ Passwords should be salted before hashing and never stored as plaintext \n",
" $\\to$ Ed25519 signature can be stored on hardware authenticator providing second factor to the password \n",
" **Scheme for service to service authentication: mTLS Ed25519 256bit** \n",
" $\\to$ Mutual certificate based authentication for every two points in infrastructure \n",
" $\\to$ Ed25519 with 256-bit key comparable secure as RSA with 3072-bit key, but much cheaper to compute - saving cost on the infrastrucure \n",
"4. System must be resistant to common attacks, including side-channel attacks and brute force attacks, using strong cryptographic primitives and practices \n",
"**Mitigation of common attacks:** \n",
" $\\to$ AES-NI instructions to resis power analysis with 256-bit key to resis brute force \n",
" $\\to$ TLS 1.3 insted of 1.2 to not even include insecure schemes in the transport protocol \n",
" $\\to$ XTS mode and HMAC to mitigate tampering with data at rest\n",
" $\\to$ Argon2id for password hashing and salting to resist dictionary and bruteforce FPGA attacks in case hashes got leaked \n",
" $\\to$ Ed25519 to resist simple RSA power analysis "
]
},
{
"cell_type": "markdown",
"id": "2226a20b-4e40-4f57-881f-9ba9658ce358",
"metadata": {},
"source": [
"## Bonus Task\n",
"Show that exponential ElGamal (where the ciphertext is constructed as $c = (c_1, c_2) = (g^y, g^m \\times s)$ is not IND-CCA2 secure. You are allowed to make single encryption query and single decryption\n",
"query to the challenger."
]
},
{
"cell_type": "markdown",
"id": "cc53f0ce-b56b-4560-ab2a-ead78a0f80a9",
"metadata": {},
"source": [
"#### Indistinguishability under adaptive chosen-ciphertext attack \n",
"1. The challenger generates a key pair $Pk, Sk$, and publishes $PK$ to the adversary\n",
"2. The adversary may perform any number of calls to the encryptions and decryption oracle based on arbitrary ciphertexts\n",
"3. Eventually, the adversary submits two distinct chosen plaintexts $m_0, m_1$ to the challenger.\n",
"4. The challenger selects a bit $b \\gets \\{0, 1\\}$ uniformly at random, and sends the ciphertext $c = E(Pk, M_b)$ back\n",
"5. The adversary is free to perform any number of additional computations or encryptions and may make further calls to the decryption oracle\n",
"7. Adversary guesses $b$\n",
" \n",
"A scheme is IND-CCA2secure secure if this advantage is negligible for all adversaries"
]
},
{
"cell_type": "markdown",
"id": "b89d823e-919a-4426-a860-9474b55918a5",
"metadata": {},
"source": [
"#### Adversary's startegy\n",
"1. Challenger computes a public key $h := g^x$\n",
"2. Adversary selects two messages $m_0, m_1$\n",
"3. Challenger responds with $Ct = (c_0, c_1) = (g^y, g^{m_b} \\times h^y)$\n",
"4. Adversary chooses $k \\in N$ computes and submits $Ct{'} := (c_0, c_1 \\times g^k)$ for decryption\n",
"5. Oracle returns $D(Ct{'}) = \\frac{c_1 \\times g^k}{{c_0}^x} = \\frac{g^{m_b} \\times h^y \\times g^k}{g^{y \\times x}} = \\frac {g^{m_b} \\times h^y \\times g^k}{h^y} = g^{m_b + k}$\n",
"6. Adversary computes $g^{m_0 + k}$ and $g^{m_1 + k}$, compares them to decrypted $Ct{'}$\n",
"since $m_0, m_1, k$ are known to the Adversary, he will always succeed $\\Rightarrow$ exponential ElGamal is not IND-CCA2 secure"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

5
hw3/run.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
docker run -p 8888:8888 \
-v "$(pwd)":/work \
jupyter

7
hw4/Makefile Normal file
View File

@ -0,0 +1,7 @@
all: reseni.pdf
ieee.cls:
curl -O https://raw.githubusercontent.com/citation-style-language/styles/master/ieee.csl
reseni.pdf: reseni.md
pandoc reseni.md --citeproc -o reseni.pdf

512
hw4/ieee.csl Normal file
View File

@ -0,0 +1,512 @@
<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only">
<info>
<title>IEEE</title>
<id>http://www.zotero.org/styles/ieee</id>
<link href="http://www.zotero.org/styles/ieee" rel="self"/>
<!-- <link href="https://ieeeauthorcenter.ieee.org/wp-content/uploads/IEEE-Reference-Guide.pdf" rel="documentation"/> - 2018 guidelines -->
<link href="http://journals.ieeeauthorcenter.ieee.org/wp-content/uploads/sites/7/IEEE_Reference_Guide.pdf" rel="documentation"/>
<link href="https://journals.ieeeauthorcenter.ieee.org/your-role-in-article-production/ieee-editorial-style-manual/" rel="documentation"/>
<author>
<name>Michael Berkowitz</name>
<email>mberkowi@gmu.edu</email>
</author>
<contributor>
<name>Julian Onions</name>
<email>julian.onions@gmail.com</email>
</contributor>
<contributor>
<name>Rintze Zelle</name>
<uri>http://twitter.com/rintzezelle</uri>
</contributor>
<contributor>
<name>Stephen Frank</name>
<uri>http://www.zotero.org/sfrank</uri>
</contributor>
<contributor>
<name>Sebastian Karcher</name>
</contributor>
<contributor>
<name>Giuseppe Silano</name>
<email>g.silano89@gmail.com</email>
<uri>http://giuseppesilano.net</uri>
</contributor>
<contributor>
<name>Patrick O'Brien</name>
</contributor>
<contributor>
<name>Brenton M. Wiernik</name>
</contributor>
<contributor>
<name>Oliver Couch</name>
<email>oliver.couch@gmail.com</email>
</contributor>
<category citation-format="numeric"/>
<category field="engineering"/>
<category field="generic-base"/>
<summary>IEEE style as per the 2023 guidelines, V 11.29.2023.</summary>
<updated>2024-03-27T11:41:27+00:00</updated>
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
</info>
<locale xml:lang="en">
<date form="text">
<date-part name="month" form="short" suffix=" "/>
<date-part name="day" form="numeric-leading-zeros" suffix=", "/>
<date-part name="year"/>
</date>
<terms>
<term name="chapter" form="short">ch.</term>
<term name="chapter-number" form="short">ch.</term>
<term name="presented at">presented at the</term>
<term name="available at">available</term>
</terms>
</locale>
<!-- Macros -->
<macro name="status">
<choose>
<if variable="page issue volume" match="none">
<text variable="status" text-case="capitalize-first" suffix="" font-weight="bold"/>
</if>
</choose>
</macro>
<macro name="edition">
<choose>
<if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
<choose>
<if is-numeric="edition">
<group delimiter=" ">
<number variable="edition" form="ordinal"/>
<text term="edition" form="short"/>
</group>
</if>
<else>
<text variable="edition" text-case="capitalize-first" suffix="."/>
</else>
</choose>
</if>
</choose>
</macro>
<macro name="issued">
<choose>
<if type="article-journal report" match="any">
<date variable="issued">
<date-part name="month" form="short" suffix=" "/>
<date-part name="year" form="long"/>
</date>
</if>
<else-if type="bill book chapter graphic legal_case legislation song thesis" match="any">
<date variable="issued">
<date-part name="year" form="long"/>
</date>
</else-if>
<else-if type="paper-conference" match="any">
<date variable="issued">
<date-part name="month" form="short"/>
<date-part name="year" prefix=" "/>
</date>
</else-if>
<else-if type="motion_picture" match="any">
<date variable="issued" form="text" prefix="(" suffix=")"/>
</else-if>
<else>
<date variable="issued" form="text"/>
</else>
</choose>
</macro>
<macro name="author">
<names variable="author">
<name and="text" et-al-min="7" et-al-use-first="1" initialize-with=". "/>
<label form="short" prefix=", " text-case="capitalize-first"/>
<et-al font-style="italic"/>
<substitute>
<names variable="editor"/>
<names variable="translator"/>
<text macro="director"/>
</substitute>
</names>
</macro>
<macro name="editor">
<names variable="editor">
<name initialize-with=". " delimiter=", " and="text"/>
<label form="short" prefix=", " text-case="capitalize-first"/>
</names>
</macro>
<macro name="director">
<names variable="director">
<name and="text" et-al-min="7" et-al-use-first="1" initialize-with=". "/>
<et-al font-style="italic"/>
</names>
</macro>
<macro name="locators">
<group delimiter=", ">
<text macro="edition"/>
<group delimiter=" ">
<text term="volume" form="short"/>
<number variable="volume" form="numeric"/>
</group>
<group delimiter=" ">
<number variable="number-of-volumes" form="numeric"/>
<text term="volume" form="short" plural="true"/>
</group>
<group delimiter=" ">
<text term="issue" form="short"/>
<number variable="issue" form="numeric"/>
</group>
</group>
</macro>
<macro name="title">
<choose>
<if type="bill book graphic legal_case legislation motion_picture song standard software" match="any">
<text variable="title" font-style="italic"/>
</if>
<else>
<text variable="title" quotes="true"/>
</else>
</choose>
</macro>
<macro name="publisher">
<choose>
<if type="bill book chapter graphic legal_case legislation motion_picture paper-conference song" match="any">
<group delimiter=": ">
<text variable="publisher-place"/>
<text variable="publisher"/>
</group>
</if>
<else>
<group delimiter=", ">
<text variable="publisher"/>
<text variable="publisher-place"/>
</group>
</else>
</choose>
</macro>
<macro name="event">
<choose>
<!-- Published Conference Paper -->
<if type="paper-conference speech" match="any">
<choose>
<if variable="container-title" match="any">
<group delimiter=" ">
<text term="in"/>
<text variable="container-title" font-style="italic"/>
</group>
</if>
<!-- Unpublished Conference Paper -->
<else>
<group delimiter=" ">
<text term="presented at"/>
<text variable="event"/>
</group>
</else>
</choose>
</if>
</choose>
</macro>
<macro name="access">
<choose>
<if type="webpage post post-weblog" match="any">
<!-- https://url.com/ (accessed Mon. DD, YYYY). -->
<choose>
<if variable="URL">
<group delimiter=". " prefix=" ">
<group delimiter=": ">
<text term="accessed" text-case="capitalize-first"/>
<date variable="accessed" form="text"/>
</group>
<text term="online" prefix="[" suffix="]" text-case="capitalize-first"/>
<group delimiter=": ">
<text term="available at" text-case="capitalize-first"/>
<text variable="URL"/>
</group>
</group>
</if>
</choose>
</if>
<else-if match="any" variable="DOI">
<!-- doi: 10.1000/xyz123. -->
<text variable="DOI" prefix=" doi: " suffix="."/>
</else-if>
<else-if variable="URL">
<!-- Accessed: Mon. DD, YYYY. [Medium]. Available: https://URL.com/ -->
<group delimiter=". " prefix=" " suffix=". ">
<!-- Accessed: Mon. DD, YYYY. -->
<group delimiter=": ">
<text term="accessed" text-case="capitalize-first"/>
<date variable="accessed" form="text"/>
</group>
<!-- [Online Video]. -->
<group prefix="[" suffix="]" delimiter=" ">
<choose>
<if variable="medium" match="any">
<text variable="medium" text-case="capitalize-first"/>
</if>
<else>
<text term="online" text-case="capitalize-first"/>
<choose>
<if type="motion_picture">
<text term="video" text-case="capitalize-first"/>
</if>
</choose>
</else>
</choose>
</group>
</group>
<!-- Available: https://URL.com/ -->
<group delimiter=": " prefix=" ">
<text term="available at" text-case="capitalize-first"/>
<text variable="URL"/>
</group>
</else-if>
</choose>
</macro>
<macro name="page">
<choose>
<if type="article-journal" variable="number" match="all">
<group delimiter=" ">
<text value="Art."/>
<text term="issue" form="short"/>
<text variable="number"/>
</group>
</if>
<else>
<group delimiter=" ">
<label variable="page" form="short"/>
<text variable="page"/>
</group>
</else>
</choose>
</macro>
<macro name="citation-locator">
<group delimiter=" ">
<choose>
<if locator="page">
<label variable="locator" form="short"/>
</if>
<else>
<label variable="locator" form="short" text-case="capitalize-first"/>
</else>
</choose>
<text variable="locator"/>
</group>
</macro>
<macro name="geographic-location">
<group delimiter=", " suffix=".">
<choose>
<if variable="publisher-place">
<text variable="publisher-place" text-case="title"/>
</if>
<else-if variable="event-place">
<text variable="event-place" text-case="title"/>
</else-if>
</choose>
</group>
</macro>
<!-- Series -->
<macro name="collection">
<choose>
<if variable="collection-title" match="any">
<text term="in" suffix=" "/>
<group delimiter=", " suffix=". ">
<text variable="collection-title"/>
<text variable="collection-number" prefix="no. "/>
<text variable="volume" prefix="vol. "/>
</group>
</if>
</choose>
</macro>
<!-- Citation -->
<citation>
<sort>
<key variable="citation-number"/>
</sort>
<layout delimiter=", ">
<group prefix="[" suffix="]" delimiter=", ">
<text variable="citation-number"/>
<text macro="citation-locator"/>
</group>
</layout>
</citation>
<!-- Bibliography -->
<bibliography entry-spacing="0" second-field-align="flush">
<layout>
<!-- Citation Number -->
<text variable="citation-number" prefix="[" suffix="]"/>
<!-- Author(s) -->
<text macro="author" suffix=", "/>
<!-- Rest of Citation -->
<choose>
<!-- Specific Formats -->
<if type="article-journal">
<group delimiter=", ">
<text macro="title"/>
<text variable="container-title" font-style="italic" form="short"/>
<text macro="locators"/>
<text macro="page"/>
<text macro="issued"/>
<text macro="status"/>
</group>
<choose>
<if variable="URL DOI" match="none">
<text value="."/>
</if>
<else>
<text value=","/>
</else>
</choose>
<text macro="access"/>
</if>
<else-if type="paper-conference speech" match="any">
<group delimiter=", " suffix=", ">
<text macro="title"/>
<text macro="event"/>
<text macro="editor"/>
</group>
<text macro="collection"/>
<group delimiter=", " suffix=".">
<text macro="publisher"/>
<text macro="issued"/>
<text macro="page"/>
<text macro="status"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="chapter">
<group delimiter=", " suffix=".">
<text macro="title"/>
<group delimiter=" ">
<text term="in" suffix=" "/>
<text variable="container-title" font-style="italic"/>
</group>
<text macro="locators"/>
<text macro="editor"/>
<text macro="collection"/>
<text macro="publisher"/>
<text macro="issued"/>
<group delimiter=" ">
<label variable="chapter-number" form="short"/>
<text variable="chapter-number"/>
</group>
<text macro="page"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="report">
<group delimiter=", " suffix=".">
<text macro="title"/>
<text macro="publisher"/>
<group delimiter=" ">
<text variable="genre"/>
<text variable="number"/>
</group>
<text macro="issued"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="thesis">
<group delimiter=", " suffix=".">
<text macro="title"/>
<text variable="genre"/>
<text macro="publisher"/>
<text macro="issued"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="software">
<group delimiter=". " suffix=".">
<text macro="title"/>
<text macro="issued" prefix="(" suffix=")"/>
<text variable="genre"/>
<text macro="publisher"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="article">
<group delimiter=", " suffix=".">
<text macro="title"/>
<text macro="issued"/>
<group delimiter=": ">
<text macro="publisher" font-style="italic"/>
<text variable="number"/>
</group>
</group>
<text macro="access"/>
</else-if>
<else-if type="webpage post-weblog post" match="any">
<group delimiter=", " suffix=".">
<text macro="title"/>
<text variable="container-title"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="patent">
<group delimiter=", ">
<text macro="title"/>
<text variable="number"/>
<text macro="issued"/>
</group>
<text macro="access"/>
</else-if>
<!-- Online Video -->
<else-if type="motion_picture">
<text macro="geographic-location" suffix=". "/>
<group delimiter=", " suffix=".">
<text macro="title"/>
<text macro="issued"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="standard">
<group delimiter=", " suffix=".">
<text macro="title"/>
<group delimiter=" ">
<text variable="genre"/>
<text variable="number"/>
</group>
<text macro="geographic-location"/>
<text macro="issued"/>
</group>
<text macro="access"/>
</else-if>
<!-- Generic/Fallback Formats -->
<else-if type="bill book graphic legal_case legislation report song" match="any">
<group delimiter=", " suffix=". ">
<text macro="title"/>
<text macro="locators"/>
</group>
<text macro="collection"/>
<group delimiter=", " suffix=".">
<text macro="publisher"/>
<text macro="issued"/>
<text macro="page"/>
</group>
<text macro="access"/>
</else-if>
<else-if type="article-magazine article-newspaper broadcast interview manuscript map patent personal_communication song speech thesis webpage" match="any">
<group delimiter=", " suffix=".">
<text macro="title"/>
<text variable="container-title" font-style="italic"/>
<text macro="locators"/>
<text macro="publisher"/>
<text macro="page"/>
<text macro="issued"/>
</group>
<text macro="access"/>
</else-if>
<else>
<group delimiter=", " suffix=". ">
<text macro="title"/>
<text variable="container-title" font-style="italic"/>
<text macro="locators"/>
</group>
<text macro="collection"/>
<group delimiter=", " suffix=".">
<text macro="publisher"/>
<text macro="page"/>
<text macro="issued"/>
</group>
<text macro="access"/>
</else>
</choose>
</layout>
</bibliography>
</style>

226
hw4/reseni.md Normal file
View File

@ -0,0 +1,226 @@
---
title: Analysis of Electronic Resident Identity Card proposal
author: Ondřej Hladůvka
documentclass: extarticle
classoption: 10pt
geometry: "left=3.5cm,right=3.5cm,top=1cm,bottom=1cm,includeheadfoot"
# disable word splitting
header-includes: \hyphenpenalty=10000
# references
csl: ieee.csl
link-citations: true
references:
- id: rc4
container-title: "RFC 7465 Prohibiting RC4 Cipher Suites"
type: report
genre: RFC
number: 7465
author: Andrei Popov
issued: 2015
URL: https://datatracker.ietf.org/doc/html/rfc7465
- id: des
container-title: RFC 4772 Security Implications of Using the Data Encryption Standard (DES)
type: report
genre: RFC
number: 4772
author: Scott G. Kelly
issued: 2006
URL: https://datatracker.ietf.org/doc/html/rfc4772
- id: rsa-pss
container-title: RFC 3447 Public-Key Cryptography Standards (PKCS) \#1
type: report
genre: RFC
number: 3447
author: Jakob Jonsson and Burt Kaliski
issued: 2003
URL: https://datatracker.ietf.org/doc/html/rfc3447#section-8.1
- id: elgamal
title: A Public-Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms
author: Taher Elgamal
container-title: IEEE Transactions on Information Theory
volume: 31
issue: 4
page: 469-472
type: article
issued: 1985
DOI: 10.1109/TIT.1985.1057074
- id: SHA3
title: "SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash, and ParallelHash"
type: report
genre: NIST Special Publication
number: 800-185
publisher: National Institute of Standards and Technology (NIST)
author:
- Kelsey John
- Chang Shu-jen
- Perlner Ray
issued: 2016
URL: https://doi.org/10.6028/NIST.SP.800-185
- id: ecdsa
type: report
title: Module-Lattice-Based Digital Signature Standard (ML-DSA)
collection-title: FIPS 204
publisher: National Institute of Standards and Technology (NIST)
issued: 2024
URL: https://doi.org/10.6028/NIST.FIPS.204
- id: luov
type: report
title: Status Report on the Second Round of the NIST Post-Quantum Cryptography Standardization Process Section 3.24
collection-title: NIST Interagency or Internal Report (NISTIR) 8309
publisher: National Institute of Standards and Technology (NIST)
issued: 2020
author:
- Alkemade Nicky
- Alperin-Sheriff Joel
- Apon Daniel
- Cooper David
- Dang Quynh
- Kelsey John
- Licht Sean
- Liu Yi-Kai
- Miller Dustin Moody
- Peralta Rene
- Perlner Ray
- Smith-Tone David
- Alagic Gorjan
URL: https://nvlpubs.nist.gov/nistpubs/ir/2020/NIST.IR.8309.pdf
- id: clone-attack
type: article-journal
title: Android Data-Clone Attack via Operating System Customization
author:
- Song Wenna
- Ming Jiang
- Jiang Lin
- Yan Han
- Xiang Yi
- Chen Yuan
- Fu Jianming
- Peng Guojun
issued: 2020
container-title: IEEE Access
page: 184708184720
DOI: 10.1109/ACCESS.2020.3035089
URL: https://ieeexplore.ieee.org/document/9246570
- id: owasp-auth
type: report
title: Authentication Cheat Sheet
collection-title: OWASP Cheat Sheet Series
publisher: Open Web Application Security Project (OWASP)
issued: 2023
URL: https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
- id: luov-attack
type: article
title: "The Nested Subset Differential Attack: A Practical Direct Attack Against LUOV which Forges a Signature within 210 Minutes"
author: Beullens Ward
publisher: International Association for Cryptologic Research (IACR)
collection-title: IACR Cryptology ePrint Archive
issued: 2020
URL: https://eprint.iacr.org/2020/967
---
<!-- Does the system proposed in the paper satisfy all the stated system requirements Provide a short explanation and reasoning for each requirement. -->
<!-- Identify if there are additional inconsistencies in the system or in the system description -->
<!--Provide conclusion, summarising if the system should be implemented as a real-life project. -->
## Introduction
This analysis evaluates proposed e-ID system's compliance agains given criteria.
## Proposed requirements compliance
<!-- done -->
### The system must manage encryption keys and signing keys securely, including usage of Hardware Security Modules (HSMs) where applicable
Not met. Usage of HSM is not even mentioned outside of section 2.2. thus it si certainly not enforced.
<!-- done -->
### The e-ID data must be encrypted using strong, industry-standard encryption algorithms
Not met. Section 2.3 describes encryption of the e-ID credential by the issuer with:
DES[@des] and RC4[@rc4] which are insecure.
SHA3 which is a hash family[@SHA3], not encryption.
RSA-PSS which is signature algorithm[@rsa-pss], not encryption.
And ElGamal-OFB which is not a block cipher[@elgamal], thus its not standardized in OFB mode
<!-- done -->
### The system should rely on use of digital signatures to verify the authenticity of the e-ID data and to ensure that the data has not been tampered with
Partially met.
LUOV/ECDSA signatures are proposed, but the issuers signature on the e-ID is not explicitly verified by RPs.
<!-- done -->
### The system must ensure that e-ID that was not created by the issuer does not pass verification by the RP
Not met.
In Presentation protocol step 8 RPs only check for "meaningful plaintext," not issuer signatures, enabling tampering and unauthorised access.
<!-- done -->
### The system must ensure post-quantum security for all the components
Not met.
ECDSA is vulnerable to Shors algorithm, as confirming by NIST PQC standardization [@ecdsa]. But its still proposed in both issuing and presentation protocols.
<!-- done -->
### The system must use standardised cryptographic algorithms
Not met.
LUOV is not standardized and was rulled out by NIST[@luov].
Voulnabirities was found[@luov-attack] and proposal does not mention any mitigation.
DES[@des] and RC4[@rc4] are deprecated.
<!-- done -->
### The system must ensure that attackers getting access to the users device are not able present honest users credential to the RP
Not met.
System lacks device-level authentication or any other second factor, allowing attackers to present credentials.
<!-- done -->
### The system must ensure strong user authentication before credential is issued
Not met.
System proposes just photo verification which is weak and unrealiable[@owasp-auth]. No multi-factor authentication is required.
<!-- done -->
### The system must ensure that adversary cloning the mobile device memory, does not gain access to user private information
Not met.
Private keys arent explicitly stored in HSM, thus they are vulnerable to memory cloning[@clone-attack].
<!-- done -->
### The system must ensure that adversary cloning the mobile device memory is not able to issue revocation, issuing and presentation requests (without active participation of user)
Not met.
Revocation requires no user verification enabling misuse by attackers.
## Additional notes
### Insecure Communication
Section 2.2 proposes to send all the information over
public communication channel without TLS, this is a critical flaw.
### Offline Revocation
Users can self-revoke/modify e-IDs without issuer, risking fraud.
### Unencrypted Cloud Storage
Lack of encryption at rest for cloud storage of e-IDs
risks data breach.
### Denial of service
System do not restrict the number of field in the credentials, risking overload by maliciously large input.
## Conclusion
Proposal makes several false claims, proposes usage of deprecated (DES, RC4) as well as experimental ciphers (LUOV).
Does not enforce HSM usage, multifactor authentication and data at rest encryption.
It also fails at choosing standardised ciphers and does not enforce post-quantum cryptography.
And is by design vulnarable to denial of service.
**I do not recommend system implementation until these issues are resolved as it would not improve security compared to present system.**
\newpage <!-- inline latex commands :3 -->
## References
<!-- these will be generated automatically by citeproc -->

BIN
hw4/reseni.pdf Normal file

Binary file not shown.