January 18, 2018 Written by

The Tutorial B5 has shown how you can break AES on a relative “easy” way. We have learned much new theoretic information for that method. But the Tutorial was limited on the Attack himself as well as the background and explanations how the Attack works. But the evaluation of the traces and the meaningful gradation on the display was realized by the software itself.

But in our own Test on real Hardware we may not use that software so easily. Because of that the Tutorial B6 shows how to evaluate the traces manually. It explains all necessary steps for interpreting and plotting the deliverables with a Python-Script.

We have scripted the program flowchart from figure 16 with Python code by ourselves:

 

Here ist he final code with comments:

import numpy as np
import sys

from datetime import datetime
startTime = datetime.now()

np.seterr(all='warn')

# number of bin 1's from dec 0 to dec 256
HW = [bin(n).count("1") for n in range(0,256)]

print HW
sbox=(

0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16)

# Bitwise xor and sbox lookup
def intermediate(pt, keyguess):
    return sbox[pt ^ keyguess]

# load traces and textin from script arguments
trace_path = sys.argv[1]
pt_path = sys.argv[2]

# load traces and textin to variables
traces = np.load(trace_path) # *.npy
pt = np.load(pt_path) # *.npy

# count traces
numtraces = np.shape(traces)[0]-1
numpoint = np.shape(traces)[1]

print "Traces: ",numtraces
print "Punkte: ",numpoint
print ""
print "Calculating..."

# bestguess array mit 16 nullen fuellen
bestguess = [0]*16 

# for each subkey (bnum) run this loop
for bnum in range(0, 16):

    print "Subkey: ", bnum

    # Initialize arrays
    cpaoutput = [0]*256
    maxcpa = [0]*256 

    # For every key we assume (00, 01, ... , fc, fd, fe, ff) go through this loop
    for kguess in range(0, 256):
        print "Subkey %2d, hyp = %02x: \n"%(bnum, kguess), # example: Subkey 15, hyp = ea:

        #Initialize arrays & variables to zero
        sumnum = np.zeros(numpoint) # covar of x and y
        sumden1 = np.zeros(numpoint) # var of x
        sumden2 = np.zeros(numpoint) # var of y
        hyp = np.zeros(numtraces)

        #Get the number of ones in SBOX output
        for tnum in range(0, numtraces):
            hyp[tnum] = HW[intermediate(pt[tnum][bnum], kguess)]

        #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(0, numtraces):
            hdiff = (hyp[tnum] - meanh) # Hamming Distanz
            tdiff = traces[tnum,:] - meant           

            sumnum = sumnum + (hdiff*tdiff) # Covar of x and y
            sumden1 = sumden1 + hdiff*hdiff # var of x
            sumden2 = sumden2 + tdiff*tdiff # var of y

        cpaoutput[kguess] = sumnum / np.sqrt( sumden1 * sumden2 ) # pearson correlation coefficient
        maxcpa[kguess] = max(abs(cpaoutput[kguess]))

        #print maxcpa[kguess] # z.B. 0.579157504278 

    #Find maximum value of key
    bestguess[bnum] = np.argmax(maxcpa) 

print ""
print "Best Key Guess: "
for b in bestguess: print "%02x "%b,
print ""
print "\nExecution time: ",datetime.now() - startTime

Last modified on Wednesday, 31 January 2018 20:45