Esempio n. 1
0
    def DESDpaCC(self, sboxNum, plot = False):
        """ Returns DES DPA Confusion coefficents Matrix of size [number of keys x number of keys]
        #inputs:
        sboxNum - the sbox number we are targeting (values 1 to 8)
        plot - if True, will plot the matrix as a histogram
        """
        numPT = 2 ** 6      # number of possible PT/CT
        numKey = 2 ** 6     # number of possible keys
        cc = np.zeros((numKey,numKey), np.float)    # Confusion Coefficient matrix
        histogram = []

        for ki in range(numKey):
            for kj in range(numKey):
                numNotEqual = 0
                for ptBlock in range(numPT):
                    sboxOuti = des_block.sbox(sboxNum, ptBlock ^ ki)
                    sboxOutj = des_block.sbox(sboxNum, ptBlock ^ kj)
                    if (self.msb(sboxOuti) != self.msb(sboxOutj)):
                        numNotEqual += 1.0
                coefficient = numNotEqual / numPT
                cc[ki][kj] = coefficient
                if (ki != kj and ki<kj):
                    histogram.append(coefficient)

        if (plot):
            # Plot a histogram of the coefficients
            weights = np.ones_like(histogram)/len(histogram)
            fig = plt.hist(histogram, 1000, weights=weights)
            plt.ylabel('Frequency')
            plt.xlabel('Confusion coefficient')
            plt.show(fig)
        return cc
Esempio n. 2
0
    def DESDpaCC(self, sboxNum, plot=False):
        """ Returns DES DPA Confusion coefficents Matrix of size [number of keys x number of keys]
        #inputs:
        sboxNum - the sbox number we are targeting (values 1 to 8)
        plot - if True, will plot the matrix as a histogram
        """
        numPT = 2**6  # number of possible PT/CT
        numKey = 2**6  # number of possible keys
        cc = np.zeros((numKey, numKey),
                      np.float)  # Confusion Coefficient matrix
        histogram = []

        for ki in range(numKey):
            for kj in range(numKey):
                numNotEqual = 0
                for ptBlock in range(numPT):
                    sboxOuti = des_block.sbox(sboxNum, ptBlock ^ ki)
                    sboxOutj = des_block.sbox(sboxNum, ptBlock ^ kj)
                    if (self.msb(sboxOuti) != self.msb(sboxOutj)):
                        numNotEqual += 1.0
                coefficient = numNotEqual / numPT
                cc[ki][kj] = coefficient
                if (ki != kj and ki < kj):
                    histogram.append(coefficient)

        if (plot):
            # Plot a histogram of the coefficients
            weights = np.ones_like(histogram) / len(histogram)
            fig = plt.hist(histogram, 1000, weights=weights)
            plt.ylabel('Frequency')
            plt.xlabel('Confusion coefficient')
            plt.show(fig)
        return cc
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
    def DESCpaCC(self, sboxNum, plot=False, leakage='HW'):
        """ Returns DES CPA 2-way Confusion coefficents Matrix of size [number of keys x number of keys]
        #inputs:
        sboxNum - the sbox number we are targeting (values 1 to 8)
        plot - if True, will plot the matrix as a histogram
        leakage - The leakage model. This takes values 'HW', 'HD', 'HDRound'
        """

        numPT = 2**6  # number of possible PT/CT
        numKey = 2**6  # number of possible keys
        cc = np.zeros((numKey, numKey),
                      np.float)  # Confusion Coefficient matrix
        histogram = []

        for ki in range(numKey):
            for kj in range(numKey):
                numNotEqual = 0.0
                k = []
                for ptBlock in range(numPT):
                    sboxIni = ptBlock ^ ki
                    sboxInj = ptBlock ^ kj

                    sboxOuti = des_block.sbox(sboxNum, sboxIni)
                    sboxOutj = des_block.sbox(sboxNum, sboxInj)
                    if leakage == 'HW':
                        k.append((self.hw(sboxOuti) - self.hw(sboxOutj))**2)
                    if leakage == 'HD':
                        k.append(
                            (HD(sboxOuti, sboxIni) - HD(sboxOutj, sboxInj))**2)

                cc[ki][kj] = np.mean(k)
                if (ki != kj and ki < kj):
                    histogram.append(cc[ki][kj])

        if (plot):
            weights = np.ones_like(histogram) / len(histogram)
            fig = plt.hist(histogram, 1000, weights=weights)
            plt.ylabel('Frequency')
            plt.xlabel('Confusion coefficient')
            plt.show(fig)

        return cc
