Commit 56463a5f12f7cd28d380ceb63a6c9d4cdf5609a9

Authored by Brice Colombier
1 parent 83ac50c342
Exists in master

AW decoder working when locking and masking not invoked both

Showing 3 changed files with 170 additions and 39 deletions

AW_decoder/AW_decoder.vhd View file @ 56463a5
... ... @@ -5,15 +5,19 @@
5 5  
6 6 PORT (
7 7 formatted_AW : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
8   - AW : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
  8 + AW : OUT STD_LOGIC_VECTOR(8 DOWNTO 0));
9 9  
10 10 END ENTITY AW_decoder;
11 11  
12 12 ARCHITECTURE rtl OF AW_decoder IS
13 13  
  14 + SIGNAL locking_0 IS STD_LOGIC;
  15 + SIGNAL locking_1 IS STD_LOGIC;
  16 +
14 17 BEGIN
15 18  
16   -
  19 + -- Formatted AW: 10101110, MSB first
  20 + -- AW: 1010 1010, MSB first
17 21  
18 22 END ARCHITECTURE rtl;
AW_decoder/gen_AW_decoder.py View file @ 56463a5
1 1 import random as rd
  2 +from operator import itemgetter
  3 +import math
2 4  
3   -def gen_AW_decoder (AW, in_width, locking=True, masking=True):
  5 +def gen_assoc_mask_ANDs (fan_in_ANDs, pos_1s_output, pos_1s_input):
  6 + assoc_mask_ANDs = []
  7 + if fan_in_ANDs > 1:
  8 + remain = 0
  9 + while pos_1s_output:
  10 + current_fan_in = int(math.ceil(fan_in_ANDs))
  11 + remain+=current_fan_in - fan_in_ANDs
  12 + if remain > 1:
  13 + remain -= 1
  14 + assoc_mask_ANDs.append((pos_1s_input[-current_fan_in+1:], pos_1s_output.pop()))
  15 + del pos_1s_input[-current_fan_in+1:]
  16 + else:
  17 + assoc_mask_ANDs.append((pos_1s_input[-current_fan_in:], pos_1s_output.pop()))
  18 + del pos_1s_input[-current_fan_in:]
  19 + elif fan_in_ANDs == 1:
  20 + assoc_mask_ANDs = list(zip(pos_1s_input, pos_1s_output))
  21 + assoc_mask_ANDs = [(x[0], x[1]) for x in assoc_mask_ANDs]
  22 + elif fan_in_ANDs < 1 and fan_in_ANDs != 0:
  23 + remain = 0
  24 + fan_out_ANDs = 1/fan_in_ANDs
  25 + while pos_1s_input:
  26 + current_fan_out = int(math.ceil(fan_out_ANDs))
  27 + remain+=current_fan_out - fan_out_ANDs
  28 + if remain > 1:
  29 + remain -= 1
  30 + assoc_mask_ANDs.append((pos_1s_input.pop(), pos_1s_output[-current_fan_out+1:]))
  31 + del pos_1s_output[-current_fan_out+1:]
  32 + else:
  33 + assoc_mask_ANDs.append((pos_1s_input.pop(), pos_1s_output[-current_fan_out:]))
  34 + del pos_1s_output[-current_fan_out:]
  35 + else:
  36 + raise ValueError("Fan-in zero")
  37 + assoc_mask_ANDs = [(x[0], x[1][0]) if (type(x[1]) == list and len(x[1]) == 1) else x for x in assoc_mask_ANDs]
  38 + assoc_mask_ANDs = [(x[0][0], x[1]) if (type(x[0]) == list and len(x[0]) == 1) else x for x in assoc_mask_ANDs]
  39 + return assoc_mask_ANDs
  40 +
  41 +def gen_assoc_mask_ORs (fan_in_ORs, pos_0s_output, pos_0s_input):
  42 + assoc_mask_ORs = []
  43 + if fan_in_ORs > 1:
  44 + remain = 0
  45 + while pos_0s_output:
  46 + current_fan_in = int(math.ceil(fan_in_ORs))
  47 + remain+=current_fan_in - fan_in_ORs
  48 + if remain > 1:
  49 + remain -= 1
  50 + assoc_mask_ORs.append((pos_0s_input[-current_fan_in+1:], pos_0s_output.pop()))
  51 + del pos_0s_input[-current_fan_in+1:]
  52 + else:
  53 + assoc_mask_ORs.append((pos_0s_input[-current_fan_in:], pos_0s_output.pop()))
  54 + del pos_0s_input[-current_fan_in:]
  55 + elif fan_in_ORs == 1:
  56 + assoc_mask_ORs = list(zip(pos_0s_input, pos_0s_output))
  57 + assoc_mask_ORs = [(x[0], x[1]) for x in assoc_mask_ORs]
  58 + elif fan_in_ORs < 1 and fan_in_ORs != 0:
  59 + remain = 0
  60 + fan_out_ORs = 1/fan_in_ORs
  61 + while pos_0s_input:
  62 + current_fan_out = int(math.ceil(fan_out_ORs))
  63 + remain+=current_fan_out - fan_out_ORs
  64 + if remain > 1:
  65 + remain -= 1
  66 + assoc_mask_ORs.append((pos_0s_input.pop(), pos_0s_output[-current_fan_out+1:]))
  67 + del pos_0s_output[-current_fan_out+1:]
  68 + else:
  69 + assoc_mask_ORs.append((pos_0s_input.pop(), pos_0s_output[-current_fan_out:]))
  70 + del pos_0s_output[-current_fan_out:]
  71 + else:
  72 + raise ValueError("Fan-in zero")
  73 + assoc_mask_ORs = [(x[0], x[1][0]) if (type(x[1]) == list and len(x[1]) == 1) else x for x in assoc_mask_ORs]
  74 + assoc_mask_ORs = [(x[0][0], x[1]) if (type(x[0]) == list and len(x[0]) == 1) else x for x in assoc_mask_ORs]
  75 + return assoc_mask_ORs
  76 +
  77 +def gen_AW_decoder (AW, width_formatted_AW, locking=True, masking=True):
