--- title: micro-ecc layout: default --- micro-ecc ========== A small ECDH and ECDSA implementation for 32-bit microcontrollers. See [easy-ecc](https://github.com/kmackay/easy-ecc) for a fast and secure pure-C implementation for \*nix and Windows. Features -------- * Resistant to known side-channel attacks. * Written in C, with optional inline assembly for ARM and Thumb platforms. * Small code size: ECDH in as little as 2KB, ECDH + ECDSA in as little as 3KB when compiled for Thumb (eg, Cortex-M0). * No dynamic memory allocation. * Reasonably fast: on an LPC1114 at 48MHz (ARM Cortex-M0, 32-cycle 32x32 bit multiply), 192-bit ECDH shared secret calculation takes as little as ~175ms (depending on selected optimizations). * Support for 4 standard curves: secp128r1, secp192r1, secp256r1, and secp384r1 * BSD 2-clause license. Usage Notes ----------- #### Integer Representation #### To reduce code size, all large integers are represented using little-endian words - so the least significant word is first. For example, the standard representation of the prime modulus for the curve secp128r1 is `FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF`; in micro-ecc, this would be represented as `uint32_t p[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffd};`. You can use the `ecc_bytes2native()` and `ecc_native2bytes()` functions to convert between the native integer representation and the standardized octet representation. #### Generating Keys #### You can use the `makekeys` program in the `apps` directory to generate keys (on Linux or OS X). You can run `make` in that directory to build for your native platform (or use [emk](http://kmackay.ca/emk)). To generate a single public/private key pair, run `makekeys`. It will print out the public and private keys in a representation suitable to be copied into your source code. You can generate multiple key pairs at once using `makekeys ` to generate n keys. #### Using the Code #### I recommend just copying (or symlink) ecc.h and ecc.c into your project. Then just `#include "ecc.h"` to use the micro-ecc functions. See ecc.h for documentation for each function. Speed and Size -------------- Available optimizations are: * `ECC_SQUARE_FUNC` - Use a separate function for squaring. * `ECC_ASM` - Choose the type of inline assembly to use. The available options are `ecc_asm_none`, `ecc_asm_thumb`, `ecc_asm_thumb2`, and `ecc_asm_arm`. All tests were performed on an LPC1114 running at 48MHz. The listed code sizes include all code and data required by the micro-ecc library (including `aebi_lmul` when not using assembly), but do not include the sizes of the code using the library functions. The following compiler options were used (using gcc 4.8): * Compile: `-mcpu=cortex-m0 -mthumb -ffunction-sections -fdata-sections -Os` * Link: `-mcpu=cortex-m0 -mthumb -nostartfiles -nostdlib -Wl,--gc-sections` ### Effect of optimization settings ### These tests were performed using the curve secp192r1. Only ECDH code was used (no ECDSA). When enabled, ECC_ASM was defined to `ecc_asm_thumb`.
Optimizations ECDH time (ms) Code size (bytes)
none 438.9 2212
ECC_SQUARE_FUNC 406.7 2412
ECC_ASM 186.3 2036
both 175.7 2170
### ECDH for different curves ### In these tests, `ECC_ASM` was defined to `ecc_asm_thumb` and `ECC_SQUARE_FUNC` was defined to `1` in all cases.
secp128r1 secp192r1 secp256r1 secp384r1
ECDH time (ms): 89.9 175.7 465.1 1370.3
Code size (bytes): 2324 2170 2512 2244
### ECDSA speed and combined code size ### In these tests, the measured speed is the time to verify an ECDSA signature. The measured code size is the combined code size for ECDH and ECDSA. `ECC_ASM` was defined to `ecc_asm_thumb` and `ECC_SQUARE_FUNC` was defined to `1` in all cases.
secp128r1 secp192r1 secp256r1 secp384r1
ECDSA verify time (ms): 106.7 217.1 555.2 1576.1
Code size (bytes): 3138 3014 3334 3158
### Maximum stack usage ### In these tests, `ECC_ASM` was defined to `ecc_asm_thumb` and `ECC_SQUARE_FUNC` was defined to `1` in all cases. The table values are the maximum possible stack usage for each function, in bytes.
secp128r1 secp192r1 secp256r1 secp384r1
ecc_make_key() 336 416 528 728
ecc_valid_public_key() 192 232 304 424
ecdh_shared_secret() 360 456 584 816
ecdsa_sign() 400 504 640 888
ecdsa_verify() 400 520 672 952