Plotting PGE vs Number of Traces for UFO FPGA


I’m running the CPA tests (from the tutorial) on the Spartan 6 UFO board for CW Lite. Since we’re really finding the correct round 10 key, the PGE vs Traces plot doesn’t come out right. So this is perhaps more of a Python question, cause I’m not really sure how to change the code to make it right (I’m very new to Python). The code I’ve used to plot is the following:

import holoviews as hv
import holoviews as hv
from tqdm import tnrange
def byte_to_color(idx):
    return hv.Palette.colormaps['Category20'](idx/16.0)

plot_data = cwa.analyzer_plots(results)
ret = plot_data.pge_vs_trace(0)
curve = hv.Curve((ret[0],ret[1]), "Traces Used in Calculation", "Partial Guessing Entropy of Byte")
for bnum in tnrange(1, 16):
    ret = plot_data.pge_vs_trace(bnum)
    curve *= hv.Curve((ret[0],ret[1])).opts(color=byte_to_color(bnum))
curve.opts(width=900, height=600)

The same goes for the Max Correlation vs Iteration Number plots:

import numpy as np
a = []
b = []
for bnum in tnrange(0, 16):
    data = plot_data.corr_vs_trace(bnum)
    best = [0] * len(data[1][0])
    for i in range(255):
        if i == key[bnum]:
            if max(best) < max(data[1][i]): best = data[1][i]

pda = pd.DataFrame(a).transpose().rename(str, axis='columns')
pdb = pd.DataFrame(b).transpose().rename(str, axis='columns')
curve = hv.Curve(pdb['0'].tolist(), "Iteration Number", "Max Correlation").options(color='black')
for i in tnrange(1,len(pdb.columns)):
    curve *= hv.Curve(pdb[str(i)]).options(color='black')
for i in tnrange(len(pda.columns)):
    curve *= hv.Curve(pda[str(i)]).options(color=byte_to_color(i))
curve.opts(width=900, height=600)

How do I need to change the code snippets to get the correct plots?


Which tutorial are you running? We don’t have one specific to the Spartan6 UFO target, so what you should do is use (assuming you’re using the reference Spartan6 bitfile):

  • the capture code from any UFO CPA tutorial, e.g. this one – just be sure to reduce the number of samples per trace, and collect more traces (5k should be plenty)
  • the analyzer code from the CW305 tutorial

What version of CW software are you running? If you’re using a release, then you’ll have to update to the latest 5.1.3 release. There was a bug in prior CW5 releases that was fixed by this commit.



I got it to work now, needed to scrutinize my python analyzer code a little bit to find a couple of bugs (the setup was all good, and I’m using v. 5.1.3). These lines from the CW305 tutorial were also very helpful:

from chipwhisperer.analyzer.attacks.models.aes.key_schedule import key_schedule_rounds
recv_lastroundkey = [kguess[0][0] for kguess in results_callback.find_maximums()]


Great, glad to hear it :slight_smile: