class Benchmark(Experiment): """ Measures the time LTFArray.eval takes to evaluate a set of inputs. """ def __init__(self, progress_log_prefix, parameters): super().__init__(progress_log_prefix, parameters) self.set = None self.ltf_array = None def prepare(self): self.set = sample_inputs(self.parameters.n, self.parameters.N, RandomState(seed=self.parameters.seed_input)) self.ltf_array = LTFArray( weight_array=LTFArray.normal_weights(self.parameters.n, self.parameters.k), transform=self.parameters.transform, combiner=self.parameters.combiner, ) def run(self): self.ltf_array.eval(self.set) def analyze(self): return Result( experiment_id=self.id, pid=getpid(), measured_time=self.measured_time, )
def test_bias_influence_array(self): """ This method tests the influence of the bias array. The results should be different. """ n = 8 k = 4 mu = 1 sigma = 0.5 challenges = tools.all_inputs(n) weight_array = LTFArray.normal_weights( n, k, mu=mu, sigma=sigma, random_instance=RandomState(0xBADA556)) bias_array = LTFArray.normal_weights( 1, k, mu=mu, sigma=sigma * 2, random_instance=RandomState(0xBADAFF1)) biased_ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=bias_array, ) ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=None, ) # the second dimension of the weight_array must be the number of elements in biased weight_array self.assertEqual( shape(ltf_array.weight_array)[1], shape(biased_ltf_array.weight_array)[1]) assert_array_equal(biased_ltf_array.weight_array[:, :n], ltf_array.weight_array[:, :n]) assert_array_equal(biased_ltf_array.weight_array[:, :n], weight_array) assert_array_equal(biased_ltf_array.weight_array[:, n], reshape(bias_array, (k, ))) assert_array_equal(ltf_array.weight_array[:, n], zeros((k, ))) biased_responses = biased_ltf_array.eval(challenges) responses = ltf_array.eval(challenges) self.assertFalse(array_equal(biased_responses, responses))
def test_majority_voting(self): """This method is used to test if majority vote works. The first test checks for unequal PUF responses with a LTFArray without noise and a SimulationMajorityLTFArray instance with noise. The second test checks if majority voting works and the instance with and without noise generate equal resonses. """ weight_prng1 = RandomState(seed=0xBADA55) noise_prng = RandomState(seed=0xC0FFEE) crp_count = 16 # number of random inputs per test set n = 8 k = 16 mu = 0 sigma = 1 vote_count = 1 weight_array = LTFArray.normal_weights(n, k, mu, sigma, weight_prng1) mv_noisy_ltf_array = SimulationMajorityLTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, sigma_noise=1, random_instance_noise=noise_prng, vote_count=vote_count, ) ltf_array = LTFArray(weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor) inputs = tools.random_inputs( n, crp_count, random_instance=RandomState(seed=0xDEADDA7A)) ltf_array_result = ltf_array.eval(inputs) mv_noisy_ltf_array_result = mv_noisy_ltf_array.eval(inputs) # These test checks if the output is different because of noise self.assertFalse( array_equal(ltf_array_result, mv_noisy_ltf_array_result), 'These arrays must be different') # reset pseudo random number generator noise_prng = RandomState(seed=0xC0FFEE) # increase the vote_count in order to get equality vote_count = 2845 mv_noisy_ltf_array = SimulationMajorityLTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, sigma_noise=1, random_instance_noise=noise_prng, vote_count=vote_count, ) # This checks if the majority vote works mv_noisy_ltf_array_result = mv_noisy_ltf_array.eval(inputs) assert_array_equal(mv_noisy_ltf_array_result, ltf_array_result)
def test_bias_influence_value(self): """ This method tests the influence of the bias value. The results should be different. """ n = 8 k = 4 mu = 1 sigma = 0.5 challenges = tools.all_inputs(n) weight_array = LTFArray.normal_weights( n, k, mu=mu, sigma=sigma, random_instance=RandomState(0xBADA556)) bias_value = 2.5 biased_ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=bias_value, ) ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=None, ) # the second dimension of the weight_array must be the number of elements in biased weight_array self.assertEqual( shape(ltf_array.weight_array)[1], shape(biased_ltf_array.weight_array)[1]) bias_array = biased_ltf_array.weight_array[:, -1] bias_array_compared = [bias == bias_array[0] for bias in bias_array] # the bias values should be equal for this test. self.assertTrue(array(bias_array_compared).all()) biased_responses = biased_ltf_array.eval(challenges) responses = ltf_array.eval(challenges) self.assertFalse(array_equal(biased_responses, responses))
def test_majority_voting(self): weight_prng1 = RandomState(seed=0xBADA55) noise_prng = RandomState(seed=0xC0FFEE) crp_count = 16 # number of random inputs per test set n = 8 k = 16 mu = 0 sigma = 1 vote_count = 1 weight_array = LTFArray.normal_weights(n, k, mu, sigma, weight_prng1) mv_noisy_ltf_array = SimulationMajorityLTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, sigma_noise=1, random_instance_noise=noise_prng, vote_count=vote_count, ) ltf_array = LTFArray(weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor) inputs = array( list( tools.random_inputs( n, crp_count, random_instance=RandomState(seed=0xDEADDA7A)))) ltf_array_result = ltf_array.eval(inputs) mv_noisy_ltf_array_result = mv_noisy_ltf_array.eval(inputs) # These test checks if the output is different because of noise self.assertFalse( array_equal(ltf_array_result, mv_noisy_ltf_array_result), 'These arrays must be different') # reset pseudo random number generator noise_prng = RandomState(seed=0xC0FFEE) # increase the vote_count in order to get equality vote_count = 277 mv_noisy_ltf_array = SimulationMajorityLTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, sigma_noise=1, random_instance_noise=noise_prng, vote_count=vote_count, ) # This checks if the majority vote works mv_noisy_ltf_array_result = mv_noisy_ltf_array.eval(inputs) assert_array_equal(mv_noisy_ltf_array_result, ltf_array_result)
class LTFBenchmarkExperiment(BenchmarkExperiment): """ Measures the time LTFArray.eval takes to evaluate a set of inputs. """ def __init__(self, progress_log_prefix, parameters): super().__init__(progress_log_prefix, parameters) self.set = None self.ltf_array = None def prepare(self): self.set = sample_inputs(self.parameters.n, self.parameters.N, RandomState(seed=self.parameters.seed_input)) self.ltf_array = LTFArray( weight_array=LTFArray.normal_weights(self.parameters.n, self.parameters.k), transform=self.parameters.transform, combiner=self.parameters.combiner, ) def run(self): self.ltf_array.eval(self.set)
def test_bias_influence_array(self): """ This method tests the influence of the bias array. The results should be different. """ n = 8 k = 4 mu = 1 sigma = 0.5 challenges = array(list(tools.all_inputs(n))) weight_array = LTFArray.normal_weights(n, k, mu=mu, sigma=sigma, random_instance=RandomState(0xBADA556)) bias_array = LTFArray.normal_weights(1, k, mu=mu, sigma=sigma*2, random_instance=RandomState(0xBADAFF1)) biased_ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=bias_array, ) ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=None, ) # the second dimension of the weight_array plus one must be the number of elements in biased weight_array self.assertEqual(shape(ltf_array.weight_array)[1]+1, shape(biased_ltf_array.weight_array)[1]) bias_array = biased_ltf_array.weight_array[:, -1] bias_array_compared = [bias == bias_array[0] for bias in bias_array[1:]] # the bias values should be different for this test. It is possible that they are all equal but this chance is # low. self.assertFalse(array(bias_array_compared).all()) biased_responses = biased_ltf_array.eval(challenges) responses = ltf_array.eval(challenges) # The arithmetic mean of the res self.assertFalse(array_equal(biased_responses, responses))
def test_bias(self): """ Probabilistic test for checking the bias feature in eval. """ N = 100 for test_parameters in self.test_set: n = test_parameters[0] k = test_parameters[1] mu = test_parameters[2] sigma = test_parameters[3] bias = test_parameters[4] weight_array = LTFArray.normal_weights(n, k, mu, sigma) input_len = n - 1 if bias else n inputs = RandomState(seed=0xBAADA555).choice( [-1, +1], (N, input_len)) # bad ass testing biased_ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=bias, ) ltf_array = LTFArray( weight_array=weight_array, transform=LTFArray.transform_id, combiner=LTFArray.combiner_xor, bias=False, ) biased_eval = biased_ltf_array.eval(inputs) inputs = tools.iter_append_last(inputs, 1)\ if biased_ltf_array.bias else inputs eval = ltf_array.eval(inputs) assert_array_equal(biased_eval, eval)
def run(self): r = self.socket.recv(64) if r[0:8] != b"ENO/GET/": print("[*] Invalid Packet") p_dny = b"ENO/DNY/\x00\x10/" + b'\x00' * 32 + b'/' + b'\x00' * 17 self.socket.send(p_dny) return if b"dbg=1" in r: info = b""" ========================================================================= MAGIC DRAGON MASTER AUTHORITY Cert Level 1: Strong Prime Number for Certificate self-signing Authentication: None Cert Level 2: Privileged Certificate for Border Authorities Authentication: Challenge Response Protocol System Details: 64 Round 48-Bit 4-XOR Arbiter PUF ========================================================================= """ self.socket.send(info) elif b"cert_level=1" in r: p = number.getPrime(64) print(p) self.socket.send(struct.pack(">Q", p)) print("[*] CERT LVL 1 OK") elif b"cert_level=2" in r: try: with open('weights.txt', 'rb') as f: weights = np.load(f) except: weights = LTFArray.normal_weights(n=48, k=4) with open('weights.txt', 'wb') as f: np.save(f, weights, allow_pickle=False) # print(weights) instance = LTFArray( weight_array=weights, transform=LTFArray.transform_atf, combiner=LTFArray.combiner_xor, ) challenges = [] c_string = b"" for n in range(0, 64): c = np.zeros(48, dtype=np.int8) for i in range(0, 48): c[i] = random.choice([-1, 1]) challenges.append(c) # prepare message c = np.copy(c) c[c == 1] = 0 c[c == -1] = 1 cm = b"" for b in c: cm += str(b).encode() c_string += cm + b'\n' print("[*] Challenges prepared") challenges = np.array(challenges) correct_response = instance.eval(challenges) self.socket.send(c_string) print("[*] Expect Response") r = self.socket.recv(64) if len(r) != 64: print("[*] Invalid Response") else: given_response = np.zeros(64, dtype=np.int8) for i in range(0, 64): given_response[i] = np.int8(r[i]) correct_response[correct_response == 1] = 0 correct_response[correct_response == -1] = 1 print(correct_response) if (given_response == correct_response).all(): print("[*] ACCEPT") x = 12074235067132104677358030448740169086211171545373284647579234906840326968311237601092259613113724502049948022317426840853777753513486274652991559584610574 self.socket.send(construct.BytesInteger(64).build(x)) else: print("[*] REJECT") cm = b"" for b in correct_response: cm += str(b).encode() self.socket.send(cm) self.socket.close()