4 78 """Generates a decoder for the Activation Word
5 79  
6   - in_width: width of the input coming from the cipher
  80 + width_formatted_AW: width of the formatted AW
7 81 """
8 82  
9 83 unlocking_word = ""
... ... @@ -13,7 +87,7 @@
13 87 try:
14 88 unlocking_word, unmasking_word = AW.split()
15 89 except ValueError:
16   - raise ValueError("Incorrect AW provided, must be \"AW_lock|AW_mask\"")
  90 + raise ValueError("Incorrect AW provided, must be \"AW_lock AW_mask\"")
17 91 else:
18 92 if len(AW.split()) == 1:
19 93 unlocking_word = AW
20 94  
21 95  
22 96  
... ... @@ -34,26 +108,78 @@
34 108 # Entity
35 109 vhd_file.write("ENTITY AW_decoder IS\n\n")
36 110 vhd_file.write(" PORT (\n")
37   - vhd_file.write(" formatted_AW : IN STD_LOGIC_VECTOR("+str(in_width-1)+" DOWNTO 0);\n")
  111 + vhd_file.write(" formatted_AW : IN STD_LOGIC_VECTOR("+str(width_formatted_AW-1)+" DOWNTO 0);\n")
38 112 vhd_file.write(" AW : OUT STD_LOGIC_VECTOR("+str(len(AW)-1)+" DOWNTO 0));\n\n")
39 113 vhd_file.write("END ENTITY AW_decoder;\n\n")
40 114 # Architecture
41 115 vhd_file.write("ARCHITECTURE rtl OF AW_decoder IS\n\n")
42   - vhd_file.write("BEGIN\n\n\n\n")
43   - formatted_AW = ''.join([str(int(2*rd.random())) for i in xrange(in_width)])
44   - formatted_AW_LSB = formatted_AW[:len(formatted_AW)/2]
45   - formatted_AW_MSB = formatted_AW[len(formatted_AW)/2:]
46   - pos_0s_MSB_AW = [x for x in range(len(formatted_AW_MSB)) if formatted_AW_MSB[x] == '0']
47   - pos_1s_MSB_AW = [x for x in range(len(formatted_AW_MSB)) if formatted_AW_MSB[x] == '1']
48   - # Locking part
49   -
50   -
51   - vhd_file.write("END ARCHITECTURE rtl;\n")
  116 + if locking:
  117 + vhd_file.write(" SIGNAL locking_0 IS STD_LOGIC;\n")
  118 + vhd_file.write(" SIGNAL locking_1 IS STD_LOGIC;\n\n")
  119 + vhd_file.write("BEGIN\n\n")
  120 + # Computation
  121 + formatted_AW = ''.join([str(int(2*rd.random())) for i in xrange(width_formatted_AW)])
  122 + print "Formatted AW:", formatted_AW
  123 + print " AW:", AW
  124 + assoc_mask_ORs = []
  125 + pos_0s_AW = [x for x in range(len(AW)) if AW[x] == '0']
  126 + rd.shuffle(pos_0s_AW)
  127 + pos_1s_AW = [x for x in range(len(AW)) if AW[x] == '1']
  128 + rd.shuffle(pos_1s_AW)
  129 + pos_0s_formatted_AW = [x for x in range(len(formatted_AW)) if formatted_AW[x] == '0']
  130 + rd.shuffle(pos_0s_formatted_AW)
  131 + pos_1s_formatted_AW = [x for x in range(len(formatted_AW)) if formatted_AW[x] == '1']
  132 + rd.shuffle(pos_1s_formatted_AW)
  133 + vhd_file.write(" -- Formatted AW: "+formatted_AW[::-1]+", MSB first\n")
  134 + vhd_file.write(" -- AW: "+AW[::-1]+", MSB first\n")
  135 + if masking and not locking:
  136 + fan_in_ANDs = float(len([x for x in formatted_AW if x == '1']))/(len([x for x in AW if x == '1']))
  137 + fan_in_ORs = float(len([x for x in formatted_AW if x == '0']))/(len([x for x in AW if x == '0']))
  138 + assoc_mask_ANDs = gen_assoc_mask_ANDs (fan_in_ANDs, pos_1s_AW, pos_1s_formatted_AW)
  139 + assoc_mask_ORs = gen_assoc_mask_ORs (fan_in_ORs, pos_0s_AW, pos_0s_formatted_AW)
  140 + print "Mask ANDs", assoc_mask_ANDs
  141 + print "Mask ORs", assoc_mask_ORs
  142 + vhd_file.write("\n -- Mask ANDs\n")
  143 + for (inputs, outputs) in assoc_mask_ANDs:
  144 + if type(inputs) == int and type(outputs) == int:
  145 + vhd_file.write(" AW("+str(outputs)+") <= formatted_AW("+str(inputs)+");\n")
  146 + elif type(inputs) == int and type(outputs) == list:
  147 + for output in outputs:
  148 + vhd_file.write(" AW("+str(output)+") <= formatted_AW("+str(inputs)+")\n")
  149 + elif type(inputs) == list and type(outputs) == int:
  150 + vhd_file.write(" AW("+str(outputs)+") <= "+" AND ".join(["formatted_AW("+str(i)+")" for i in inputs])+";\n")
  151 + vhd_file.write("\n -- Mask ORs\n")
  152 + for (inputs, outputs) in assoc_mask_ORs:
  153 + if type(inputs) == int and type(outputs) == int:
  154 + vhd_file.write(" AW("+str(outputs)+") <= formatted_AW("+str(inputs)+");\n")
  155 + elif type(inputs) == int and type(outputs) == list:
  156 + for output in outputs:
  157 + vhd_file.write(" AW("+str(output)+") <= formatted_AW("+str(inputs)+");\n")
  158 + elif type(inputs) == list and type(outputs) == int:
  159 + vhd_file.write(" AW("+str(outputs)+") <= "+" OR ".join(["formatted_AW("+str(i)+")" for i in inputs])+";\n")
  160 + if locking and not masking:
  161 + assoc_lock_ANDs = [(pos_1s_formatted_AW, pos_1s_AW)]
  162 + assoc_lock_ORs = [(pos_0s_formatted_AW, pos_0s_AW)]
  163 + # for (inputs, outputs) in
  164 + print "Lock ANDs", assoc_lock_ANDs
  165 + print "Lock ORs", assoc_lock_ORs
  166 + vhd_file.write("\n -- Lock AND\n")
  167 + for (inputs, outputs) in assoc_lock_ANDs:
  168 + vhd_file.write(" locking_1 <= "+" AND ".join(["formatted_AW("+str(i)+")" for i in inputs])+";\n")
  169 + for output in outputs:
  170 + vhd_file.write(" AW("+str(output)+") <= locking_1;\n")
  171 + vhd_file.write("\n -- Lock OR\n")
  172 + for (inputs, outputs) in assoc_lock_ORs:
  173 + vhd_file.write(" locking_0 <= "+" OR ".join(["formatted_AW("+str(i)+")" for i in inputs])+";\n")
  174 + for output in outputs:
  175 + vhd_file.write(" AW("+str(output)+") <= locking_0;\n")
  176 + vhd_file.write("\nEND ARCHITECTURE rtl;\n")
