Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sasc:laboratoare:03 [2016/03/07 21:40]
sergiu.costea [Exercise 1]
sasc:laboratoare:03 [2017/03/07 15:32] (current)
dan.dragan
Line 1: Line 1:
-===== Lab 03 =====+===== Lab 03 - PRGs =====
  
  
-==== Exercise 1 ====+==== Exercise 1 (4p) ====
  
-Advantage. The purpose of this problem is to clarify the concept of advantageConsider the following two experiments $\mathsf{EXP}(0)$ and $\mathsf{EXP}(1)$:​ +In this exercise we'll try to break a Linear Congruential Generator, that may be used to generate "​poor"​ random numbers
-  * In $\mathsf{EXP}(0)$ the challenger flips fair coin (probability $1/2$ for HEADS and $1/2$ for TAILS) and sends the result to the adversary $\mathsf{A}$+We implemented such weak RNG to generate ​sequence of bytes and then encrypted a plaintext message
-  * In $\mathsf{EXP}(1)$ the challenger always sends TAILS to the adversary.+The resulting ciphertext in hexadecimal is this: 
 +<​code>​ 
 +a432109f58ff6a0f2e6cb280526708baece6680acc1f5fcdb9523129434ae9f6ae9edc2f224b73a8 
 +</​code>​
  
-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 +You know that the LCG uses the following formula ​to produce each byte:
-$\mathsf{Adv} = \left| \mathsf{Pr}\left[W_{0}\right] − \mathsf{Pr}\left[W_{1}\right] \right| \in \left[0, 1\right]$ .+
  
-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 classthen we say that the two experiments are indistinguishable.+s_next = (a * s_prev + bmod p
  
-a. Calculate the advantage of each of the following adversaries:​ +where both s_prev ​and s_next are byte values (between ​and 255) and p is 257
-  * A1: Always output $1$. +Both a and b are values between ​and 256.
-  * 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.+
  
-b. What is the maximum advantage possible in distinguishing these two experiments?​ Explain why. 
  
-==== Exercise 2 ====+You also know that the first 16 letters of the plaintext are "Let all creation"​ and that the ciphertext was generated by xor-ing a string of consecutive bytes generated by the LCG with the plaintext.
  
-Let's use the experiment defined earlier as a pseudorandom generator (PRG) as follows:+Can you break the LCG and predict the RNG stream so that in the end you find the entire plaintext ? 
 + 
 +You may use this starting code: 
 +<code python '​ex1_weak_rng.py'>​ 
 +import sys 
 +import random 
 +import string 
 +import operator 
 + 
 +#Parameters for weak LC RNG 
 +class WeakRNG: 
 +    "​Simple class for weak RNG" 
 +    def __init__(self):​ 
 +        self.rstate = 0 
 +        self.maxn = 255 
 +        self.a = 0 #Set this to correct value 
 +        self.b = 0 #Set this to correct value 
 +        self.p = 257 
 + 
 +    def init_state(self):​ 
 +        "​Initialise rstate"​ 
 +        self.rstate = 0 #Set this to some value 
 +        self.update_state() 
 + 
 +    def update_state(self):​ 
 +        "​Update state"​ 
 +        self.rstate = (self.a * self.rstate + self.b) % self.p 
 + 
 +    def get_prg_byte(self):​ 
 +        "​Return a new PRG byte and update PRG state"​ 
 +        b = self.rstate & 0xFF 
 +        self.update_state() 
 +        return b 
 + 
 +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 main(): 
 + 
 +  #Initialise weak rng 
 +  wr = WeakRNG() 
 +  wr.init_state() 
 + 
 +  #Print ciphertext 
 +  CH = '​a432109f58ff6a0f2e6cb280526708baece6680acc1f5fcdb9523129434ae9f6ae9edc2f224b73a8'​ 
 +  print "Full ciphertext in hexa: " + CH 
 + 
 +  #Print known plaintext 
 +  pknown = 'Let all creation'​ 
 +  nb = len(pknown) 
 +  print "Known plaintext: " + pknown 
 +  pkh = pknown.encode('​hex'​) 
 +  print "​Plaintext in hexa: " + pkh 
 + 
 +  #Obtain first nb bytes of RNG 
 +  gh = hexxor(pkh, CH[0:​nb*2]) 
 +  print gh 
 +  gbytes = [] 
 +  for i in range(nb):​ 
 +    gbytes.append(ord(gh[2*i:​2*i+2].decode('​hex'​))) 
 +  print "Bytes of RNG: " 
 +  print gbytes 
 + 
 +  #Break the LCG here: 
 +  #1. find a and b 
 +  #2. predict/​generate rest of RNG bytes 
 +  #3. decrypt plaintext 
 + 
 +  # Print full plaintext 
 +  p = ''​ 
 +  print "Full plaintext is: " + p 
 + 
 + 
 +if __name__ == "​__main__":​ 
 +  main() ​  
 +</​code>​ 
 + 
 +==== Exercise 2 (3p) ==== 
 + 
 +Let's use the experiment defined earlier as a pseudorandom generator ($\mathsf{PRG}$) as follows:
   - Set a desired output length $n$   - Set a desired output length $n$
-  - Obtain a random sequence $R$ of bits of length $n$ (say flipping a coin, using Linear-congruential generator, or any other method+  - Obtain a random sequence $R$ of bits of length $n$ (e.g. using the Linear-congruential generator ​from Exercise 1
-  - For each bit r in the random sequence R generated in the previous step, output a bit b as follows: +  - For each bit $rin the random sequence ​$Rgenerated in the previous step, output a bit $bas follows: 
-  * if the bit $r$ is $0$, then output a random bit $b$ (e.g. flip a coin and output either $0$ or $1$ depending on its result)+  * if the bit $r$ is $0$, then output a random bit $b \in \{01\}$
   * if the bit $r$ is $1$, then output $1$   * if the bit $r$ is $1$, then output $1$
  
Line 48: Line 129:
 <note tip>​Also,​ in Python you may find the functions sqrt, fabs and erfc from the module math useful</​note>​ <note tip>​Also,​ in Python you may find the functions sqrt, fabs and erfc from the module math useful</​note>​
  
 +==== Exercise 3 - LFSR (3p) ====
  
 +In this exercise we'll build a simple Linear Feedback Shift Register (LFSR). LFSRs produce random bit strings with good statistical properties, but are very easy to predict.
  
 +The register is a sequence of $n$ bits; a LFSR is defined by:
 +  * an initial state (the initial bit contents of the register)
 +  * a polynomial that describes how bit shifts should be performed
  
 +For example, given an $18$ bit LFSRm the polynomial $X^{18} + X^{11} + 1$ and the initial state:
 +<​code>​
 +  state = '​001001001001001001'​
 +                     ​* ​     *
 +</​code>​
 +
 +we generate a new bit $b$ by $\mathsf{xor}$-ing bits $11$ ($0$) and $18$ ($1$), thus obtaining $b = 1$. We then shift the whole register to the right (thus dropping the right-most bit, which is the bit we add to the generated random sequence) and insert $b$ to the left. Thus, the new state is:
 +<​code>​
 +  state = '​100100100100100100'​
 +</​code>​
  
 +The process is repeated until the desired number of bits have been generated.
  
  
 +Using the above starting state and polynomial, generate $100$ random bits and run the monobit statistical test from the previous exercise to see if their frequency seems random.
sasc/laboratoare/03.1457379628.txt.gz · Last modified: 2016/03/07 21:40 by sergiu.costea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0