Cifra is a collection of cryptographic primitives targeted at embedded use.
In order of descending emphasis, cifra aims for:
Additionally cifra imports curve25519 from elsewhere (μNaCl, NaCl, tweetNaCl, Adam Langley's curve25519-donna) for comparison between various implementations on embedded targets.
Available at Read the Docs.
There is quite a lot of testing available:
make test
in the src
directory. This builds and runs assorted test programs.make test
in the src/arm
directory. This expects to find qemu-system-gnuarmeclipse
on the path. These tests assume a Cortex-M3 target.make test.stm32f0
in the src/arm
directory. This expects to find openocd
on the path, with an STM32F0xx attached via stlinkv2. It uses ARM semihosting to report results.make test.stm32f1
or make test.stm32f3
as above.Additionally all embedded targets expect to find the arm-none-eabi
toolchain to be on the path.
All measurements performed at -Os
(optimise for space), on the following MCUs:
Core | Part number | Price (1s) | Max clock | Flash | SRAM |
---|---|---|---|---|---|
Cortex-M0 | STM32F030F4P6 | 1.17EUR | 48MHz | 16KB | 4KB |
Cortex-M3 | STM32F103C8T6 | 2.87EUR | 72MHz | 64KB | 20KB |
Cortex-M4F | STM32F303K6T6 | 4.53EUR | 72MHz | 32KB | 12KB |
More measurements are available for AEAD modes on my blog post: Benchmarking Modern Authenticated Encryption on €1 devices.
This test does a key schedule, then encrypts one block.
Core | Cycles (key schedule + block) | Cycles (key schedule) | Cycles (block) | Stack | Code size |
---|---|---|---|---|---|
Cortex-M0 | 7156 | 2147 | 5009 | 312B | 1020B |
Cortex-M3 | 4692 | 1591 | 3101 | 300B | 960B |
Cortex-M4F | 4591 | 1571 | 3020 | 300B | 960B |
Core | Cycles (key schedule + block) | Cycles (key schedule) | Cycles (block) | Stack | Code size |
---|---|---|---|---|---|
Cortex-M0 | 10611 | 3650 | 6961 | 396B | 1100B |
Cortex-M3 | 6735 | 2450 | 4285 | 380B | 1048B |
Cortex-M4F | 6588 | 2416 | 4172 | 380B | 1048B |
This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data. It includes the initial key schedule.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 57022 | 796B | 2600B |
Cortex-M3 | 44306 | 812B | 2644B |
Cortex-M4F | 43657 | 812B | 2644B |
This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data. It includes the initial key schedule.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 50564 | 932B | 2836B |
Cortex-M3 | 32855 | 932B | 2780B |
Cortex-M4F | 32159 | 932B | 2780B |
This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data. It includes the initial key schedule.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 37677 | 772B | 2280B |
Cortex-M3 | 24462 | 780B | 2256B |
Cortex-M4F | 23949 | 780B | 2256B |
This test encrypts and authenticates a 16 byte message, with 16 bytes additionally authenticated data.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 10692 | 320B | 1636B |
Cortex-M3 | 6909 | 320B | 1820B |
Cortex-M4F | 6855 | 320B | 1820B |
This test encrypts a 64 byte message.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 5981 | 564B | 1416B |
Cortex-M3 | 3487 | 544B | 1328B |
Cortex-M4F | 3468 | 544B | 1328B |
(For comparison with AES, add an AES256 key schedule plus 4 blocks. That's about 33K cycles.)
This test encrypts a 64 byte message.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 6173 | 560B | 1412B |
Cortex-M3 | 3320 | 552B | 1272B |
Cortex-M4F | 3311 | 552B | 1272B |
This test hashes the empty string (one compression function invocation).
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 11561 | 312B | 1760B |
Cortex-M3 | 6530 | 300B | 1708B |
Cortex-M4F | 6278 | 300B | 1708B |
This test hashes the empty string (one compression function invocation).
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 38447 | 796B | 2888B |
Cortex-M3 | 28771 | 836B | 2988B |
Cortex-M4F | 28777 | 836B | 2980B |
This test hashes the empty string (one sponge permutation).
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 93648 | 848B | 2212B |
Cortex-M3 | 74321 | 856B | 2164B |
Cortex-M4F | 72215 | 856B | 2140B |
This test hashes the empty string (one sponge permutation).
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 92565 | 880B | 2212B |
Cortex-M3 | 73509 | 888B | 2164B |
Cortex-M4F | 71419 | 888B | 2140B |
This test computes a MAC with a 32 byte key over the message “hello world”.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 48924 | 1328B | 2200B |
Cortex-M3 | 28333 | 1324B | 2132B |
Cortex-M4F | 27337 | 1324B | 2132B |
This test computes a MAC with a 32 byte key over the message “hello world”. It includes the AES nonce processing.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 15719 | 704B | 1920B |
Cortex-M3 | 11328 | 696B | 1964B |
Cortex-M4F | 10706 | 696B | 1932B |
This test is one point multiplication.
This uses the implementation from μNaCl by Düll, Haase, Hinterwälder, Hutter, Paar, Sánchez and Schwabe.
Core | Cycles | Stack | Code size |
---|---|---|---|
Cortex-M0 | 4070271 | 464B | 5596B |
Cortex-M3 | 3720363 | 448B | 5536B |
Cortex-M4F | 3720105 | 448B | 5536B |
See curve25519-shootout for comparitive measurements for other curve25519 implementations.
Cifra requires memcpy
, memset
, and abort
.
len % 64 = 55
for SHA1/SHA224/SHA256 or len % 128 = 119
for SHA384/SHA512. SHA3 was not affected. Better testing is now in place.CC0.
Please attribute the author. This is a request only, and not a license term.
Joseph Birr-Pixton jpixton@gmail.com