Base Class for Simulations

Batch Evaluation

pypuf PUF simulations are build to evaluate several given challenges at once, to provide better performance. The interfaces are defined accordingly, see below.

Adding Simulations

Simulations should extend the base class simulation.Simulation and provide a instantiation function that takes a seed argument for reproducible results. Weak PUFs can be added by setting challenge_length to zero.

API

class pypuf.simulation.Simulation

A PUF simulation that can be evaluated on challenges.

property challenge_length: int

The expected challenge length of this simulation, int.

property response_length: int

The length of responses generated by this simulation, int.

eval(challenges: ndarray) ndarray

Evaluate the PUF on a list of given challenges.

Parameters:

challenges – List of challenges to evaluate on. Challenges must be given as ndarray of shape (\(N\), challenge_length), where \(N\) is the number of challenges to be evaluated. Evaluating many challenges at once may have performance benefits, to evaluate a single challenge, provide an ndarray with shape (1, challenge_length). In cases where challenge_length = 0, an empty array with shape (\(N\), 0) needs to be provided to determine the number of responses requested.

Returns:

ndarray, shape (\(N\), response_length), listing the simulated responses to the challenges in order they were given.

r_eval(r: int, challenges: ndarray) ndarray

Evaluates the Simulation r times on the list of \(N\) challenges given and returns an array of shape (r, \(N\), self.response_length) of all responses.

>>> from pypuf.simulation import XORArbiterPUF
>>> from pypuf.io import random_inputs
>>> puf = XORArbiterPUF(n=64, k=4, noisiness=.02, seed=1)
>>> responses = puf.r_eval(5, random_inputs(N=2, n=64, seed=4))
>>> responses[0, :, :]  # unstable example
array([[ 1.,  1., -1., -1., -1.]])
>>> responses[1, :, :]  # stable example
array([[1., 1., 1., 1., 1.]])

Note

To approximate the expected respones value, use average along the last axis:

>>> from numpy import average
>>> average(responses, axis=-1)
array([[-0.2],
       [ 1. ]])
static seed(description: str) int

Helper function that turns a string into an integer that can be consumed as seed by a pseudo-random number generator (PRNG). Usage scenario: create a descriptive seed and use it to initialize the PRNG.

>>> from numpy.random import default_rng
>>> from pypuf.simulation import Simulation
>>> seed = 'parameter seed for my PUF instance'
>>> prng = default_rng(seed=Simulation.seed(seed))
>>> parameters = prng.normal(size=(3, 4))
>>> parameters
array([[ 1.64917478, -1.28702893,  0.17287684, -1.69475886],
       [-1.74432269,  1.59592227,  1.12435243, -0.23488442],
       [-0.74190059,  0.95516568, -2.25170753, -0.22208081]])