Overview
Generating Uniform Random Challenges
- pypuf.io.random_inputs(n: int, N: int, seed: int) ndarray
Generates \(N\) uniformly random challenges of length n and returns them as a numpy.ndarray of shape \((N, n)\). The randomness is based on the provided
seed.Note
pypuf uses \(\{-1,1\}\) to represent bit values for both challenges and responses. To convert from \(\{-1,1\}\) notation to the more traditional \(\{0,1\}\) encoding, use
x = (1 - x) // 2. For the reverse conversion, usex = 1 - 2*x>>> import numpy as np >>> import pypuf.io >>> challenges = pypuf.io.random_inputs(n=64, N=10, seed=1) >>> np.unique(challenges) array([-1, 1], dtype=int8) >>> challenges01 = (1 - challenges) // 2 >>> np.unique(challenges01) array([0, 1], dtype=int8) >>> challenges11 = 1 - 2 * challenges01 >>> (challenges11 == challenges).all() True
Storing Challenge-Response Data
pypuf stores challenge-response data in objects of the class pypuf.io.ChallengeResponseSet.
These objects contain two numpy arrays with the challenges and responses, respectively and provide a number of
auxiliary functions for convenient management.
To create a instance of pypuf.io.ChallengeResponseSet for given challenges and responses, use
>>> import numpy as np
>>> challenges = np.array([[-1, -1, -1, -1], [-1, -1, -1, 1]])
>>> responses = np.array([1, 1])
>>> import pypuf.io
>>> crp = pypuf.io.ChallengeResponseSet(challenges, responses)
To create an instance of pypuf.io.ChallengeResponseSet from a pypuf.simulation.Simulation, use
>>> import pypuf.simulation
>>> puf = pypuf.simulation.ArbiterPUF(n=64, seed=1)
>>> import pypuf.io
>>> crp = pypuf.io.ChallengeResponseSet.from_simulation(puf, N=1000, seed=2)
pypuf CRP data can be stored on disk and loaded back into pypuf:
>>> crp = pypuf.io.ChallengeResponseSet.from_simulation(puf, N=1000, seed=2)
>>> crp.save('crps.npz')
>>> crp_loaded = pypuf.io.ChallengeResponseSet.load('crps.npz')
>>> crp == crp_loaded
True
pypuf.io.ChallengeResponseSet can also be sliced to obtain a single challenge-response pair or to get a
subset of CRPs:
>>> crp = pypuf.io.ChallengeResponseSet.from_simulation(puf, N=1000, seed=2)
>>> crp[0]
(array([-1,...), array([[1.]]))
>>> crp[:10]
<10 CRPs with challenge length 64 and response length 1, each response measured 1 time(s)>
- class pypuf.io.ChallengeResponseSet(challenges: ndarray, responses: ndarray)
- __init__(challenges: ndarray, responses: ndarray) None
Create a challenge-response object containing the given challenges and responses of a PUF token.
- Parameters:
challenges (numpy.ndarray) – Challenges to the PUF token organized as array of shape \((N, n)\), where \(N\) is the number of challenges and \(n\) is the challenge length.
responses (numpy.ndarray) – Responses of the PUF token organized as array of shape \((N, m, r)\), where \(N\) is the number of challenges, \(m\) is the response length, and \(r\) is the number of measurements per challenge. The last axis is optional.
- property challenge_length: int
The length \(n\) of the recorded challenges.
- classmethod load(f: str) object
Loads CRPs from the given file
f.
- property response_length: int
The length \(m\) of the recorded responses.
- save(f: str) None
Saves the CRPs to the given file
f.