Power Analysis
Recovering a key from how much current a chip draws while it uses it. Statistics turn a noisy measurement into one key byte at a time, which is why 16 bytes cost 4096 guesses instead of 2 to the 128.
Power analysis is the passive branch of Wiki: side-channel work: you measure how much current a device draws while it computes on a secret, and you recover the secret from the shape of that measurement. It does not need a bug, a debug port, or a firmware dump. It needs the device to keep doing the same operation while you watch.
Why current depends on data
In CMOS logic almost all the energy is spent on transitions. A gate that stays put costs nearly nothing; a gate that switches charges or discharges a capacitance and draws a spike. So the instantaneous current is roughly proportional to how many bits changed in that clock cycle, and both classic leakage models fall straight out of that:
- Hamming weight: the number of bits set in the value being handled. It models a precharged bus, where a byte is driven onto lines that were all reset to a fixed level, so the cost depends on the value itself. This is the model that works on small software implementations.
- Hamming distance: the number of bits that differ between the previous and the new content of a register. It models a register being overwritten, and it is the model you need on hardware accelerators, where the interesting event is the state register changing between the last two rounds.
Choosing the wrong one of those two is the most common reason a technically correct attack produces no peak.
The three named attacks
- Simple power analysis reads a single trace directly. It works when the sequence of operations depends on the secret: a square-and-multiply exponentiation whose multiply steps are visible, a PIN comparison that returns early, an RSA key whose bits you can literally count off the trace.
- Differential power analysis (Kocher, 1999) splits many traces into two groups according to one predicted bit and subtracts the group means. If the prediction was right the difference spikes; if it was wrong it stays flat.
- Correlation power analysis (Brier, Clavier and Olivier, 2004) replaces that difference of means with a Pearson correlation between the predicted leakage of a whole intermediate value and the measured samples. It uses more of the information in each trace, so it needs fewer of them, and it is what everybody runs today.
Why one byte at a time
CPA works because AES, like most block ciphers, mixes the key into the data in small pieces before it diffuses anything. After the first AddRoundKey and SubBytes, the byte SBOX(p XOR k) depends on exactly one plaintext byte and one key byte. So you can guess that one key byte, predict the leakage for every trace, and check the prediction against the measurement, independently of the other fifteen.
That turns an impossible 2^128 search into 16 independent searches of 256, and it is the entire reason the attack is practical. The correct hypothesis correlates with the real leakage; the wrong 255 do not, and their apparent correlation shrinks as you add traces.
import numpy as np
def cpa_byte(traces, plaintexts, byte, sbox):
"""traces (N, S) float, plaintexts (N, 16) uint8 -> ranked key guesses."""
scores = np.zeros(256)
t = traces - traces.mean(axis=0)
t_norm = (t * t).sum(axis=0)
for guess in range(256):
inter = sbox[plaintexts[:, byte] ^ guess]
hyp = np.unpackbits(inter[:, None], axis=1).sum(axis=1).astype(float)
h = hyp - hyp.mean()
r = (h @ t) / np.sqrt((h @ h) * t_norm)
scores[guess] = np.abs(r).max()
return scores.argsort()[::-1]
Two properties of that function are the whole diagnostic toolkit. The correlation of the correct guess grows with the number of traces while the others decay, so plotting the top score against trace count tells you whether you are converging or fooling yourself. And the peak sits at a specific sample index, the moment the S-box output is handled, so all sixteen bytes should peak at nearby, sensible places. A winner whose peak lands in a random spot is a ghost peak.
Getting a usable trace
The measurement is the hard part, not the statistics.
- Insert a shunt of a few ohms to a few tens of ohms in the target's supply or ground path and measure the voltage across it, or hold an EM probe over the package and skip the electrical contact entirely. EM is often better because it localises: it can see one block of the die rather than the whole chip.
- Trigger on the operation, not on the power-up. A GPIO the target toggles before encrypting is the clean case; otherwise you pattern-match a distinctive shape in the signal.
- Sample fast enough, and ideally in step with the target clock. Synchronous sampling is why a ChipWhisperer at 4 samples per cycle beats a fast oscilloscope sampling asynchronously: no clock drift between traces means far less alignment work.
Alignment is not a detail
Correlation is computed per sample index across traces: sample 812 of trace 1 is compared with sample 812 of trace 2. If one trace is shifted by a handful of samples, the operation you are attacking no longer lives at the same index, and the correlation for the correct key averages away with everything else.
That is exactly why jitter is a countermeasure. Random delays, dummy rounds, and an unstable internal oscillator all attack the alignment assumption rather than the leakage itself. The counter-measures against the countermeasure are static alignment on a sharp reference feature, cross-correlation alignment, and resampling on a recovered clock.
What the numbers look like
An unprotected 8-bit software AES on a training board typically falls in tens to a few hundred traces. A first-order masked implementation is immune to the plain attack above and needs either a second-order attack (combine two sample points) or orders of magnitude more traces. A hardware AES engine on a modern application processor, running at hundreds of megahertz with everything else on the die switching at the same time, is a different sport: EM probing, careful localisation, and often millions of traces.
Report a negative result honestly. "No correlation with this rig, this model and this many traces" is a finding. "Immune to power analysis" is not something a single failed campaign can establish.
Pitfalls
- The wrong leakage model. Hamming weight of the S-box output on a hardware core will find nothing. Try Hamming distance on the last round instead, modelling the state register overwrite from the ciphertext.
- Ghost peaks. With too few traces some wrong guess always wins. Sweep the trace count and watch whether the winner is stable.
- A constant plaintext. Averaging repeated encryptions of the same input removes noise but also removes the variation the attack needs. Vary the plaintext, average only over identical repeats of the same input if you average at all.
- Trigger jitter. An interrupt that fires between the trigger and the operation shifts the trace. Disable what you can on the target before blaming the statistics.
- Confusing this with fault work. Power analysis observes. Its active sibling, injecting a fault and comparing outputs, is Wiki: differential-fault-analysis.