Esempio n. 7
0
    def DESCpaCC(self, sboxNum, plot = False, leakage ='HW'):
        """ Returns DES CPA 2-way Confusion coefficents Matrix of size [number of keys x number of keys]
        #inputs:
        sboxNum - the sbox number we are targeting (values 1 to 8)
        plot - if True, will plot the matrix as a histogram
        leakage - The leakage model. This takes values 'HW', 'HD', 'HDRound'
        """

        numPT = 2 ** 6      # number of possible PT/CT
        numKey = 2 ** 6     # number of possible keys
        cc = np.zeros((numKey,numKey), np.float)    # Confusion Coefficient matrix
        histogram = []

        for ki in range(numKey):
            for kj in range(numKey):
                numNotEqual = 0.0
                k = []
                for ptBlock in range(numPT):
                    sboxIni = ptBlock ^ ki
                    sboxInj = ptBlock ^ kj

                    sboxOuti = des_block.sbox(sboxNum, sboxIni)
                    sboxOutj = des_block.sbox(sboxNum, sboxInj)
                    if leakage =='HW':
                        k.append((self.hw(sboxOuti) - self.hw(sboxOutj)) ** 2)
                    if leakage =='HD':
                        k.append((HD(sboxOuti, sboxIni) - HD(sboxOutj,sboxInj)) ** 2)


                cc[ki][kj] = np.mean(k)
                if (ki != kj and ki<kj):
                    histogram.append(cc[ki][kj])

        if (plot):
            weights = np.ones_like(histogram)/len(histogram)
            fig = plt.hist(histogram, 1000, weights=weights)
            plt.ylabel('Frequency')
            plt.xlabel('Confusion coefficient')
            plt.show(fig)

        return cc
Esempio n. 8
0
    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
Esempio n. 9
0
    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 = HW(sboxOut)
                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
Esempio n. 10
0
    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
Esempio n. 11
0
    def dpaPoint(self,
                 sk,
                 sboxNum,
                 samplePoint,
                 startTrace=0,
                 endTrace=0,
                 bit=1):
        """The dpaPoint function calculates the DPA signal to noise ratio for a single sample of a given traceset.

        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'
        if bit is provided, returns the SNR of that specific sbox output bit. This takes values of 0,1,2,3
        """

        if endTrace == 0:
            endTrace = self.acq.numTraces

        LSB = []

        for i in range(2):
            LSB.append([])
        numTraces = endTrace - startTrace

        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)

            LSB[(sboxOut & (2**bit)) >> bit].append(
                self.acq.traces[i + startTrace][samplePoint])

        signalDPA = np.abs(np.mean(LSB[0]) - np.mean(LSB[1]))
        noiseDPA = []

        # Traditional method for calculating SNR for DPA
        for j in range(2):
            noiseDPA.append(np.std(LSB[j]))
        noiseDPA = np.mean(noiseDPA)

        return signalDPA * self.acq.yscale, noiseDPA * self.acq.yscale
Esempio n. 12
0
    def dom(self, subkey, sboxNum, startTrace=0, endTrace=0):
        """
        Calculate DPA DOM:
        a. Calculate LSB of sbox out given subkey
        b. average all the traces with LSB= one. Repeat for LSB= zero
        c. Calculate the difference of means

        Input:
        subkey (6bit key which is input to sbox)
        sboxNum (1...8)

        Return a trace of the difference of means
        """
        traceLSB0 = np.zeros(self.acq.numSamples, dtype = np.float64)
        traceLSB1 = np.zeros(self.acq.numSamples, dtype = np.float64)
        diff = np.zeros(self.acq.numSamples, dtype = np.float64)
        numLSB0 = 0
        numLSB1 = 0
        if (endTrace == 0):
            endTrace = self.acq.numTraces


        for i in range(startTrace, endTrace):
            ptStr = self.ptNumpyArray2String(self.acq.inputtext[i])
            #print ("ptStr is " + ptStr)
            ptBlock = des_block.ptblock2(ptStr, sboxNum)     # 6-bit block of plaintext which is fed into sboxNum
            sboxOut = des_block.sbox(sboxNum, ptBlock ^ subkey)

            if ((sboxOut & 1) == 1):
                # Sum traces (traceLSB1) with LSB = 1
                numLSB1 += 1
                for j in range(self.acq.numSamples):
                    traceLSB1[j] += self.acq.traces[i][j]
            else:
                # Sum traces (traceLSB0) with LSB = 0
                numLSB0 += 1
                for j in range(self.acq.numSamples):
                    traceLSB0[j] += self.acq.traces[i][j]
        for j in range(self.acq.numSamples):
            traceLSB0[j] = traceLSB0[j] / numLSB0
            traceLSB1[j] = traceLSB1[j] / numLSB1
            diff[j] = traceLSB1[j] - traceLSB0[j]

        #print "numLSB0 = %d, numLSB1 = %d" % (numLSB0, numLSB1)

        return diff
