sca/ascad: fft methods

This commit is contained in:
xenia 2021-05-17 21:43:30 -04:00
parent 07482a4c58
commit 62e0abb3ae
2 changed files with 83 additions and 0 deletions

View File

@ -1 +1,2 @@
/ASCAD_databases
__pycache__

View File

@ -6,8 +6,10 @@ logger = logging.getLogger(__name__)
import h5py
import matplotlib.pyplot as plt
import numpy
import scipy.fft
import scipy.signal
import tqdm
# import opt_einsum
import numpy_popcount
@ -79,6 +81,7 @@ def align(db, ntraces):
# P - (n,m) array of n predictions for each of the m candidates
# O - (n,t) array of n traces with t samples each
# returns an (m,t) correlation matrix of m traces t samples each
# TODO : is opt_einsum faster?
class Correlator:
def __init__(self, P):
self.P = P - numpy.mean(P, axis=0)
@ -118,6 +121,80 @@ def attack_firstorder(db, traces, ntraces):
plt.show()
def attack_firstorder_fft(db, traces, ntraces):
# lol
ntraces = 2000
db = h5py.File("./ASCAD_databases/ASCAD_desync100.h5", "r")["Attack_traces"]
traces = db["traces"][0:ntraces, :].astype("double")
logger.info("making first order model")
model = numpy.repeat(numpy.arange(256, dtype='uint8'), ntraces).reshape((256, ntraces))
for i in tqdm.trange(ntraces):
(pt, ct, key, mask, desync) = db["metadata"][i]
pt_v = pt[2]
mask_v = mask[15]
model[:, i] = AES_SBOX[model[:, i] ^ pt_v] ^ mask_v
model = numpy_popcount.popcount(model).astype("double").transpose()
logger.info("making fft traces")
fft_traces = numpy.zeros(traces.shape, traces.dtype)
for i in range(traces.shape[0]):
fft_traces[i, :] = numpy.abs(scipy.fft.fft(traces[i, :]))
traces = fft_traces[:, 1:350]
avg = numpy.mean(traces, axis=0)
peaks = avg.argsort()[-50:][::-1]
traces = numpy.hstack([traces[:, i:i+1] for i in peaks])
correlator = Correlator(model)
coefs = correlator.corr_submatrix(traces)
# plot absmax
coefs = numpy.abs(coefs)
max_by_key = numpy.max(coefs, axis=1)
plt.plot(max_by_key)
plt.show()
# def attack_secondorder_fft(db, traces, ntraces):
# # needs work
# # lol
# ntraces = 10000
# db = h5py.File("./ASCAD_databases/ASCAD.h5", "r")["Attack_traces"]
# traces = db["traces"][0:ntraces, :].astype("double")
#
# logger.info("making second order model")
# model = numpy.repeat(numpy.arange(256, dtype='uint8'), ntraces).reshape((256, ntraces))
# for i in tqdm.trange(ntraces):
# (pt, ct, key, mask, desync) = db["metadata"][i]
# pt_v = pt[2]
# mask_v = mask[15]
# model[:, i] = AES_SBOX[model[:, i] ^ pt_v] ^ mask_v
# model = numpy_popcount.popcount(model).astype("double").transpose()
#
# logger.info("making fft traces")
# fft_traces = numpy.zeros((traces.shape[0], traces.shape[1]), traces.dtype)
# for i in range(traces.shape[0]):
# fft_i = numpy.abs(scipy.fft.fft(traces[i, :]))
# conv_i = numpy.abs(numpy.conj(fft_i) * fft_i)
# fft_traces[i, :] = conv_i
#
# traces = fft_traces
# # traces = fft_traces[:, 1:350]
# # avg = numpy.mean(traces, axis=0)
# # peaks = avg.argsort()[-50:][::-1]
# # traces = numpy.hstack([traces[:, i:i+1] for i in peaks])
#
# correlator = Correlator(model)
# coefs = correlator.corr_submatrix(traces)
#
# # plot absmax
# coefs = numpy.abs(coefs)
# max_by_key = numpy.max(coefs, axis=1)
# plt.plot(max_by_key)
# plt.show()
def attack_secondorder(db, traces, ntraces):
logger.info("making second order model")
model = numpy.repeat(numpy.arange(256, dtype='uint8'), ntraces).reshape((256, ntraces))
@ -157,6 +234,11 @@ def attack_secondorder(db, traces, ntraces):
def main(db):
ntraces = 2000
# traces = None
# attack_firstorder_fft(db, traces, ntraces)
# return
traces = align(db, ntraces)
# for i in range(10):