Design Solutions Research & Design Hub

Side-Channel Power Analysis

Written by Colin O'Flynn


Easy Path to Proof




char passwd[32];
char correct_passwd[] = “h0px3”;
my_read(passwd, 32);

uint8_t passbad = 0;


for(uint8_t i = 0; i < sizeof(correct_passwd); i++){
if (correct_passwd[i] != passwd[i]){
passbad = 1;




Advertise Here





char passwd[32];
char correct_passwd[] = “h0px3”;
my_read(passwd, 32);

uint8_t passbad = 0;


passbad |= correct_passwd[i] ^ passwd[i];





Let’s try that experiment! To do this, I’m actually going to target a specific area of an encryption algorithm. Why not just plot the location of the received data directly? While we could do that, there is a good chance we’d trick ourselves into thinking the signal is stronger than it really is. In particular, if I use a serial interface to send 0xFF on repeat, I would also expect a strong signal because this serial interface is being driven to one level! So instead, I’m going to use something like the setup in Figure 4, where the input data are passed through a random look-up table. This look-up table is reversible, which is to say that every one of the 256 inputs maps to only one output.


Advertise Here

A very simple piece of code that simplifies our validation of the power consumption is related to number of bits set to one on a data bus.

Including this look-up table means that to get a certain number of ones at the output, we are sending an unrelated number of ones in the input. For example, to get seven bits set to one, we could look at the output 0xF7 or 0x7F. In our particular look-up table that would mean that 0x26 and 0x6b, respectively, get sent—those with 3 bits and 5 bits. Therefore, the messages going over the serial port wouldn’t have the same number of bits set. As a result, we wouldn’t expect to see as much influence on our signal from just the serial data line.

How do we know where the actual output is? Our evaluation path will be to send hundreds or even thousands of random bytes to firmware that is executing the code in Figure 4. Because we know the input to the look-up table—we sent it after all—we know the output of the look-up table. This means we could put every possible trace into a “group” based on the number of ones in the output of the look-up table. This number of ones will be the “Hamming weight” of the data.

Based on my claims from Figure 3, I would expect that at some point in time, there would be a measurable difference in the power consumption. Let’s try to validate that now. If we plot the average of each group, there is a point where the averages noticeably diverge, as in Figure 5. The final confirmation is to plot the value at this point in time versus the Hamming weight of the data, which has an almost linear fit (Figure 6). Note that we are actually measuring a one-sided voltage drop across a shunt resistor, which we AC-couple to remove the DC bias. Importantly, if we were drawing no current, we actually would have a zero voltage. As we increase our instantaneous current draw, we will see a higher negative value due to the AC-coupling. Therefore, in this graph we see a lower voltage measurement for more bits set to one. It’s a minor detail, but in case you were wondering why things are “flipped,” there is a reason behind it.

The average power consumption for different output Hamming weights (bits set to one) of the look-up table in Figure 4.
We can see a strong linear relationship between the number of bits set to one on the bus (Hamming weight) and the power consumption at a specific instant in time.

What is really interesting is that all “other” points have very little difference. This makes sense if you consider that any part not within our data of interest has been effectively randomly sorted into different groups. If you take the average of each group, it makes sense that the average power consumption at these other points is the same. So, we not only see the relationship between data being processed and power consumption, but we also see the point in time where our look-up table was used.

You might wonder how this works for an attack. It turns out the start of the AES algorithm looks very much like Figure 4, except that, instead of just taking the input data, the input data is XOR’d with a byte of the secret key (Figure 7). We know from Figure 5 that we can detect the averages diverging if we group each power trace into the correct Hamming weight, and from Figure 6 that there is a strong linear relationship.

The beginning of the real AES algorithm involves a secret key being XOR’d with some input data, before being passed through a look-up table (Substitution Box).

The “attack” is that we can recover bytes of the encryption key, one byte at a time. This means we can break a 16-byte AES-128 or a 32-byte AES-256 key in reasonable time—even just a few minutes. This is done by sending random (known) input data. We don’t need to observe the output of the algorithm in this example.

We could then guess every possibility for 1 byte of the secret key marked in Figure 7. For each of the 256 possibilities for this byte, we could perform the same procedure and group power traces into “possible” Hamming weight groups. If our byte of the secret key matches the real secret key byte, we should be able to create plots similar to those in Figure 5 and Figure 6. If the guessed key does not match, we expect the average of each power trace to overlap as it did for all non-interesting positions.

We can quantify how good the “match” is simply by looking for the linear relationship that we found from our experiment that created Figure 6. This is done by measuring the correlation between Hamming weight and power at each point in time. The correlation can be thought of as a measure of how close to a straight line the data points create. Plotting the correlation over time for each guess, you would see that at the same point in time that we saw the output of the lookup table, we also see a strong correlation. This strong correlation suggests that there is a solution to the problem of “what value of the secret key would allow us to properly group the power traces?”

The solution to that problem becomes a single byte of the encryption key. We can repeat this for each successful byte, and suddenly you’ve broken an AES-128 encryption key. This simple idea underpins one way that side-channel power analysis works to derive encryption keys by monitoring only the input data and the power consumption. The fun part is trying to prove the basics yourself. If you need more hints, check out the ChipWhisperer 5.0 release, which includes several Jupyter-based tutorials that will help you recreate the figures used in my article—except you’ll be recreating them with real measurements, not just simulations or assumptions. 

Additional materials from the author are available at:

NewAE Technology |





Become a Sponsor
Website | + posts

Colin O’Flynn, writes the column Embedded System Essentials for Circuit Cellar. Colin has been building and breaking electronic devices for many years, and is currently completing a PhD at Dalhousie University in Halifax, NS, Canada. His most recent work focuses on embedded security, but he still enjoys everything from FPGA development to hand-soldering his prototype circuits. Some of his work is posted on his website.