예제 #1
0
    def calculate_stabilities(self, instance, challenge_prng):
        """
        Calculate the stability for random chosen challenges.
        :param instance: SimulationMajorityLTFArray
                         A simulation of a Majority Vote Arbiter PUF. 
        :param challenge_prng: RandomState
                               Pseudo-random number generator which is used to generate challenges.
        """
        challenges = np.array(
            list(
                tools.random_inputs(self.n,
                                    self.N,
                                    random_instance=challenge_prng)))
        eval_array = np.zeros(len(challenges))

        # Evaluation of the PUF in order to measure the stability
        for i in range(self.iterations):
            eval_array = eval_array + instance.eval(challenges)

        # Calculation of the stability for every challenge
        stab_array = (np.abs(eval_array) + self.iterations) / (2 *
                                                               self.iterations)
        # Number which counts the satisfying challenges
        num_goal_fulfilled = 0
        # Check of the desired_stability
        for i in range(self.N):
            if stab_array[i] >= self.desired_stability:
                num_goal_fulfilled += 1
        # Relative frequency
        self.overall_stab = num_goal_fulfilled / self.N
예제 #2
0
    def test_transformations_combiner(self):
        """
        This test checks all combinations of transformations and combiners for SimulationMajorityLTFArray to run.
        """
        noise_prng = RandomState(seed=0xC0FFEE)
        weight_prng1 = RandomState(seed=0xBADA55)
        crp_count = 16  # number of random inputs per test set
        n = 64
        k = 2
        mu = 0
        sigma = 1
        vote_count = 1
        weight_array = LTFArray.normal_weights(n, k, mu, sigma, weight_prng1)

        inputs = tools.random_inputs(
            n, crp_count, random_instance=RandomState(seed=0xDEADDA7A))

        combiners = get_functions_with_prefix('combiner_',
                                              SimulationMajorityLTFArray)
        transformations = get_functions_with_prefix(
            'transform_', SimulationMajorityLTFArray)

        for transformation in transformations:
            for combiner in combiners:
                mv_noisy_ltf_array = SimulationMajorityLTFArray(
                    weight_array=weight_array,
                    transform=transformation,
                    combiner=combiner,
                    sigma_noise=1,
                    random_instance_noise=noise_prng,
                    vote_count=vote_count,
                )
                mv_noisy_ltf_array.eval(inputs)
예제 #3
0
 def run(self):
     inputs = random_inputs(self.parameters.n, self.parameters.N,
                            RandomState(self.parameters.seed))
     self.responses = self.instance.val(inputs)
     self.uniqueness = zeros(shape=(self.parameters.k, self.parameters.k))
     for (idx1, i1), (idx2, i2) in combinations(
             enumerate(self.individual_instances), 2):
         self.uniqueness[idx1,
                         idx2] = average(i1.eval(inputs) * i2.eval(inputs))
예제 #4
0
    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)
예제 #5
0
 def test_chi_vectorized(self):
     """This function checks the return type of this function."""
     n = 8
     N = 2**int(n / 2)
     s = random_input(n)
     inputs = random_inputs(n, N)
     chi_arr = chi_vectorized(s, inputs)
     self.assertEqual(len(chi_arr), N,
                      'The array must contain {0} arrays.'.format(N))
     self.assertEqual(chi_arr.dtype, BIT_TYPE,
                      'The array must be of type {0}'.format(BIT_TYPE))
예제 #6
0
    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)
예제 #7
0
 def test_poly_mult_div(self):
     """This method checks the shape and type of two dimensional arrays."""
     n = 8
     k = 2
     N = 2**int(n / 2)
     challenges_11 = random_inputs(n, N)
     challenges_01 = array(
         [transform_challenge_11_to_01(c) for c in challenges_11],
         dtype=BIT_TYPE)
     irreducible_polynomial = array([1, 0, 1, 0, 0, 1, 1, 0, 1],
                                    dtype=BIT_TYPE)
     poly_mult_div(challenges_01, irreducible_polynomial, k)
     self.check_multi_dimensional_array(challenges_01, N, n, BIT_TYPE)
