Side Channel Analysis/Power Analysis Attack in SAKURA X


You’ll have to concentrate based on your desired model - for example if your hypothetical value is based on the leakage of the first S-Box operation that would be the one to concentrate on.

But using a Hamming Distance (HD) model would be more suitable. I haven’t used the SAKURA X myself so don’t know details of how many traces it would take. What speed is the AES core running at?



PS: The current ChipWhisperer SW doesn’t work for HD on first-round. That’s something I wanted to fix so might try to do tha tnow, and would give you a ‘known good’ reference at least…

Is it the default AES module? Assuming it’s the same as the SASEBO-GII & SAKURA-G AES core, there isn’t any countermeasures. Definitely try the HD model, as again assuming you are using some default AES module it’s much closer to the leakage exhibited by the FPGA design.

Yeah I think you’ve essentially got the idea, although haven’t gone through those details. You can choose to target some specific point when determining the HD… I think I was previously using the difference between the SBox input & output. I’m just trying to check on my own system with SAKURA-G how the HD works on the first round - as mentioned I was previously only targeting the last round. I’ll update this with some details…

Alright, had some time to remember details of the SAKURA implementation of AES. Remember the objective of a ‘Hamming Distance’ model is to determine how many bits change on some data line / data bus.

For the implementation used in the SAKURA-G (and I assume SAKURA-X too), it does an entire round in one clock cycle. What this means for you is that the only thing you can really do a ‘hamming distance’ attack against is the state, which will will call STN, where N is the round number. See the following figure:

The classic HD attack on the SAKURA-G platform is actually using the cipher text. Thus what we are attacking is the difference between ST9 and ST10. The code in Python I’m using for this is as follows:

def HypHD(ct, key, bnum):
    st10 = ct[INVSHIFT[bnum]]
    st9 =  aes_tables.i_sbox[ct[bnum] ^ key]
    return getHW(st9 ^ st10)

The problem is you cannot do something similar with the input round due to the presence of mixcols. You have no way of testing how a single 8-bit sequence changed due to a different key guess. You CAN do this for the last round since it omits mixcols.

If you look at the FPGA source code, the only thing you can do easily do for the first-round attack is compare the PREVIOUS ciphertext to the new value of textin XOR keyguess. i.e. something like this:

def HypHD(pt, key, bnum, lastct):
    st2 = pt[bnum] ^ key
    st1 = lastct[bnum]
    return getHW(st1 ^ st2)

This works since the FPGA holds the last valid state (i.e. the generated ciphertext) until it’s overwritten with the new plaintext XOR with the first-round key. The result is you can do the HD attack against the change in this state.

Hopefully this helps! Either way you’ll need to have recorded the ciphertext (i.e. output). If you don’t have that because your system doesn’t record it you can always cheat for testing purposes - i.e. you already know the input plaintext, you (presumably) know the encryption key, so just generate what the ciphertext should have been.

But I’d try to recreate the first attack and get that working before anything else.

The S-Box input/output isn’t stored in the same register, so you won’t get any real correlation on the HD between the input & output. This works for software AES since it’s putting the results on/off the databus. But won’t work in hardware since the input & output are a separate bus.

Yup, and also the inverse shift-rows. In my previous code sample, here is the INVSHIFT values for reference (the inv s-box is as found anywhere else):

INVSHIFT = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11]

You can technically run the attack over the entire trace and let the attack determine the area of interest. But for example here is my power trace from the SAKURA-G:

Doing the CPA attack on the last round I’ve gone from points 300 - 350, you can see it’s all around points 312 basically:

Finally zooming in on the original waveform:

You can use the tools designed for the SASEGO-GII + DPA Contest v3. In particular there is the ‘roundkey’ tool at, if you want an .exe I’ve uploaded one at

You can convert between last & first round key with that tool. For example to go from last-round to first-round:

C:\Users\colin\Downloads>RoundKey.EXE -r "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" 00: 71 01 06 70 45 1F D5 3B C2 92 3F BE 04 4B F0 DA 01: C3 8D 51 82 86 92 84 B9 44 00 BB 07 40 4B 4B DD 02: 72 3E 90 8B F4 AC 14 32 B0 AC AF 35 F0 E7 E4 E8 03: E2 57 0B 07 16 FB 1F 35 A6 57 B0 00 56 B0 54 E8 04: 0D 77 90 B6 1B 8C 8F 83 BD DB 3F 83 EB 6B 6B 6B 05: 62 08 EF 5F 79 84 60 DC C4 5F 5F 5F 2F 34 34 34 06: 5A 10 F7 4A 23 94 97 96 E7 CB C8 C9 C8 FF FC FD 07: 0C A0 A3 A2 2F 34 34 34 C8 FF FC FD 00 00 00 00 08: EF C3 C0 C1 C0 F7 F4 F5 08 08 08 08 08 08 08 08 09: C4 F3 F0 F1 04 04 04 04 0C 0C 0C 0C 04 04 04 04 10: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F .

Here the last-round key was 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F.

Yeah, glad things are working :slight_smile: It’s always frustrating when you are starting out tracking down the issues…

Anyway the negative correlation should indeed be valid - I actually take the absolute value in my attack ranking. When generating the hypothetical values you are only generating positive values (i.e. 3 lines changed, etc). But the measurement will have a positive or negative value depending on if you are going from higher value -> lower or lower -> higher. You can also flip the order of this by measuring from the VCC vs the GND shunt, you’d expect the opposite polarity. So indeed it is working!

You’d have to make your own code to do the reversal. Check out my post a few back - I’ve got a link to the “round key checking tool” from the SAKURA project. It has code in C++ which you might be able to convert, or you can just use the binary directly (also in my post is a link to a binary).

Should be possible - you can play around with various low-pass filters in your software, for example MATLAB has a few through toolboxes. Another thing to try is to limit the points to just those of interest… i.e. once you determine where the biggest peak is located at, only input points around that peak.

Hi Ali,
Did you managed to get things work completely?
I’ve just started to work with Sakura-X and saw the same waveform as you.
I wanted to make sure if I’m on the right track before I continue.
Thank you.