Esempio n. 13
0
    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
Esempio n. 14
0
    def domSinglePoint(self, subkey, sboxNum, samplePoint, startTrace=0, endTrace=0):
        """
        Calculate DPA DOM for a single point:
        a. Calculate LSB of sbox out given subkey
        b. average all the traces with LSB= one. Repeat for LSB= zero
        c. Calculate the difference of means

        Input:
        subkey (6bit key which is input to sbox)
        sboxNum (1...8)

        Return a trace of the difference of means
        """
        traceLSB0 = 0.0
        traceLSB1 = 0.0
        diff = 0.0
        numLSB0 = 0
        numLSB1 = 0
        if (endTrace == 0):
            endTrace = self.acq.numTraces


        for i in range(startTrace, endTrace):
            ptStr = self.ptNumpyArray2String(self.acq.inputtext[i])
            #print ("ptStr is " + ptStr)
            ptBlock = des_block.ptblock2(ptStr, sboxNum)     # 6-bit block of plaintext which is fed into sboxNum
            sboxOut = des_block.sbox(sboxNum, ptBlock ^ subkey)

            if ((sboxOut & 1) == 1):
                # Sum traces (traceLSB1) with LSB = 1
                numLSB1 += 1.0
                traceLSB1 += self.acq.traces[i][samplePoint]
            else:
                # Sum traces (traceLSB0) with LSB = 0
                numLSB0 += 1.0
                traceLSB0 += self.acq.traces[i][samplePoint]
        traceLSB0 = traceLSB0 / numLSB0
        traceLSB1 = traceLSB1 / numLSB1
        diff = traceLSB1 - traceLSB0
        #print "traceLSB0 = %f, traceLSB1 = %f" %(traceLSB0, traceLSB1)
        #print "numLSB0 = %f, numLSB1 = %f" % (numLSB0, numLSB1)

        return diff
Esempio n. 15
0
    def dpaPoint(self, sk, sboxNum, samplePoint, startTrace = 0, endTrace=0, bit=1):
        """The dpaPoint function calculates the DPA signal to noise ratio for a single sample of a given traceset.

        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'
        if bit is provided, returns the SNR of that specific sbox output bit. This takes values of 0,1,2,3
        """

        if endTrace == 0:
            endTrace = self.acq.numTraces


        LSB = []

        for i in range(2):
            LSB.append([])
        numTraces = endTrace - startTrace

        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)

            LSB[(sboxOut & (2**bit)) >> bit].append(self.acq.traces[i+startTrace][samplePoint])

        signalDPA = np.abs(np.mean(LSB[0]) - np.mean(LSB[1]))
        noiseDPA = []

        # Traditional method for calculating SNR for DPA
        for j in range(2):
            noiseDPA.append(np.std(LSB[j]))
        noiseDPA = np.mean(noiseDPA)

        return signalDPA * self.acq.yscale, noiseDPA * self.acq.yscale
Esempio n. 16
0
    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
Esempio n. 17
0
    def CPA_K(self, correctKey=0, leakage='HW'):
        """Returns the 3-way CPA confusion matrix K, K* and K**
        (refer to "A Statistics-based Fundamental Model for Side-channel Attack Analysis.")

        #inputs:
        correctKey - takes values (0...63)
        leakage - the leakage model. Takes values 'HW' and 'HD'.
        """
        Nk = self.NkDES
        numPT = 2 ** 6
        sboxNum = self.sboxNum
        cv = self.CPA_CV(correctKey = correctKey) # Diagonal of the confusion matrix
        K = np.zeros((Nk, Nk))
        Ks = np.zeros((Nk, Nk))     # K*
        Kss = np.zeros((Nk, Nk))    # K**
        keys = np.arange(64)    # List of wrong keys
        keys = np.delete(keys, correctKey)

        evkc = []    # E [V | kc]
        for ptBlock in range(numPT):
            sboxOutc = des_block.sbox(sboxNum, ptBlock ^ correctKey)
            evkc.append(self.hw(sboxOutc))
        evkc = np.mean(evkc)
        #print evkc

        for i in keys:
            for j in keys:
                # Calculate kcij = E[(V|kc - V|ki) * (V|kc - V|ki)]
                # Calculate kcijss = E[4 * (V|kc - E[V|kc])^2 * (V|kc - V|ki) * (V|kc - V | kj)]
                kcij = []
                kcijs = []
                kcijss = []
                for ptBlock in range(numPT):
                    sboxOutc = des_block.sbox(sboxNum, ptBlock ^ correctKey)
                    sboxOuti = des_block.sbox(sboxNum, ptBlock ^ i)
                    sboxOutj = des_block.sbox(sboxNum, ptBlock ^ j)
                    if self.leakage =='HW':
                        vkc = self.hw(sboxOutc) # V | kc
                        vki = self.hw(sboxOuti) # V | ki
                        vkj = self.hw(sboxOutj) # V | kj
                    elif self.leakage =='HD':
                        vkc = HD(sboxOutc, correctKey^ptBlock) # V | kc
                        vki = HD(sboxOuti, i^ptBlock) # V | ki
                        vkj = HD(sboxOutj, j^ptBlock) # V | kj


                    kcij.append((vkc - vki) * (vkc -vkj))
                    kcijs.append(((vkc-vki)**2) * ((vkc-vkj)**2))
                    kcijss.append( 4 * ((vkc - evkc)**2) * (vkc - vki) * (vkc -vkj))
                kcij = np.mean(kcij)
                kcijss = np.mean(kcijss)
                kcijs = np.mean(kcijs)

                K[i][j] = kcij
                Ks[i][j] = kcijs
                Kss[i][j] = kcijs

        K = np.delete(K, correctKey,0)
        K = np.delete(K, correctKey,1)
        Ks = np.delete(Ks, correctKey,0)
        Ks = np.delete(Ks, correctKey,1)
        Kss = np.delete(Kss, correctKey,0)
        Kss = np.delete(Kss, correctKey,1)

        return K, Ks, Kss
Esempio n. 18
0
    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
Esempio n. 19
0
    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
Esempio n. 20
0
    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
Esempio n. 21
0
    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
Esempio n. 22
0
    def CPA_K(self, correctKey=0, leakage='HW'):
        """Returns the 3-way CPA confusion matrix K, K* and K**
        (refer to "A Statistics-based Fundamental Model for Side-channel Attack Analysis.")

        #inputs:
        correctKey - takes values (0...63)
        leakage - the leakage model. Takes values 'HW' and 'HD'.
        """
        Nk = self.NkDES
        numPT = 2**6
        sboxNum = self.sboxNum
        cv = self.CPA_CV(
            correctKey=correctKey)  # Diagonal of the confusion matrix
        K = np.zeros((Nk, Nk))
        Ks = np.zeros((Nk, Nk))  # K*
        Kss = np.zeros((Nk, Nk))  # K**
        keys = np.arange(64)  # List of wrong keys
        keys = np.delete(keys, correctKey)

        evkc = []  # E [V | kc]
        for ptBlock in range(numPT):
            sboxOutc = des_block.sbox(sboxNum, ptBlock ^ correctKey)
            evkc.append(self.hw(sboxOutc))
        evkc = np.mean(evkc)
        #print evkc

        for i in keys:
            for j in keys:
                # Calculate kcij = E[(V|kc - V|ki) * (V|kc - V|ki)]
                # Calculate kcijss = E[4 * (V|kc - E[V|kc])^2 * (V|kc - V|ki) * (V|kc - V | kj)]
                kcij = []
                kcijs = []
                kcijss = []
                for ptBlock in range(numPT):
                    sboxOutc = des_block.sbox(sboxNum, ptBlock ^ correctKey)
                    sboxOuti = des_block.sbox(sboxNum, ptBlock ^ i)
                    sboxOutj = des_block.sbox(sboxNum, ptBlock ^ j)
                    if self.leakage == 'HW':
                        vkc = self.hw(sboxOutc)  # V | kc
                        vki = self.hw(sboxOuti)  # V | ki
                        vkj = self.hw(sboxOutj)  # V | kj
                    elif self.leakage == 'HD':
                        vkc = HD(sboxOutc, correctKey ^ ptBlock)  # V | kc
                        vki = HD(sboxOuti, i ^ ptBlock)  # V | ki
                        vkj = HD(sboxOutj, j ^ ptBlock)  # V | kj

                    kcij.append((vkc - vki) * (vkc - vkj))
                    kcijs.append(((vkc - vki)**2) * ((vkc - vkj)**2))
                    kcijss.append(4 * ((vkc - evkc)**2) * (vkc - vki) *
                                  (vkc - vkj))
                kcij = np.mean(kcij)
                kcijss = np.mean(kcijss)
                kcijs = np.mean(kcijs)

                K[i][j] = kcij
                Ks[i][j] = kcijs
                Kss[i][j] = kcijs

        K = np.delete(K, correctKey, 0)
        K = np.delete(K, correctKey, 1)
        Ks = np.delete(Ks, correctKey, 0)
        Ks = np.delete(Ks, correctKey, 1)
        Kss = np.delete(Kss, correctKey, 0)
        Kss = np.delete(Kss, correctKey, 1)

        return K, Ks, Kss