diff --git a/sca/ascad/.gitignore b/sca/ascad/.gitignore index a2a8af1..7493065 100644 --- a/sca/ascad/.gitignore +++ b/sca/ascad/.gitignore @@ -1 +1,2 @@ /ASCAD_databases +__pycache__ diff --git a/sca/ascad/attack.py b/sca/ascad/attack.py index cf7b84f..33e26e4 100644 --- a/sca/ascad/attack.py +++ b/sca/ascad/attack.py @@ -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):