52 177  
53   - return formatted_AW_MSB, pos_0s_MSB_AW, pos_1s_MSB_AW
  178 + return formatted_AW
54 179  
55 180 if __name__ == "__main__":
56   - print gen_AW_decoder("0001 1010", 8, locking=True, masking=True)
57   - print gen_AW_decoder("00011010", 8, locking=False, masking=True)
58   - print gen_AW_decoder("00011010", 8, locking=True, masking=False)
  181 + # gen_AW_decoder("00000011", 8, locking=False, masking=True) # AW given LSB first
  182 + # gen_AW_decoder("01010101", 8, locking=True, masking=False)
  183 + gen_AW_decoder("0101 0101", 8, locking=True, masking=True)
  184 +
... ... @@ -101,7 +101,7 @@
101 101 filetypes=ftypes))
102 102  
103 103 def build_graph(self):
104   - self.graph_info.set(str("Building the graph from file "+self.filename.get().split("/")[-1]+"..."))
  104 + self.update_status("Building the graph from file "+self.filename.get().split("/")[-1]+"...")
105 105 self.master.config(cursor="wait")
106 106 self.graph_info_label.configure(foreground="black")
107 107 self.master.update()
108 108  
... ... @@ -126,10 +126,11 @@
126 126 self.g, self.prim_in, self.prim_out, self.nodes = build_verilog_struct(self.filename.get())
127 127 self.graph_info.set(str(str(len(self.nodes))+" nodes, "+
128 128 str(len(self.prim_in))+" inputs, "+
129   - str(len(self.prim_out))+" outputs."))
  129 + str(len(self.prim_out))+" outputs."))
  130 + self.update_status("")
