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