optimize
This commit is contained in:
parent
9876dcff1f
commit
bc068c75a4
|
@ -66,49 +66,50 @@ def align(db, ntraces):
|
||||||
alignments[i] = lag
|
alignments[i] = lag
|
||||||
|
|
||||||
alignments -= numpy.min(alignments)
|
alignments -= numpy.min(alignments)
|
||||||
|
max_start = max(alignments)
|
||||||
|
min_end = 700
|
||||||
|
|
||||||
traces = numpy.zeros((ntraces, 800), 'double')
|
traces = numpy.zeros((ntraces, 800), 'double')
|
||||||
for i in range(ntraces):
|
for i in range(ntraces):
|
||||||
traces[i, alignments[i]:alignments[i]+700] = db["traces"][i]
|
traces[i, alignments[i]:alignments[i]+700] = db["traces"][i]
|
||||||
|
|
||||||
return traces
|
return traces[:, max_start:min_end]
|
||||||
|
|
||||||
|
|
||||||
def main(db):
|
# P - (n,m) array of n predictions for each of the m candidates
|
||||||
ntraces = 1000
|
# O - (n,t) array of n traces with t samples each
|
||||||
traces = align(db, ntraces)
|
# 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):
|
def corr_submatrix(self, O):
|
||||||
# plt.plot(traces[i], color=numpy.hstack((numpy.random.random(3), [0.5])))
|
O -= numpy.mean(O, axis=0)
|
||||||
# plt.show()
|
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))
|
model = numpy.repeat(numpy.arange(256, dtype='uint8'), ntraces).reshape((256, ntraces))
|
||||||
for i in tqdm.trange(ntraces):
|
for i in tqdm.trange(ntraces):
|
||||||
(pt, ct, key, mask, desync) = db["metadata"][i]
|
(pt, ct, key, mask, desync) = db["metadata"][i]
|
||||||
pt_v = pt[2]
|
pt_v = pt[2]
|
||||||
mask_v = mask[15]
|
mask_v = mask[15]
|
||||||
model[:, i] = AES_SBOX[model[:, i] ^ pt_v] ^ mask_v
|
model[:, i] = AES_SBOX[model[:, i] ^ pt_v] ^ mask_v
|
||||||
model = numpy_popcount.popcount(model).astype("double")
|
model = numpy_popcount.popcount(model).astype("double").transpose()
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# boring, slow, uses too much RAM
|
# boring, slow, uses too much RAM
|
||||||
# input_matrix = numpy.vstack((model, traces.transpose()))
|
# input_matrix = numpy.vstack((model, traces.transpose()))
|
||||||
# coefs = numpy.corrcoef(input_matrix)[0:256, 256:]
|
# coefs = numpy.corrcoef(input_matrix)[0:256, 256:]
|
||||||
|
|
||||||
# uwu
|
# uwu
|
||||||
coefs = corr_submatrix(traces, model.transpose())
|
correlator = Correlator(model)
|
||||||
|
coefs = correlator.corr_submatrix(traces)
|
||||||
|
|
||||||
# plot absmax
|
# plot absmax
|
||||||
coefs = numpy.abs(coefs)
|
coefs = numpy.abs(coefs)
|
||||||
|
@ -116,35 +117,56 @@ def main(db):
|
||||||
plt.plot(max_by_key)
|
plt.plot(max_by_key)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
# logger.info("making 2nd order")
|
|
||||||
# traces = traces.transpose()
|
def attack_secondorder(db, traces, ntraces):
|
||||||
# traces_x = numpy.zeros((700*699//2, ntraces), 'double')
|
logger.info("making second order model")
|
||||||
# tx_i = 0
|
model = numpy.repeat(numpy.arange(256, dtype='uint8'), ntraces).reshape((256, ntraces))
|
||||||
# for i in tqdm.trange(700):
|
for i in tqdm.trange(ntraces):
|
||||||
# for j in range(i+1, 700):
|
(pt, ct, key, mask, desync) = db["metadata"][i]
|
||||||
# traces_x[tx_i, :] = numpy.abs(traces[i, :] - traces[j, :])
|
pt_v = pt[2]
|
||||||
# tx_i += 1
|
mask_v = mask[15]
|
||||||
#
|
model[:, i] = AES_SBOX[model[:, i] ^ pt_v]
|
||||||
# logger.info("doing corr")
|
model = numpy_popcount.popcount(model).astype("double").transpose()
|
||||||
# ncolumns = 100
|
|
||||||
# step = traces_x.shape[0] // ncolumns
|
logger.info("making second order combinations")
|
||||||
# all_coefs = None
|
nticks = traces.shape[1]
|
||||||
# for i in tqdm.trange(ncolumns):
|
traces_x = numpy.zeros((ntraces, nticks*(nticks - 1)//2), 'double')
|
||||||
# start = i * step
|
tx_i = 0
|
||||||
# end = (i + 1) * step
|
for i in tqdm.trange(nticks):
|
||||||
# input_matrix = numpy.vstack((model, traces_x[start:end, :]))
|
for j in range(i+1, nticks):
|
||||||
# coefs = numpy.corrcoef(input_matrix)[0:256, 256:]
|
traces_x[:, tx_i] = numpy.abs(traces[:, i] - traces[:, j])
|
||||||
# if all_coefs is None:
|
tx_i += 1
|
||||||
# all_coefs = coefs
|
|
||||||
# else:
|
logger.info("doing corr")
|
||||||
# all_coefs = numpy.hstack((all_coefs, coefs))
|
correlator = Correlator(model)
|
||||||
#
|
ncolumns = 10
|
||||||
#
|
step = traces_x.shape[1] // ncolumns
|
||||||
# all_coefs = numpy.abs(all_coefs)
|
all_coefs = []
|
||||||
# max_by_key = numpy.max(all_coefs, axis=1)
|
for i in tqdm.trange(ncolumns):
|
||||||
# plt.plot(max_by_key)
|
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()
|
# plt.show()
|
||||||
|
|
||||||
|
attack_firstorder(db, traces, ntraces)
|
||||||
|
attack_secondorder(db, traces, ntraces)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from tqdm.contrib.logging import logging_redirect_tqdm
|
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