micro-ecc: Compact ECDH and ECDSA for Embedded C
ECDH and ECDSA for 8-bit, 32-bit, and 64-bit processors.
At a glance
- What is it?
- micro-ecc is a C library for elliptic-curve key agreement and signatures on 8-bit, 32-bit, and 64-bit processors. Its fixed-memory design, supported curves, and processor-specific assembly make it relevant to embedded projects that can accept a low-level cryptographic integration.
- Who is it for?
- micro-ecc fits developers integrating ECDH or ECDSA into constrained C or C++ systems, especially AVR, ARM, and Thumb targets. It is a poor fit for projects requiring dynamic curve selection, compressed points at most public APIs, or a higher-level key-management service.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 14 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
micro-ecc's Target Is Constrained C Systems
micro-ecc addresses a specific embedded-systems problem: implementing elliptic-curve Diffie-Hellman and elliptic-curve Digital Signature Algorithm operations without pulling in a large cryptography framework or allocating memory at runtime. It is aimed at developers building firmware and device software for 8-bit, 32-bit, and 64-bit processors. The README specifically mentions optional GCC inline assembly for AVR, ARM, and Thumb platforms, which makes processor support part of the library's design rather than a general desktop abstraction.
The implementation is C and is expected to work with compilers that support `stdint.h`. The README also names Visual Studio 2013 as a supported compiler environment, although Windows builds require linking `advapi32.lib`. C++ projects can include the header, but the core implementation remains `uECC.c` with its associated include files.
This is library code, not a complete cryptographic product. The repository does not document certificate handling, identity verification, key storage policy, certificate revocation, a protocol for authenticating ECDH peers, or a high-level key derivation API. A developer can adopt micro-ecc as the curve-operation layer, but the surrounding application remains responsible for deciding what the keys represent and how they are protected.
Curve Operations, Point Encoding, and Build-Time Selection
The README describes support for five standard curves: `secp160r1`, `secp192r1`, `secp224r1`, `secp256r1`, and `secp256k1`. It also points to a separate `static` branch for builds where the curve is selected at compile time. The default branch documentation does not specify the complete runtime curve-selection interface, so projects requiring a particular configuration should inspect `uECC.h` and the branch they intend to ship rather than assuming that every curve can be selected in one binary.
Point encoding follows SEC 1. Compressed points use the standard compressed representation. Uncompressed points use the standard representation but omit the `0x04` prefix. That omission matters during integration: callers must not prepend `0x04` and pass the result directly to the library. The README also states that functions other than `uECC_decompress()` accept only uncompressed points. Applications receiving compressed public keys therefore need an explicit `uECC_decompress()` call before using those points with the other APIs.
To move an uncompressed point into the compressed format, call `uECC_compress()`. This two-function boundary makes representation conversion visible in application code. The documentation does not describe validation behavior for malformed points, so input validation cannot be inferred from the README and should be checked against the implementation and function documentation.
Copying uECC into a Non-Arduino C or C++ Build
The README does not provide a package-manager installation command. Instead, it recommends copying the `uECC` files into the project or creating a symbolic link to them. The following include is the documented entry point for a C or C++ source file:
#include "uECC.h"After copying or linking the files, the build must compile `uECC.c` with the settings appropriate to the target. The header says it documents each function, so a first implementation should start there and identify the curve operations, encoding functions, and types required by the application. The repository also contains `types.h`, `uECC_vli.h`, `platform-specific.inc`, curve-specific include files, and architecture assembly include files. Copying only `uECC.h` and `uECC.c` is therefore not documented as sufficient; the README's recommendation to copy the `uECC` files implies that the associated implementation files need to travel with them.
The project also includes `examples/ecc_test/`, which is the repository's named example area. The README does not document the commands for building or running that example, so no unverified command is supplied here. A developer should first inspect that directory and use the build system already used by the host project rather than inventing flags.
Compiler Settings for AVR, ARM, and Thumb
micro-ecc exposes compile-time options through the compilation command rather than requiring all settings to be changed in the source. The README gives `uECC_OPTIMIZATION_LEVEL` as an example and states that it can be set with a compiler definition such as the following:
-DuECC_OPTIMIZATION_LEVEL=3The exact placement of that option belongs in the project's Makefile or equivalent build configuration. Changing a default in `uECC.c` is not the documented approach. This distinction matters because `uECC.c` must be compiled with the intended values rather than merely included from another translation unit.
Target requirements are explicit. Thumb-1 builds must use `-fomit-frame-pointer`. ARM and Thumb-2 builds with `uECC_OPTIMIZATION_LEVEL` set to 3 or higher must also use that option. GCC enables it by default at `-O1` or higher. AVR builds must be compiled with optimizations enabled, also using `-O1` or higher. The Windows build additionally links `advapi32.lib`.
This example should not be copied blindly to every processor. The README attaches the `-fomit-frame-pointer` requirement to Thumb-1 and qualifying ARM or Thumb-2 builds, while its AVR requirement is optimization rather than that exact frame-pointer option.
Arduino Integration Needs No Package Command
Arduino is the one installation path described as a managed library flow. The README directs users to open `Sketch`, then `Include Library`, then `Manage Libraries`, and to search for micro-ecc in the Library Manager. After installation, uECC should appear under `Sketch`, then `Import Library`, where it can be included like other Arduino libraries.
This path is appropriate for sketches that use micro-ecc's documented C API. It does not remove the need to select a compatible curve and point representation. The README's general rule still applies: public point data passed to functions other than `uECC_decompress()` must use the uncompressed representation without the `0x04` prefix.
The repository also contains `library.properties`, which is consistent with the Arduino library layout, but the README does not state the library's displayed version or compatibility matrix. Those details should be checked in the Arduino Library Manager entry and the repository files before choosing an installed revision. The newest listed release is `v1.2`, and the release information identifies it as containing fixes for `CVE-2020-27209`.
The Fixed-Memory Design Creates Clear Integration Boundaries
A defining constraint is the absence of dynamic memory allocation. That suits firmware environments where the allocator, heap layout, and runtime memory budget are tightly controlled. It also makes the library's resource behavior easier to reason about at the component level, although the README does not publish code-size or memory measurements, so a particular target's footprint cannot be inferred from the repository description alone.
The tradeoff is integration responsibility. Callers must handle private-key material, provide public-point data in the representation required by each function, and decide how ECDH output becomes application key material. The README says private keys use the standard format, but it does not document a complete private-key generation or storage workflow. It also does not claim that ECDH output is automatically passed through a named key derivation function.
The side-channel claim is similarly bounded. The README lists resistance to known side-channel attacks, which is a reason to examine the implementation carefully, but it is not a blanket guarantee for every compiler, optimization setting, processor, physical environment, or integration. The supported assembly paths and target-specific build requirements demonstrate that deployment conditions matter.
BSD-2-Clause and Release-Specific Upgrade Work
micro-ecc is distributed under the BSD 2-clause license, as stated in both the README and the repository metadata. That permissive license is relevant to organizations reviewing whether the source can be incorporated into firmware projects, subject to the actual license text in `LICENSE.txt`. The repository facts do not establish legal compatibility with a particular product, so license approval remains a project-specific review rather than a conclusion of this article.
The release history has an important security dimension. Version `v1.2` is listed as containing fixes for `CVE-2020-27209`, while `v1.1` dates from 2022-01-22 and `v1.0` dates from 2017-05-23. The repository is not archived, and the last push was on 2026-10-09. That is recent activity, but the README does not provide a compatibility or migration guide for moving an existing embedded build from `v1.1` to `v1.2`.
Upgrading therefore requires source-level review. Check `uECC.h` for API changes, rebuild `uECC.c` with the target's required options, and run the repository's `test/` and `examples/ecc_test/` material in the existing build environment. The README does not claim automated coverage for a particular board or processor.
Editorial conclusion
micro-ecc fits developers integrating ECDH or ECDSA into constrained C or C++ systems, especially AVR, ARM, and Thumb targets. It is a poor fit for projects requiring dynamic curve selection, compressed points at most public APIs, or a higher-level key-management service. Before adoption, verify the exact processor build flags, review every function in uECC.h, and confirm that the selected release and application-level key lifecycle satisfy the required security process.
Frequently asked questions
Which curves and processor widths does micro-ecc support?
The README lists `secp160r1`, `secp192r1`, `secp224r1`, `secp256r1`, and `secp256k1`, with support stated for 8-bit, 32-bit, and 64-bit architectures.
How do I install micro-ecc in a C project?
The README recommends copying or symbolically linking the uECC files into the project and including `uECC.h`. It does not provide a package-manager installation command.
Does micro-ecc allocate memory dynamically?
No. Dynamic memory allocation is explicitly listed as absent, which makes it suitable for projects that avoid runtime heap use.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kmackay-micro-ecc)Was this useful?