130 131 except:
131   - self.graph_info.set("Error in building the graph")
132   - self.graph_info_label.configure(foreground="red")
  132 + self.update_status("Error in building the graph")
  133 +
133 134 self.master.config(cursor="")
134 135 self.master.update()
135 136  
136 137  
... ... @@ -140,11 +141,12 @@
140 141 with open(self.server_reference_response_file.get(), "r") as rrfile:
141 142 line = rrfile.readline()
142 143 if line[:20] != "Reference response: ":
143   - raise SyntaxError ("The file could not be parsed as a Reference Response file")
  144 + self.update_status("The file could not be parsed as a Reference Response file")
144 145 else:
145 146 self.server_reference_response = str(line[20:])
146 147 self.server_reference_response_displayed.set(self.server_reference_response)
147 148 self.server_reference_response = response_converter_to_bin_list(self.server_reference_response)
  149 + self.update_status("")
148 150  
149 151 def open_activation_word(self):
150 152 awtypes = [("Activation word", ".txt")]
... ... @@ -154,7 +156,7 @@
154 156 line = awfile.readline()
155 157 line = awfile.readline() # Get the second line
156 158 if not set(line) <= {"0", "1"}:
157   - raise SyntaxError ("The file could not be parsed as an Activation Word file")
  159 + self.update_status("The file could not be parsed as an Activation Word file")
