A Python package for simulating delay-based Physical Unclonable Functions (PUFs) using Lim's Linear Additive Delay Model (LADM). This module supports Arbiter PUFs (APUFs) and XORPUFs. Provides challenge generation, response simulation (with noise), and bit-packing utilities.
-
$d$ -layer Arbiter PUF (APUF): simulate$d$ layers, compute$k$ -bit responses given$k$ challenges ($d$ -bit binary vectors). -
XORPUF (
XORPUF): simulate multiple APUF instances, compute responses and XOR them for increased complexity. -
Challenge generators:
generate_k_challenges(k, d, seed)generate_n_k_challenges(n, k, d, seed)-
generate_challenges_mp(n, k, d, seed, processes)for parallel batch generation.
-
Response data-type (
Response): BothAPUFandXORPUFreturn a$k$ -bit response given$k$ challenges.Responseprovides a conventient interface to study PUF challenge-response behaviours.
pip install apufRequires Python 3.9+ and
numpy.
Import the module and call the functions directly:
from apuf import APUF, XORPUF, generate_k_challenges
# 1) Single APUF
apuf = APUF(d=64, mean=0.0, std=0.05)
# 2) Generate 10 random challenges (phase vectors)
chals = generate_k_challenges(k=10, d=64, seed=42) # shape (65, 10)
# 3) Measure responses twice with Gaussian noise (mean=0, std=0.005)
resp1 = apuf.get_responses(chals, nmean=0.0, nstd=0.005)
resp2 = apuf.get_responses(chals, nmean=0.0, nstd=0.005)
# 4) Due to measurement noise, resp1 and resp2 may be different
diff = resp1 - resp2
# 4.1) We can compute Hamming distance
hamming_distance = resp1.dist(resp2)
# 4.2) And fractional/normalized HD
fHD = resp1.dist(resp2)/len(resp1)
# 5) Pack responses into bytes for convenience
resp_bytes = APUF.compact_responses(resp)
print(resp, resp_bytes)Below you will find a short reference for the core classes and functions.
Response - Represents a PUF response vector.
- Bitwise operations:
^,&,|,~ .dist(other)returns Hamming distance..hwreturns Hamming weight (number of 1s).
APUF(d: int = 128, mean: float = 0.0, std: float = 0.05) - Simulates a single APUF.
get_responses(chals: np.ndarray, nmean: float = 0.0, nstd: float = 0.005) -> Responsecompact_responses(resp: Response) -> bytes
XORPUF(children: list[APUF]) - Simulates an XORPUF by XORing responses of child APUFs.
get_responses(chals: np.ndarray) -> Response
generate_k_challenges(k: int, d: int, seed: int = None) -> np.ndarraygenerate_n_k_challenges(n: int, k: int, d: int, seed: int = None) -> np.ndarraygenerate_challenges_mp(n: int, k: int, d: int, seed: int = None, processes: int = cpu_count()) -> list[np.ndarray]
Full docstrings and type hints are available in code.
Run the provided unit tests with unittest:
git clone https://github.com/nikita-tripathi-geo/APUF-simulation.git
cd APUF-simulation
pip install -r requirements.txt
python -m unittest tests/*.pyContributions, issues and feature requests are welcome! Please see Issues.
This project is licensed under the MIT License – see the LICENSE file for details.
MIT License (c) Nikita Tripathi