def cpaPoint2(self, sk, sboxNum, samplePoint, startTrace=0, endTrace=0, leakage='HW'): """Same as cpaPoint but uses the traditional `means' method instead of the covariance method. """ if endTrace == 0: endTrace = self.acq.numTraces HammW = [] for i in range(5): HammW.append([]) numTraces = endTrace - startTrace #covMethod = np.zeros((2,numTraces)) for i in range(numTraces): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2( ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxOut = des_block.sbox(sboxNum, ptBlock ^ sk) if leakage == 'HW': hyp = HW( sboxOut ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HDRound': hyp = HD( sboxOut, des_block.ptRoundIn(ptStr, sboxNum) ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HD': hyp = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 HammW[hyp].append(self.acq.traces[i + startTrace][samplePoint]) noiseCPA = [] signalCPA = [] signalCPAdiff = [] for j in range(5): noise = np.std(HammW[j]) if (np.isnan(noise)): print "noise isnan, rejected" pass else: noiseCPA.append(noise) signalCPA.append(np.mean(HammW[j])) noiseCPA = np.mean(noiseCPA) for j in range(4): signalCPAdiff.append(np.abs(signalCPA[j + 1] - signalCPA[j])) signalCPA = np.mean(signalCPAdiff) return signalCPA * self.acq.yscale, noiseCPA * self.acq.yscale
def cpaPoint(self, sk, sboxNum, samplePoint, startTrace = 0, endTrace=0, leakage='HW'): """The cpaPoint function calculates the CPA signal to noise ratio for a single sample of a given traceset. This saves a lot of time compared to cpaTrace. The recommended usage scenario will be to determine the sample point of interest using cpaTrace (with fewer traces), and then to use cpaPoint (with many traces) Inputs: subkey - the correct subkey (which is 0 to 63 for DES) sboxNum - the sbox number we are targeting (values 1 to 8) samplePoint - the single samplePoint to calculate the SNR for startTrace, endTrace - SNR is calculated from Trace startTrace to endTrace. This value is optional. If left out, it will calculate SNR for entire trace set leakage - The leakage model. This takes values 'HW', 'HD', 'HDRound' returns: signal, noise """ if endTrace == 0: endTrace = self.acq.numTraces HammW = [] for i in range(5): HammW.append([]) numTraces = endTrace - startTrace covMethod = np.zeros((2,numTraces)) for i in range(numTraces): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2(ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxOut = des_block.sbox(sboxNum, ptBlock ^ sk) if leakage =='HW': hyp = HW(sboxOut) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HDRound': hyp = HD(sboxOut,des_block.ptRoundIn(ptStr,sboxNum)) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HD': hyp = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 HammW[hyp].append(self.acq.traces[i+startTrace][samplePoint]) covMethod[0][i] = self.acq.traces[i+startTrace][samplePoint] covMethod[1][i] = hyp noiseCPA = [] signalCPA = [] signalCPAdiff = [] for j in range(5): noise = np.std(HammW[j]) if (np.isnan(noise)): pass else: noiseCPA.append(noise) noiseCPA = np.mean(noiseCPA) signalCov = np.abs(((np.cov(covMethod))[1][0])) return signalCov*self.acq.yscale, noiseCPA *self.acq.yscale
def corrCoefficient(self, subkey, sboxNum, startTrace = 0, endTrace = 0, leakage='HW'): """ Calculate CPA correlation co-efficient: a. Calculate sbox output for the given subkey b. Calculate hypothesis (which is hamming weight or hamming distance depending on power model) c. Calculate pearson's correlation co-efficient of given subkey Input: subkey (6bit key which is input to sbox) sboxNum (1...8) Return the correlation co-efficient of the given subkey """ # Based on ChipWhisperer CPASimpleLoop.py sumnum = np.zeros(self.acq.numSamples) sumden1 = np.zeros(self.acq.numSamples) sumden2 = np.zeros(self.acq.numSamples) if (endTrace == 0): endTrace = self.acq.numTraces # Generate hypotheticals hyp = np.zeros(endTrace - startTrace) for i in range(endTrace - startTrace): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2(ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) if leakage =='HW': hyp[i] = HW(sboxOut) elif leakage =='HDRound': hyp[i] = HD(sboxOut,des_block.ptRoundIn(ptStr,sboxNum)) elif leakage =='HD': hyp[i] = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 meanh = np.mean(hyp, dtype = np.float) meant = np.mean(self.acq.traces[startTrace:endTrace], axis=0, dtype=np.float) for tnum in range(endTrace - startTrace): hdiff = (hyp[tnum] - meanh) tdiff = self.acq.traces[tnum+startTrace,:] - meant sumnum += hdiff * tdiff sumden1 += hdiff * hdiff sumden2 += tdiff * tdiff #print sumden1 #print sumden2 #print np.sqrt(sumden1 * sumden2) corr = sumnum / np.sqrt (sumden1 * sumden2) return corr
def corrCoefficientSinglePointRivian(self, subkey, sboxNum, samplePoint, startTrace=0, endTrace=0, leakage='HW'): """ Calculate CPA correlation co-efficient: a. Calculate sbox out given subkey b. Calculate hypothesis (which is hamming weight or hamming distance depending on power model) c. Calculate pearson's correlation co-efficient of given subkey Input: subkey (6bit key which is input to sbox) sboxNum (1...8) Return the correlation co-efficient of the given subkey """ # Based on ChipWhisperer CPASimpleLoop.py if (endTrace == 0): endTrace = self.acq.numTraces coeff = [] # Generate hypotheticals hyp = np.zeros(endTrace - startTrace) for i in range(endTrace - startTrace): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2( ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) if leakage == 'HW': hyp[i] = HW( sboxOut ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HDRound': hyp[i] = HD( sboxOut, des_block.ptRoundIn(ptStr, sboxNum) ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HD': hyp[i] = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 coeff.append(hyp[i] * self.acq.traces[i + startTrace]) corr = np.mean(coeff) return corr
def buildTemplate(self, subkey, sboxNum, samplePoint, startTrace = 0, endTrace = 0, excludeStartTrace =None, excludeEndTrace=None): """ Calculate template for each sbox input b. Calculate variance of the noise # Inputs: subkey - the correct subkey sboxNum - the sbox number we are targeting (values 1 to 8) samplePoint - the single sample point to calculate the PI for startTrace, endTrace - SNR is calculated from Trace startTrace to endTrace. This value is optional. If left out, it will calculate SNR for entire trace set excludestartTrace, excludedEndTrace - Exclude the traces between excludeStartTrace to excludeEndTrace. This interval should be between startTrace and endTrace. It is used for cross validation. """ self.noise = [] self.samplePoint = samplePoint self.num = endTrace - startTrace for i in range(DES_PI.NK): self.noise.append([]) if (excludeStartTrace ==None and excludeEndTrace == None): exclude = False else: exclude = True if (endTrace == 0): endTrace = self.acq.numTraces for i in range(endTrace - startTrace): if (exclude == True and i>= excludeStartTrace and i<=excludeEndTrace): pass else: ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2(ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) hyp = HD(sboxOut,des_block.ptRoundIn(ptStr,sboxNum)) self.noise[hyp].append(self.acq.traces[i + startTrace][samplePoint]) for i in range(DES_PI.NK): self.mean[i] = np.mean(self.noise[i]) self.sd[i] = np.std(self.noise[i]) #print "Num Measurements for sbox input %d is %d" % (i, len(noise[i])) if len(self.noise[i]) == 0: print "Not enough measurements for sbox input %d ! Please rebuild the template with more measurements" % i print self.mean print self.sd
def cpaPoint2(self, sk, sboxNum, samplePoint, startTrace = 0, endTrace=0, leakage='HW'): """Same as cpaPoint but uses the traditional `means' method instead of the covariance method. """ if endTrace == 0: endTrace = self.acq.numTraces HammW = [] for i in range(5): HammW.append([]) numTraces = endTrace - startTrace #covMethod = np.zeros((2,numTraces)) for i in range(numTraces): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2(ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxOut = des_block.sbox(sboxNum, ptBlock ^ sk) if leakage =='HW': hyp = HW(sboxOut) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HDRound': hyp = HD(sboxOut,des_block.ptRoundIn(ptStr,sboxNum)) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HD': hyp = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 HammW[hyp].append(self.acq.traces[i+startTrace][samplePoint]) noiseCPA = [] signalCPA = [] signalCPAdiff = [] for j in range(5): noise = np.std(HammW[j]) if (np.isnan(noise)): print "noise isnan, rejected" pass else: noiseCPA.append(noise) signalCPA.append(np.mean(HammW[j])) noiseCPA = np.mean(noiseCPA) for j in range(4): signalCPAdiff.append(np.abs(signalCPA[j+1] - signalCPA[j])) signalCPA = np.mean(signalCPAdiff) return signalCPA*self.acq.yscale, noiseCPA*self.acq.yscale
def corrCoefficientSinglePointRivian(self, subkey, sboxNum, samplePoint, startTrace = 0, endTrace = 0, leakage ='HW'): """ Calculate CPA correlation co-efficient: a. Calculate sbox out given subkey b. Calculate hypothesis (which is hamming weight or hamming distance depending on power model) c. Calculate pearson's correlation co-efficient of given subkey Input: subkey (6bit key which is input to sbox) sboxNum (1...8) Return the correlation co-efficient of the given subkey """ # Based on ChipWhisperer CPASimpleLoop.py if (endTrace == 0): endTrace = self.acq.numTraces coeff = [] # Generate hypotheticals hyp = np.zeros(endTrace - startTrace) for i in range(endTrace - startTrace): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2(ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) if leakage =='HW': hyp[i] = HW(sboxOut) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HDRound': hyp[i] = HD(sboxOut,des_block.ptRoundIn(ptStr,sboxNum)) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HD': hyp[i] = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 coeff.append(hyp[i] * self.acq.traces[i + startTrace]) corr = np.mean(coeff) return corr
def cpaTrace(self, subkey, sboxNum, startTrace =0, endTrace = 0, leakage='HW'): """The cpaTrace function calculates the CPA signal to noise ratio over all the samples of a traceset Inputs: subkey - the correct subkey (which is 0 to 63 for DES) sboxNum - the sbox number we are targeting (values 1 to 8) startTrace, endTrace - SNR is calculated from Trace startTrace to endTrace. This value is optional. If left out, it will calculate SNR for entire trace set leakage - The leakage model. This takes values 'HW', 'HD', 'HDRound' Returns: Signal matrix, noise matrix """ sumnum = np.zeros(self.acq.numSamples) if (endTrace == 0): endTrace = self.acq.numTraces # Group traces according to the hamming weight of the leakage traceHW = [] noise = [] for i in range(5): traceHW.append(None) noise.append(None) # Generate hypotheticals hyp = np.zeros(endTrace - startTrace, dtype=int) for i in range(endTrace - startTrace): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2(ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) if leakage =='HW': hyp[i] = HW(sboxOut) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HDRound': hyp[i] = HD(sboxOut,des_block.ptRoundIn(ptStr,sboxNum)) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage =='HD': hyp[i] = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 if traceHW[hyp[i]] == None: traceHW[hyp[i]] = self.acq.traces[i] else: traceHW[hyp[i]] = np.vstack((traceHW[hyp[i]] ,self.acq.traces[i])) meanh = np.mean(hyp, dtype = np.float) meant = np.mean(self.acq.traces[startTrace:endTrace], axis=0, dtype=np.float) noise = np.std(traceHW[0], axis=0) for i in range(5): noise = np.vstack((noise, np.std(traceHW[i], axis=0))) noise = np.mean(noise, axis = 0) for tnum in range(endTrace - startTrace): hdiff = (hyp[tnum] - meanh) tdiff = self.acq.traces[tnum+startTrace,:] - meant sumnum += hdiff * tdiff signal = np.abs(sumnum / (endTrace - startTrace)) return signal, noise
def corrCoefficient(self, subkey, sboxNum, startTrace=0, endTrace=0, leakage='HW'): """ Calculate CPA correlation co-efficient: a. Calculate sbox output for the given subkey b. Calculate hypothesis (which is hamming weight or hamming distance depending on power model) c. Calculate pearson's correlation co-efficient of given subkey Input: subkey (6bit key which is input to sbox) sboxNum (1...8) Return the correlation co-efficient of the given subkey """ # Based on ChipWhisperer CPASimpleLoop.py sumnum = np.zeros(self.acq.numSamples) sumden1 = np.zeros(self.acq.numSamples) sumden2 = np.zeros(self.acq.numSamples) if (endTrace == 0): endTrace = self.acq.numTraces # Generate hypotheticals hyp = np.zeros(endTrace - startTrace) for i in range(endTrace - startTrace): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2( ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) if leakage == 'HW': hyp[i] = HW(sboxOut) elif leakage == 'HDRound': hyp[i] = HD(sboxOut, des_block.ptRoundIn(ptStr, sboxNum)) elif leakage == 'HD': hyp[i] = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 meanh = np.mean(hyp, dtype=np.float) meant = np.mean(self.acq.traces[startTrace:endTrace], axis=0, dtype=np.float) for tnum in range(endTrace - startTrace): hdiff = (hyp[tnum] - meanh) tdiff = self.acq.traces[tnum + startTrace, :] - meant sumnum += hdiff * tdiff sumden1 += hdiff * hdiff sumden2 += tdiff * tdiff #print sumden1 #print sumden2 #print np.sqrt(sumden1 * sumden2) corr = sumnum / np.sqrt(sumden1 * sumden2) return corr
def cpaPoint(self, sk, sboxNum, samplePoint, startTrace=0, endTrace=0, leakage='HW'): """The cpaPoint function calculates the CPA signal to noise ratio for a single sample of a given traceset. This saves a lot of time compared to cpaTrace. The recommended usage scenario will be to determine the sample point of interest using cpaTrace (with fewer traces), and then to use cpaPoint (with many traces) Inputs: subkey - the correct subkey (which is 0 to 63 for DES) sboxNum - the sbox number we are targeting (values 1 to 8) samplePoint - the single samplePoint to calculate the SNR for startTrace, endTrace - SNR is calculated from Trace startTrace to endTrace. This value is optional. If left out, it will calculate SNR for entire trace set leakage - The leakage model. This takes values 'HW', 'HD', 'HDRound' returns: signal, noise """ if endTrace == 0: endTrace = self.acq.numTraces HammW = [] for i in range(5): HammW.append([]) numTraces = endTrace - startTrace covMethod = np.zeros((2, numTraces)) for i in range(numTraces): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2( ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxOut = des_block.sbox(sboxNum, ptBlock ^ sk) if leakage == 'HW': hyp = HW( sboxOut ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HDRound': hyp = HD( sboxOut, des_block.ptRoundIn(ptStr, sboxNum) ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HD': hyp = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 HammW[hyp].append(self.acq.traces[i + startTrace][samplePoint]) covMethod[0][i] = self.acq.traces[i + startTrace][samplePoint] covMethod[1][i] = hyp noiseCPA = [] signalCPA = [] signalCPAdiff = [] for j in range(5): noise = np.std(HammW[j]) if (np.isnan(noise)): pass else: noiseCPA.append(noise) noiseCPA = np.mean(noiseCPA) signalCov = np.abs(((np.cov(covMethod))[1][0])) return signalCov * self.acq.yscale, noiseCPA * self.acq.yscale
def cpaTrace(self, subkey, sboxNum, startTrace=0, endTrace=0, leakage='HW'): """The cpaTrace function calculates the CPA signal to noise ratio over all the samples of a traceset Inputs: subkey - the correct subkey (which is 0 to 63 for DES) sboxNum - the sbox number we are targeting (values 1 to 8) startTrace, endTrace - SNR is calculated from Trace startTrace to endTrace. This value is optional. If left out, it will calculate SNR for entire trace set leakage - The leakage model. This takes values 'HW', 'HD', 'HDRound' Returns: Signal matrix, noise matrix """ sumnum = np.zeros(self.acq.numSamples) if (endTrace == 0): endTrace = self.acq.numTraces # Group traces according to the hamming weight of the leakage traceHW = [] noise = [] for i in range(5): traceHW.append(None) noise.append(None) # Generate hypotheticals hyp = np.zeros(endTrace - startTrace, dtype=int) for i in range(endTrace - startTrace): ptStr = self.ptNumpyArray2String(self.acq.inputtext[i + startTrace]) ptBlock = des_block.ptblock2( ptStr, sboxNum) # 6-bit block of plaintext which is fed into sboxNum sboxIn = ptBlock ^ subkey sboxOut = des_block.sbox(sboxNum, sboxIn) if leakage == 'HW': hyp[i] = HW( sboxOut ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HDRound': hyp[i] = HD( sboxOut, des_block.ptRoundIn(ptStr, sboxNum) ) # or use HD(sboxOut, sboxIn) for hardware implementations elif leakage == 'HD': hyp[i] = HD(sboxOut, sboxIn) else: print "undefined leakage model" return 0 if traceHW[hyp[i]] == None: traceHW[hyp[i]] = self.acq.traces[i] else: traceHW[hyp[i]] = np.vstack( (traceHW[hyp[i]], self.acq.traces[i])) meanh = np.mean(hyp, dtype=np.float) meant = np.mean(self.acq.traces[startTrace:endTrace], axis=0, dtype=np.float) noise = np.std(traceHW[0], axis=0) for i in range(5): noise = np.vstack((noise, np.std(traceHW[i], axis=0))) noise = np.mean(noise, axis=0) for tnum in range(endTrace - startTrace): hdiff = (hyp[tnum] - meanh) tdiff = self.acq.traces[tnum + startTrace, :] - meant sumnum += hdiff * tdiff signal = np.abs(sumnum / (endTrace - startTrace)) return signal, noise