-
Notifications
You must be signed in to change notification settings - Fork 0
/
LR_attack_XORPUF.py
101 lines (80 loc) · 3.3 KB
/
LR_attack_XORPUF.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# -*- coding: utf-8 -*-
"""
Created on Wed Sep 27 14:21:08 2023
@author: Mieszko Ferens
Script to run an experiment for modelling an XOR Arbiter PUF using LR.
"""
import argparse
import pandas as pd
from pathlib import Path
import numpy as np
from pypuf.simulation import XORArbiterPUF
from pypuf.io import random_inputs
import pypuf.attack
class ChallengeResponseSet():
def __init__(self, n, challenges, responses):
self.challenge_length = n
self.challenges = challenges
self.responses = np.expand_dims(
np.expand_dims(responses,axis=1),axis=1)
def main():
# Set-up logging
import logging
logging.basicConfig(level=logging.DEBUG)
# Parse arguments
parser = argparse.ArgumentParser()
parser.add_argument("--outdir", type=str, default="./Results/")
parser.add_argument("--seed", type=int, default=0, help="Random seed.")
parser.add_argument("--n-bits", type=int, default=64,
help="Challenge length in bits.")
parser.add_argument("--k", type=int, default=1,
help="Number of parallel APUFs in the XOR PUF.")
parser.add_argument("--train-data", type=int, default=50000,
help="Number of training data samples for the model.")
parser.add_argument("--test-data", type=int, default=10000,
help="Number of testing data samples for the model.")
args = parser.parse_args()
# Generate the PUF
puf = XORArbiterPUF(args.n_bits, args.k, args.seed)
# Generate the challenges
challenges = random_inputs(
args.n_bits, args.train_data + args.test_data, args.seed)
# Get responses
responses = puf.eval(challenges)
# Split the data into training and testing
train = args.train_data
test = train + args.test_data
# Prepare the data for training and testing
train_crps = ChallengeResponseSet(
args.n_bits, np.array(challenges[:train], dtype=np.int8),
np.array(responses[:train], dtype=np.float64))
test_x = challenges[train:test]
test_y = np.expand_dims(0.5 - 0.5*responses[train:test], axis=1)
# Use an LR as a predictor
model = pypuf.attack.LRAttack2021(
train_crps, seed=args.seed, k=args.k, epochs=100, lr=.001, bs=1000,
stop_validation_accuracy=.97)
# Train the model
model.fit()
# Test the model
pred_y = model._model.eval(test_x)
pred_y = pred_y.reshape(len(pred_y), 1)
# Calculate accuracy
accuracy = np.count_nonzero(((pred_y<0.5) + test_y)-1)/len(test_y)
print("---\n" +
"Accuracy in the testing data: " + str(accuracy*100) + "%")
# Log data into csv format
data = pd.DataFrame({"seed": [args.seed],
"n_bits": [args.n_bits],
"k": [args.k],
"train_data": [args.train_data],
"test_data": [args.test_data],
"accuracy": [accuracy]})
filepath = Path(args.outdir + "out_LR_" + str(args.k) + "XOR.csv")
if(filepath.is_file()):
data.to_csv(filepath, header=False, index=False, mode='a')
else:
filepath.parent.mkdir(parents=True, exist_ok=True)
data.to_csv(filepath, header=True, index=False, mode='a')
if(__name__ == "__main__"):
main()