hw3
This commit is contained in:
parent
e5d8cd6214
commit
b8056c084c
|
@ -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, m∣∣m′) = 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, m∣∣m′) = 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, m∣∣m′) = F(k, 0∣∣m) ⊕ F(k, m′∣∣1), where m, m′∈ {0, 1}^(n−1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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^(n−1)) ⊕ F(k,0^(n−1)||1)) ⊕ (F(k,0||0^(n−1)) ⊕ F(k,1^(n−1||1)) \n",
|
||||
"y_1 ⊕ y_2 = F(k,0||1^(n−1)) ⊕ F(k,1^(n−1||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 n−block message m = m1∣∣m2∣∣. . .∣∣m_n by some block cipher E in\n",
|
||||
"CFB mode. Let use denote ciphertext produced by E as c = c1∣∣c2∣∣. . .∣∣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 |
|
@ -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-CCA2–secure 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
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
docker run -p 8888:8888 \
|
||||
-v "$(pwd)":/work \
|
||||
jupyter
|
Loading…
Reference in New Issue