158 160 else:
159 161 self.activation_word.set(line)
160 162  
161 163  
... ... @@ -173,12 +175,13 @@
173 175 self.PUF_response = list(reversed(response_converter_to_bin_list(temp_hex_response)))
174 176 self.PUF_response_displayed.set(response_converter_to_hex(self.PUF_response))
175 177 except:
176   - self.status.set("Response could not be obtained")
  178 + print("Error")
  179 + self.update_status("Response could not be obtained")
177 180  
178 181 def save_as_reference_response(self):
179 182 with open("./user_space/rr.txt", "w") as rrfile:
180 183 rrfile.write("Reference response: "+self.PUF_response_displayed.get())
181   - self.save_as_reference_response_status.set("Reference response saved under ./user_space/rr.txt")
  184 + self.update_status("Reference response saved under ./user_space/rr.txt")
182 185  
183 186 def pop_up_about(self):
184 187 self.top = Toplevel(background="White")
... ... @@ -214,7 +217,7 @@
214 217 self.License_text = self.License_file.read()
215 218 self.License_file.close()
216 219 except:
217   - self.License_text = "Cannot find LICENSE.txt"
  220 + self.update_status("Cannot find LICENSE.txt")
218 221 self.msg = Label(self.top,
219 222 text=self.License_text,
220 223 background="white")
... ... @@ -224,7 +227,7 @@
224 227 self.tcl_obj.eval(self.board_manager.source_tcl_package())
225 228 tcl_return = self.tcl_obj.eval(self.board_manager.connect(self.com_port.get()))
226 229 if tcl_return == "-1": # Error handling
227   - self.status.set("Could not connect to the board")
  230 + self.update_status("Could not connect to the board")
228 231 else: # Connection successful
229 232 self.com_port_button_connect.configure(state=DISABLED)
230 233 self.com_port_button_disconnect.configure(state=NORMAL)
... ... @@ -279,7 +282,7 @@
279 282 with open(key_file_name, "w") as key_file:
280 283 key_file.write("Salt = "+self.salt+"\n")
281 284 key_file.write("Key = "+self.key)
282   - self.message_key_saved.set("Key saved under "+key_file_name)
  285 + self.update_status("Key saved under "+key_file_name)
283 286  
284 287 def generate_save_modified_design(self):
285 288 filename = self.filename.get().split("/")[-1]
... ... @@ -295,7 +298,7 @@
295 298 filename = ".".join(filename)
296 299 filename = "/".join(self.filename.get().split("/")[:-1])+"/"+filename
297 300 convert_back_bench(self.graph_modified, filename)
298   - self.message_modified_design_saved.set(str("Modified design saved under "+filename))
  301 + self.update_status(str("Modified design saved under "+filename))
299 302  
300 303 def save_AW(self):
301 304 filename = self.filename.get().split("/")[-1]
... ... @@ -305,8 +308,8 @@
305 308 filename = ".".join(filename)
306 309 filename = "/".join(self.filename.get().split("/")[:-1])+"/"+filename
307 310 with open(filename, "w") as aw_file:
308   - aw_file.write("Unocking word concatenated with unmasking word\n"+self.unlocking_word+self.unmasking_word)
309   - self.message_AW_saved.set(str("Activation word saved under "+filename))
  311 + aw_file.write("Unlocking word concatenated with unmasking word\n"+self.unlocking_word+" "+self.unmasking_word)
  312 + self.update_status(str("Activation word saved under "+filename))
310 313  
311 314 def perform_reconciliation(self):
312 315 self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
313 316  
314 317  
... ... @@ -328,21 +331,19 @@
328 331 print "Differences before/after: ", [a for (a, (b, c)) in enumerate(zip(server_before, server_after)) if b != c]
329 332 print ("Reconciliation done")
330 333  
  334 + def update_status(self, text):
  335 + self.status.set(text)
  336 +
331 337 def reset_board(self, port=2):
332 338 self.tcl_obj.eval(self.board_manager.reset_boards(port=2))
333 339  
334 340 def reset(self):
335 341 print ("To be implemented soon")
336 342  
337   -def every_second():
338   - # To be filled
339   - fenetre.after(1000, every_second)
340   -
341 343 if __name__ == "__main__":
342 344  
343 345 fenetre = Tk()
344 346 app = App(fenetre)
345 347  
346   - fenetre.after(1000, every_second)
347 348 fenetre.mainloop()