예제 #8
0
    def test_ltf_eval(self):
        """
        Test ltf_eval for correct evaluation of LTFs.
        """

        weight_prng_1 = RandomState(seed=0xBADA55)
        weight_prng_2 = RandomState(seed=0xBADA55)
        noise_prng_1 = RandomState(seed=0xC0FFEE)
        noise_prng_2 = RandomState(seed=0xC0FFEE)

        N = 100  # number of random inputs per test set

        for test_parameters in self.test_set:
            n = test_parameters[0]
            k = test_parameters[1]
            mu = test_parameters[2]
            sigma = test_parameters[3]

            transformed_inputs = LTFArray.transform_id(
                tools.random_inputs(
                    n, N, random_instance=RandomState(seed=0xBAADA555)), k)

            ltf_array = LTFArray(
                weight_array=LTFArray.normal_weights(n, k, mu, sigma,
                                                     weight_prng_1),
                transform=LTFArray.transform_id,
                combiner=LTFArray.combiner_xor,
            )

            noisy_ltf_array = NoisyLTFArray(
                weight_array=LTFArray.normal_weights(n, k, mu, sigma,
                                                     weight_prng_2),
                # weight_prng_2 was seeded identically to weight_prng_1
                transform=LTFArray.transform_id,
                combiner=LTFArray.combiner_xor,
                sigma_noise=1,
                random_instance=noise_prng_1,
            )

            evaled_ltf_array = ltf_array.ltf_eval(transformed_inputs)
            assert_array_equal(
                around(evaled_ltf_array + noise_prng_2.normal(
                    loc=0, scale=1, size=(len(evaled_ltf_array), k)),
                       decimals=10),
                around(noisy_ltf_array.ltf_eval(transformed_inputs),
                       decimals=10))
예제 #9
0
    def test_ltf_eval(self):
        """
        Test ltf_eval for correct evaluation of LTFs.
        """

        N = 100  # number of random inputs per test set

        def ltf_eval_slow(challenge, weights):
            """
            evaluate a single challenge with a single ltf specified by weights
            """
            assert len(challenge) == len(weights) - 1
            return dot(challenge,
                       weights[:n]) + weights[n]  # weights[n] is the bias

        for test_parameters in self.test_set:
            n = test_parameters[0]
            k = test_parameters[1]
            mu = test_parameters[2]
            sigma = test_parameters[3]

            inputs = tools.random_inputs(n,
                                         N,
                                         random_instance=RandomState(0xA1))

            ltf_array = LTFArray(
                weight_array=LTFArray.normal_weights(n, k, mu, sigma),
                transform=LTFArray.transform_id,
                combiner=LTFArray.combiner_xor,
            )

            fast_evaluation_result = around(ltf_array.ltf_eval(
                LTFArray.transform_id(inputs, k)),
                                            decimals=8)
            slow_evaluation_result = []
            for challenge in inputs:
                slow_evaluation_result.append([
                    ltf_eval_slow(challenge, ltf_array.weight_array[l])
                    for l in range(k)
                ])
            slow_evaluation_result = around(slow_evaluation_result, decimals=8)

            self.assertTupleEqual(shape(slow_evaluation_result), (N, k))
            self.assertTupleEqual(shape(fast_evaluation_result), (N, k))
            assert_array_equal(slow_evaluation_result, fast_evaluation_result)
예제 #10
0
 def test_random_inputs(self):
     """This checks the shape and type of the returned multidimensional array."""
     n = 8
     N = 2**(int(n / 2))
     rand_arrays = random_inputs(n, N)
     self.check_multi_dimensional_array(rand_arrays, N, n, BIT_TYPE)
예제 #11
0
 def run(self):
     self.responses = self.instance.eval(
         random_inputs(self.parameters.n, self.parameters.N,
                       RandomState(self.parameters.seed)))