The setup
I worked with an STM32 Nucleo board (STM32F401RE) and implemented a few lightweight cryptographic algorithms, including Ascon and Speck, alongside a standard like AES for comparison. My goal was to measure not just execution time, but also energy consumption, code size, and RAM usage, to get a more complete picture of how these algorithms behave on a real microcontroller.
Prerequisites
arm-none-eabi-gcc toolchain, and a current sensor (I used an INA219) if you want energy numbers.// Example: measuring cycle count for an encryption function
uint32_t start = DWT->CYCCNT;
ascon_encrypt(plaintext, ciphertext, key, nonce);
uint32_t cycles = DWT->CYCCNT - start;What I measured
- Cycles per byte — raw speed on the chip
- Energy per encryption — using a current sensor on the supply line
- Code size (flash) and peak RAM usage
What went wrong
At first, my results looked almost too good to be true. After digging deeper, I realized I had made a few classic mistakes: compiler optimizations were eliminating parts of the code, I wasn't accounting for initialization time, and my measurements weren't consistent across different build configurations. It was a good reminder that benchmarking is hard, and small details can completely change the results.
Watch out
-O2 or higher, the compiler may remove an encryption call whose output is never used. Mark buffers volatile or consume the result."The biggest lesson was that benchmarking is less about running code and more about controlling for everything else."
The results
| Algorithm | Cycles / byte | Flash (KB) | RAM (B) | Energy (µJ) |
|---|---|---|---|---|
| Ascon-128 | 142 | 3.1 | 320 | 4.8 |
| Speck-64/128 | 96 | 1.4 | 180 | 3.2 |
| AES-128 | 188 | 6.2 | 560 | 6.9 |
What I learned
Through this process, I gained a much deeper appreciation for the constraints of embedded systems. Memory, power, and performance are always trade-offs, and what looks good in theory doesn't always translate to real hardware. I also learned the importance of building a rigorous and repeatable benchmarking setup, from controlling compiler flags to measuring actual energy consumption using a current sensor.

My benchmarking checklist
- Fix compiler flags and record them with every result
- Warm up and exclude initialization time
- Repeat many runs and report averages and variance
- Verify outputs so the compiler can't skip work
Tip
What I'd do differently
If I were to do this again, I'd spend more time upfront on the benchmarking methodology, including defining clear metrics and running more iterations to account for variance. I'd also like to explore more algorithms and test on a lower-power STM32 board to see how the results change in an even more constrained environment.
References
- NIST Lightweight Cryptography Standardization — the competition Ascon won
- Ascon specification — official algorithm site
- STM32F401RE reference manual
