def __init__(self, parent, showScriptParameter=None, tmanager=None, console=None): super(ProfilingTemplate, self).__init__() if console: self.console = console self.setParent(parent) self._tmanager = None self._project = None resultsParams = [{'name':'Load Template', 'type':'group', 'children':[ ]}, {'name':'Generate New Template', 'type':'group', 'children':[ {'name':'Trace Start', 'key':'tgenstart', 'value':0, 'type':'int', 'set':self.updateScript}, {'name':'Trace End', 'key':'tgenstop', 'value':self.parent().traceMax, 'type':'int', 'set':self.updateScript}, {'name':'POI Selection', 'key':'poimode', 'type':'list', 'values':{'TraceExplorer Table':0, 'Read from Project File':1}, 'value':0, 'set':self.updateScript}, {'name':'Read POI', 'type':'action', 'action':self.updateScript}, {'name':'Generate Templates', 'type':'action', 'action': lambda:self.runScriptFunction.emit("generateTemplates")} ]}, ] self.params = Parameter.create(name='Template Attack', type='group', children=resultsParams) if showScriptParameter is not None: self.showScriptParameter = showScriptParameter # print self.showScriptParameter ExtendedParameter.setupExtended(self.params, self) self.addGroup("generateTemplates") self.sr = None self.stats = DataTypeDiffs() self.setProfileAlgorithm(TemplateBasic)
def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPASimpleLoop, self).__init__() self.model = targetModel self.leakage = leakageFunction self.stats = DataTypeDiffs() self.modelstate = {'knownkey': None}
def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPAProgressive, self).__init__() resultsParams = [{'name':'Iteration Mode', 'key':'itmode', 'type':'list', 'values':{'Depth-First':'df', 'Breadth-First':'bf'}, 'value':'bf'}, {'name':'Skip when PGE=0', 'key':'checkpge', 'type':'bool', 'value':False}, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) if showScriptParameter is not None: self.showScriptParameter = showScriptParameter # print self.showScriptParameter ExtendedParameter.setupExtended(self.params, self) self.model = targetModel self.leakage = leakageFunction self.sr = None self.stats = DataTypeDiffs() self.updateScript()
def __init__(self, model, showScriptParameter=None, parent=None): super(CPAExperimentalChannelinfo, self).__init__() resultsParams = [ { 'name': 'Reporting Interval', 'key': 'reportinterval', 'type': 'int', 'value': 100 }, { 'name': 'Iteration Mode', 'key': 'itmode', 'type': 'list', 'values': { 'Depth-First': 'df', 'Breadth-First': 'bf' }, 'value': 'bf' }, { 'name': 'Skip when PGE=0', 'key': 'checkpge', 'type': 'bool', 'value': False }, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) ExtendedParameter.setupExtended(self.params, self) self.model = model self.sr = None self._parent = parent # print self._parent.parent self.stats = DataTypeDiffs()
def __init__(self, model, showScriptParameter=None, parent=None): super(CPAExperimentalChannelinfo, self).__init__() resultsParams = [{'name':'Reporting Interval', 'key':'reportinterval', 'type':'int', 'value':100}, {'name':'Iteration Mode', 'key':'itmode', 'type':'list', 'values':{'Depth-First':'df', 'Breadth-First':'bf'}, 'value':'bf'}, {'name':'Skip when PGE=0', 'key':'checkpge', 'type':'bool', 'value':False}, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) ExtendedParameter.setupExtended(self.params, self) self.model = model self.sr = None self._parent = parent # print self._parent.parent self.stats = DataTypeDiffs()
class CPAProgressive(AutoScript, QObject): """ CPA Attack done as a loop, but using an algorithm which can progressively add traces & give output stats """ paramListUpdated = Signal(list) def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPAProgressive, self).__init__() resultsParams = [{'name':'Iteration Mode', 'key':'itmode', 'type':'list', 'values':{'Depth-First':'df', 'Breadth-First':'bf'}, 'value':'bf'}, {'name':'Skip when PGE=0', 'key':'checkpge', 'type':'bool', 'value':False}, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) if showScriptParameter is not None: self.showScriptParameter = showScriptParameter # print self.showScriptParameter ExtendedParameter.setupExtended(self.params, self) self.model = targetModel self.leakage = leakageFunction self.sr = None self.stats = DataTypeDiffs() self.updateScript() def updateScript(self, ignored=None): # self.addFunction('init', 'setReportingInterval', '%d' % self.findParam('reportinterval').value()) pass def paramList(self): return [self.params] def setTargetBytes(self, brange): self.brange = brange def setReportingInterval(self, ri): self._reportingInterval = ri def addTraces(self, tracedata, tracerange, progressBar=None, pointRange=None): brange=self.brange self.all_diffs = range(0,16) numtraces = tracerange[1] - tracerange[0] if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256 * (numtraces / self._reportingInterval + 1)) pbcnt = 0 cpa = [None]*(max(brange)+1) for bnum in brange: cpa[bnum] = CPAProgressiveOneSubkey() brangeMap = [None]*(max(brange)+1) i = 1 for bnum in brange: brangeMap[bnum] = i i += 1 skipPGE = False # self.findParam('checkpge').value() bf = True # self.findParam('itmode').value() == 'bf' #bf specifies a 'breadth-first' search. bf means we search across each #subkey by only the amount of traces specified. Depth-First means we #search each subkey completely, then move onto the next. if bf: brange_df = [0] brange_bf = brange else: brange_bf = [0] brange_df = brange for bnum_df in brange_df: tstart = 0 tend = self._reportingInterval while tstart < numtraces: if tend > numtraces: tend = numtraces if tstart > numtraces: tstart = numtraces data = [] textins = [] textouts = [] knownkeys = [] for i in range(tstart, tend): # Handle Offset tnum = i + tracerange[0] d = tracedata.getTrace(tnum) if d is None: continue data.append(d) textins.append(tracedata.getTextin(tnum)) textouts.append(tracedata.getTextout(tnum)) knownkeys.append(tracedata.getKnownKey(tnum)) traces = np.array(data) textins = np.array(textins) textouts = np.array(textouts) # knownkeys = np.array(knownkeys) for bnum_bf in brange_bf: if bf: bnum = bnum_bf else: bnum = bnum_df skip = False if (self.stats.simplePGE(bnum) != 0) or (skipPGE == False): if isinstance(pointRange, list): bptrange = pointRange[bnum] else: bptrange = pointRange (data, pbcnt) = cpa[bnum].oneSubkey(bnum, bptrange, traces, tend - tstart, textins, textouts, knownkeys, progressBar, self.model, self.leakage, cpa[bnum].modelstate, pbcnt) self.stats.updateSubkey(bnum, data, tnum=tend) else: skip = True if progressBar.wasSkipped() or skip: progressBar.clearSkipped() pbcnt = brangeMap[bnum] * 256 * (numtraces / self._reportingInterval + 1) if bf is False: tstart = numtraces tend += self._reportingInterval tstart += self._reportingInterval if self.sr is not None: self.sr() def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): self.sr = sr def processKnownKey(self, inpkey): if hasattr(self.model, 'processKnownKey'): return self.model.processKnownKey(self.leakage, inpkey) else: return inpkey
class ProfilingTemplate(AutoScript, QObject): """ Template Attack done as a loop, but using an algorithm which can progressively add traces & give output stats """ paramListUpdated = Signal(list) notifyUser = Signal(str, str) def __init__(self, parent, showScriptParameter=None, tmanager=None, console=None): super(ProfilingTemplate, self).__init__() if console: self.console = console self.setParent(parent) self._tmanager = None self._project = None resultsParams = [{'name':'Load Template', 'type':'group', 'children':[ ]}, {'name':'Generate New Template', 'type':'group', 'children':[ {'name':'Trace Start', 'key':'tgenstart', 'value':0, 'type':'int', 'set':self.updateScript}, {'name':'Trace End', 'key':'tgenstop', 'value':self.parent().traceMax, 'type':'int', 'set':self.updateScript}, {'name':'POI Selection', 'key':'poimode', 'type':'list', 'values':{'TraceExplorer Table':0, 'Read from Project File':1}, 'value':0, 'set':self.updateScript}, {'name':'Read POI', 'type':'action', 'action':self.updateScript}, {'name':'Generate Templates', 'type':'action', 'action': lambda:self.runScriptFunction.emit("generateTemplates")} ]}, ] self.params = Parameter.create(name='Template Attack', type='group', children=resultsParams) if showScriptParameter is not None: self.showScriptParameter = showScriptParameter # print self.showScriptParameter ExtendedParameter.setupExtended(self.params, self) self.addGroup("generateTemplates") self.sr = None self.stats = DataTypeDiffs() self.setProfileAlgorithm(TemplateBasic) # Not needed as setProfileAlgorithm calls this # self.updateScript() def log(self, s): if hasattr(self, 'console') and self.console: self.console.append(s) def setProfileAlgorithm(self, algo): self.profiling = algo() self.profiling.setTraceManager(self._tmanager) self.profiling.setProject(self._project) self.profiling.scriptsUpdated.connect(self.updateScript) self.updateScript() def updateScript(self, ignored=None): # self.addFunction('init', 'setReportingInterval', '%d' % self.findParam('reportinterval').value()) ted = self.parent().parent().utilList[0].exampleScripts[0] self.addFunction('generateTemplates', 'initAnalysis', '', obj='userScript') self.addVariable('generateTemplates', 'tRange', '(%d, %d)' % (self.findParam('tgenstart').value(), self.findParam('tgenstop').value())) if self.findParam('poimode').value() == 0: self.addVariable('generateTemplates', 'poiList', '%s' % ted.poi.poiArray) self.addVariable('generateTemplates', 'partMethod', '%s()' % ted.partObject.partMethod.__class__.__name__) self.importsAppend("from chipwhisperer.analyzer.utils.Partition import %s" % ted.partObject.partMethod.__class__.__name__) else: poidata = self.loadPOIs()[-1] self.addVariable('generateTemplates', 'poiList', '%s' % poidata["poi"]) self.addVariable('generateTemplates', 'partMethod', '%s()' % poidata["partitiontype"]) self.importsAppend("from chipwhisperer.analyzer.utils.Partition import %s" % poidata["partitiontype"]) self.addFunction('generateTemplates', 'profiling.generate', 'tRange, poiList, partMethod', 'templatedata') #Save template data to project self.addFunction('generateTemplates', 'saveTemplatesToProject', 'tRange, templatedata', 'tfname') self.scriptsUpdated.emit() def paramList(self): return [self.params] def traceLimitsChanged(self, traces, points): tstart = self.findParam('tgenstart') tend = self.findParam('tgenstop') tstart.setLimits((0, traces)) tend.setValue(traces) tend.setLimits((1, traces)) def setByteList(self, brange): self.brange = brange def setKeyround(self, keyround): self.keyround = keyround def setReportingInterval(self, intv): self._reportinginterval = intv def setModeltype(self, modeltype): self.modeltype = modeltype def traceManager(self): return self._tmanager def setTraceManager(self, tmanager): self._tmanager = tmanager # Set for children self.profiling.setTraceManager(tmanager) def setProject(self, proj): self._project = proj # Set for children self.profiling.setProject(proj) def project(self): if self._project is None: self.setProject(self.parent().project()) return self._project def saveTemplatesToProject(self, trange, templatedata): cfgsec = self.project().addDataConfig(sectionName="Template Data", subsectionName="Templates") cfgsec["tracestart"] = trange[0] cfgsec["traceend"] = trange[1] cfgsec["poi"] = templatedata["poi"] cfgsec["partitiontype"] = templatedata["partitiontype"] fname = self.project().getDataFilepath('templates-%s-%d-%d.npz' % (cfgsec["partitiontype"], trange[0], trange[1]), 'analysis') # Save template file np.savez(fname["abs"], **templatedata) # mean=self.profiling.templateMeans, cov=self.profiling.templateCovs) cfgsec["filename"] = fname["rel"] print "Saved template to: %s" % fname["abs"] return fname["abs"] def loadTemplatesFromProject(self): # Load Template foundsecs = self.parent().project().getDataConfig(sectionName="Template Data", subsectionName="Templates") templates = [] for f in foundsecs: fname = self.parent().project().convertDataFilepathAbs(f["filename"]) t = np.load(fname) templates.append(t) # Validate in case someone tries to change via project file if f["partitiontype"] != t["partitiontype"]: print "WARNING: PartitionType for template from .npz file (%s) differs from project file (%s). npz file being used." if (strListToList(str(f["poi"])) != t["poi"]).any(): print "WARNING: POI for template from .npz file (%s) differs from project file (%s). npz file being used." return templates def loadPOIs(self): section = self.project().getDataConfig("Template Data", "Points of Interest") poiList = [] for s in section: poistr = str(s["poi"]) poieval = strListToList(poistr) poiList.append(s.copy()) poiList[-1]["poi"] = poieval return poiList def addTraces(self, traces, plaintexts, ciphertexts, knownkeys=None, progressBar=None, pointRange=None): # Hack for now - just use last template found template = self.loadTemplatesFromProject()[-1] pois = template["poi"] numparts = len(template['mean'][0]) results = np.zeros((16, 256)) tdiff = self._reportinginterval if progressBar: progressBar.setMinimum(0) progressBar.setMaximum(16 * len(traces)) pcnt = 0 for tnum in range(0, len(traces)): for bnum in range(0, 16): newresultsint = [multivariate_normal.logpdf(traces[tnum][pois[bnum]], mean=template['mean'][bnum][i], cov=np.diag(template['cov'][bnum][i])) for i in range(0, numparts)] ptype = template["partitiontype"] if ptype == "PartitionHWIntermediate": newresults = [] # Map to key guess format for i in range(0, 256): # Get hypothetical hamming weight hypint = HypHW(plaintexts[tnum], None, i, bnum) newresults.append(newresultsint[ hypint ]) elif ptype == "PartitionHDLastRound": newresults = [] # Map to key guess format for i in range(0, 256): # Get hypothetical hamming distance # hypint = HypHD(plaintexts[tnum], None, i, bnum) hypint = HypHD(None, ciphertexts[tnum], i, bnum) newresults.append(newresultsint[ hypint ]) else: newresults = newresultsint results[bnum] += newresults self.stats.updateSubkey(bnum, results[bnum], tnum=(tnum + 1)) if progressBar: progressBar.setValue(pcnt) progressBar.updateStatus((tnum, len(traces)), bnum) pcnt += 1 if progressBar.wasCanceled(): raise KeyboardInterrupt # Do plotting if required if (tnum % tdiff) == 0 and self.sr: self.sr() def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): self.sr = sr
class ProfilingTemplate(AutoScript, QObject): """ Template Attack done as a loop, but using an algorithm which can progressively add traces & give output stats """ paramListUpdated = Signal(list) notifyUser = Signal(str, str) def __init__(self, parent, showScriptParameter=None, tmanager=None, console=None): super(ProfilingTemplate, self).__init__() if console: self.console = console self.setParent(parent) self._tmanager = None self._project = None resultsParams = [{'name':'Load Template', 'type':'group', 'children':[ ]}, {'name':'Generate New Template', 'type':'group', 'children':[ {'name':'Trace Start', 'key':'tgenstart', 'value':0, 'type':'int', 'set':self.updateScript}, {'name':'Trace End', 'key':'tgenstop', 'value':self.parent().traceMax, 'type':'int', 'set':self.updateScript}, {'name':'POI Selection', 'key':'poimode', 'type':'list', 'values':{'TraceExplorer Table':0, 'Read from Project File':1}, 'value':0, 'set':self.updateScript}, {'name':'Read POI', 'type':'action', 'action':self.updateScript}, {'name':'Generate Templates', 'type':'action', 'action': lambda:self.runScriptFunction.emit("generateTemplates")} ]}, ] self.params = Parameter.create(name='Template Attack', type='group', children=resultsParams) if showScriptParameter is not None: self.showScriptParameter = showScriptParameter # print self.showScriptParameter ExtendedParameter.setupExtended(self.params, self) self.addGroup("generateTemplates") self.sr = None self.stats = DataTypeDiffs() self.setProfileAlgorithm(TemplateBasic) # Not needed as setProfileAlgorithm calls this # self.updateScript() def log(self, s): if hasattr(self, 'console') and self.console: self.console.append(s) def setProfileAlgorithm(self, algo): self.profiling = algo() self.profiling.setTraceManager(self._tmanager) self.profiling.setProject(self._project) self.profiling.scriptsUpdated.connect(self.updateScript) self.updateScript() def updateScript(self, ignored=None): # self.addFunction('init', 'setReportingInterval', '%d' % self.findParam('reportinterval').value()) ted = self.parent().parent().utilList[0].exampleScripts[0] self.addFunction('generateTemplates', 'initAnalysis', '', obj='userScript') self.addVariable('generateTemplates', 'tRange', '(%d, %d)' % (self.findParam('tgenstart').value(), self.findParam('tgenstop').value())) if self.findParam('poimode').value() == 0: self.addVariable('generateTemplates', 'poiList', '%s' % ted.poi.poiArray) self.addVariable('generateTemplates', 'partMethod', '%s()' % ted.partObject.partMethod.__class__.__name__) self.importsAppend("from chipwhisperer.analyzer.utils.Partition import %s" % ted.partObject.partMethod.__class__.__name__) else: poidata = self.loadPOIs()[-1] self.addVariable('generateTemplates', 'poiList', '%s' % poidata["poi"]) self.addVariable('generateTemplates', 'partMethod', '%s()' % poidata["partitiontype"]) self.importsAppend("from chipwhisperer.analyzer.utils.Partition import %s" % poidata["partitiontype"]) self.addFunction('generateTemplates', 'profiling.generate', 'tRange, poiList, partMethod', 'templatedata') #Save template data to project self.addFunction('generateTemplates', 'saveTemplatesToProject', 'tRange, templatedata', 'tfname') self.scriptsUpdated.emit() def paramList(self): return [self.params] def traceLimitsChanged(self, traces, points): tstart = self.findParam('tgenstart') tend = self.findParam('tgenstop') tstart.setLimits((0, traces)) tend.setValue(traces) tend.setLimits((1, traces)) def setByteList(self, brange): self.brange = brange def setKeyround(self, keyround): self.keyround = keyround def setReportingInterval(self, intv): self._reportinginterval = intv def traceManager(self): return self._tmanager def setTraceManager(self, tmanager): self._tmanager = tmanager # Set for children self.profiling.setTraceManager(tmanager) def setProject(self, proj): self._project = proj # Set for children self.profiling.setProject(proj) def project(self): if self._project is None: self.setProject(self.parent().project()) return self._project def saveTemplatesToProject(self, trange, templatedata): cfgsec = self.project().addDataConfig(sectionName="Template Data", subsectionName="Templates") cfgsec["tracestart"] = trange[0] cfgsec["traceend"] = trange[1] cfgsec["poi"] = templatedata["poi"] cfgsec["partitiontype"] = templatedata["partitiontype"] fname = self.project().getDataFilepath('templates-%s-%d-%d.npz' % (cfgsec["partitiontype"], trange[0], trange[1]), 'analysis') # Save template file np.savez(fname["abs"], **templatedata) # mean=self.profiling.templateMeans, cov=self.profiling.templateCovs) cfgsec["filename"] = fname["rel"] print "Saved template to: %s" % fname["abs"] return fname["abs"] def loadTemplatesFromProject(self): # Load Template foundsecs = self.parent().project().getDataConfig(sectionName="Template Data", subsectionName="Templates") templates = [] for f in foundsecs: fname = self.parent().project().convertDataFilepathAbs(f["filename"]) t = np.load(fname) templates.append(t) # Validate in case someone tries to change via project file if f["partitiontype"] != t["partitiontype"]: print "WARNING: PartitionType for template from .npz file (%s) differs from project file (%s). npz file being used." if (strListToList(str(f["poi"])) != t["poi"]).any(): print "WARNING: POI for template from .npz file (%s) differs from project file (%s). npz file being used." return templates def loadPOIs(self): section = self.project().getDataConfig("Template Data", "Points of Interest") poiList = [] for s in section: poistr = str(s["poi"]) poieval = strListToList(poistr) poiList.append(s.copy()) poiList[-1]["poi"] = poieval return poiList def addTraces(self, traces, plaintexts, ciphertexts, knownkeys=None, progressBar=None, pointRange=None): if multivariate_normal is None: print "ERROR: Version of SciPy too old, require > 0.14, have %s" % (scipy.version.version) print " Please update your version of SciPy to support this attack" return # Hack for now - just use last template found template = self.loadTemplatesFromProject()[-1] pois = template["poi"] numparts = len(template['mean'][0]) results = np.zeros((16, 256)) tdiff = self._reportinginterval if progressBar: progressBar.setMinimum(0) progressBar.setMaximum(16 * len(traces)) pcnt = 0 for tnum in range(0, len(traces)): for bnum in range(0, 16): newresultsint = [multivariate_normal.logpdf(traces[tnum][pois[bnum]], mean=template['mean'][bnum][i], cov=np.diag(template['cov'][bnum][i])) for i in range(0, numparts)] ptype = template["partitiontype"] if ptype == "PartitionHWIntermediate": newresults = [] # Map to key guess format for i in range(0, 256): # Get hypothetical hamming weight # hypint = HypHW(plaintexts[tnum], None, i, bnum) hypint = AESModel.leakage(plaintexts[tnum], ciphertexts[tnum], i, bnum, AESModel.LEAK_HW_SBOXOUT_FIRSTROUND, None) newresults.append(newresultsint[ hypint ]) elif ptype == "PartitionHDLastRound": newresults = [] # Map to key guess format for i in range(0, 256): # Get hypothetical hamming distance # hypint = HypHD(plaintexts[tnum], None, i, bnum) # hypint = HypHD(None, ciphertexts[tnum], i, bnum) hypint = AESModel.leakage(plaintexts[tnum], ciphertexts[tnum], i, bnum, AESModel.LEAK_HD_LASTROUND_STATE, None) newresults.append(newresultsint[ hypint ]) # TODO Temp elif ptype == "PartitionHDRounds": newresults = [] # Map to key guess format for i in range(0, 256): # Get hypothetical hamming distance # hypint = HypHD(plaintexts[tnum], None, i, bnum) if bnum == 0: hypint = getHW(plaintexts[tnum][bnum] ^ i) else: knownkey = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c] s1 = plaintexts[tnum][bnum - 1] ^ knownkey[bnum - 1] s2 = plaintexts[tnum][bnum] ^ i hypint = getHW(s1 ^ s2) newresults.append(newresultsint[ hypint ]) else: newresults = newresultsint results[bnum] += newresults self.stats.updateSubkey(bnum, results[bnum], tnum=(tnum + 1)) if progressBar: progressBar.setValue(pcnt) progressBar.updateStatus((tnum, len(traces)), bnum) pcnt += 1 if progressBar.wasCanceled(): raise KeyboardInterrupt # Do plotting if required if (tnum % tdiff) == 0 and self.sr: self.sr() def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): self.sr = sr
class CPASimpleLoop(QObject): """ CPA Attack done as a loop - the 'classic' attack provided for familiarity to textbook samples. This attack does not provide trace-by-trace statistics however, you can only gather results once all the traces have been run through the attack. """ def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPASimpleLoop, self).__init__() self.model = targetModel self.leakage = leakageFunction self.stats = DataTypeDiffs() self.modelstate = {"knownkey": None} def oneSubkey( self, bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, knownkeys, progressBar, model, leakagetype, state, pbcnt, ): diffs = [0] * 256 if pointRange == None: traces = traces_all # padbefore = 0 # padafter = 0 else: traces = np.array(traces_all[:, pointRange[0] : pointRange[1]]) # padbefore = pointRange[0] # padafter = len(traces_all[0, :]) - pointRange[1] # print "%d - %d (%d %d)"%( pointRange[0], pointRange[1], padbefore, padafter) # For each 0..0xFF possible value of the key byte for key in range(0, 256): # Initialize arrays & variables to zero sumnum = np.zeros(len(traces[0, :])) sumden1 = np.zeros(len(traces[0, :])) sumden2 = np.zeros(len(traces[0, :])) hyp = [0] * numtraces # Formula for CPA & description found in "Power Analysis Attacks" # by Mangard et al, page 124, formula 6.2. # Generate hypotheticals for tnum in range(numtraces): if len(plaintexts) > 0: pt = plaintexts[tnum] else: pt = [] if len(ciphertexts) > 0: ct = ciphertexts[tnum] else: ct = [] if knownkeys and len(knownkeys) > 0: nk = knownkeys[tnum] else: nk = None state["knownkey"] = nk hypint = model.leakage(pt, ct, key, bnum, leakagetype, state) hyp[tnum] = hypint hyp = np.array(hyp) # Mean of hypothesis meanh = np.mean(hyp, dtype=np.float64) # Mean of all points in trace meant = np.mean(traces, axis=0, dtype=np.float64) # For each trace, do the following for tnum in range(numtraces): hdiff = hyp[tnum] - meanh tdiff = traces[tnum, :] - meant sumnum = sumnum + (hdiff * tdiff) sumden1 = sumden1 + hdiff * hdiff sumden2 = sumden2 + tdiff * tdiff if progressBar: progressBar.setValue(pbcnt) # progressBar.setLabelText("Byte %02d: Hyp=%02x"%(bnum, key)) pbcnt = pbcnt + 1 if progressBar.wasCanceled(): raise KeyboardInterrupt diffs[key] = sumnum / np.sqrt(sumden1 * sumden2) # if padafter > 0: # diffs[key] = np.concatenate([diffs[key], np.zeros(padafter)]) # if padbefore > 0: # diffs[key] = np.concatenate([np.zeros(padbefore), diffs[key]]) return (diffs, pbcnt) def setTargetBytes(self, brange): self.brange = brange def setReportingInterval(self, ri): # Not used for simpleloop pass def addTraces(self, tracedata, tracerange, progressBar=None, pointRange=None, tracesLoop=None): brange = self.brange self.all_diffs = range(0, 16) if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256) numtraces = tracerange[1] - tracerange[0] # Load all traces data = [] textins = [] textouts = [] knownkeys = [] for i in range(tracerange[0], tracerange[1]): # Handle Offset tnum = i + tracerange[0] d = tracedata.getTrace(tnum) if d is None: continue data.append(d) textins.append(tracedata.getTextin(tnum)) textouts.append(tracedata.getTextout(tnum)) knownkeys.append(tracedata.getKnownKey(tnum)) traces = np.array(data) textins = np.array(textins) textouts = np.array(textouts) pbcnt = 0 for bnum in brange: (data, pbcnt) = self.oneSubkey( bnum, pointRange, traces, numtraces, textins, textouts, knownkeys, progressBar, self.model, self.leakage, self.modelstate, pbcnt, ) self.stats.updateSubkey(bnum, data) def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): pass def processKnownKey(self, inpkey): if hasattr(self.model, "processKnownKey"): return self.model.processKnownKey(self.leakage, inpkey) else: return inpkey
class CPAExperimentalChannelinfo(QObject): """ CPA Attack done as a loop, but using an algorithm which can progressively add traces & give output stats """ paramListUpdated = Signal(list) def __init__(self, model, showScriptParameter=None, parent=None): super(CPAExperimentalChannelinfo, self).__init__() resultsParams = [ { 'name': 'Reporting Interval', 'key': 'reportinterval', 'type': 'int', 'value': 100 }, { 'name': 'Iteration Mode', 'key': 'itmode', 'type': 'list', 'values': { 'Depth-First': 'df', 'Breadth-First': 'bf' }, 'value': 'bf' }, { 'name': 'Skip when PGE=0', 'key': 'checkpge', 'type': 'bool', 'value': False }, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) ExtendedParameter.setupExtended(self.params, self) self.model = model self.sr = None self._parent = parent # print self._parent.parent self.stats = DataTypeDiffs() def paramList(self): return [self.params] def setByteList(self, brange): self.brange = brange def addTraces(self, tracedata, tracerange, progressBar=None, pointRange=None): keyround = self.keyround modeltype = self.modeltype brange = self.brange foundkey = [] self.all_diffs = range(0, 16) tdiff = self.findParam('reportinterval').value() numtraces = tracerange[1] - tracerange[0] if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256 * (numtraces / tdiff + 1)) pbcnt = 0 #r = Parallel(n_jobs=4)(delayed(traceOneSubkey)(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, modeltype, progressBar, self.model, pbcnt) for bnum in brange) #self.all_diffs, pb = zip(*r) #pbcnt = 0 cpa = [None] * (max(brange) + 1) for bnum in brange: cpa[bnum] = CPAProgressiveOneSubkey() # cpa[bnum] = MinDistOneSubkey() # cpa[bnum] = TemplateOneSubkey() brangeMap = [None] * (max(brange) + 1) i = 1 for bnum in brange: brangeMap[bnum] = i i += 1 skipPGE = self.findParam('checkpge').value() bf = self.findParam('itmode').value() == 'bf' #bf specifies a 'breadth-first' search. bf means we search across each #subkey by only the amount of traces specified. Depth-First means we #search each subkey completely, then move onto the next. if bf: brange_df = [0] brange_bf = brange else: brange_bf = [0] brange_df = brange #H = np.load('channelinfo-masked.npy') #H = np.load('csi-masked-newkey.npy') #H = np.load('channelinfo.npy') #mio = sio.loadmat('equalizer.mat') #H = mio['equaltotal'] # H = np.load('equalization.npy') # self.project() ? project = self._parent.parent().proj section = project.getDataConfig("Template Data", "Equalization Matrix") # section = project.getDataConfig("Template Data", "AOF Matrix") fname = project.convertDataFilepathAbs(section[0]["filename"]) H = np.load(fname) #for j in range(0, 16): #4 = 500-800 #test = H.copy() #for i in range(0, 5): # threshold = max(abs(test[j])) # test[j, abs(test[j,:]) >= threshold ] = 0 #print "%f %d"%(threshold, (abs(H[j,:]) > threshold).sum()) #H[j, abs(H[j,:]) < threshold] = 0 for bnum_df in brange_df: #CPAMemoryOneSubkey #CPASimpleOneSubkey #(self.all_diffs[bnum], pbcnt) = sCPAMemoryOneSubkey(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, modeltype, progressBar, self.model, pbcnt) tstart = 0 tend = tdiff while tstart < numtraces: if tend > numtraces: tend = numtraces if tstart > numtraces: tstart = numtraces data = [] textins = [] textouts = [] knownkeys = [] for i in range(tstart, tend): # Handle Offset tnum = i + tracerange[0] d = tracedata.getTrace(tnum) if d is None: continue data.append(d) textins.append(tracedata.getTextin(tnum)) textouts.append(tracedata.getTextout(tnum)) knownkeys.append(tracedata.getKnownKey(tnum)) traces = np.array(data) textins = np.array(textins) textouts = np.array(textouts) for bnum_bf in brange_bf: if bf: bnum = bnum_bf else: bnum = bnum_df traces_fixed = np.dot(traces - traces.mean(axis=0), H[bnum]) + 4 skip = False if (self.stats.simplePGE(bnum) != 0) or (skipPGE == False): (data, pbcnt) = cpa[bnum].oneSubkey( bnum, pointRange, traces_fixed, tend - tstart, textins, textouts, keyround, modeltype, progressBar, self.model, pbcnt) self.stats.updateSubkey(bnum, data, tnum=tend) else: skip = True if progressBar.wasSkipped() or skip: progressBar.clearSkipped() pbcnt = brangeMap[bnum] * 256 * (numtraces / tdiff + 1) if bf is False: tstart = numtraces tend += tdiff tstart += tdiff if self.sr is not None: self.sr() if progressBar is not None: pbcnt = 0 def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): self.sr = sr
def __init__(self, hardwareModel, leakageModel, showScriptParameter=None, parent=None): super(CPASimpleLoop, self).__init__() self.hardwareModel = hardwareModel self.leakageModel = leakageModel self.stats = DataTypeDiffs()
class CPASimpleLoop(QObject): """ CPA Attack done as a loop - the 'classic' attack provided for familiarity to textbook samples. This attack does not provide trace-by-trace statistics however, you can only gather results once all the traces have been run through the attack. """ def __init__(self, hardwareModel, leakageModel, showScriptParameter=None, parent=None): super(CPASimpleLoop, self).__init__() self.hardwareModel = hardwareModel self.leakageModel = leakageModel self.stats = DataTypeDiffs() def oneSubkey(self, bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, progressBar, model, pbcnt): diffs = [0]*256 if pointRange == None: traces = traces_all padbefore = 0 padafter = 0 else: traces = np.array(traces_all[:, pointRange[bnum][0] : pointRange[bnum][1]]) padbefore = pointRange[bnum][0] padafter = len(traces_all[0,:]) - pointRange[bnum][1] #print "%d - %d (%d %d)"%( pointRange[bnum][0], pointRange[bnum][1], padbefore, padafter) #For each 0..0xFF possible value of the key byte for key in range(0, 256): #Initialize arrays & variables to zero sumnum = np.zeros(len(traces[0,:])) sumden1 = np.zeros(len(traces[0,:])) sumden2 = np.zeros(len(traces[0,:])) hyp = [0] * numtraces #Formula for CPA & description found in "Power Analysis Attacks" # by Mangard et al, page 124, formula 6.2. #Generate hypotheticals for tnum in range(numtraces): if len(plaintexts) > 0: pt = plaintexts[tnum] if len(ciphertexts) > 0: ct = ciphertexts[tnum] if keyround == "first" or keyround == 0: ct = None elif keyround == "last" or keyround == -1: pt = None else: raise ValueError("keyround invalid") #Generate the output of the SBOX # if modeltype == "Hamming Weight": # hypint = model.HypHW(pt, ct, key, bnum); # elif modeltype == "Hamming Distance": # hypint = model.HypHD(pt, ct, key, bnum); # else: # raise ValueError("modeltype invalid") hypint = model(pt, ct, key, bnum) hyp[tnum] = hypint hyp = np.array(hyp) #Mean of hypothesis meanh = np.mean(hyp, dtype=np.float64) #Mean of all points in trace meant = np.mean(traces, axis=0, dtype=np.float64) #For each trace, do the following for tnum in range(numtraces): hdiff = (hyp[tnum] - meanh) tdiff = traces[tnum,:] - meant sumnum = sumnum + (hdiff*tdiff) sumden1 = sumden1 + hdiff * hdiff sumden2 = sumden2 + tdiff * tdiff if progressBar: progressBar.setValue(pbcnt) #progressBar.setLabelText("Byte %02d: Hyp=%02x"%(bnum, key)) pbcnt = pbcnt + 1 if progressBar.wasCanceled(): raise KeyboardInterrupt diffs[key] = sumnum / np.sqrt( sumden1 * sumden2 ) if padafter > 0: diffs[key] = np.concatenate([diffs[key], np.zeros(padafter)]) if padbefore > 0: diffs[key] = np.concatenate([np.zeros(padbefore), diffs[key]]) return (diffs, pbcnt) def setTargetBytes(self, brange): self.brange = brange def setKeyround(self, keyround): self.keyround = keyround def addTraces(self, traces, plaintexts, ciphertexts, knownkeys=None, progressBar=None, pointRange=None, tracesLoop=None): keyround=self.keyround brange=self.brange traces_all = np.array(traces) plaintexts =np.array(plaintexts) ciphertexts =np.array(ciphertexts) foundkey = [] self.all_diffs = range(0,16) if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256) numtraces = len(traces_all[:,0]) pbcnt = 0 for bnum in brange: (data, pbcnt) = self.oneSubkey(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, progressBar, self.leakageModel, pbcnt) self.stats.updateSubkey(bnum, data) def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): pass
class CPASimpleLoop(QObject): """ CPA Attack done as a loop - the 'classic' attack provided for familiarity to textbook samples. This attack does not provide trace-by-trace statistics however, you can only gather results once all the traces have been run through the attack. """ def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPASimpleLoop, self).__init__() self.model = targetModel self.leakage = leakageFunction self.stats = DataTypeDiffs() self.modelstate = {'knownkey': None} def oneSubkey(self, bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, knownkeys, progressBar, model, leakagetype, state, pbcnt): diffs = [0] * 256 if pointRange == None: traces = traces_all # padbefore = 0 # padafter = 0 else: traces = np.array(traces_all[:, pointRange[0]:pointRange[1]]) # padbefore = pointRange[0] # padafter = len(traces_all[0, :]) - pointRange[1] # print "%d - %d (%d %d)"%( pointRange[0], pointRange[1], padbefore, padafter) #For each 0..0xFF possible value of the key byte for key in range(0, 256): #Initialize arrays & variables to zero sumnum = np.zeros(len(traces[0, :])) sumden1 = np.zeros(len(traces[0, :])) sumden2 = np.zeros(len(traces[0, :])) hyp = [0] * numtraces #Formula for CPA & description found in "Power Analysis Attacks" # by Mangard et al, page 124, formula 6.2. #Generate hypotheticals for tnum in range(numtraces): if len(plaintexts) > 0: pt = plaintexts[tnum] else: pt = [] if len(ciphertexts) > 0: ct = ciphertexts[tnum] else: ct = [] if knownkeys and len(knownkeys) > 0: nk = knownkeys[tnum] else: nk = None state['knownkey'] = nk hypint = model.leakage(pt, ct, key, bnum, leakagetype, state) hyp[tnum] = hypint hyp = np.array(hyp) #Mean of hypothesis meanh = np.mean(hyp, dtype=np.float64) #Mean of all points in trace meant = np.mean(traces, axis=0, dtype=np.float64) #For each trace, do the following for tnum in range(numtraces): hdiff = (hyp[tnum] - meanh) tdiff = traces[tnum, :] - meant sumnum = sumnum + (hdiff * tdiff) sumden1 = sumden1 + hdiff * hdiff sumden2 = sumden2 + tdiff * tdiff if progressBar: progressBar.setValue(pbcnt) #progressBar.setLabelText("Byte %02d: Hyp=%02x"%(bnum, key)) pbcnt = pbcnt + 1 if progressBar.wasCanceled(): raise KeyboardInterrupt diffs[key] = sumnum / np.sqrt(sumden1 * sumden2) # if padafter > 0: # diffs[key] = np.concatenate([diffs[key], np.zeros(padafter)]) # if padbefore > 0: # diffs[key] = np.concatenate([np.zeros(padbefore), diffs[key]]) return (diffs, pbcnt) def setTargetBytes(self, brange): self.brange = brange def setReportingInterval(self, ri): # Not used for simpleloop pass def addTraces(self, tracedata, tracerange, progressBar=None, pointRange=None, tracesLoop=None): brange = self.brange self.all_diffs = range(0, 16) if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256) numtraces = tracerange[1] - tracerange[0] # Load all traces data = [] textins = [] textouts = [] knownkeys = [] for i in range(tracerange[0], tracerange[1]): # Handle Offset tnum = i + tracerange[0] d = tracedata.getTrace(tnum) if d is None: continue data.append(d) textins.append(tracedata.getTextin(tnum)) textouts.append(tracedata.getTextout(tnum)) knownkeys.append(tracedata.getKnownKey(tnum)) traces = np.array(data) textins = np.array(textins) textouts = np.array(textouts) pbcnt = 0 for bnum in brange: (data, pbcnt) = self.oneSubkey(bnum, pointRange, traces, numtraces, textins, textouts, knownkeys, progressBar, self.model, self.leakage, self.modelstate, pbcnt) self.stats.updateSubkey(bnum, data) def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): pass def processKnownKey(self, inpkey): if hasattr(self.model, 'processKnownKey'): return self.model.processKnownKey(self.leakage, inpkey) else: return inpkey
class CPAProgressive(AutoScript, QObject): """ CPA Attack done as a loop, but using an algorithm which can progressively add traces & give output stats """ paramListUpdated = Signal(list) def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPAProgressive, self).__init__() resultsParams = [{'name':'Iteration Mode', 'key':'itmode', 'type':'list', 'values':{'Depth-First':'df', 'Breadth-First':'bf'}, 'value':'bf'}, {'name':'Skip when PGE=0', 'key':'checkpge', 'type':'bool', 'value':False}, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) if showScriptParameter is not None: self.showScriptParameter = showScriptParameter # print self.showScriptParameter ExtendedParameter.setupExtended(self.params, self) self.model = targetModel self.leakage = leakageFunction self.sr = None self.stats = DataTypeDiffs() self.updateScript() def updateScript(self, ignored=None): # self.addFunction('init', 'setReportingInterval', '%d' % self.findParam('reportinterval').value()) pass def paramList(self): return [self.params] def setTargetBytes(self, brange): self.brange = brange def setKeyround(self, keyround): self.keyround = keyround def setDirection(self, dir): self._direction = dir def setModeltype(self, modeltype): self.modeltype = modeltype def setReportingInterval(self, ri): self._reportingInterval = ri def addTraces(self, traces, plaintexts, ciphertexts, knownkeys=None, progressBar=None, pointRange=None): keyround=self.keyround brange=self.brange traces_all = np.array(traces) plaintexts =np.array(plaintexts) ciphertexts =np.array(ciphertexts) foundkey = [] self.all_diffs = range(0,16) numtraces = len(traces_all[:,0]) if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256 * (numtraces / self._reportingInterval + 1)) pbcnt = 0 #r = Parallel(n_jobs=4)(delayed(traceOneSubkey)(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, modeltype, progressBar, self.model, pbcnt) for bnum in brange) #self.all_diffs, pb = zip(*r) #pbcnt = 0 cpa = [None]*(max(brange)+1) for bnum in brange: cpa[bnum] = CPAProgressiveOneSubkey() brangeMap = [None]*(max(brange)+1) i = 1 for bnum in brange: brangeMap[bnum] = i i += 1 skipPGE = False # self.findParam('checkpge').value() bf = True # self.findParam('itmode').value() == 'bf' #bf specifies a 'breadth-first' search. bf means we search across each #subkey by only the amount of traces specified. Depth-First means we #search each subkey completely, then move onto the next. if bf: brange_df = [0] brange_bf = brange else: brange_bf = [0] brange_df = brange for bnum_df in brange_df: #CPAMemoryOneSubkey #CPASimpleOneSubkey #(self.all_diffs[bnum], pbcnt) = sCPAMemoryOneSubkey(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, modeltype, progressBar, self.model, pbcnt) tstart = 0 tend = self._reportingInterval while tstart < numtraces: if tend > numtraces: tend = numtraces if tstart > numtraces: tstart = numtraces for bnum_bf in brange_bf: if bf: bnum = bnum_bf else: bnum = bnum_df skip = False if (self.stats.simplePGE(bnum) != 0) or (skipPGE == False): (data, pbcnt) = cpa[bnum].oneSubkey(bnum, pointRange, traces_all[tstart:tend], tend - tstart, plaintexts[tstart:tend], ciphertexts[tstart:tend], keyround, self.leakage, progressBar, self.model, pbcnt, self._direction, knownkeys) self.stats.updateSubkey(bnum, data, tnum=tend) else: skip = True if progressBar.wasSkipped() or skip: progressBar.clearSkipped() pbcnt = brangeMap[bnum] * 256 * (numtraces / self._reportingInterval + 1) if bf is False: tstart = numtraces tend += self._reportingInterval tstart += self._reportingInterval if self.sr is not None: self.sr() def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): self.sr = sr
def __init__(self, targetModel, leakageFunction, showScriptParameter=None, parent=None): super(CPASimpleLoop, self).__init__() self.model = targetModel self.leakage = leakageFunction self.stats = DataTypeDiffs() self.modelstate = {"knownkey": None}
class CPAExperimentalChannelinfo(QObject): """ CPA Attack done as a loop, but using an algorithm which can progressively add traces & give output stats """ paramListUpdated = Signal(list) def __init__(self, model, showScriptParameter=None, parent=None): super(CPAExperimentalChannelinfo, self).__init__() resultsParams = [{'name':'Reporting Interval', 'key':'reportinterval', 'type':'int', 'value':100}, {'name':'Iteration Mode', 'key':'itmode', 'type':'list', 'values':{'Depth-First':'df', 'Breadth-First':'bf'}, 'value':'bf'}, {'name':'Skip when PGE=0', 'key':'checkpge', 'type':'bool', 'value':False}, ] self.params = Parameter.create(name='Progressive CPA', type='group', children=resultsParams) ExtendedParameter.setupExtended(self.params, self) self.model = model self.sr = None self._parent = parent # print self._parent.parent self.stats = DataTypeDiffs() def paramList(self): return [self.params] def setByteList(self, brange): self.brange = brange def addTraces(self, tracedata, tracerange, progressBar=None, pointRange=None): keyround=self.keyround modeltype=self.modeltype brange=self.brange foundkey = [] self.all_diffs = range(0,16) tdiff = self.findParam('reportinterval').value() numtraces = tracerange[1] - tracerange[0] if progressBar: pbcnt = 0 progressBar.setMinimum(0) progressBar.setMaximum(len(brange) * 256 * (numtraces/tdiff + 1)) pbcnt = 0 #r = Parallel(n_jobs=4)(delayed(traceOneSubkey)(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, modeltype, progressBar, self.model, pbcnt) for bnum in brange) #self.all_diffs, pb = zip(*r) #pbcnt = 0 cpa = [None]*(max(brange)+1) for bnum in brange: cpa[bnum] = CPAProgressiveOneSubkey() # cpa[bnum] = MinDistOneSubkey() # cpa[bnum] = TemplateOneSubkey() brangeMap = [None]*(max(brange)+1) i = 1 for bnum in brange: brangeMap[bnum] = i i += 1 skipPGE = self.findParam('checkpge').value() bf = self.findParam('itmode').value() == 'bf' #bf specifies a 'breadth-first' search. bf means we search across each #subkey by only the amount of traces specified. Depth-First means we #search each subkey completely, then move onto the next. if bf: brange_df = [0] brange_bf = brange else: brange_bf = [0] brange_df = brange #H = np.load('channelinfo-masked.npy') #H = np.load('csi-masked-newkey.npy') #H = np.load('channelinfo.npy') #mio = sio.loadmat('equalizer.mat') #H = mio['equaltotal'] # H = np.load('equalization.npy') # self.project() ? project = self._parent.parent().proj section = project.getDataConfig("Template Data", "Equalization Matrix") # section = project.getDataConfig("Template Data", "AOF Matrix") fname = project.convertDataFilepathAbs(section[0]["filename"]) H = np.load(fname) #for j in range(0, 16): #4 = 500-800 #test = H.copy() #for i in range(0, 5): # threshold = max(abs(test[j])) # test[j, abs(test[j,:]) >= threshold ] = 0 #print "%f %d"%(threshold, (abs(H[j,:]) > threshold).sum()) #H[j, abs(H[j,:]) < threshold] = 0 for bnum_df in brange_df: #CPAMemoryOneSubkey #CPASimpleOneSubkey #(self.all_diffs[bnum], pbcnt) = sCPAMemoryOneSubkey(bnum, pointRange, traces_all, numtraces, plaintexts, ciphertexts, keyround, modeltype, progressBar, self.model, pbcnt) tstart = 0 tend = tdiff while tstart < numtraces: if tend > numtraces: tend = numtraces if tstart > numtraces: tstart = numtraces data = [] textins = [] textouts = [] knownkeys = [] for i in range(tstart, tend): # Handle Offset tnum = i + tracerange[0] d = tracedata.getTrace(tnum) if d is None: continue data.append(d) textins.append(tracedata.getTextin(tnum)) textouts.append(tracedata.getTextout(tnum)) knownkeys.append(tracedata.getKnownKey(tnum)) traces = np.array(data) textins = np.array(textins) textouts = np.array(textouts) for bnum_bf in brange_bf: if bf: bnum = bnum_bf else: bnum = bnum_df traces_fixed = np.dot(traces - traces.mean(axis=0), H[bnum]) + 4 skip = False if (self.stats.simplePGE(bnum) != 0) or (skipPGE == False): (data, pbcnt) = cpa[bnum].oneSubkey(bnum, pointRange, traces_fixed, tend - tstart, textins, textouts, keyround, modeltype, progressBar, self.model, pbcnt) self.stats.updateSubkey(bnum, data, tnum=tend) else: skip = True if progressBar.wasSkipped() or skip: progressBar.clearSkipped() pbcnt = brangeMap[bnum] * 256 * (numtraces/tdiff + 1) if bf is False: tstart = numtraces tend += tdiff tstart += tdiff if self.sr is not None: self.sr() if progressBar is not None: pbcnt = 0 def getStatistics(self): return self.stats def setStatsReadyCallback(self, sr): self.sr = sr