This shows you the differences between two versions of the page.
sasc:laboratoare:04 [2016/03/14 21:24] sergiu.costea [Exercise 1] |
sasc:laboratoare:04 [2017/03/16 16:21] (current) marios.choudary |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Lab 04 ===== | + | ===== Lab 04 - PRGs, PRFs and PRPs ===== |
Line 6: | Line 6: | ||
http://cs.curs.pub.ro/2014/pluginfile.php/13095/mod_resource/content/1/sasc_curs4.pdf | http://cs.curs.pub.ro/2014/pluginfile.php/13095/mod_resource/content/1/sasc_curs4.pdf | ||
- | ==== Exercise 1 ==== | + | ==== Exercise 1 (4p) ==== |
- | Let $F : K × X \to Y$ be a secure PRF with $K = X = Y = \{0, 1\}^{n}$. | + | Advantage. The purpose of this problem is to clarify the concept of advantage. Consider the following two experiments $\mathsf{EXP}(0)$ and $\mathsf{EXP}(1)$: |
+ | * In $\mathsf{EXP}(0)$ the challenger flips a fair coin (probability $1/2$ for HEADS and $1/2$ for TAILS) and sends the result to the adversary $\mathsf{A}$. | ||
+ | * In $\mathsf{EXP}(1)$ the challenger always sends TAILS to the adversary. | ||
- | * a) Show that $F_1(k,x) = F(k,x) \| 0$ is not a secure PRF. (for strings $y$ and $z$ we use $y \| z$ to denote the concatenation of $y$ and $z$) | + | Let r = 0 for HEADS and r = 1 for TAILS. Then we have the experiment as shown below: |
- | * b) Prove that $F_2(k, x) = F \left(k, x \oplus 1^{n}\right)$ is a secure PRF. Here $x \oplus 1^{n}$ is the bit-wise complement of $x$. To prove security argue the contra-positive: a distinguisher $A$ that breaks $F_2$ implies a distinguisher $B$ that breaks $F$ and whose running time is about the same as $A$’s. | + | {{:sasc:laboratoare:adversar_prg.png?400|}} |
- | * c) Let $K_3 = \{0, 1\}^{n+1}$. Construct a new PRF $F_3 : K_3 \times X \to Y$ with the following property: the PRF $F_3$ is secure, however if the adversary learns the last bit of the key then the PRF is no longer secure. This shows that leaking even a single bit of the secret key can completely destroy the PRF security property. | + | |
- | <note tip> | + | |
- | Hint: Let $k_3 = k \| b$ where $k \in \{0,1\}^{n}$ and $b \in \{0,1\}$. Set $F_3(k_3,x)$ to be the same as $F (k, x)$ for all $x \neq 0^{n}$. Define $F_3\left(k_3, 0^{n}\right)$ so that $F_3$ is a secure PRF, but becomes easily distinguishable from a random function if the last bit of the secret key $k_3$ is known to the adversary. Prove that your $F_3$ is a secure PRF by arguing the contra-positive, as in part (b). | + | |
- | </note> | + | |
- | * d) Construct a new PRF $F_4 : K_2 × X \to Y$ that remains secure if the attacker learns any single bit of the key. Your function $F_2$ may only call $F$ once. Briefly explain why your PRF remains secure if any single bit of the key is leaked. | + | |
- | ==== Exercise 2 ==== | + | The adversary’s goal is to distinguish these two experiments: at the end of each experiment the adversary outputs a bit $0$ or $1$ for its guess for which experiment it is in. For $b = 0,1$ let $W_{b}$ be the event that in experiment $b$ the adversary output $1$. The adversary tries to maximize its distinguishing advantage, namely the quantity |
+ | $\mathsf{Adv} = \left| \mathsf{Pr}\left[W_{0}\right] − \mathsf{Pr}\left[W_{1}\right] \right| \in \left[0, 1\right]$ . | ||
- | Let's analyse some substitution-permutation networks (SPN). | + | The advantage $\mathsf{Adv}$ captures the adversary’s ability to distinguish the two experiments. If the advantage is $0$ then the adversary behaves exactly the same in both experiments and therefore does not distinguish between them. If the advantage is $1$ then the adversary can tell perfectly what experiment it is in. If the advantage is negligible for all efficient adversaries (as defined in class) then we say that the two experiments are indistinguishable. |
- | === SPN 1 === | + | Calculate the advantage of each of the following adversaries: |
+ | * A1: Always output $1$. | ||
+ | * A2: Ignore the result reported by the challenger, and randomly output $0$ or $1$ with even probability. | ||
+ | * A3: Output $1$ if HEADS was received from the challenger, else output $0$. | ||
+ | * A4: Output $0$ if HEADS was received from the challenger, else output $1$. | ||
+ | * A5: If HEADS was received, output $1$. If TAILS was received, randomly output $0$ or $1$ with even probability. | ||
- | We have the SPN from this figure: | ||
- | {{:sasc:laboratoare:spn_1r_reduced_2s.png|}} | ||
- | where S denotes the AES S-box (we'll discuss this in some detail during the next lecture), and 'Permutation' is a simple permutation block that simply shifts the input 4 bits to the right as in a queue. Both this S-box and the permutation are invertible and known by the attacker (you). Each input (x1, x2) is 8-bit (1 byte), as well as the keys k1, k2, and the outputs y1, y2. | + | ==== Exercise 2 (4p) ==== |
- | - How can you find the key ? | + | Let $F : K × X \to Y$ be a secure PRF with $K = X = Y = \{0, 1\}^{n}$. |
- | - Given the message/ciphertext pair ('Hi' - as characters, 0xba52 - as hex number), find the key bytes k1 and k2. Print them in ascii. | + | |
+ | * a) Show that $F_1(k,x) = F(k,x) \| 0$ is not a secure PRF. (for strings $y$ and $z$ we use $y \| z$ to denote the concatenation of $y$ and $z$) | ||
+ | * b) Prove that $F_2(k, x) = F \left(k, x \oplus 1^{n}\right)$ is a secure PRF. Here $x \oplus 1^{n}$ is the bit-wise complement of $x$. To prove security argue the contra-positive: a distinguisher $A$ that breaks $F_2$ implies a distinguisher $B$ that breaks $F$ and whose running time is about the same as $A$’s. | ||
+ | * c) Let $K_3 = \{0, 1\}^{n+1}$. Construct a new PRF $F_3 : K_3 \times X \to Y$ with the following property: the PRF $F_3$ is secure, however if the adversary learns the last bit of the key then the PRF is no longer secure. This shows that leaking even a single bit of the secret key can completely destroy the PRF security property. | ||
<note tip> | <note tip> | ||
- | For these exercises you can use the following helper/starter code: | + | Hint: Let $k_3 = k \| b$ where $k \in \{0,1\}^{n}$ and $b \in \{0,1\}$. Set $F_3(k_3,x)$ so that $F_3$ is a secure PRF, but becomes easily distinguishable from a random function if the last bit of the secret key $k_3$ is known to the adversary. Prove that your $F_3$ is a secure PRF by arguing the contra-positive, as in part (b). |
</note> | </note> | ||
- | <code> | + | ==== Exercise 3 (2p) ==== |
- | import sys | + | |
- | import random | + | |
- | import string | + | |
- | import operator | + | |
- | # Rijndael S-box | + | Let $F : K × X \to Y$ be a secure PRF with $K = X = Y = \{0, 1\}^{n}$. |
- | sbox = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, | + | |
- | 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, | + | |
- | 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, | + | |
- | 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, | + | |
- | 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, | + | |
- | 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, | + | |
- | 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, | + | |
- | 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, | + | |
- | 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, | + | |
- | 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, | + | |
- | 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, | + | |
- | 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, | + | |
- | 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, | + | |
- | 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, | + | |
- | 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, | + | |
- | 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, | + | |
- | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, | + | |
- | 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, | + | |
- | 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, | + | |
- | 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, | + | |
- | 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, | + | |
- | 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, | + | |
- | 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, | + | |
- | 0x54, 0xbb, 0x16] | + | |
- | + | ||
- | + | ||
- | # Rijndael Inverted S-box | + | |
- | rsbox = [0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, | + | |
- | 0x9e, 0x81, 0xf3, 0xd7, 0xfb , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, | + | |
- | 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb , 0x54, | + | |
- | 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, | + | |
- | 0x42, 0xfa, 0xc3, 0x4e , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, | + | |
- | 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 , 0x72, 0xf8, | + | |
- | 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, | + | |
- | 0x65, 0xb6, 0x92 , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, | + | |
- | 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 , 0x90, 0xd8, 0xab, | + | |
- | 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, | + | |
- | 0x45, 0x06 , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, | + | |
- | 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b , 0x3a, 0x91, 0x11, 0x41, | + | |
- | 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, | + | |
- | 0x73 , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, | + | |
- | 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e , 0x47, 0xf1, 0x1a, 0x71, 0x1d, | + | |
- | 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b , | + | |
- | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, | + | |
- | 0xfe, 0x78, 0xcd, 0x5a, 0xf4 , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, | + | |
- | 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f , 0x60, | + | |
- | 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, | + | |
- | 0x93, 0xc9, 0x9c, 0xef , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, | + | |
- | 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 , 0x17, 0x2b, | + | |
- | 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, | + | |
- | 0x21, 0x0c, 0x7d] | + | |
- | + | ||
- | def strxor(a, b): # xor two strings (trims the longer input) | + | |
- | return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)]) | + | |
- | + | ||
- | def hexxor(a, b): # xor two hex strings (trims the longer input) | + | |
- | ha = a.decode('hex') | + | |
- | hb = b.decode('hex') | + | |
- | return "".join([chr(ord(x) ^ ord(y)).encode('hex') for (x, y) in zip(ha, hb)]) | + | |
- | + | ||
- | def bitxor(a, b): # xor two bit strings (trims the longer input) | + | |
- | return "".join([str(int(x)^int(y)) for (x, y) in zip(a, b)]) | + | |
- | + | ||
- | def str2bin(ss): | + | |
- | """ | + | |
- | Transform a string (e.g. 'Hello') into a string of bits | + | |
- | """ | + | |
- | bs = '' | + | |
- | for c in ss: | + | |
- | bs = bs + bin(ord(c))[2:].zfill(8) | + | |
- | return bs | + | |
- | + | ||
- | def hex2bin(hs): | + | |
- | """ | + | |
- | Transform a hex string (e.g. 'a2') into a string of bits (e.g.10100010) | + | |
- | """ | + | |
- | bs = '' | + | |
- | for c in hs: | + | |
- | bs = bs + bin(int(c,16))[2:].zfill(4) | + | |
- | return bs | + | |
- | + | ||
- | def bin2hex(bs): | + | |
- | """ | + | |
- | Transform a bit string into a hex string | + | |
- | """ | + | |
- | return hex(int(bs,2))[2:] | + | |
- | + | ||
- | def byte2bin(bval): | + | |
- | """ | + | |
- | Transform a byte (8-bit) value into a bitstring | + | |
- | """ | + | |
- | return bin(bval)[2:].zfill(8) | + | |
- | + | ||
- | + | ||
- | def permute4(s): | + | |
- | """ | + | |
- | Perform a permutatation by shifting all bits 4 positions right. | + | |
- | The input is assumed to be a 16-bit bitstring | + | |
- | """ | + | |
- | ps = '' | + | |
- | ps = ps + s[12:16] | + | |
- | ps = ps + s[0:12] | + | |
- | return ps | + | |
- | + | ||
- | def permute_inv4(s): | + | |
- | """ | + | |
- | Perform the inverse of permute4 | + | |
- | The input is assumed to be a 16-bit bitstring | + | |
- | """ | + | |
- | ps = '' | + | |
- | ps = ps + s[4:16] | + | |
- | ps = ps + s[0:4] | + | |
- | return ps | + | |
- | + | ||
- | def spn_1r_reduced_2s(k, x): | + | |
- | """ | + | |
- | Performs an encryption with a substitution-permutation network. | + | |
- | Key k = {k1, k2}, total of 16 bits (2 x 8 bits) | + | |
- | Input x = {x1, x2}, total of 16 bits (2 x 8 bits) | + | |
- | Both k and x are assumed to be bitstrings. | + | |
- | + | ||
- | Return: | + | |
- | a 16-bit bitstring containing the encryption y = {y1, y2} | + | |
- | """ | + | |
- | + | ||
- | # Split input and key | + | |
- | x1 = x[0:8] | + | |
- | x2 = x[8:16] | + | |
- | k1 = k[0:8] | + | |
- | k2 = k[8:16] | + | |
- | + | ||
- | #Apply S-box | + | |
- | u1 = bitxor(x1, k1) | + | |
- | v1 = sbox[int(u1,2)] | + | |
- | v1 = byte2bin(v1) | + | |
- | + | ||
- | u2 = bitxor(x2, k2) | + | |
- | v2 = sbox[int(u2,2)] | + | |
- | v2 = byte2bin(v2) | + | |
- | + | ||
- | #Apply permutation | + | |
- | pin = v1 + v2 | + | |
- | pout = permute4(pin) | + | |
- | + | ||
- | return pout | + | |
- | + | ||
- | def spn_1r_full_2s(k, x): | + | |
- | """ | + | |
- | Performs an encryption with a substitution-permutation network. | + | |
- | Key k = {k1, k2, k3, k4}, total of 32 bits (4 x 8 bits) | + | |
- | Input x = {x1, x2}, total of 16 bits (2 x 8 bits) | + | |
- | Both k and x are assumed to be bitstrings. | + | |
- | + | ||
- | Return: | + | |
- | a 16-bit bitstring containing the encryption y = {y1, y2} | + | |
- | """ | + | |
- | + | ||
- | # Split input and key | + | |
- | x1 = x[0:8] | + | |
- | x2 = x[8:16] | + | |
- | k1 = k[0:8] | + | |
- | k2 = k[8:16] | + | |
- | k3 = k[16:24] | + | |
- | k4 = k[24:32] | + | |
- | + | ||
- | #Apply S-box | + | |
- | u1 = bitxor(x1, k1) | + | |
- | v1 = sbox[int(u1,2)] | + | |
- | v1 = byte2bin(v1) | + | |
- | + | ||
- | u2 = bitxor(x2, k2) | + | |
- | v2 = sbox[int(u2,2)] | + | |
- | v2 = byte2bin(v2) | + | |
- | + | ||
- | #Apply permutation | + | |
- | pin = v1 + v2 | + | |
- | pout = permute4(pin) | + | |
- | #Apply final XOR | + | Give example of a secure PRG $G : K \to Z$ with $Z = \{0, 1\}^{nt}$. |
- | po1 = pout[0:8] | + | |
- | po2 = pout[8:16] | + | |
- | y1 = bitxor(po1, k3) | + | |
- | y2 = bitxor(po2, k4) | + | |
- | return y1+y2 | + | ==== Exercise 4 (2p) ==== |
- | + | ||
- | def main(): | + | |
- | #Run reduced 2-byte SPN | + | In class we showed the indistinguishability game, which we used to determine the advantage of an adversary against an encryption scheme that wants to provide semantic security (i.e. against an eavesdropper that observes a single ciphertext). |
- | msg = 'Hi' | + | In the game, the adversary sends two messages, $m_0$ and $m_1$ and gets to see the encryption $c_b = E(k, m_b)$ of one of them (depending on the random bit $b$). The adversary's task is to determine correctly which message was encrypted by returning a bit $b'$. |
- | key = '??' # Find this | + | |
- | xs = str2bin(msg) | + | |
- | ks = str2bin(key) | + | |
- | ys = spn_1r_reduced_2s(ks, xs) | + | |
- | print 'Two y halves of reduced SPN: ' + ys[0:8] + ' (hex: ' + bin2hex(ys[0:8]) + '), ' + ys[8:16] + ' (hex: ' + bin2hex(ys[8:16]) + ')' | + | |
- | #Run full 2-byte SPN | + | We defined security of encryption scheme E against an eavesdropper in two ways: |
- | msg = 'Om' | + | |
- | key = '????' # Find this | + | |
- | xs = str2bin(msg) | + | |
- | ks = str2bin(key) | + | |
- | ys = spn_1r_full_2s(ks, xs) | + | |
- | print 'Two y halves of full SPN (2 bytes): ' + ys[0:8] + ' (hex: ' + bin2hex(ys[0:8]) + '), ' + ys[8:16] + ' (hex: ' + bin2hex(ys[8:16]) + ')' | + | |
+ | * $Pr[A(c_b)=b] \le \frac{1}{2} + negl(n)$ | ||
+ | * $|Pr[A(c_1)=1] - Pr[A(c_0)=1]| \le negl(n)$ | ||
+ | where $A(c_i) = j$ means that when the adversary receives the encryption of message $i$ he returns the bit $b'=j$. | ||
- | if __name__ == "__main__": | + | Show that the two are equivalent. |
- | main() | + | |
- | </code> | + | |
+ | <hidden> | ||
+ | Hint: start from the first form ($Pr[A(c_b)=b] \le negl(n)$) and develop the probability as | ||
+ | $\frac{1}{2}Pr[A(c_0)=0] + \frac{1}{2}Pr[A(c_1)=1]$. | ||
+ | Then replace $Pr[A(c_0)=0]$ by $1 - Pr[A(c_0)=1]$. | ||
+ | </hidden> | ||