optimize
This commit is contained in:
parent
9876dcff1f
commit
bc068c75a4
|
@ -66,49 +66,50 @@ def align(db, ntraces):
|
|||
alignments[i] = lag
|
||||
|
||||
alignments -= numpy.min(alignments)
|
||||
max_start = max(alignments)
|
||||
min_end = 700
|
||||
|
||||
traces = numpy.zeros((ntraces, 800), 'double')
|
||||
for i in range(ntraces):
|
||||
traces[i, alignments[i]:alignments[i]+700] = db["traces"][i]
|
||||
|
||||
return traces
|
||||
return traces[:, max_start:min_end]
|
||||
|
||||
|
||||
def main(db):
|
||||
ntraces = 1000
|
||||
traces = 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
|
||||
class Correlator:
|
||||
def __init__(self, P):
|
||||
self.P = P - numpy.mean(P, axis=0)
|
||||
self.tmp1 = numpy.einsum("nm,nm->m", self.P, self.P, optimize='optimal')
|
||||
self.P = self.P.transpose()
|
||||
|
||||
# for i in range(10):
|
||||
# plt.plot(traces[i], color=numpy.hstack((numpy.random.random(3), [0.5])))
|
||||
# plt.show()
|
||||
def corr_submatrix(self, O):
|
||||
O -= numpy.mean(O, axis=0)
|
||||
numerator = self.P @ O
|
||||
tmp2 = numpy.einsum("nt,nt->t", O, O, optimize='optimal')
|
||||
denominator = numpy.sqrt(numpy.outer(self.tmp1, tmp2))
|
||||
return numerator / denominator
|
||||
|
||||
logger.info("making model")
|
||||
|
||||
def attack_firstorder(db, traces, ntraces):
|
||||
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")
|
||||
|
||||
# O - (n,t) array of n traces with t samples each
|
||||
# P - (n,m) array of n predictions for each of the m candidates
|
||||
# returns an (m,t) correaltion matrix of m traces t samples each
|
||||
def corr_submatrix(O, P):
|
||||
O -= numpy.mean(O, axis=0)
|
||||
P -= numpy.mean(P, axis=0)
|
||||
|
||||
numerator = numpy.einsum("nm,nt->mt", P, O, optimize='optimal')
|
||||
denominator = numpy.sqrt(numpy.outer((P * P).sum(axis=0), (O * O).sum(axis=0)))
|
||||
|
||||
return numerator / denominator
|
||||
model = numpy_popcount.popcount(model).astype("double").transpose()
|
||||
|
||||
# boring, slow, uses too much RAM
|
||||
# input_matrix = numpy.vstack((model, traces.transpose()))
|
||||
# coefs = numpy.corrcoef(input_matrix)[0:256, 256:]
|
||||
|
||||
# uwu
|
||||
coefs = corr_submatrix(traces, model.transpose())
|
||||
correlator = Correlator(model)
|
||||
coefs = correlator.corr_submatrix(traces)
|
||||
|
||||
# plot absmax
|
||||
coefs = numpy.abs(coefs)
|
||||
|
@ -116,35 +117,56 @@ def main(db):
|
|||
plt.plot(max_by_key)
|
||||
plt.show()
|
||||
|
||||
# logger.info("making 2nd order")
|
||||
# traces = traces.transpose()
|
||||
# traces_x = numpy.zeros((700*699//2, ntraces), 'double')
|
||||
# tx_i = 0
|
||||
# for i in tqdm.trange(700):
|
||||
# for j in range(i+1, 700):
|
||||
# traces_x[tx_i, :] = numpy.abs(traces[i, :] - traces[j, :])
|
||||
# tx_i += 1
|
||||
#
|
||||
# logger.info("doing corr")
|
||||
# ncolumns = 100
|
||||
# step = traces_x.shape[0] // ncolumns
|
||||
# all_coefs = None
|
||||
# for i in tqdm.trange(ncolumns):
|
||||
# start = i * step
|
||||
# end = (i + 1) * step
|
||||
# input_matrix = numpy.vstack((model, traces_x[start:end, :]))
|
||||
# coefs = numpy.corrcoef(input_matrix)[0:256, 256:]
|
||||
# if all_coefs is None:
|
||||
# all_coefs = coefs
|
||||
# else:
|
||||
# all_coefs = numpy.hstack((all_coefs, coefs))
|
||||
#
|
||||
#
|
||||
# all_coefs = numpy.abs(all_coefs)
|
||||
# max_by_key = numpy.max(all_coefs, axis=1)
|
||||
# plt.plot(max_by_key)
|
||||
|
||||
def attack_secondorder(db, traces, ntraces):
|
||||
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]
|
||||
model = numpy_popcount.popcount(model).astype("double").transpose()
|
||||
|
||||
logger.info("making second order combinations")
|
||||
nticks = traces.shape[1]
|
||||
traces_x = numpy.zeros((ntraces, nticks*(nticks - 1)//2), 'double')
|
||||
tx_i = 0
|
||||
for i in tqdm.trange(nticks):
|
||||
for j in range(i+1, nticks):
|
||||
traces_x[:, tx_i] = numpy.abs(traces[:, i] - traces[:, j])
|
||||
tx_i += 1
|
||||
|
||||
logger.info("doing corr")
|
||||
correlator = Correlator(model)
|
||||
ncolumns = 10
|
||||
step = traces_x.shape[1] // ncolumns
|
||||
all_coefs = []
|
||||
for i in tqdm.trange(ncolumns):
|
||||
start = i * step
|
||||
end = (i + 1) * step
|
||||
coefs = correlator.corr_submatrix(traces_x[:, start:end])
|
||||
|
||||
all_coefs.append(coefs)
|
||||
|
||||
all_coefs = numpy.hstack(all_coefs)
|
||||
|
||||
all_coefs = numpy.abs(all_coefs)
|
||||
max_by_key = numpy.max(all_coefs, axis=1)
|
||||
plt.plot(max_by_key)
|
||||
plt.show()
|
||||
|
||||
def main(db):
|
||||
ntraces = 2000
|
||||
traces = align(db, ntraces)
|
||||
|
||||
# for i in range(10):
|
||||
# plt.plot(traces[i], color=numpy.hstack((numpy.random.random(3), [0.5])))
|
||||
# plt.show()
|
||||
|
||||
attack_firstorder(db, traces, ntraces)
|
||||
attack_secondorder(db, traces, ntraces)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from tqdm.contrib.logging import logging_redirect_tqdm
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 23 KiB |
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Loading…
Reference in New Issue