Matchstick Cryptography: How to Squeeze ECDSA into a Cheap Microcontroller
When it comes to protecting data in IoT or cheap hardware, developers often hit a wall. Try deploying a full OpenSSL on some 8-bit AVR or weak ARM Cortex-M0. More likely than not, your firmware simply won't fit into memory, and even if it does, there won't be any resources left for the main application logic. That's where the micro-ecc project comes in handy—it does one thing, but does it damn well.
What's the Point of This Project
micro-ecc is a compact implementation of ECDH (key exchange) and ECDSA (digital signature) algorithms in C. The project's author, Ken MacKay, clearly set out to create a library that would run anywhere there's at least some processor.
The main trick here is the complete abandonment of dynamic memory allocation. No malloc and heap, just stack and static storage. For embedded systems this is critical: you know exactly how much memory cryptography will consume at compile time, and you don't fear fragmentation or runtime leaks.
What the Library Can Do
The library supports five standard curves, including the popular secp256r1 (also known as P-256) and the "Bitcoin" secp256k1.
The main features look like this:
- Works on 8, 32, and 64-bit architectures.
- Protected against known side-channel attacks.
- Written in pure C, but there are assembly snippets for AVR and ARM to squeeze out maximum speed.
- Distributed under the liberal BSD 2-clause license.
By the way, if you're working with Arduino, the project is available right in the Library Manager. No need to download anything manually—just find micro-ecc and add it to your sketch.
Small Code for Big Tasks
The author claims the code is optimized for size. In the world of microcontrollers, this is often more important than raw speed. If you just need to verify a firmware update signature once a month, it doesn't matter whether it takes 100ms or 500ms. What matters is that the verification code doesn't eat up 80% of your flash memory.
That said, there are optional optimizations in the code. For example, through uECC_OPTIMIZATION_LEVEL you can tweak performance. But be careful: with high optimization levels for ARM platforms, GCC may require specific flags like -fomit-frame-pointer, otherwise everything might break.
What It Looks Like in Code
The library has a minimalist interface. To get started, you just copy a couple of files into your project and include the header file.
#include "uECC.h"
// Создаем ключи
uint8_t public_key[64];
uint8_t private_key[32];
const struct uECC_Curve_t * curve = uECC_secp256r1();
uECC_make_key(public_key, private_key, curve);
Curve points are represented in uncompressed form without the 0x04 prefix by default. If you need to save every byte when transmitting over radio, the library provides uECC_compress() and uECC_decompress() functions.
Who This Is For
I see several scenarios where micro-ecc is simply indispensable. First, device authentication. For example, when your sensor needs to prove to the server that it is what it is, not a counterfeit. ECDSA is perfect for generating such a signature.
Second, Secure Boot. If you're writing a custom bootloader for STM32 or some AVR, micro-ecc will help verify the signature of a new firmware image before writing it to flash.
Third, if you're creating wearable electronics or battery-powered sensors. The fewer CPU cycles spent on calculations, the longer the device lives. Assembly snippets for ARM and AVR will come in very handy here.
A Few Notes for the Road
Despite its awesomeness, the project has its quirks. The README is quite terse, so for details on each function you'll have to dig into the uECC.h. Documentation lives right in the code comments.
If you're planning to build the project on Windows, don't forget to link the system library advapi32.lib—it's needed for working with entropy. And for AVR, make sure to enable compiler optimization (-O1 and higher), otherwise the library may not work correctly due to stack handling specifics.
Overall, this is a great example of what a specialized library should look like: a narrow focus, minimal dependencies, and predictable behavior. If your hardware is too weak for TLS but you need security—micro-ecc definitely deserves a spot in your src/lib.