1*f0865ec9SKyle Evans[![compilation](https://github.com/libecc/libecc/actions/workflows/libecc_compilation_tests.yml/badge.svg?branch=master)](https://github.com/libecc/libecc/actions/workflows/libecc_compilation_tests.yml) 2*f0865ec9SKyle Evans[![runtime](https://github.com/libecc/libecc/actions/workflows/libecc_runtime_tests.yml/badge.svg?branch=master)](https://github.com/libecc/libecc/actions/workflows/libecc_runtime_tests.yml) 3*f0865ec9SKyle Evans[![crossarch](https://github.com/libecc/libecc/actions/workflows/libecc_crossarch_tests.yml/badge.svg?branch=master)](https://github.com/libecc/libecc/actions/workflows/libecc_crossarch_tests.yml) 4*f0865ec9SKyle Evans[![python](https://github.com/libecc/libecc/actions/workflows/libecc_python_tests.yml/badge.svg?branch=master)](https://github.com/libecc/libecc/actions/workflows/libecc_python_tests.yml) 5*f0865ec9SKyle Evans[![examples](https://github.com/libecc/libecc/actions/workflows/libecc_examples.yml/badge.svg?branch=master)](https://github.com/libecc/libecc/actions/workflows/libecc_examples.yml) 6*f0865ec9SKyle Evans 7*f0865ec9SKyle Evans 8*f0865ec9SKyle Evans# libecc project 9*f0865ec9SKyle Evans 10*f0865ec9SKyle Evans## Copyright and license 11*f0865ec9SKyle EvansCopyright (C) 2017-2023 12*f0865ec9SKyle Evans 13*f0865ec9SKyle EvansThis software is licensed under a dual BSD and GPL v2 license. 14*f0865ec9SKyle EvansSee [LICENSE](LICENSE) file at the root folder of the project. 15*f0865ec9SKyle Evans 16*f0865ec9SKyle Evans## Authors 17*f0865ec9SKyle Evans 18*f0865ec9SKyle Evans * Ryad BENADJILA (<mailto:ryadbenadjila@gmail.com>) 19*f0865ec9SKyle Evans * Arnaud EBALARD (<mailto:arnaud.ebalard@ssi.gouv.fr>) 20*f0865ec9SKyle Evans * Jean-Pierre FLORI (<mailto:jpflori@gmail.com>) 21*f0865ec9SKyle Evans 22*f0865ec9SKyle Evans## Contributors 23*f0865ec9SKyle Evans * Nicolas VIVET (<mailto:nicolas.vivet@ssi.gouv.fr>) 24*f0865ec9SKyle Evans * Karim KHALFALLAH (<mailto:karim.khalfallah@ssi.gouv.fr>) 25*f0865ec9SKyle Evans * Niels SAMWEL (<mailto:nsamwel@google.com>) 26*f0865ec9SKyle Evans 27*f0865ec9SKyle Evans## Description 28*f0865ec9SKyle EvansThis software implements a library for elliptic curves based 29*f0865ec9SKyle Evanscryptography (ECC). The API supports signature algorithms specified 30*f0865ec9SKyle Evansin the [ISO 14888-3:2018](https://www.iso.org/standard/76382.html) 31*f0865ec9SKyle Evansstandard and some other signature algorithms as well as ECDH primitives, with the following specific curves and hash functions: 32*f0865ec9SKyle Evans 33*f0865ec9SKyle Evans * **Signatures**: 34*f0865ec9SKyle Evans * Core ISO 14888-3:2018 algorithms: ECDSA, ECKCDSA, ECGDSA, ECRDSA, EC{,O}SDSA, ECFSDSA, SM2. 35*f0865ec9SKyle Evans * EdDSA (25519 and 448 as specified in [RFC 8032](https://datatracker.ietf.org/doc/html/rfc8032)). 36*f0865ec9SKyle Evans * BIGN (as standardized in [STB 34.101.45-2013](https://github.com/bcrypto/bign)). We allow a more lax usage of 37*f0865ec9SKyle Evans BIGN than in the standard as we allow any curve and any hash function. 38*f0865ec9SKyle Evans * BIP0340, also known as the "Schnorr" Bitcoin proposal, as specified in [bip-0340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). 39*f0865ec9SKyle Evans We allow a more lax usage of BIP0340 than the standard as we allow any curve and any hash function (the standard mandates SECP256K1 with SHA-256). 40*f0865ec9SKyle Evans 41*f0865ec9SKyle Evans * **ECDH**: 42*f0865ec9SKyle Evans * ECC-CDH (Elliptic Curve Cryptography Cofactor Diffie-Hellman) as described in [section 5.7.1.2 of the NIST SP 800-56A Rev. 3](https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final) standard. 43*f0865ec9SKyle Evans * X25519 and X448 as specified in [RFC7748](https://datatracker.ietf.org/doc/html/rfc7748) (with some specificities, see the details below). 44*f0865ec9SKyle Evans * **Curves**: SECP{192,224,256,384,521}R1, SECP{192,224,256}K1, BRAINPOOLP{192,224,256,320,384,512}{R1,T1}, 45*f0865ec9SKyle Evans FRP256V1, GOST{256,512}, GOSTR3410-2001-CryptoPro{A,B,C,XchA,XchB,Test}-ParamSet, GOSTR3410-2012-{256,512}-ParamSet{A,B,C}, GOSTR3410-2012-256-ParamSetD, GOSTR3410-2012-512-ParamSetTest, SM2P256V1, SM2P{192,256}Test, WEI{25519,448}, BIGN{256,384,512}V1. The library can be easily expanded with 46*f0865ec9SKyle Evans user defined curves using a standalone helper script. 47*f0865ec9SKyle Evans * **Hash functions**: SHA-2 and SHA-3 hash functions (224, 256, 384, 512), SM3, RIPEMD-160, 48*f0865ec9SKyle EvansGOST 34.11-2012 as described in [RFC 6986](https://datatracker.ietf.org/doc/html/rfc6986) 49*f0865ec9SKyle Evans(also known as [Streebog](https://tc26.ru/en/events/research-projects-competition/streebog-competition.html)), 50*f0865ec9SKyle EvansSHAKE256 in its restricted version with 114 bytes output (mainly for Ed448), BELT-HASH (as standardized in 51*f0865ec9SKyle Evans[STB 34.101.31-2011](https://github.com/bcrypto/belt)), and BASH-{224,256,384,512} (as standardized in 52*f0865ec9SKyle Evans[STB 34.101.77-2020](http://apmi.bsu.by/assets/files/std/bash-spec24.pdf)). 53*f0865ec9SKyle Evans**HMAC** based on any of these hash functions is also included. 54*f0865ec9SKyle Evans 55*f0865ec9SKyle EvansECDSA comes in two variants: the classical non-deterministic one, and the **deterministic** ECDSA 56*f0865ec9SKyle Evansas described in [RFC 6979](https://datatracker.ietf.org/doc/html/rfc6979). The deterministic version 57*f0865ec9SKyle Evansgenerates nonces using a HMAC-DRBG process, and is suitable for situations where there is 58*f0865ec9SKyle Evansno RNG or where entropy sources are considered weak (please note that any leak on these nonces 59*f0865ec9SKyle Evansbits can lead to devastating attacks exploiting the [Hidden Number Problem](https://eprint.iacr.org/2020/615.pdf)). 60*f0865ec9SKyle EvansOn the downside, the deterministic version of ECDSA is susceptible to [fault attacks](https://eprint.iacr.org/2017/1014.pdf). 61*f0865ec9SKyle EvansHence, one will have to **carefully select** the suitable version to use depending on the usage and 62*f0865ec9SKyle Evansattack context (i.e. which of side-channel attacks or fault attacks are easier to perform). 63*f0865ec9SKyle EvansThe same applies to BIGN that comes in two flavours as standardized in [STB 34.101.45-2013](https://github.com/bcrypto/bign): 64*f0865ec9SKyle Evansnon-deterministic and deterministic (following an iterative generation process using the BELT hash function and its underlying block cipher). 65*f0865ec9SKyle Evans 66*f0865ec9SKyle EvansThe library also supports EdDSA (Ed25519 and Ed448) as defined in [RFC 8032](https://datatracker.ietf.org/doc/html/rfc8032) with 67*f0865ec9SKyle Evansall their variants (with context, pre-hashed). 68*f0865ec9SKyle EvansSince the core of the library supports short Weierstrass curves, and as 69*f0865ec9SKyle EvansEdDSA uses instead Twisted Edwards curves with dedicated formulas, we use 70*f0865ec9SKyle Evans**isogenies** as described in the [lwig-curve-representations](https://datatracker.ietf.org/doc/html/draft-ietf-lwig-curve-representations) 71*f0865ec9SKyle Evansdraft. Isogenies are transformations (homomorphisms that are almost isomorphisms) between 72*f0865ec9SKyle Evanscurves models, allowing to implement operations on one model by operating with 73*f0865ec9SKyle Evansformulas on another model. Concretely, in our case we perform computations on 74*f0865ec9SKyle Evansthe Weierstrass WEI25519 that is isogenic to Ed25519 (Twisted Edwards) 75*f0865ec9SKyle Evansand Curve25519 (Montgomery) curves. This, of course, induces overheads in computations 76*f0865ec9SKyle Evanswhile having the great benefit of keeping the library core mathematical foundations simple 77*f0865ec9SKyle Evansand keep the defense-in-depth (regarding software security and side-channels) focused on 78*f0865ec9SKyle Evansa rather limited part: see the discussions below on libecc efforts with regards to security. 79*f0865ec9SKyle Evans 80*f0865ec9SKyle EvansPlease note that as for deterministic ECDSA and BIGN, EdDSA signatures are trivially susceptible to 81*f0865ec9SKyle Evans[fault attacks](https://eprint.iacr.org/2017/1014.pdf) without having a non-deterministic 82*f0865ec9SKyle Evansvariant. Hence, when using EdDSA one will have to either ensure that the usage context naturally prevents 83*f0865ec9SKyle Evanssuch attacks, that the platform implements countermeasures (e.g. using secure MCUs, etc.) or that 84*f0865ec9SKyle Evansother means allow to detect/mitigate such attacks (e.g. on the compilation toolchain side). 85*f0865ec9SKyle Evans 86*f0865ec9SKyle EvansPlease refer to [this CFRG thread](https://mailarchive.ietf.org/arch/browse/cfrg/?gbt=1&index=5l3XCLHLCVfOmnkcv4mo2-pEV94) 87*f0865ec9SKyle Evansfor more insight on why deterministic versus non-deterministic EC signature schemes is still an open debate 88*f0865ec9SKyle Evansand how the usage context and **attack model** is **crucial** when choosing to use one or the other. 89*f0865ec9SKyle Evans 90*f0865ec9SKyle Evans 91*f0865ec9SKyle Evans**Batch verification** is implemented for the signature algorithms that support it - the signature schemes 92*f0865ec9SKyle Evansthat preserve some "reversible" projective point coordinate information in the signature value. 93*f0865ec9SKyle EvansThis is the case for some "Schnorr" based schemes, namely ECFSDSA ("full Schnorr" from ISO14888-3), EdDSA and BIP0340. 94*f0865ec9SKyle EvansBatch verification allows (thanks to the Bos-Coster algorithm) to bring speedups between 2 to 6.5 times 95*f0865ec9SKyle Evansthe regular verification for batches of at least 10 signatures, which is not negligible depending on the usage. 96*f0865ec9SKyle EvansBeware that for the specific case of BIP0340, results might depend on the underlying prime of the curve, since 97*f0865ec9SKyle Evansthe batch verification makes heavy use of square root residues and the Tonelli-Shanks algorithm complexity 98*f0865ec9SKyle Evansis sensitive to the prime "form" (e.g. is equal to 1 modulo 4, etc.). Finally, beware that the speedup of 99*f0865ec9SKyle Evansbatch verification comes at an increased memory cost: the Bos-Coster algorithm requires a scratchpad memory space 100*f0865ec9SKyle Evansthat increases linearly with the number of signatures to be checked. 101*f0865ec9SKyle Evans 102*f0865ec9SKyle Evans 103*f0865ec9SKyle EvansRegarding the specific case of ECRDSA (the Russian standard), libecc implements by default the 104*f0865ec9SKyle Evans[RFC 7091](https://datatracker.ietf.org/doc/html/rfc7091) and [draft-deremin-rfc4491-bis](https://datatracker.ietf.org/doc/html/draft-deremin-rfc4491-bis) 105*f0865ec9SKyle Evansversions to comply with the standard test vectors (provided in the form of X.509 certificates). 106*f0865ec9SKyle EvansThis version of the algorithm **differs** from the ISO/IEC 14888-3 description and test vectors, 107*f0865ec9SKyle Evansthe main difference coming from the way the hash of the message to be signed/verified is processed: 108*f0865ec9SKyle Evansin the RFCs, the little endian representation of the hash is taken as big number while in ISO/IEC the big endian 109*f0865ec9SKyle Evansrepresentation is used. This seems (to be confirmed) to be a discrepancy of ISO/IEC 14888-3 algorithm description 110*f0865ec9SKyle Evansthat must be fixed there. In order to allow users to still be able to reproduce the ISO/IEC behavior, we provide 111*f0865ec9SKyle Evansa compilation toggle that will force this mode `USE_ISO14888_3_ECRDSA=1`: 112*f0865ec9SKyle Evans 113*f0865ec9SKyle Evans<pre> 114*f0865ec9SKyle Evans $ USE_ISO14888_3_ECRDSA=1 make 115*f0865ec9SKyle Evans</pre> 116*f0865ec9SKyle Evans 117*f0865ec9SKyle Evans**ECDH (Elliptic Curve Diffie-Hellman)** variants are also implemented in the 118*f0865ec9SKyle Evanslibrary. Classical ECDH over Weierstrass curves is implemented in the form 119*f0865ec9SKyle Evansof ECC-CDH (Elliptic Curve Cryptography Cofactor Diffie-Hellman) as described 120*f0865ec9SKyle Evansin [section 5.7.1.2 of the NIST SP 800-56A Rev. 3](https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final) standard. Montgomery curves 121*f0865ec9SKyle Evansbased algorithms (Curve25519 and Curve448) are included as specified in [RFC7748](https://datatracker.ietf.org/doc/html/rfc7748), 122*f0865ec9SKyle Evansalthough the implementation somehow diverges from the canonical ones as u coordinates on the curve 123*f0865ec9SKyle Evansquadratic twist are rejected (this is due to the underlying usage of isogenies to 124*f0865ec9SKyle Evanshandle Montgomery curves). This divergence does not impact the ECDH use case though. 125*f0865ec9SKyle Evans 126*f0865ec9SKyle Evans 127*f0865ec9SKyle EvansAdvanced usages of this library also include the possible implementation 128*f0865ec9SKyle Evansof elliptic curve based protocols as well as any algorithm 129*f0865ec9SKyle Evanson top of prime fields based elliptic curves (or prime fields, or rings 130*f0865ec9SKyle Evansof integers). Many examples are present in the [src/examples](src/examples) 131*f0865ec9SKyle Evansfolder, notable ones being: 132*f0865ec9SKyle Evans * Pollard-Rho, Miller-Rabin and square residues over finite fields. 133*f0865ec9SKyle Evans * The RSA cryptosystem as defined in the PKCS#1 [RFC8017](https://datatracker.ietf.org/doc/html/rfc8017) 134*f0865ec9SKyle Evansstandard. This implementation also comes with the integration of deprecated hash 135*f0865ec9SKyle Evansfunctions such as MD2, MD4, MD5, SHA-0, SHA-1, MDC-2, GOSTR34-11-94 and so on in order to be compliant with existing 136*f0865ec9SKyle Evanssignatures (e.g. in X.509). These primitives are **not** included in the core 137*f0865ec9SKyle Evanslibrary on purpose: they are **dangerous and broken** and must only be used for 138*f0865ec9SKyle Evanstests purposes. 139*f0865ec9SKyle Evans * The DSA cryptosystem as defined in [FIPS 186-4](https://csrc.nist.gov/publications/detail/fips/186/4/final). 140*f0865ec9SKyle Evans * The SDSA (Schnorr DSA) as defined in ISO14888-3 141*f0865ec9SKyle Evans * The KCDSA (Korean DSA) as defined in ISO14888-3 142*f0865ec9SKyle Evans * The GOSTR34-10-94 function as defined in [RFC4491](https://www.rfc-editor.org/rfc/rfc4491) 143*f0865ec9SKyle Evans * The SSS (Shamir Secret Sharing) algorithm over a prime field of 256 bits. 144*f0865ec9SKyle Evans 145*f0865ec9SKyle Evans 146*f0865ec9SKyle Evans**NOTE**: for all the primitives (specifically relevant for signature primitives), a maximum 147*f0865ec9SKyle Evansallowed size for big numbers is **4096 bits** with word size **64 bits** (this will be less 148*f0865ec9SKyle Evansfor word sizes 16 and 32 bits). This is due to an internal limitation of libecc 149*f0865ec9SKyle Evanson big numbers allocation documented [here](include/libecc/nn/nn_config.h). We can live with 150*f0865ec9SKyle Evansthis limitation as the library is primarily intended to focus on ECC based algorithms. 151*f0865ec9SKyle EvansHowever, one should be aware that for example RSA with modulus > 4096 will fail (as well 152*f0865ec9SKyle Evansand DSA and other El-Gamal based algorithms): these primitives are only included as 153*f0865ec9SKyle Evansexamples and should be used with care. 154*f0865ec9SKyle Evans 155*f0865ec9SKyle Evans**NOTE**: handling 4096 bits NN numbers must be explicitly configured at compilation 156*f0865ec9SKyle Evanstime using the `-DUSER_NN_BIT_LEN=4096` toggle in the `CFLAGS` or `EXTRA_CFLAGS` as explained 157*f0865ec9SKyle Evansin [the dedicated section](https://github.com/ANSSI-FR/libecc#modifying-the-big-numbers-size). 158*f0865ec9SKyle Evans 159*f0865ec9SKyle Evans 160*f0865ec9SKyle EvansCompared to other cryptographic libraries providing such 161*f0865ec9SKyle Evansfeatures, the differentiating points are: 162*f0865ec9SKyle Evans 163*f0865ec9SKyle Evans * A focus on code readability and auditability. The code is pure C99, 164*f0865ec9SKyle Evans with no dynamic allocation and includes pre/post-asserts in the code. 165*f0865ec9SKyle Evans Hence, this library is a good candidate for embedded targets (it should be 166*f0865ec9SKyle Evans easily portable accross various platforms). 167*f0865ec9SKyle Evans * A clean layer separation for all needed mathematical abstractions and 168*f0865ec9SKyle Evans operations. Strong typing (as "strong" as C99 allows, of course) of 169*f0865ec9SKyle Evans mathematical objects has been used in each layer. 170*f0865ec9SKyle Evans * The library has NOT been designed to break performance records, though 171*f0865ec9SKyle Evans it does a decent job (see the [performance section discussion](#performance)). Similarly, 172*f0865ec9SKyle Evans the library memory footprint (in terms of ROM and RAM usage) is not the 173*f0865ec9SKyle Evans smallest achievable one (though some efforts have been made to limit it 174*f0865ec9SKyle Evans and fit "common" platforms, see the [dedicated section](#constrained-devices)). 175*f0865ec9SKyle Evans * libecc library core has **no external dependency** (not even the standard 176*f0865ec9SKyle Evans libc library) to make it portable. See the 177*f0865ec9SKyle Evans [section about portability](#compatibility-and-portability) for more information. 178*f0865ec9SKyle Evans 179*f0865ec9SKyle Evans## Building 180*f0865ec9SKyle Evans 181*f0865ec9SKyle Evans### Building the static libraries and the signature self tests 182*f0865ec9SKyle Evans 183*f0865ec9SKyle EvansThe main [Makefile](Makefile) is in the root directory, and compiling is as simple as 184*f0865ec9SKyle Evansexecuting: 185*f0865ec9SKyle Evans 186*f0865ec9SKyle Evans<pre> 187*f0865ec9SKyle Evans $ make 188*f0865ec9SKyle Evans</pre> 189*f0865ec9SKyle Evans 190*f0865ec9SKyle EvansBy default, compilation is quiet. **Verbose compilation** (i.e. showing all the compilation 191*f0865ec9SKyle Evansexecuted commands) can be achieved using the `VERBOSE=1` toggle: 192*f0865ec9SKyle Evans 193*f0865ec9SKyle Evans<pre> 194*f0865ec9SKyle Evans $ VERBOSE=1 make 195*f0865ec9SKyle Evans</pre> 196*f0865ec9SKyle Evans 197*f0865ec9SKyle EvansThis will compile different elements in the [build](build/) directory: 198*f0865ec9SKyle Evans 199*f0865ec9SKyle Evans * Three **archive** static libraries, each one containing (based on) the previous ones: 200*f0865ec9SKyle Evans * **libarith.a**: this library contains the Natural Numbers (NN) and Finite field over primes 201*f0865ec9SKyle Evans (Fp) arithmetic layers. 202*f0865ec9SKyle Evans * **libec.a**: this library is based on libarith.a and contains the EC curves implementation 203*f0865ec9SKyle Evans (points abstraction, point addition/doubling formulas and scalar multiplication). 204*f0865ec9SKyle Evans * **libsign.a**: this library is based on libec.a and contains all our ISO 14888-3 signature 205*f0865ec9SKyle Evans algorithms over some statically defined curves and hash functions. 206*f0865ec9SKyle Evans * Two binaries based on the libsign.a static library: 207*f0865ec9SKyle Evans * **ec\_self\_tests**: the self tests for signature/verification algorithm of ISO 14888-3 208*f0865ec9SKyle Evans with known and random test vectors, as well as performance tests. Launching the self tests without 209*f0865ec9SKyle Evans an argument will execute the three tests (known and fixed test vectors, random sign/verify 210*f0865ec9SKyle Evans checks, and performance measurements). One can also launch each test separately. 211*f0865ec9SKyle Evans 212*f0865ec9SKyle Evans For known test vectors: 213*f0865ec9SKyle Evans<pre> 214*f0865ec9SKyle Evans $ ./build/ec_self_tests vectors 215*f0865ec9SKyle Evans ======= Known test vectors test =================== 216*f0865ec9SKyle Evans [+] ECDSA-SHA224/secp224r1 selftests: known test vectors sig/verif ok 217*f0865ec9SKyle Evans [+] ECDSA-SHA256/secp256r1 selftests: known test vectors sig/verif ok 218*f0865ec9SKyle Evans [+] ECDSA-SHA512/secp256r1 selftests: known test vectors sig/verif ok 219*f0865ec9SKyle Evans ... 220*f0865ec9SKyle Evans</pre> 221*f0865ec9SKyle Evans 222*f0865ec9SKyle Evans For sign/verify checks (with random key pairs and random data): 223*f0865ec9SKyle Evans 224*f0865ec9SKyle Evans<pre> 225*f0865ec9SKyle Evans $ ./build/ec_self_tests rand 226*f0865ec9SKyle Evans ======= Random sig/verif test =================== 227*f0865ec9SKyle Evans [+] ECDSA-SHA224/FRP256V1 randtests: random import/export with sig(0)/verif(0) ok 228*f0865ec9SKyle Evans [+] ECDSA-SHA224/SECP224R1 randtests: random import/export with sig(0)/verif(0) ok 229*f0865ec9SKyle Evans ... 230*f0865ec9SKyle Evans</pre> 231*f0865ec9SKyle Evans 232*f0865ec9SKyle Evans For performance measurements: 233*f0865ec9SKyle Evans 234*f0865ec9SKyle Evans<pre> 235*f0865ec9SKyle Evans $ ./build/ec_self_tests perf 236*f0865ec9SKyle Evans ======= Performance test ===================== 237*f0865ec9SKyle Evans [+] ECDSA-SHA224/FRP256V1 perf: 462 sign/s and 243 verif/s 238*f0865ec9SKyle Evans [+] ECDSA-SHA224/SECP224R1 perf: 533 sign/s and 276 verif/s 239*f0865ec9SKyle Evans ... 240*f0865ec9SKyle Evans</pre> 241*f0865ec9SKyle Evans 242*f0865ec9SKyle Evans**NOTE**: it is possible to parallelize self tests (known and random) using the 243*f0865ec9SKyle Evans[OpenMP](https://en.wikipedia.org/wiki/OpenMP) framework (usually packaged with 244*f0865ec9SKyle Evansmost distros) by using the `OPENMP_SELF_TESTS=1` compilation toggle. This requires 245*f0865ec9SKyle Evansthe `WITH_STDLIB` option (as it obviously uses the standard library). Performance 246*f0865ec9SKyle Evanstests are not parallelized due to possible shared ressources exhaustion between CPUs and cores 247*f0865ec9SKyle Evans(e.g. caches, Branch Prediction Units, etc.). 248*f0865ec9SKyle Evans 249*f0865ec9SKyle Evans- **ec\_utils**: a tool for signing and verifying user defined files, with a user 250*f0865ec9SKyle Evansprovided signature algorithm/curve/hash function triplet. The tool can also be 251*f0865ec9SKyle Evansused to generate signature keys. 252*f0865ec9SKyle Evans 253*f0865ec9SKyle Evans Generate keys for ECKCDSA over the BRAINPOOLP512R1 curve, with 254*f0865ec9SKyle Evansthe 'mykeypair' prefix: 255*f0865ec9SKyle Evans<pre> 256*f0865ec9SKyle Evans $ ./build/ec_utils gen_keys BRAINPOOLP512R1 ECKCDSA mykeypair 257*f0865ec9SKyle Evans</pre> 258*f0865ec9SKyle Evans 259*f0865ec9SKyle Evans This will create four files. Two 260*f0865ec9SKyle Evansbinary '.bin' files corresponding to the private key (mykeypair\_private\_key.bin) 261*f0865ec9SKyle Evansand the public key (mykeypair\_public\_key.bin). Two header '.h' files are also 262*f0865ec9SKyle Evanscreated, corresponding to a C style header version of the keys so that these can 263*f0865ec9SKyle Evansbe included and used in a C program using libecc. Note that both kind of keys 264*f0865ec9SKyle Evans(public and private) include leading metadata (type, algorithm, curve, etc) for 265*f0865ec9SKyle Evanspossible sanity checks when they are used (e.g. to detect passing of an ECDSA 266*f0865ec9SKyle Evansprivate key to an ECKCDSA signature call, etc). 267*f0865ec9SKyle Evans 268*f0865ec9SKyle Evans Once the key pair has been created, 269*f0865ec9SKyle Evansone can sign a raw binary file named 'myfile' and store the signature in 270*f0865ec9SKyle Evans'sig.bin'. In the example below, we use SHA3\_512 as the hash function for 271*f0865ec9SKyle Evansthe signature. BRAINPOOLP512R1 and ECKCDSA are explicitly given (matching the 272*f0865ec9SKyle Evanstype of key we generated during previous step). Note that the call would yield 273*f0865ec9SKyle Evansan error if invalid parameters were given (thanks to the metadata elements 274*f0865ec9SKyle Evansdescribed above). 275*f0865ec9SKyle Evans<pre> 276*f0865ec9SKyle Evans $ ./build/ec_utils sign BRAINPOOLP512R1 ECKCDSA SHA3_512 myfile mykeypair_private_key.bin sig.bin 277*f0865ec9SKyle Evans</pre> 278*f0865ec9SKyle Evans After this, a raw signature is created, mainly consisting of the ECKCDSA (r, s) big 279*f0865ec9SKyle Evansnumbers concatenated (the length of this file should be 1024 bits = 2 x 512 bits). The signature can now be verified with 280*f0865ec9SKyle Evansthe 'verify' command and the public key, the result being either **OK** or **failed**: 281*f0865ec9SKyle Evans<pre> 282*f0865ec9SKyle Evans $ ./build/ec_utils verify BRAINPOOLP512R1 ECKCDSA SHA3_512 myfile mykeypair_public_key.bin sig.bin 283*f0865ec9SKyle Evans Signature check of myfile OK 284*f0865ec9SKyle Evans</pre> 285*f0865ec9SKyle Evans 286*f0865ec9SKyle Evans The ec\_utils tool can also be used to produce/verify **structured binaries** 287*f0865ec9SKyle Evanscontaining a header, raw binary and their signature (see the 'struct\_sign' and 'struct\_verify' commands for a help on 288*f0865ec9SKyle Evansthis mode). The rationale behind these commands is to ease the production/verification of self-contained signed images 289*f0865ec9SKyle Evans(which can be useful when dealing with embedded firmware updates for instance). 290*f0865ec9SKyle Evans 291*f0865ec9SKyle Evans### Building the user examples 292*f0865ec9SKyle Evans 293*f0865ec9SKyle EvansSince it is possible to use libecc as a NN (**positive** Natural Numbers), Fp (Finite field over primes) or EC curve layer library, 294*f0865ec9SKyle Evanswe provide some examples in the [src/examples](src/examples) folder. Compiling these examples is as simple as: 295*f0865ec9SKyle Evans<pre> 296*f0865ec9SKyle Evans $ cd src/examples 297*f0865ec9SKyle Evans $ make 298*f0865ec9SKyle Evans</pre> 299*f0865ec9SKyle Evans 300*f0865ec9SKyle Evans* NN layer examples: 301*f0865ec9SKyle Evans * [src/examples/basic/nn_miller_rabin.c](src/examples/basic/nn_miller_rabin.c): this example implements the 302*f0865ec9SKyle Evans [Miller-Rabin](https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test) composition (or probabilistic primality) test as 303*f0865ec9SKyle Evans described in the [Handbook of Applied Cryptography (4.29)](http://cacr.uwaterloo.ca/hac/about/chap4.pdf). 304*f0865ec9SKyle Evans * [src/examples/basic/nn_pollard_rho.c](src/examples/nn_pollard_rho.c): this example is a straightforward 305*f0865ec9SKyle Evans implementation of the [Pollard's Rho](https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm) integer factorization 306*f0865ec9SKyle Evans algorithm as specified in the [Handbook of Applied Cryptography (3.9)](http://cacr.uwaterloo.ca/hac/about/chap3.pdf). 307*f0865ec9SKyle Evans 308*f0865ec9SKyle Evans* Fp layer examples: 309*f0865ec9SKyle Evans * [src/examples/basic/fp_square_residue.c](src/examples/basic/fp_square_residue.c): this is an implementation of 310*f0865ec9SKyle Evans the [Tonelli-Shanks](https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm) algorithm for finding quadratic residues 311*f0865ec9SKyle Evans over a prime field Fp. Given a prime field element x, the algorithm finds y so that y<sup>2</sup> = x (or informs that there 312*f0865ec9SKyle Evans is no solution if this is the case). 313*f0865ec9SKyle Evans 314*f0865ec9SKyle Evans* Curves layer examples: 315*f0865ec9SKyle Evans * [src/examples/basic/curve_basic_examples.c](src/examples/basic/curve_basic_examples.c): this example shows basic 316*f0865ec9SKyle Evans features of libec for playing with elliptic curves group arithmetic, namely loading defined named curves, generating random points on 317*f0865ec9SKyle Evans these curves, checking point addition and doubling formulas as well as scalar multiplication (both Montgomery and non Montgomery based). 318*f0865ec9SKyle Evans 319*f0865ec9SKyle Evans * [src/examples/basic/curve_ecdh.c](src/examples/basic/curve_ecdh.c): the purpose of this code is to provide a toy example of 320*f0865ec9SKyle Evans how to implement an [Elliptic Curve Diffie-Hellman](https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman) protocol between two 321*f0865ec9SKyle Evans entities 'Alice' and 'Bob' in order to produce a shared secret over a public channel. 322*f0865ec9SKyle Evans 323*f0865ec9SKyle Evans**WARNING**: these examples are **toy implementations** not to be used in a production environment (for instance, the code 324*f0865ec9SKyle Evanshas neither been designed to be efficient nor robust against side channel attacks). Their purpose is only to show basic usage of the 325*f0865ec9SKyle Evanslibarith and libec libraries. 326*f0865ec9SKyle Evans 327*f0865ec9SKyle EvansThe **public headers** containing the functions to be used by higher level code are [include/libecc/libarith.h](include/libecc/libarith.h), 328*f0865ec9SKyle Evans[include/libecc/libec.h](include/libecc/libec.h) and [include/libecc/libsig.h](include/libecc/libsig.h): they are respectively used for the NN and Fp arithmetic layers, 329*f0865ec9SKyle Evansthe Elliptic Curves layer, and the signature layer. 330*f0865ec9SKyle Evans 331*f0865ec9SKyle EvansMore advanced examples are present in the examples folder: 332*f0865ec9SKyle Evans 333*f0865ec9SKyle Evans* Obsolete hash algorithms as an expansion to libecc core algorithms, in [src/examples/hash](src/examples/hash) (MD2, MD4, MD5, MDC2, SHA-0, 334*f0865ec9SKyle EvansSHA-1, and TDES for supporting MDC2). Please **be careful** when using them, it is advised to use them as toy primitives in **non-production code** 335*f0865ec9SKyle Evans(e.g. for checking old protocols and cipher suites). 336*f0865ec9SKyle Evans 337*f0865ec9SKyle Evans* Pre-ECC Signature schemes (based on Fp finite fields discrete logarithm) in [src/examples/sig](src/examples/sig) (RSA, DSA, SDSA, KCDSA, 338*f0865ec9SKyle EvansGOSTR34-10-94). Beware that for these signatures, you will have to expand the NN size to bigger values than the default (e.g. supporting RSA 4096 339*f0865ec9SKyle Evanswill need a size of at least 4096 bits for NN, see how to expand the size in the documentation [here](include/libecc/nn/nn_config.h)). Although some 340*f0865ec9SKyle Evansefforts have been made when developing these signature algorithms, using them in production code should be decided with care (e.g. regarding 341*f0865ec9SKyle Evansside-channel attack and so on). 342*f0865ec9SKyle Evans 343*f0865ec9SKyle Evans* SSS (Shamir Secret Sharing) in [src/examples/sss](src/examples/sss). 344*f0865ec9SKyle Evans 345*f0865ec9SKyle Evans 346*f0865ec9SKyle Evans### Building the NN and Fp arithmetic tests 347*f0865ec9SKyle Evans 348*f0865ec9SKyle Evanslibecc is provided with arithmetic random tests for the low level NN and Fp routines (addition, subtraction, logical 349*f0865ec9SKyle Evansoperations, multiplication and Montgomery multiplication, ...). 350*f0865ec9SKyle Evans 351*f0865ec9SKyle EvansThese tests are located inside the [src/arithmetic_tests/](src/arithmetic_tests/) folder. More specifically, the tests 352*f0865ec9SKyle Evansare split in two files: 353*f0865ec9SKyle Evans 354*f0865ec9SKyle Evans* [src/arithmetic_tests/arithmetic_tests.c](src/arithmetic_tests/arithmetic_tests.c): a '.c' file to be compiled and linked with libecc 355*f0865ec9SKyle Evansstatic library and performing a set of tests given on the standard input or in a file. The tests have a specific ASCII 356*f0865ec9SKyle Evansformat with expected input/output as big numbers, and crafted **opcodes** defining the operation type (addition over 357*f0865ec9SKyle EvansNN, over Fp, ...). 358*f0865ec9SKyle Evans* [src/arithmetic_tests/arithmetic_tests_generator.py](src/arithmetic_tests/arithmetic_tests_generator.py): a python 359*f0865ec9SKyle Evansscript that generates a set of arithmetic tests. 360*f0865ec9SKyle Evans 361*f0865ec9SKyle Evans### Building with the meson build system 362*f0865ec9SKyle Evans 363*f0865ec9SKyle EvansIn parallel to the `Makefile` build system, a migration to the newer and more user friendly `meson` build is a 364*f0865ec9SKyle Evans**work in progress**. Compiling with `meson` can be simply achieved with: 365*f0865ec9SKyle Evans 366*f0865ec9SKyle Evans<pre> 367*f0865ec9SKyle Evans $ meson setup builddir && cd builddir && meson dist 368*f0865ec9SKyle Evans</pre> 369*f0865ec9SKyle Evans 370*f0865ec9SKyle EvansPlease note that you will need `meson`, `ninja` and `dunamai` (that can be installed from the Python `pip` installer). 371*f0865ec9SKyle Evans 372*f0865ec9SKyle EvansMost of libecc compilation options have been migrated, please check the output of the `meson configure` command to get 373*f0865ec9SKyle Evansa complete list of these (in the 'Project options' category). For instance, compiling libecc with a word size of 32 and 374*f0865ec9SKyle Evansa debug mode can be triggered with: 375*f0865ec9SKyle Evans 376*f0865ec9SKyle Evans<pre> 377*f0865ec9SKyle Evans $ meson setup -Dwith_wordsize=32 -Dwith_debug=true builddir && cd builddir && meson dist 378*f0865ec9SKyle Evans</pre> 379*f0865ec9SKyle Evans 380*f0865ec9SKyle Evans## Configuring the libecc library 381*f0865ec9SKyle Evans 382*f0865ec9SKyle Evans### Basic configuration 383*f0865ec9SKyle Evans 384*f0865ec9SKyle Evanslibecc can be statically configured at compilation time: the user can tune what curves, hash functions and signature 385*f0865ec9SKyle Evansalgorithms are embedded in 'libsign.a' and all the binaries using it. 386*f0865ec9SKyle Evans 387*f0865ec9SKyle EvansThe main entry point to configure/tune the library is [include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h). By default libecc 388*f0865ec9SKyle Evansembeds everything. In order to remove something, one has to **comment** the element to remove (i.e. comment the 389*f0865ec9SKyle Evans`WITH_XXX` macro). For instance, removing 390*f0865ec9SKyle EvansFRP256V1 is simply done by commenting the line: 391*f0865ec9SKyle Evans<pre> 392*f0865ec9SKyle Evans /* Supported curves */ 393*f0865ec9SKyle Evans /* #define WITH_CURVE_FRP256V1 */ /* REMOVING FRP256V1 */ 394*f0865ec9SKyle Evans #define WITH_CURVE_SECP192R1 395*f0865ec9SKyle Evans #define WITH_CURVE_SECP224R1 396*f0865ec9SKyle Evans #define WITH_CURVE_SECP256R1 397*f0865ec9SKyle Evans #define WITH_CURVE_SECP384R1 398*f0865ec9SKyle Evans #define WITH_CURVE_SECP521R1 399*f0865ec9SKyle Evans #define WITH_CURVE_BRAINPOOLP224R1 400*f0865ec9SKyle Evans #define WITH_CURVE_BRAINPOOLP256R1 401*f0865ec9SKyle Evans #define WITH_CURVE_BRAINPOOLP384R1 402*f0865ec9SKyle Evans #define WITH_CURVE_BRAINPOOLP512R1 403*f0865ec9SKyle Evans #define WITH_CURVE_GOST256 404*f0865ec9SKyle Evans #define WITH_CURVE_GOST512 405*f0865ec9SKyle Evans ... 406*f0865ec9SKyle Evans</pre> 407*f0865ec9SKyle Evans 408*f0865ec9SKyle EvansAs another example, if one wants to build a custom project supporting only 409*f0865ec9SKyle EvansECFSDA using SHA3-256 on BrainpoolP256R1, this can be done by keeping only the 410*f0865ec9SKyle Evansfollowing elements in 411*f0865ec9SKyle Evans[include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h): 412*f0865ec9SKyle Evans 413*f0865ec9SKyle Evans<pre> 414*f0865ec9SKyle Evans #define WITH_SIG_ECFSDSA 415*f0865ec9SKyle Evans #define WITH_HASH_SHA3_256 416*f0865ec9SKyle Evans #define WITH_CURVE_BRAINPOOLP256R1 417*f0865ec9SKyle Evans</pre> 418*f0865ec9SKyle Evans 419*f0865ec9SKyle Evans### Advanced configuration 420*f0865ec9SKyle Evans 421*f0865ec9SKyle Evans#### Modifying the word size 422*f0865ec9SKyle Evans 423*f0865ec9SKyle Evanslibecc supports 16, 32 and 64 bits word sizes. Though this word size is usually inferred during compilation 424*f0865ec9SKyle Evansand adapted depending on the detected platform (to fit the best performance), the user can force it in three ways: 425*f0865ec9SKyle Evans 426*f0865ec9SKyle Evans* Overloading the `WORDSIZE` macro in [include/libecc/words/words.h](include/libecc/words/words.h). 427*f0865ec9SKyle Evans* Overloading the `WORDSIZE` macro in the Makefile `CFLAGS`. 428*f0865ec9SKyle Evans* Use specific Makefile targets. 429*f0865ec9SKyle Evans 430*f0865ec9SKyle EvansPlease refer to the [portability guide](#libecc-portability-guide) for details on this. 431*f0865ec9SKyle Evans 432*f0865ec9SKyle Evans#### Modifying the big numbers size 433*f0865ec9SKyle Evans 434*f0865ec9SKyle Evanslibecc infers the Natural Numbers maximum length from the **curves** parameters that have been statically 435*f0865ec9SKyle Evansdefined in [include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h). Though this behaviour is perfectly fine and transparent 436*f0865ec9SKyle Evansfor the user when dealing with the elliptic curves and signature layers, this can become a limitation when building 437*f0865ec9SKyle Evanscode around the NN and Fp arithmetic layers. The user will be stuck with a hard coded maximum size of numbers depending 438*f0865ec9SKyle Evanson the curve that is used by libecc, which can be a nonsense if he is only interested in the big number basic 439*f0865ec9SKyle Evansalgorithmic side (when the default curves are used, this maximum size is 521 bits, corresponding to SECP521 440*f0865ec9SKyle Evansparameters). 441*f0865ec9SKyle Evans 442*f0865ec9SKyle Evanslibecc provides a way to **overload the NN maximum size**, with a strong limit depending on the word size (around 443*f0865ec9SKyle Evans5300 bits for 64-bit words, around 2650 bits for 32-bit words, and around 1300 bits for 16-bit words). See 444*f0865ec9SKyle Evansthe comments in [include/libecc/nn/nn_config.h](include/libecc/nn/nn_config.h) for more details about this. In order to manually increase 445*f0865ec9SKyle Evansthe NN size, the user will have to define the macro `USER_NN_BIT_LEN`, either directly in 446*f0865ec9SKyle Evans[include/libecc/nn/nn_config.h](include/libecc/nn/nn_config.h), or more appropriately through overloading the Makefile `CFLAGS` 447*f0865ec9SKyle Evanswith `-DUSER_NN_BIT_LEN=` (see [the dedicated section](#overloading-makefile-variables) for more on how to do this). 448*f0865ec9SKyle Evans 449*f0865ec9SKyle Evans**NOTE**: objects and binaries compiled with different word sizes and/or user defined NN maximum bit lengths **are not compatible**, 450*f0865ec9SKyle Evansand could produce executables with dangerous runtime behaviour. In order to prevent possible honest mistakes, there is 451*f0865ec9SKyle Evansa safety net function catching such situations **at compilation time** in [include/libecc/nn/nn_config.h](include/libecc/nn/nn_config.h): the 452*f0865ec9SKyle Evans`nn_check_libconsistency` routine will throw an error. For instance, if 'libarith.a' has been compiled with 453*f0865ec9SKyle Evans`WORDSIZE=64`, and one tries to compile the arithmetic tests with `WORDSIZE=32`, here is the error the compiler 454*f0865ec9SKyle Evansshould produce: 455*f0865ec9SKyle Evans 456*f0865ec9SKyle Evans<pre> 457*f0865ec9SKyle Evans... 458*f0865ec9SKyle Evansarithmetic_tests.c:(.text+0x3af21) : undefined reference to « nn_consistency_check_maxbitlen521wordsize32 » 459*f0865ec9SKyle Evans... 460*f0865ec9SKyle Evans</pre> 461*f0865ec9SKyle Evans 462*f0865ec9SKyle Evans#### Small RAM footprint devices (small stack usage) 463*f0865ec9SKyle Evans 464*f0865ec9SKyle EvansIn order to squeeze the stack usage on very constrained devices, a `SMALLSTACK` toggle can be activated. Beware that this toggle 465*f0865ec9SKyle Evansremoves some countermeasures (Itoh et al. masking) in order to fit in 8KB of RAM stack usage. Also beware that this is incompatible 466*f0865ec9SKyle Evanswith EdDSA and X25519 as these specific functions need more than this amount of stack because of the isogenies usage (you should get 467*f0865ec9SKyle Evansa compilation error when trying to activate them with `SMALLSTACK=1`). 468*f0865ec9SKyle Evans 469*f0865ec9SKyle Evans<pre> 470*f0865ec9SKyle Evans$ SMALLSTACK=1 make 471*f0865ec9SKyle Evans</pre> 472*f0865ec9SKyle Evans 473*f0865ec9SKyle Evans 474*f0865ec9SKyle Evans## Expanding the libecc library 475*f0865ec9SKyle Evans 476*f0865ec9SKyle EvansThough libecc has been designed to be compiled with a static embedding of all its features (i.e. no dynamic modules 477*f0865ec9SKyle Evansloading), its **static code extensibility** has been a matter of attention. The library can be: 478*f0865ec9SKyle Evans* Easily expanded by **adding new curves**, with **zero coding effort**. Note that **only curves over prime fields are 479*f0865ec9SKyle Evanssupported**. 480*f0865ec9SKyle Evans* Expanded with new hash functions and new signature algorithms with some coding effort, but clean and well defined 481*f0865ec9SKyle EvansAPIs should ease this task. 482*f0865ec9SKyle Evans 483*f0865ec9SKyle Evans### Adding user defined curves 484*f0865ec9SKyle Evans 485*f0865ec9SKyle EvansA companion python script [scripts/expand_libecc.py](scripts/expand_libecc.py) will transparently add (and remove) new 486*f0865ec9SKyle Evansuser defined curves in the source tree of the project. The '.h' headers defining the new curves 487*f0865ec9SKyle Evanswill be created in a dedicated folder: [include/libecc/curves/user_defined/](include/libecc/curves/user_defined/). 488*f0865ec9SKyle Evans 489*f0865ec9SKyle EvansThe python script should have a self explanatory and complete help: 490*f0865ec9SKyle Evans<pre> 491*f0865ec9SKyle Evans $ python scripts/expand_libecc.py -h 492*f0865ec9SKyle Evans This script is intented to *statically* expand the ECC library with user defined curves. 493*f0865ec9SKyle Evans ... 494*f0865ec9SKyle Evans</pre> 495*f0865ec9SKyle Evans 496*f0865ec9SKyle EvansIn order to add a curve, one can give explicit parameters (prime, order, ...) on the command line or 497*f0865ec9SKyle Evansprovide a [RFC3279](https://www.ietf.org/rfc/rfc3279.txt) formatted ASN.1 file (DER or PEM) with the 498*f0865ec9SKyle Evansparameters. Sanity checks are performed by the script. The script is also able to generate 499*f0865ec9SKyle Evans**test vectors** for the new curve with the `--add-test-vectors` toggle. 500*f0865ec9SKyle Evans 501*f0865ec9SKyle EvansLet's show how we can add the BRAINPOOLP320R1 supported by OpenSSL. We use the `ecparam` option of 502*f0865ec9SKyle Evansthe `openssl` command line: 503*f0865ec9SKyle Evans 504*f0865ec9SKyle Evans<pre> 505*f0865ec9SKyle Evans $ openssl ecparam -param_enc explicit -outform DER -name brainpoolP320r1 -out brainpoolP320r1.der 506*f0865ec9SKyle Evans</pre> 507*f0865ec9SKyle Evans 508*f0865ec9SKyle EvansThis creates a DER file 'brainpoolP320r1.der' embedding the parameters (beware of the `-param_enc explicit` 509*f0865ec9SKyle Evansoption that is important here). Now, in order to add this new curve to libecc, we will execute: 510*f0865ec9SKyle Evans<pre> 511*f0865ec9SKyle Evans $ python scripts/expand_libecc.py --name="mynewcurve" --ECfile=brainpoolP320r1.der --add-test-vectors=1 512*f0865ec9SKyle Evans Test vectors generation asked: this can take some time! Please wait ... 513*f0865ec9SKyle Evans 1/56 514*f0865ec9SKyle Evans</pre> 515*f0865ec9SKyle Evans 516*f0865ec9SKyle EvansThis will create a new header file 'ec_params_user_defined_mynewcurve.h' in the [include/libecc/curves/user_defined/](include/libecc/curves/user_defined/) 517*f0865ec9SKyle Evansfolder, and it will modify some libecc core files to transparently add this curve for the next compilation (modified files 518*f0865ec9SKyle Evansare [include/libecc/curves/curves_list.h](include/libecc/curves/curves_list.h), [src/tests/ec_self_tests_core.h](src/tests/ec_self_tests_core.h), 519*f0865ec9SKyle Evans[include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h) and [include/libecc/lib_ecc_types.h](include/libecc/lib_ecc_types.h)). 520*f0865ec9SKyle Evans 521*f0865ec9SKyle EvansThe test vectors generation can take some time since all the possible triplets (curve, hash function, signature algorithm) are 522*f0865ec9SKyle Evansprocessed with the new curve. 523*f0865ec9SKyle Evans 524*f0865ec9SKyle EvansAfter compiling the library, the new curve should show up in the self tests: 525*f0865ec9SKyle Evans<pre> 526*f0865ec9SKyle Evans $ ./build/ec_self_tests 527*f0865ec9SKyle Evans ======= Known test vectors test ================= 528*f0865ec9SKyle Evans ... 529*f0865ec9SKyle Evans [+] ECDSA_SHA224_USER_DEFINED_MYNEWCURVE_0 selftests: known test vectors sig/verif ok 530*f0865ec9SKyle Evans ... 531*f0865ec9SKyle Evans ======= Random sig/verif test =================== 532*f0865ec9SKyle Evans ... 533*f0865ec9SKyle Evans [+] ECDSA-SHA224/USER_DEFINED_MYNEWCURVE randtests: random import/export with sig/verif ok 534*f0865ec9SKyle Evans ... 535*f0865ec9SKyle Evans ======= Performance test ======================== 536*f0865ec9SKyle Evans ... 537*f0865ec9SKyle Evans [+] ECDSA-SHA224/USER_DEFINED_MYNEWCURVE perf: 269 sign/s and 141 verif/s 538*f0865ec9SKyle Evans ... 539*f0865ec9SKyle Evans</pre> 540*f0865ec9SKyle Evans 541*f0865ec9SKyle EvansIt should also appear in the `ec_utils` help: 542*f0865ec9SKyle Evans<pre> 543*f0865ec9SKyle Evans $ ./build/ec_utils sign 544*f0865ec9SKyle Evans Bad args number for ./build/ec_utils sign: 545*f0865ec9SKyle Evans arg1 = curve name: FRP256V1 USER_DEFINED_MYNEWCURVE ... 546*f0865ec9SKyle Evans arg2 = signature algorithm type: ECDSA ... 547*f0865ec9SKyle Evans arg3 = hash algorithm type: SHA224 ... 548*f0865ec9SKyle Evans arg4 = input file to sign 549*f0865ec9SKyle Evans arg5 = input file containing the private key (in raw binary format) 550*f0865ec9SKyle Evans arg6 = output file containing the signature 551*f0865ec9SKyle Evans <arg7 (optional) = ancillary data to be used> 552*f0865ec9SKyle Evans</pre> 553*f0865ec9SKyle Evans 554*f0865ec9SKyle EvansIt is possible to remove a user defined curve by using the python script and its name: 555*f0865ec9SKyle Evans<pre> 556*f0865ec9SKyle Evans $ python scripts/expand_libecc.py --remove --name mynewcurve 557*f0865ec9SKyle Evans You asked to remove everything related to user defined mynewcurve curve. Enter y to confirm, n to cancel [y/n]. y 558*f0865ec9SKyle Evans Removing user defined curve mynewcurve ... 559*f0865ec9SKyle Evans</pre> 560*f0865ec9SKyle Evans 561*f0865ec9SKyle EvansIt is also possible to remove **all** the user defined curves at once: 562*f0865ec9SKyle Evans<pre> 563*f0865ec9SKyle Evans $ python scripts/expand_libecc.py --remove-all 564*f0865ec9SKyle Evans</pre> 565*f0865ec9SKyle Evans 566*f0865ec9SKyle EvansFinally, two companion shell scripts are provided along with the expanding python script in order to show its basic usage: 567*f0865ec9SKyle Evans 568*f0865ec9SKyle Evans* [scripts/gen_curves_tests.sh](scripts/gen_curves_tests.sh): this script generates the default libecc curves 569*f0865ec9SKyle Evanswith explicit parameters given on the command line. Of course, since these curves are already embedded in 570*f0865ec9SKyle Evanslibecc, there is no real use of generating them - the script is only here to serve as a showcase for expanding 571*f0865ec9SKyle Evansthe library with explicit parameters. 572*f0865ec9SKyle Evans* [scripts/gen_openssl_curves_tests.sh](scripts/gen_openssl_curves_tests.sh): this script enumerates all OpenSSL 573*f0865ec9SKyle Evansnamed curves, generates a DER file with their parameters, and adds them to libecc. 574*f0865ec9SKyle Evans 575*f0865ec9SKyle Evans### Adding new hash and signature algorithms 576*f0865ec9SKyle Evans 577*f0865ec9SKyle EvansObviously, adding new algorithms (hash or signature) will require adding new code. 578*f0865ec9SKyle Evans 579*f0865ec9SKyle Evans#### Adding new hash functions 580*f0865ec9SKyle EvansWe detail hereafter the necessary steps to add a new hash function. The main file listing all the hash functions is [include/libecc/hash/hash_algs.h](include/libecc/hash/hash_algs.h). The new hash 581*f0865ec9SKyle Evansalgorithm should be added here in compliance with the API described in the `hash_mapping struct`. This API includes: 582*f0865ec9SKyle Evans 583*f0865ec9SKyle Evans * The digest and block sizes and a pretty print name for the algorithm. 584*f0865ec9SKyle Evans * `hfunc_init`: the hash function initialization routine. 585*f0865ec9SKyle Evans * `hfunc_update`: the hash function update routine. 586*f0865ec9SKyle Evans * `hfunc_finalize`: the hash function finalization routine. 587*f0865ec9SKyle Evans * `hfunc_scattered`: this function applies the hash function (i.e. compute the digest) on multiple messages 588*f0865ec9SKyle Evans (it takes as input an array of pointers to message chunks, and an array of sizes). 589*f0865ec9SKyle Evans 590*f0865ec9SKyle EvansThese libecc API functions are in fact redirections to the core routines of the hash algorithm, and 591*f0865ec9SKyle Evansthe user is expected to add the specific implementation in '.c' and '.h' files inside the [src/hash/](src/hash/) 592*f0865ec9SKyle Evansfolder. See [src/hash/sha224.c](src/hash/sha224.c) and [include/libecc/hash/sha224.h](include/libecc/hash/sha224.h) for a practical 593*f0865ec9SKyle Evansexample of how to do this with SHA-224. 594*f0865ec9SKyle Evans 595*f0865ec9SKyle EvansFinally, the user is expected to update the libecc main configuration file [include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h) 596*f0865ec9SKyle Evanswith the `WITH_MY_NEW_HASH` toggle ('my_new_hash' being the new hash function). 597*f0865ec9SKyle Evans 598*f0865ec9SKyle Evans#### Adding new signature algorithms 599*f0865ec9SKyle EvansIn order to add a new elliptic curve based signature algorithm, here is the needed work: 600*f0865ec9SKyle Evans* The main file listing all the signature algorithms is [include/libecc/sig/sig_algs_internal.h](include/libecc/sig/sig_algs_internal.h). 601*f0865ec9SKyle EvansThe signature algorithm should be added in compliance with the API described in the `ec_sig_mapping struct`. This 602*f0865ec9SKyle EvansAPI includes: 603*f0865ec9SKyle Evans * The signature type and a pretty print name. 604*f0865ec9SKyle Evans * `siglen`: a function giving the length of the produced signature. 605*f0865ec9SKyle Evans * `init_pub_key`: a routine producing a public key when given a corresponding private key. 606*f0865ec9SKyle Evans * `sign_init`, `sign_update` and `sign_finalize`: the usual functions initializing a signature, updating it with 607*f0865ec9SKyle Evans input buffers, and finalizing it to produce an output signature. 608*f0865ec9SKyle Evans * `verify_init`, `verify_update` and `verify_finalize`: the usual functions initializing a signature verification, updating 609*f0865ec9SKyle Evans it with input buffers, and finalizing it to produce a check status (i.e. signature OK or not OK). 610*f0865ec9SKyle Evans 611*f0865ec9SKyle EvansThese libecc APIs have to be plugged to the core signature functions, and the user is expected to handle this implementation 612*f0865ec9SKyle Evanswith adding the specific '.c' files inside the [src/sig](src/sig) folder and the specific '.h' files inside the [include/libecc/sig](include/libecc/sig) folder. See [src/sig/ecdsa.c](src/sig/ecdsa.c) and [include/libecc/sig/ecdsa.h](include/libecc/sig/ecdsa.h) for a practical example of how to do this with ECDSA. 613*f0865ec9SKyle Evans 614*f0865ec9SKyle EvansFinally, the user is expected to update the libecc main configuration file [include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h) 615*f0865ec9SKyle Evanswith the `WITH_MY_NEW_SIGN_ALG` toggle ('my_new_sign_alg' being the new signature algorithm). 616*f0865ec9SKyle Evans 617*f0865ec9SKyle Evans## <a name="performance"></a> Performance 618*f0865ec9SKyle Evans 619*f0865ec9SKyle EvansAs already stated, libecc has not been designed with performance in mind, but 620*f0865ec9SKyle Evanswith **simplicity** and **portability** as guiding principles; this implies 621*f0865ec9SKyle Evansseveral things when it comes to performance: 622*f0865ec9SKyle Evans 623*f0865ec9SKyle Evans* libecc does not intend to compete with libraries developed with platform specific accelerations, such as the use of **assembly** 624*f0865ec9SKyle Evansroutines or the adaptation to CPUs quirks at execution time (e.g. a CPU with very slow shift instructions). [OpenSSL](https://www.openssl.org/) 625*f0865ec9SKyle Evansis an example of such libraries with good and homogeneous performance in mind on most heterogeneous platforms (with the lack of 626*f0865ec9SKyle Evansportability on very small embedded platforms though). 627*f0865ec9SKyle Evans* Some algorithmic tricks on specific prime curves are not implemented: the same algorithms are used for all the curves. 628*f0865ec9SKyle EvansThis means for instance that curves using pseudo-Mersenne primes (such as NIST's SECP curves) won't be faster than 629*f0865ec9SKyle Evanscurves using generic random primes (such as Brainpool curves), though pseudo-Mersenne primes can benefit from a 630*f0865ec9SKyle Evansdedicated reduction algorithm, yielding **orders of magnitude faster field arithmetic** (around five to ten times faster). See 631*f0865ec9SKyle Evans[here](https://tls.mbed.org/kb/cryptography/elliptic-curve-performance-nist-vs-brainpool) for further discussions on this. 632*f0865ec9SKyle EvansConsequently, we will only focus on performance comparison with other libraries using the Brainpool curves. 633*f0865ec9SKyle Evans* We use a very straightforward elliptic curve arithmetic implementation, without using literature generic algorithmic optimizations 634*f0865ec9SKyle Evanssuch as [windowing](https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Windowed_method) or 635*f0865ec9SKyle Evans[fixed-base comb](https://link.springer.com/chapter/10.1007/3-540-45537-X_21) precomputations. 636*f0865ec9SKyle Evans 637*f0865ec9SKyle EvansNonetheless and despite all these elements, **libecc is on par with some other general purpose and portable cryptographic 638*f0865ec9SKyle Evanslibraries** such as [mbedTLS](https://tls.mbed.org) (see the performance figures given below). 639*f0865ec9SKyle Evans 640*f0865ec9SKyle EvansWe present hereafter the ECDSA performance comparison of libecc with mbedTLS and OpenSSL on various platforms representing 641*f0865ec9SKyle Evansdifferent CPU flavours. Here are some information about the tested version when not stated otherwise: 642*f0865ec9SKyle Evans 643*f0865ec9SKyle Evans* mbedTLS: stable version 2.4.2, the figures have been gathered with the builtin benchmark. 644*f0865ec9SKyle Evans* OpenSSL: debian packaged version 1.1.0e. Since OpenSSL builtin ECDSA benchmark does not handle Brainpool curves, 645*f0865ec9SKyle Evansa basic C code using "named curves" have been compiled against the installed dynamic library. 646*f0865ec9SKyle Evans 647*f0865ec9SKyle Evans### Performance oriented platforms 648*f0865ec9SKyle Evans 649*f0865ec9SKyle Evans* **Core i7-5500U** (Broadwell family) is a typical x86 mid-range current laptop CPU. 650*f0865ec9SKyle Evans* **Xeon E3-1535M** (Skylake family) is a typical x86 high-end CPU. 651*f0865ec9SKyle Evans* **Power-7** is a typical server CPU of the previous generation (2010) with 652*f0865ec9SKyle Evansa PowerPC architecture. 653*f0865ec9SKyle Evans 654*f0865ec9SKyle EvansFor all the platforms in this subsection, the CPUs have been tested in 64-bit mode. 655*f0865ec9SKyle Evans 656*f0865ec9SKyle Evans 657*f0865ec9SKyle Evans| **libecc** | Core i7-5500U @ 2.40GHz | Xeon E3-1535M v5 @ 2.90GHz | Power-7 | 658*f0865ec9SKyle Evans|-----------------|:----------------------------|:------------------------------|:--------------------------| 659*f0865ec9SKyle Evans| BP256R1 | 583 sign/s - 300 verif/s | 700 sign/s - 355 verif/s | 213 sign/s - 110 verif/s | 660*f0865ec9SKyle Evans| BP384R1 | 231 sign/s - 118 verif/s | 283 sign/s - 150 verif/s | 98 sign/s - 50 verif/s | 661*f0865ec9SKyle Evans| BP512R1 | 111 sign/s - 56 verif/s | 133 sign/s - 68 verif/s | 51 sign/s - 26 verif/s | 662*f0865ec9SKyle Evans 663*f0865ec9SKyle Evans| **mbedTLS** | Core i7-5500U @ 2.40GHz | Xeon E3-1535M v5 @ 2.90GHz | Power-7 | 664*f0865ec9SKyle Evans|-----------------|:----------------------------|:------------------------------|:--------------------------| 665*f0865ec9SKyle Evans| BP256R1 | 426 sign/s - 106 verif/s | 552 sign/s - 141 verif/s | 178 sign/s - 45 verif/s | 666*f0865ec9SKyle Evans| BP384R1 | 239 sign/s - 56 verif/s | 322 sign/s - 77 verif/s | 44 sign/s - 23 verif/s | 667*f0865ec9SKyle Evans| BP512R1 | 101 sign/s - 26 verif/s | 155 sign/s - 34 verif/s | 38 sign/s - 12 verif/s | 668*f0865ec9SKyle Evans 669*f0865ec9SKyle Evans| **OpenSSL** | Core i7-5500U @ 2.40GHz | Xeon E3-1535M v5 @ 2.90GHz | Power-7 | 670*f0865ec9SKyle Evans|-----------------|:----------------------------|:------------------------------|:--------------------------| 671*f0865ec9SKyle Evans| BP256R1 | 2463 sign/s - 1757 verif/s | 2873 sign/s - 2551 verif/s | 1879 sign/s - 1655 verif/s| 672*f0865ec9SKyle Evans| BP384R1 | 1091 sign/s - 966 verif/s | 1481 sign/s - 1265 verif/s | 792 sign/s - 704 verif/s| 673*f0865ec9SKyle Evans| BP512R1 | 727 sign/s - 643 verif/s | 1029 sign/s - 892 verif/s | 574 sign/s - 520 verif/s| 674*f0865ec9SKyle Evans 675*f0865ec9SKyle Evans### Embedded platforms with moderate constraints 676*f0865ec9SKyle Evans* **Marvel Armada A388** is a good representative of moderately constrained embedded devices, such as 677*f0865ec9SKyle EvansIAD (Internet Access Devices), NAS (Network Attached Storage), STB (Set Top Boxes) and smartphones. 678*f0865ec9SKyle EvansThis SoC is built around a Cortex-A9 ARMv7-A 32-bit architecture. 679*f0865ec9SKyle Evans* **BCM2837** is a Broadcom SoC built around the recent 64-bit ARMv8-A architecture, with a 680*f0865ec9SKyle EvansCortex-A53 core. This SoC can be found in the Raspberry Pi 3, and also represents what can 681*f0865ec9SKyle Evansbe found in recent Smartphones. 682*f0865ec9SKyle Evans* **Atom D2700** is a small x86 CPU typically embedded in NAS devices. Though its "embedded" 683*f0865ec9SKyle Evanscoloration, it uses a 64-bit mode that we have tested here. 684*f0865ec9SKyle Evans 685*f0865ec9SKyle Evans| **libecc** | Marvell A388 @ 1.6GHz | BCM2837 (aarch64) @ 1.2GHz | Atom D2700 @ 2.13GHz | 686*f0865ec9SKyle Evans|-----------------|:----------------------|----------------------------|:-----------------------| 687*f0865ec9SKyle Evans| BP256R1 | 64 sign/s - 33 verif/s| 43 sign/s - 22 verif/s | 68 sign/s - 35 verif/s | 688*f0865ec9SKyle Evans| BP384R1 | 24 sign/s - 12 verif/s| 17 sign/s - 9 verif/s | 25 sign/s - 13 verif/s | 689*f0865ec9SKyle Evans| BP512R1 | 11 sign/s - 5 verif/s | 8 sign/s - 4 verif/s | 12 sign/s - 6 verif/s | 690*f0865ec9SKyle Evans 691*f0865ec9SKyle Evans| **mbedTLS** | Marvell A388 @ 1.6GHz | BCM2837 (aarch64) @ 1.2GHz | Atom D2700 @ 2.13GHz -| 692*f0865ec9SKyle Evans|-----------------|:----------------------|----------------------------|:------------------------| 693*f0865ec9SKyle Evans| BP256R1 | 33 sign/s - 8 verif/s | 14 sign/s - 4 verif/s | 87 sign/s - 22 verif/s| 694*f0865ec9SKyle Evans| BP384R1 | 20 sign/s - 4 verif/s | 8 sign/s - 2 verif/s | 50 sign/s - 11 verif/s| 695*f0865ec9SKyle Evans| BP512R1 | 10 sign/s - 2 verif/s | 4 sign/s - 1 verif/s | 23 sign/s - 5 verif/s | 696*f0865ec9SKyle Evans 697*f0865ec9SKyle Evans| **OpenSSL** | Marvell A388 @ 1.6GHz | BCM2837 (aarch64) @ 1.2GHz | Atom D2700 @ 2.13GHz | 698*f0865ec9SKyle Evans|-----------------|:------------------------|----------------------------|:------------------------| 699*f0865ec9SKyle Evans| BP256R1 | 369 sign/s - 332 verif/s| 124 sign/s - 112 verif/s | 372 sign/s - 334 verif/s| 700*f0865ec9SKyle Evans| BP384R1 | 102 sign/s - 94 verif/s | 54 sign/s - 49 verif/s | 163 sign/s - 149 verif/s| 701*f0865ec9SKyle Evans| BP512R1 | 87 sign/s - 81 verif/s | 31 sign/s - 29 verif/s | 92 sign/s - 83 verif/s | 702*f0865ec9SKyle Evans 703*f0865ec9SKyle Evans 704*f0865ec9SKyle Evans### <a name="constrained-devices"></a> Very constrained embedded devices 705*f0865ec9SKyle EvansThe library, when configured for a 256-bit curve (SECP256R1, FRP256), SHA-256 and ECDSA signature fits in around 706*f0865ec9SKyle Evans**30 Kilo Bytes of flash/EEPROM**, and uses around **8 Kilo Bytes of RAM** (stack) with variations depending on the 707*f0865ec9SKyle Evanschosen WORDSIZE (16, 32, 64), the compilation options (optimization for space `-Os` or speed `-O3`) and the 708*f0865ec9SKyle Evanstarget (depending on the instructions encoding, produced binary code can be more or less compact). 709*f0865ec9SKyle EvansA 521-bit curve with SHA-256 hash function and ECDSA signature should fit in 38 Kilo Bytes of flash and around 710*f0865ec9SKyle Evans16 Kilo Bytes of RAM (stack), with the same variations depending on the WORDSIZE and the compilation options. 711*f0865ec9SKyle Evans 712*f0865ec9SKyle Evans**Note**: libecc does not use any heap allocation, and the only global variables used are the **constant ones**. The 713*f0865ec9SKyle Evansconstant data should end up in the flash/EEPROM section with a read only access to them: no RAM memory should 714*f0865ec9SKyle Evansbe consumed by these. The libecc read/write data are only made of local variables on the stack. Hence, RAM 715*f0865ec9SKyle Evansconsumption (essentially made of arrays representing internal objects such as numbers, point on curves ...) 716*f0865ec9SKyle Evansshould be reasonably constant across platforms. **However**, some platforms using the 717*f0865ec9SKyle Evans**[Harvard architecture](https://en.wikipedia.org/wiki/Harvard_architecture)** (as opposed to Von Neumann's one) 718*f0865ec9SKyle Evanscan have big limitations when accessing so called "program memory" as data. The 8-bit 719*f0865ec9SKyle Evans[Atmel AVR](http://www.atmel.com/products/microcontrollers/avr/) MCU 720*f0865ec9SKyle Evansis such an example. Compilers and toolchains for such architectures usually copy read only data in RAM at run time, 721*f0865ec9SKyle Evansand/or provide [non-standard ways](http://www.atmel.com/webdoc/avrlibcreferencemanual/pgmspace_1pgmspace_strings.html) 722*f0865ec9SKyle Evansto access read only data in flash/EEPROM program memory (through specific macros, pragmas, functions). The 723*f0865ec9SKyle Evansfirst case means that the RAM consumption will increase for libecc compared to the stack only usage (because of 724*f0865ec9SKyle Evansthe runtime copy). The second case means that libecc code will have to be **adapted** to the platform if the user 725*f0865ec9SKyle Evanswant to keep RAM usage at its lowest. In any case, tracking where `const` qualified data reside will be important 726*f0865ec9SKyle Evanswhen the amount of RAM is a critical matter. 727*f0865ec9SKyle Evans 728*f0865ec9SKyle EvansA full software stack containing a known test vector scenario has been compiled and tested on a **Cortex-M0** 729*f0865ec9SKyle Evans([STM32F030R8T6](http://www.st.com/en/microcontrollers/stm32f030r8.html) @ 48MHz with 64KB of flash and 8KB of RAM). 730*f0865ec9SKyle EvansIt has also been compiled and tested on a **Cortex-M3** ([STM32F103C8T6](http://www.st.com/en/microcontrollers/stm32f103c8.html) 731*f0865ec9SKyle Evans@ 72MHz with 64KB of flash and 20KB of RAM). The results of the flash/RAM occupancy are given in the table below, 732*f0865ec9SKyle Evansas well as the timings of the ECDSA signature and verification operations. 733*f0865ec9SKyle Evans 734*f0865ec9SKyle Evans**Note**: The Cortex-M0 case is a bit special in the ARM family. Since this MCU lacks a 32-bit x 32-bit to 64-bit 735*f0865ec9SKyle Evansmultiplication instruction, the multiplication is implemented using a builtin software function. This yields 736*f0865ec9SKyle Evansin poor performance with WORDSIZE=64 compared to WORDSIZE=32 (this might be explained by the calling cost to 737*f0865ec9SKyle Evansthe builtin function). 738*f0865ec9SKyle Evans 739*f0865ec9SKyle Evans 740*f0865ec9SKyle Evans| **libecc** | STM32F103C8T6 (Cortex-M3 @ 72MHz) | STM32F030R8T6 (Cortex-M0 @ 48MHz) | 741*f0865ec9SKyle Evans|-----------------|:----------------------------------|:----------------------------------| 742*f0865ec9SKyle Evans| Flash size | 32KB | 30KB | 743*f0865ec9SKyle Evans| RAM size | 8KB | 8KB | 744*f0865ec9SKyle Evans| Sign time | 950ms | 2146ms | 745*f0865ec9SKyle Evans| Verif time | 1850ms | 4182ms | 746*f0865ec9SKyle Evans 747*f0865ec9SKyle EvansIn order to compare the libecc performance on these embedded platforms, we give figures for mbedTLS on 748*f0865ec9SKyle EvansCortex-M3 taken from a [recent study by ARM](http://csrc.nist.gov/groups/ST/lwc-workshop2015/presentations/session7-vincent.pdf). 749*f0865ec9SKyle EvansAs we have previously discussed, only the figures without NIST curves specific optimizations are of interest 750*f0865ec9SKyle Evansfor a fair comparison: 751*f0865ec9SKyle Evans 752*f0865ec9SKyle Evans| **mbedTLS** | LPC1768 (Cortex-M3 @ 92MHz)<sup>1</sup> | 753*f0865ec9SKyle Evans|-----------------|:------------------------------| 754*f0865ec9SKyle Evans| Flash size | ?? | 755*f0865ec9SKyle Evans| RAM size | 3KB<sup>2</sup>| 756*f0865ec9SKyle Evans| Sign time | 1893ms | 757*f0865ec9SKyle Evans| Verif time | 3788ms | 758*f0865ec9SKyle Evans 759*f0865ec9SKyle Evans<sup>1</sup> Beware of the MCU frequency difference when comparing with libecc test case. 760*f0865ec9SKyle Evans 761*f0865ec9SKyle Evans<sup>2</sup> This figure only includes heap usage (stack usage is unknown so this is only a 762*f0865ec9SKyle Evansrough lower limit for RAM usage). 763*f0865ec9SKyle Evans 764*f0865ec9SKyle Evans 765*f0865ec9SKyle Evans## <a name="compatibility-and-portability"></a> Compatibility and Portability 766*f0865ec9SKyle Evans 767*f0865ec9SKyle Evans### libecc compatibility 768*f0865ec9SKyle Evans 769*f0865ec9SKyle EvansWhen dealing with the **portability** of a program across various platforms, many issues are 770*f0865ec9SKyle Evansin fact hidden behind this property. This is due to the very complex nature of what a 771*f0865ec9SKyle Evans**platform** is, namely: 772*f0865ec9SKyle Evans 773*f0865ec9SKyle Evans* A **core CPU** architecture (x86, ARM, MIPS, PowerPC, ...). 774*f0865ec9SKyle Evans* A target **OS** (Linux, Windows, Mac OS, ...) or more low level firmware (including a **bare-metal** 775*f0865ec9SKyle Evansprogramming model or exotic real-time OS for microcontrollers for instance). 776*f0865ec9SKyle Evans* A proper compilation **(cross-)toolchain** producing binaries for the platform. This toolchain will usually 777*f0865ec9SKyle Evansinclude a compiler and a linker, both with possibly specific flags and limitations. 778*f0865ec9SKyle Evans 779*f0865ec9SKyle EvansRegarding libecc, here are the main elements to be aware of when dealing with a "new" platform: 780*f0865ec9SKyle Evans 781*f0865ec9SKyle Evans* libecc is in pure C-99 (no assembly), so it should compile on **any platform** with a decent C-99 782*f0865ec9SKyle Evanscompatible compiler. The code is **endian neutral**, meaning that libecc should work on little endian 783*f0865ec9SKyle Evansand big endian platforms. 784*f0865ec9SKyle Evans* The Makefile has been tested with clang and gcc under Linux, as well as gcc cross-compilation variants 785*f0865ec9SKyle Evanssuch as **mingw** for Windows or gcc **Mac OS** version. In order to adapt the makefile behaviour when the 786*f0865ec9SKyle Evanscompiler is not gcc/clang compatible, the user can modify the CFLAGS as well as the LDFLAGS by exporting them. 787*f0865ec9SKyle Evans* The library supports 16-bit/32-bit/64-bit word sizes, which should ensure compatibility with most of the platforms 788*f0865ec9SKyle Evansfor 8-bit MCUs to 64-bit CPUs. If the toolchain does not have a [`stdint.h`](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html) 789*f0865ec9SKyle Evansheader, it is still possible to compile libecc by exporting LIBECC_NOSTDLIB=1: in this case, the code will try to 790*f0865ec9SKyle Evansguess and fit to native C types or throw an error so that the user can adapt [src/words/types.h](src/words/types.h) to its specific case. 791*f0865ec9SKyle Evans* The library core is platform independent. However, when the platform is not recognized (i.e. everything aside UNIX/Windows/Mac OS), 792*f0865ec9SKyle Evansan error is thrown at compilation time asking the user to provide implementations for **external dependencies** 793*f0865ec9SKyle Evansin [src/external_deps/](src/external_deps), namely: 794*f0865ec9SKyle Evans * The printing helper in [src/external_deps/print.c](src/external_deps/print.c). This helper serves output debugging purposes. 795*f0865ec9SKyle Evans * The timing helper in [src/external_deps/time.c](src/external_deps/time.c). This helper is used to measure performances of the 796*f0865ec9SKyle Evans library in the performance self tests. 797*f0865ec9SKyle Evans * The random helper in [src/external_deps/rand.c](src/external_deps/rand.c). This helper is used in the core library for the signature 798*f0865ec9SKyle Evans schemes. One should notice that a **good random source** is **crucial** for the security of Elliptic Curve based signature schemes, 799*f0865ec9SKyle Evans so great care must be taken when implementing this. 800*f0865ec9SKyle Evans 801*f0865ec9SKyle EvansSome other external dependencies could arise depending on the compilation chain and/or the platform. Such an example is the 802*f0865ec9SKyle Evansimplementation of the gcc and clang stack protection option, usually expecting the user to provide stack canaries generation 803*f0865ec9SKyle Evans(with random values) and failover behavior. 804*f0865ec9SKyle Evans 805*f0865ec9SKyle Evans 806*f0865ec9SKyle Evans### <a name="compiling-libecc-for-arm-cortex-m-with-GNU-gcc-arm"></a> Compiling libecc for ARM Cortex-M with GNU gcc-arm 807*f0865ec9SKyle Evans 808*f0865ec9SKyle EvansCompiling for Cortex-M targets should be straightforward using the arm-gcc none-eabi (for bare metal) cross-compiler as 809*f0865ec9SKyle Evanswell as the specific Cortex-M target platform SDK. In order to compile the core libsign.a static library, the only thing to do is to execute 810*f0865ec9SKyle Evansthe makefile command by overloading `CROSS_COMPILE`, `CC` and the `CFLAGS`: 811*f0865ec9SKyle Evans<pre> 812*f0865ec9SKyle Evans $ CROSS_COMPILE=arm-none-eabi- CC=gcc CFLAGS="$(TARGET_OPTS) -W -Wextra -Wall -Wunreachable-code \ 813*f0865ec9SKyle Evans -pedantic -fno-builtin -std=c99 -Os \ 814*f0865ec9SKyle Evans -ffreestanding -fno-builtin -nostdlib -DWORDSIZE=64" \ 815*f0865ec9SKyle Evans make build/libsign.a 816*f0865ec9SKyle Evans</pre> 817*f0865ec9SKyle Evans 818*f0865ec9SKyle Evanswhere `$(TARGET_OPTS)` are the flags specific to the considered target: `-mcpu=cortex-m3 -mthumb` for Cortex-M3 for example. The word size 819*f0865ec9SKyle Evansflag should be adapted to `-DWORDSIZE=32` for the specific case of Cortex-M0/M0+ as discussed in the [performance section](#performance) 820*f0865ec9SKyle Evans(because of the lacking of 32-bit to 64-bit native multiplication instruction). The library can then be used to be linked against a file 821*f0865ec9SKyle Evanscontaining the `main` calling function, and the linking part will depend on the 822*f0865ec9SKyle Evanstarget platform (in addition to the target CPU): one will use the **linker scripts** provided by the platform/board manufacturer to produce 823*f0865ec9SKyle Evansa firmware suitable for the target (ST for STM32, NXP for LPC, Atmel for SAM, ...). 824*f0865ec9SKyle Evans 825*f0865ec9SKyle EvansIf the external dependencies have been implemented by the user, it is also possible to build a self-tests binary by adding the 826*f0865ec9SKyle EvansGNU ld linker script specific to the target platform (`linker_script.ld` in the example below): 827*f0865ec9SKyle Evans<pre> 828*f0865ec9SKyle Evans $ CROSS_COMPILE=arm-none-eabi- CFLAGS="$(TARGET_OPTS) -W -Wextra -Wall -Wunreachable-code \ 829*f0865ec9SKyle Evans -pedantic -fno-builtin -std=c99 -Os \ 830*f0865ec9SKyle Evans -ffreestanding -fno-builtin -nostdlib -DWORDSIZE=64" \ 831*f0865ec9SKyle Evans LDFLAGS="-T linker_script.ld" \ 832*f0865ec9SKyle Evans make build/libsign.a 833*f0865ec9SKyle Evans</pre> 834*f0865ec9SKyle Evans 835*f0865ec9SKyle Evans**NOTE1**: By default, the linker scripts share the RAM between heap and stack. Since libecc only uses stack, it is convenient 836*f0865ec9SKyle Evans(sometimes necessary, specifically on devices with very constrained RAM, such as Cortex-M0 with 8KB) to adapt the **stack base address** 837*f0865ec9SKyle Evansso that no stack overflow errors occur. These errors can be tricky to detect since they generally produce hard faults silently at 838*f0865ec9SKyle Evansrun time. Also, a `SMALLSTACK=1` compilation toggle allows to limit stack consumption further: you can use it carefully if your device 839*f0865ec9SKyle Evansdoes not have enough stack for the regular compilation options (use with care as some side channels countermeasures are deactivated, and this 840*f0865ec9SKyle Evansmode is not compatible with the EdDSA signature and X25519 ECDH algorithm). 841*f0865ec9SKyle Evans 842*f0865ec9SKyle Evans**NOTE2**: It is up to the user to link against the libc (if standard functions are necessary) or not, but this will obviously influence the 843*f0865ec9SKyle Evansprogram size in flash. As already stated, the libc footprint is not included in the figured that have been given in 844*f0865ec9SKyle Evansthe [performance section](#performance). 845*f0865ec9SKyle Evans 846*f0865ec9SKyle Evans**NOTE3**: libecc has also been successfully tested with other non-GNU compilation SDK and toolchains such as [Keil MDK](http://www.keil.com/) 847*f0865ec9SKyle Evansconfigured to use the [ARM compiler](http://www2.keil.com/mdk5/compiler/5/). 848*f0865ec9SKyle Evans 849*f0865ec9SKyle Evans### <a name="libecc-portability-guide"></a> libecc portability guide 850*f0865ec9SKyle Evans 851*f0865ec9SKyle EvansThis section is dedicated to giving some more details on how to compile libecc when non-GNU compilers 852*f0865ec9SKyle Evansare used (i.e. C compilers that do not support gcc syntax), and/or when compiling with environments that 853*f0865ec9SKyle Evansdo not provide a **GNU make** compilation style (this is generally the case for all-in-one IDEs such as 854*f0865ec9SKyle EvansVisual Studio or other BSP and SDK provided by proprietary integrated circuits founders and board manufacturers). 855*f0865ec9SKyle Evans 856*f0865ec9SKyle Evans#### 1 - Compilers and C99 standard compliance 857*f0865ec9SKyle Evans 858*f0865ec9SKyle EvansAs we have already stated, libecc requires a C99 compiler. More specifically, libecc makes use of 859*f0865ec9SKyle Evansonly four feature of the C99 standard (over the older C89/C90 standard), namely: 860*f0865ec9SKyle Evans* The `long long int` type. 861*f0865ec9SKyle Evans* Designated initializers for structures. 862*f0865ec9SKyle Evans* The usage of the `inline` keyword. 863*f0865ec9SKyle Evans* The usage of variadic macros. 864*f0865ec9SKyle Evans 865*f0865ec9SKyle EvansHence, when compiling with a given compiler, one will have to check that the compiler is 866*f0865ec9SKyle Evans**either fully C99 compliant**, or that these four features are at least **implemented as extensions**. 867*f0865ec9SKyle EvansSuch details are generally provided by the compiler documentation. 868*f0865ec9SKyle Evans 869*f0865ec9SKyle Evans**NOTE**: if one wants to adapt libecc for compilers where some of the necessary C99 features are missing, here is a 870*f0865ec9SKyle Evansbig picture of the necessary work: 871*f0865ec9SKyle Evans* The `long long int` and structures initializers are used all over libecc code, so they are 872*f0865ec9SKyle Evans**strong requirements**, and would imply deep code modifications. 873*f0865ec9SKyle Evans* The `inline` keyword can be removed in most cases, except in the context of header files where it is used 874*f0865ec9SKyle Evansto define `static inline` functions. These functions will have to be moved to '.c' files, and one will have to 875*f0865ec9SKyle Evansdeal with minor adaptations. 876*f0865ec9SKyle Evans* The usage of variadic macros is marginal and can be removed with minimal efforts: these are only used 877*f0865ec9SKyle Evansto deal with debug helpers in [src/utils](src/utils). 878*f0865ec9SKyle Evans 879*f0865ec9SKyle Evans#### 2 - Compiling with environments without GNU make 880*f0865ec9SKyle Evans 881*f0865ec9SKyle Evanslibecc uses a GNU style [Makefile](Makefile) to automate the compilation process. One can however use other 882*f0865ec9SKyle Evanscompilation environments that are not GNU make compatible by implementing the following guidelines: 883*f0865ec9SKyle Evans* Make the compilation toolchain compile into **'.o' objects** all the necessary '.c' files in [src/nn](src/nn), 884*f0865ec9SKyle Evans[src/fp](src/fp), [src/curve](src/curve), [src/sig](src/sig), [src/utils](src/utils) and [src/hash](src/hash). 885*f0865ec9SKyle Evans* Make the compilation toolchain **link** the necessary object files to generate the static libraries: 886*f0865ec9SKyle Evans<pre> 887*f0865ec9SKyle Evans libarith.a: 888*f0865ec9SKyle Evans °°°°°°°°°°° 889*f0865ec9SKyle Evans src/fp/fp_rand.o src/fp/fp_mul.o src/fp/fp_montgomery.o src/fp/fp_mul_redc1.o src/fp/fp_add.o src/fp/fp.o 890*f0865ec9SKyle Evans src/fp/fp_pow.o src/nn/nn_mul.o src/nn/nn_mul_redc1.o src/nn/nn_logical.o src/nn/nn.o src/nn/nn_modinv.o 891*f0865ec9SKyle Evans src/nn/nn_add.o src/nn/nn_rand.o src/nn/nn_div.o src/utils/print_nn.o src/utils/print_fp.o src/utils/print_keys.o 892*f0865ec9SKyle Evans src/utils/print_curves.o src/utils/utils.o 893*f0865ec9SKyle Evans</pre> 894*f0865ec9SKyle Evans<pre> 895*f0865ec9SKyle Evans libec.a: 896*f0865ec9SKyle Evans °°°°°°°° 897*f0865ec9SKyle Evans src/fp/fp_rand.o src/fp/fp_mul.o src/fp/fp_montgomery.o src/fp/fp_mul_redc1.o src/fp/fp_add.o src/fp/fp.o src/fp/fp_pow.o 898*f0865ec9SKyle Evans src/nn/nn_mul.o src/nn/nn_mul_redc1.o src/nn/nn_logical.o src/nn/nn.o src/nn/nn_modinv.o src/nn/nn_add.o src/nn/nn_rand.o 899*f0865ec9SKyle Evans src/nn/nn_div.o src/utils/print_nn.o src/utils/print_fp.o src/utils/print_keys.o src/utils/print_curves.o src/utils/utils.o 900*f0865ec9SKyle Evans src/curves/prj_pt.o src/curves/curves.o src/curves/aff_pt.o src/curves/prj_pt_monty.o src/curves/ec_shortw.o src/curves/ec_params.o 901*f0865ec9SKyle Evans</pre> 902*f0865ec9SKyle Evans<pre> 903*f0865ec9SKyle Evans libsign.a: 904*f0865ec9SKyle Evans °°°°°°°°°° 905*f0865ec9SKyle Evans src/fp/fp_rand.o src/fp/fp_mul.o src/fp/fp_montgomery.o src/fp/fp_mul_redc1.o src/fp/fp_add.o src/fp/fp.o src/fp/fp_pow.o 906*f0865ec9SKyle Evans src/nn/nn_mul.o src/nn/nn_mul_redc1.o src/nn/nn_logical.o src/nn/nn.o src/nn/nn_modinv.o src/nn/nn_add.o src/nn/nn_rand.o 907*f0865ec9SKyle Evans src/nn/nn_div.o src/utils/print_nn.o src/utils/print_fp.o src/utils/print_keys.o src/utils/print_curves.o src/utils/utils.o 908*f0865ec9SKyle Evans src/curves/prj_pt.o src/curves/curves.o src/curves/aff_pt.o src/curves/prj_pt_monty.o src/curves/ec_shortw.o src/curves/ec_params.o 909*f0865ec9SKyle Evans src/hash/sha384.o src/hash/sha3-512.o src/hash/sha512.o src/hash/sha3-256.o src/hash/sha3-224.o src/hash/sha3.o src/hash/sha256.o 910*f0865ec9SKyle Evans src/hash/sha3-384.o src/hash/sha224.o src/hash/hash_algs.o src/sig/ecsdsa.o src/sig/ecdsa.o src/sig/ecrdsa.o src/sig/ecosdsa.o 911*f0865ec9SKyle Evans src/sig/ecfsdsa.o src/sig/eckcdsa.o src/sig/ecgdsa.o src/sig/ecsdsa_common.o src/sig/sig_algs.o src/sig/ec_key.o 912*f0865ec9SKyle Evans</pre> 913*f0865ec9SKyle Evans 914*f0865ec9SKyle EvansCompiling binaries (such as `ec_self_tests` and `ec_utils`) is nothing more than compiling concerned '.c' files under [src/tests](src/tests) 915*f0865ec9SKyle Evansand linking them with `libsign.a`. 916*f0865ec9SKyle Evans 917*f0865ec9SKyle Evans#### 3 - Dealing with the standard library and stdint 918*f0865ec9SKyle Evans 919*f0865ec9SKyle EvansSome important **preprocessor flags** are expected to be defined when compiling libecc: 920*f0865ec9SKyle Evans* `WORDSIZE=`: this is a preprocessor flag defining libecc internal words size (16, 32, or 64). By default libecc will 921*f0865ec9SKyle Evansdetect the best size depending on the platform, but if the platform is not recognized the user is expected to 922*f0865ec9SKyle Evansprovide this flag. 923*f0865ec9SKyle Evans* `WITH_STDLIB`: this flag is used for standard library usage inside libecc. Exporting the environment variable 924*f0865ec9SKyle Evans`LIBECC_NOSTDLIB=1` will trigger the **non usage** of standard includes and libraries. Standard C library headers and files 925*f0865ec9SKyle Evansare used for two things in the project: 926*f0865ec9SKyle Evans * Defining standard types through the `stdint.h` header. 927*f0865ec9SKyle EvansThough using this header helps libecc to properly define basic types in [include/libecc/words/types.h](include/libecc/words/types.h), it is not 928*f0865ec9SKyle Evansrequired to use it and some heuristics can be used to define these types without standard headers (see explanations on that 929*f0865ec9SKyle Evansin [include/libecc/words/types.h](include/libecc/words/types.h)) comments. 930*f0865ec9SKyle Evans * Defining standard library functions used by external dependencies as well as `ec_utils`. Compiling without `WITH_STDLIB` 931*f0865ec9SKyle Evansflag means that one has to provide these. 932*f0865ec9SKyle Evans 933*f0865ec9SKyle EvansIn any case, if the user forgot to provide important preprocessing flags whenever they are necessary, **errors will be thrown** during 934*f0865ec9SKyle Evansthe compilation process. As explained in [include/libecc/words/types.h](include/libecc/words/types.h), when `stdint.h` is not used (i.e. `WITH_STDLIB` 935*f0865ec9SKyle Evansnot defined), heuristics are used to guess primitive types sizes. These heuristics can fail and the user will have to adapt the types 936*f0865ec9SKyle Evansdefinitions accordingly depending on the platform. 937*f0865ec9SKyle Evans 938*f0865ec9SKyle Evans#### <a name="overloading-makefile-variables"></a> 4 - Overloading Makefile variables 939*f0865ec9SKyle Evans 940*f0865ec9SKyle EvansWhen compiling using compilers that are not compatible with the gcc syntax, but still using a GNU make 941*f0865ec9SKyle Evanscompilation environment, it is possible to **adpat the Makefile behavior**. In addition to the `LIBECC_NOSTDLIB=1` 942*f0865ec9SKyle Evansenvironment variable previously described, here is the list of the variables that tune the compilation process: 943*f0865ec9SKyle Evans 944*f0865ec9SKyle Evans* `CC`: as usual, this overloads the compiler to be used. 945*f0865ec9SKyle Evans* `CFLAGS` and `LDFLAGS`: these flags can be overloaded by user defined ones. The user defined flags will completely 946*f0865ec9SKyle Evansshadow the default flags for both the static libraries (libarith.a, libec.a, libsign.a) and the produced binaries. 947*f0865ec9SKyle Evans* `LIB_CFLAGS`, `BIN_CFLAGS`, `BIN_LDFLAGS`: when one wants to specifically tune compilation and linking flags for 948*f0865ec9SKyle Evansthe static libraries and the binaries, these flags can be used and they will shadow the `CFLAGS` and `LDFLAGS`. 949*f0865ec9SKyle Evans* `AR` and `RANLIB`: these flags override the ar and ranlib tools used to generate the static library archives. 950*f0865ec9SKyle Evans 951*f0865ec9SKyle EvansAs a simple example of when and how to use this environment variables overloading system, let's take the following case: 952*f0865ec9SKyle Evansone wants to compile libecc with an old version of gcc that does not support the `-fstack-protector-strong` option 953*f0865ec9SKyle Evans(this is the case for [gcc < 4.9](https://lwn.net/Articles/584225/)). Since this is the flag used by default in 954*f0865ec9SKyle Evanslibecc Makefile, an error will be triggered. It is possible to overcome this issue by overloading the `CFLAGS` with 955*f0865ec9SKyle Evansthe following: 956*f0865ec9SKyle Evans<pre> 957*f0865ec9SKyle Evans $ CFLAGS="-W -Werror -Wextra -Wall -Wunreachable-code -pedantic -fno-builtin -std=c99 -D_FORTIFY_SOURCE=2 \ 958*f0865ec9SKyle Evans -fstack-protector-all -O3 -DWITH_STDLIB -fPIC" make 959*f0865ec9SKyle Evans</pre> 960*f0865ec9SKyle Evans 961*f0865ec9SKyle EvansAs we can see, we keep the other `CFLAGS` from default compilation while replacing `-fstack-protector-strong` with 962*f0865ec9SKyle Evansthe **less efficient but more compatible** `-fstack-protector-all`. 963*f0865ec9SKyle Evans 964*f0865ec9SKyle EvansIn addition to compilation flags, it is also possible to overload the library **word sizes** as well as **debug** 965*f0865ec9SKyle Evansmodes through Makefile targets: 966*f0865ec9SKyle Evans* `make debug` will compile a debug version of the library and binaries, with debugging symbols. 967*f0865ec9SKyle EvansSetting the environment variable `VERBOSE_INNER_VALUES=1` will print out more values. 968*f0865ec9SKyle Evans* `make 16`, `make 32` and `make 64` will respectively compile the library with 16, 32 and 64 bits word sizes. `make debug16`, 969*f0865ec9SKyle Evans`make debug32` and `make debug64` will compile the debug versions of these. 970*f0865ec9SKyle Evans* `make force_arch32` and `make force_arch64` will force 32-bit and 64-bit architectures compilation (`-m32` and `-m64` 971*f0865ec9SKyle Evansflags under gcc). These targets allow cross-compilation for a 32-bit (respectively 64-bit) target under a 64-bit (respectively 972*f0865ec9SKyle Evans32-bit) host: a typical example is compiling for i386 under x86\_64. 973*f0865ec9SKyle Evans 974*f0865ec9SKyle Evans**NOTE**: the targets that we have described here can be used in conjunction with overloading the `CFLAGS` and `LDFLAGS`. Hence, 975*f0865ec9SKyle Evansa: `CFLAGS="-fstack-protector-all" make debug16` 976*f0865ec9SKyle Evanswill indeed compile all the binaries for debug, with a word size of 16 bits and a `-fstack-protector-all` stack protection option. 977*f0865ec9SKyle Evans 978*f0865ec9SKyle Evans 979*f0865ec9SKyle Evans#### 5 - A concrete example with SDCC 980*f0865ec9SKyle Evans 981*f0865ec9SKyle EvansAs an example to show how to adapt the compilation process to compilers that are not compatible with the 982*f0865ec9SKyle EvansGNU compilers syntax, we will detail how to proceed by exploring the [SDCC](http://sdcc.sourceforge.net/) 983*f0865ec9SKyle Evans(Small Device C Compiler) toolchain. Porting libecc to this compiler is interesting for many reasons: 984*f0865ec9SKyle Evans 985*f0865ec9SKyle Evans* The SDCC compiler uses some specific syntax, though it shares some similarities with 986*f0865ec9SKyle Evansother compilers (`-c` flag to generate object files, `-o` flag to define output file). 987*f0865ec9SKyle Evans* This compiler is "almost" C99 compliant: depending on the target, it has some C99 features 988*f0865ec9SKyle Evans[partially implemented](http://sdcc.sourceforge.net/mediawiki/index.php/Standard_compliance). 989*f0865ec9SKyle Evans* The compiler has "exotic" targets such as the Zilog Z80 MCU. 990*f0865ec9SKyle Evans 991*f0865ec9SKyle EvansWe suppose that the user has also provided the **external dependencies** for print, random and time 992*f0865ec9SKyle Evansfunctions (otherwise explicit errors will be thrown by #error directives). 993*f0865ec9SKyle Evans 994*f0865ec9SKyle EvansWe will show how overloading the Makefile flags can be of use in this case. Say that we want 995*f0865ec9SKyle Evansto compile libecc in order to embed it in a Game Boy ROM. The Game Boy console uses a proprietary 996*f0865ec9SKyle Evansversion of the Z80 MCU supported by SDCC under the target name `gbz80`. 997*f0865ec9SKyle Evans 998*f0865ec9SKyle EvansHence, a first attempt at compilation would be to: 999*f0865ec9SKyle Evans* Overload `CC=sdcc` to change the default compiler. 1000*f0865ec9SKyle Evans* Overload `AR=sdar` and `RANLIB=sdranlib` to overload the archives handling binaries (they are specific 1001*f0865ec9SKyle Evansto SDCC). 1002*f0865ec9SKyle Evans* Overload `CFLAGS="-mbgz80 --std-sdcc99"` to specify the target, and ask for the C99 compatibility mode. 1003*f0865ec9SKyle Evans* Overload `LDFLAGS=" "` with nothing since we do not want default gcc linking flags to break compilation. 1004*f0865ec9SKyle Evans 1005*f0865ec9SKyle EvansThis first attempt will trigger an error: 1006*f0865ec9SKyle Evans<pre> 1007*f0865ec9SKyle Evans $ CC=sdcc AR=sdar RANLIB=sdranlib CFLAGS="-mgbz80 --std-sdcc99" LDFLAGS=" " make 1008*f0865ec9SKyle Evans ... 1009*f0865ec9SKyle Evans src/external_deps/../words/words.h:62:2: error: #error "Unrecognized platform. \ 1010*f0865ec9SKyle Evans Please specify the word size of your target (with make 16, make 32, make 64)" 1011*f0865ec9SKyle Evans</pre> 1012*f0865ec9SKyle Evans 1013*f0865ec9SKyle EvansAs we have explained, when the platform is not recognized one has to specify the word size. We will 1014*f0865ec9SKyle Evansdo it by overloading `WORDSIZE=16`: the Z80 is an 8-bit CPU, so it seems reasonable to fit the word 1015*f0865ec9SKyle Evanssize to 16-bit (8-bit half words). The second attempt will go further but will fail at some point when 1016*f0865ec9SKyle Evanstrying to compile the final binaries: 1017*f0865ec9SKyle Evans<pre> 1018*f0865ec9SKyle Evans $ CC=sdcc AR=sdar RANLIB=sdranlib CFLAGS="-mgbz80 --std-sdcc99 -DWORDSIZE=16" LDFLAGS=" " make 1019*f0865ec9SKyle Evans ... 1020*f0865ec9SKyle Evans at 1: error 119: don't know what to do with file 'src/tests/ec_self_tests_core.o'. file extension unsupported 1021*f0865ec9SKyle Evans</pre> 1022*f0865ec9SKyle Evans 1023*f0865ec9SKyle EvansHowever, one can notice that the static libraries and some object files have been compiled, which is a 1024*f0865ec9SKyle Evansfirst step! Compiling a full binary is a bit technical due to the fact that SDCC does not know how 1025*f0865ec9SKyle Evansto deal with '.o' object files and '.a' archives. However, we can find our way out of this by renaming 1026*f0865ec9SKyle Evansthe 'libsign.a' to 'libsign.lib', and adding missing objects in the library. Compiling the `ec_self_tests` 1027*f0865ec9SKyle Evansbinary needs external dependencies ([src/external_deps/print.c](src/external_deps/print.c), 1028*f0865ec9SKyle Evans[src/external_deps/rand.c](src/external_deps/rand.c) and [src/external_deps/time.c](src/external_deps/time.c)) 1029*f0865ec9SKyle Evansas well as the two '.c' files [src/tests/ec_self_tests_core.c](src/tests/ec_self_tests_core.c) and 1030*f0865ec9SKyle Evans[src/tests/ec_self_tests.c](src/tests/ec_self_tests.c), the latter being the one containing the `main` 1031*f0865ec9SKyle Evansfunction. So we will first add the necessary objects files in the existing library with `sdar`: 1032*f0865ec9SKyle Evans<pre> 1033*f0865ec9SKyle Evans $ cp build/libsign.a build/libsign.lib 1034*f0865ec9SKyle Evans $ sdar q build/libsign.lib src/external_deps/print.o src/external_deps/rand.o src/external_deps/time.o src/tests/ec_self_tests_core.o 1035*f0865ec9SKyle Evans</pre> 1036*f0865ec9SKyle Evans 1037*f0865ec9SKyle EvansThen, we compile and link [src/tests/ec_self_tests.c](src/tests/ec_self_tests.c) with the library: 1038*f0865ec9SKyle Evans<pre> 1039*f0865ec9SKyle Evans $ sdcc -mgbz80 -DWORDSIZE=16 --std-sdcc99 src/tests/ec_self_tests.c build/libsign.lib 1040*f0865ec9SKyle Evans</pre> 1041*f0865ec9SKyle Evans 1042*f0865ec9SKyle EvansThis should create a `ec_self_tests.ihx`, which has an [Intel HEX](https://fr.wikipedia.org/wiki/HEX_(Intel)) 1043*f0865ec9SKyle Evansfile format for firmware programming. From this file, it is usually straightforward to create a Game Boy ROM file 1044*f0865ec9SKyle Evansthat can be interpreted by an [emulator](http://m.peponas.free.fr/gngb/) (there are however some quirks related 1045*f0865ec9SKyle Evansto the Game Boy platform hardware architecture, see the note below). 1046*f0865ec9SKyle Evans 1047*f0865ec9SKyle Evans**NOTE**: the purpose of the section was to show how to adapt the compilation process to compilers non 1048*f0865ec9SKyle Evanscompatible with the GNU C one. Consequently, fully porting libecc to the Game Boy platform is left as 1049*f0865ec9SKyle Evansa complementary work, and this is not a "so easy" task. Among other things, one will have to deal with 1050*f0865ec9SKyle Evansthe ROM size limitation of 32KB that can be solved using [bank switching](http://gbdev.gg8.se/wiki/articles/Memory_Bank_Controllers), 1051*f0865ec9SKyle Evanswhich will involve some code and compilation tuning. Another issue would be the RAM size of 8KB and 1052*f0865ec9SKyle Evansproperly handling the stack pointer base as described in the [previous sections](#compiling-libecc-for-arm-cortex-m-with-GNU-gcc-arm). 1053*f0865ec9SKyle Evans 1054*f0865ec9SKyle Evans## libecc, side channel attacks and constant time 1055*f0865ec9SKyle Evans 1056*f0865ec9SKyle Evans### Constant time 1057*f0865ec9SKyle Evans 1058*f0865ec9SKyle EvansThough **some efforts** have been made to have (most of) the core algorithms 1059*f0865ec9SKyle Evansconstant time, turning libecc into a library shielded against side channel attacks 1060*f0865ec9SKyle Evansis still a **work in progress**. 1061*f0865ec9SKyle Evans 1062*f0865ec9SKyle EvansBeyond pure algorithmic considerations, many aspects of a program can turn 1063*f0865ec9SKyle Evanssecret leakage resistance into a very complex problem, especially when writing 1064*f0865ec9SKyle Evansportable C code. Among other things, we can list the following: 1065*f0865ec9SKyle Evans 1066*f0865ec9SKyle Evans* Low level issues can arise when dealing with heterogeneous platforms (some 1067*f0865ec9SKyle Evansinstructions might not be constant time) and compilers optimizations 1068*f0865ec9SKyle Evans(a C code that seems constant time is in fact compiled to a non constant time assembly). 1069*f0865ec9SKyle Evans* Any shared hardware resource can become a leakage source (the caches, the 1070*f0865ec9SKyle Evansbranch prediction unit, ...). When dealing with a portable source code 1071*f0865ec9SKyle Evansmeant to run on most platforms, it is not an easy task to think of all these 1072*f0865ec9SKyle Evansleakage sources. 1073*f0865ec9SKyle Evans 1074*f0865ec9SKyle EvansFor a thorough discussion about cryptography and constant time challenges, 1075*f0865ec9SKyle Evansone can check [this page](https://bearssl.org/constanttime.html). 1076*f0865ec9SKyle Evans 1077*f0865ec9SKyle Evans### Signature algorithm blinding 1078*f0865ec9SKyle Evans 1079*f0865ec9SKyle EvansIn order to avoid a range of attacks on the signature algorithm exploiting various 1080*f0865ec9SKyle Evansside channel attacks and leading to the recovery of the secret key 1081*f0865ec9SKyle Evans(see [here](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2018/rohnp-return-of-the-hidden-number-problem.pdf) 1082*f0865ec9SKyle Evansfor more details), **blinding** operations can be used. 1083*f0865ec9SKyle Evans 1084*f0865ec9SKyle EvansSince such security countermeasures have a **significant performance hit** on the signature algorithm, we have 1085*f0865ec9SKyle Evansdecided to leave the activation of such countermeasures as a **voluntary decision** to the end user. 1086*f0865ec9SKyle EvansThe performance impact might be acceptable or not depending on the context where the signature is performed, and whether attackers exploiting side channels 1087*f0865ec9SKyle Evansare indeed considered in the threat model of the specific use case. 1088*f0865ec9SKyle EvansOf course, for **security critical use cases we recommend the blinding usage 1089*f0865ec9SKyle Evansdespite its performance cost**. 1090*f0865ec9SKyle Evans 1091*f0865ec9SKyle EvansCompiling the library with blinding is as simple as using the ``BLINDIG=1`` environment variable (or the ``-DUSE_SIG_BLINDING`` C flag): 1092*f0865ec9SKyle Evans 1093*f0865ec9SKyle Evans<pre> 1094*f0865ec9SKyle Evans $ BLINDING=1 make 1095*f0865ec9SKyle Evans</pre> 1096*f0865ec9SKyle Evans 1097*f0865ec9SKyle Evans**NOTE**: if you are **unsure** about your current security context, use the ``BLINDING=1`` by default! 1098*f0865ec9SKyle Evans 1099*f0865ec9SKyle Evans 1100*f0865ec9SKyle Evans### Overview of SCA (Side Channel Attacks) countermeasures 1101*f0865ec9SKyle Evans 1102*f0865ec9SKyle EvansAll in all, libecc has now the following approaches to limit SCA: 1103*f0865ec9SKyle Evans 1104*f0865ec9SKyle Evans* SPA (Simple Power Analysis) is thwarted using Montgomery Ladder (or Double and Add Always optionally using the ``ADALWAYS=1`` switch), plus complete formulas 1105*f0865ec9SKyle Evans(see [here](https://joostrenes.nl/publications/complete.pdf)) to avoid leaking point at infinity (by avoiding exceptions). Constant time 1106*f0865ec9SKyle Evansoperations are (tentatively) used to limit leakage of different operations, 1107*f0865ec9SKyle Evanseven though this task is very complex to achieve (especially in pure C). See 1108*f0865ec9SKyle Evansthe discussion above. 1109*f0865ec9SKyle Evans* DDPA (Data DPA) is thwarted using blinding of the point (projective 1110*f0865ec9SKyle Evanscoordinates) and of the scalar (with adding a random multiple of the 1111*f0865ec9SKyle Evanscurve order with maximum entropy). Because of its major impact on 1112*f0865ec9SKyle Evansperformance, blinding must be specifically turned on by the used using the 1113*f0865ec9SKyle Evans``BLINDING=1`` switch, see the discussion above. 1114*f0865ec9SKyle Evans* ADPA (Address-bit DPA) is limited using Itoh et al. Double and Add Always 1115*f0865ec9SKyle Evansmasked variant. See the article "A Practical Countermeasure against 1116*f0865ec9SKyle EvansAddress-Bit Differential Power Analysis" by Itoh, Izu and Takenaka for more information. 1117*f0865ec9SKyle Evans 1118*f0865ec9SKyle EvansAll these countermeasures must, of course, be validated on the specific target 1119*f0865ec9SKyle Evanswhere the library runs with leakage assessments. Because of the very nature of 1120*f0865ec9SKyle EvansC code and CPU microarchitectural details, it is very complex without such a leakage 1121*f0865ec9SKyle Evansassessment (that again depends on the target) to be sure that SCA protection 1122*f0865ec9SKyle Evansis indeed efficient. 1123*f0865ec9SKyle Evans 1124*f0865ec9SKyle Evans### libecc against FIA (Fault Injection Attacks) 1125*f0865ec9SKyle Evans 1126*f0865ec9SKyle EvansEfforts made to render libecc robust against FIA are a **work in progress**, and 1127*f0865ec9SKyle Evanswill require **substantial additions**. As for SCA robustness, many elements 1128*f0865ec9SKyle Evansmight depend on the low-level compilation process and are difficult to handle 1129*f0865ec9SKyle Evansat high-level in pure C. 1130*f0865ec9SKyle Evans 1131*f0865ec9SKyle EvansFor now, we check if points are on the curve when entering and leaving the 1132*f0865ec9SKyle Evansscalar multiplication algorithm, as well as when importing external public points. 1133*f0865ec9SKyle EvansEfforts are also made to sanity check the signature and verification contexts whenever possible, 1134*f0865ec9SKyle Evansas well as all the intermediate contexts (natural numbers, fields, hash functions, etc.). 1135*f0865ec9SKyle Evans 1136*f0865ec9SKyle EvansCurrently, no specific effort has been made to render conditional operations robust 1137*f0865ec9SKyle Evans(e.g. using double if and limiting compilation optimization). 1138*f0865ec9SKyle Evans 1139*f0865ec9SKyle Evans 1140*f0865ec9SKyle Evans## Software architecture 1141*f0865ec9SKyle Evans 1142*f0865ec9SKyle EvansThe public header of the libecc API are in the [include/libecc/](include/libecc/) 1143*f0865ec9SKyle Evansfolder. Then, the source code is composed of eight main parts that consist of the 1144*f0865ec9SKyle Evans**core source code**: 1145*f0865ec9SKyle Evans 1146*f0865ec9SKyle Evans * [1] Machine code: in [src/words](src/words/) 1147*f0865ec9SKyle Evans 1148*f0865ec9SKyle Evans >Abstraction layer to handle word size depending 1149*f0865ec9SKyle Evans >on the target machine (the word size can also be forced during 1150*f0865ec9SKyle Evans >compilation). Some useful low level macros and functions are 1151*f0865ec9SKyle Evans >handled there. 1152*f0865ec9SKyle Evans 1153*f0865ec9SKyle Evans * [2] Natural Numbers layer: in [src/nn](src/nn/) 1154*f0865ec9SKyle Evans 1155*f0865ec9SKyle Evans >This part implements all the functions 1156*f0865ec9SKyle Evans >related to positive integers arithmetic (including modular 1157*f0865ec9SKyle Evans >arithmetic). 1158*f0865ec9SKyle Evans 1159*f0865ec9SKyle Evans * [3] Fp layer: in [src/fp](src/fp/) 1160*f0865ec9SKyle Evans 1161*f0865ec9SKyle Evans >Finite field of prime order (binary fields are 1162*f0865ec9SKyle Evans >intentionally not supported). 1163*f0865ec9SKyle Evans 1164*f0865ec9SKyle Evans * [4] Elliptic curves core: in [src/curves](src/curves/) 1165*f0865ec9SKyle Evans 1166*f0865ec9SKyle Evans >This layer implements all the primitives 1167*f0865ec9SKyle Evans >handling elliptic curves over prime fields, including point 1168*f0865ec9SKyle Evans >addition and doubling, affine and projective coordinates, ... 1169*f0865ec9SKyle Evans 1170*f0865ec9SKyle Evans * [5] Curves definitions: in [include/libecc/curves/known](include/libecc/curves/known) and 1171*f0865ec9SKyle Evans [include/libecc/curves/user_defined](include/libecc/curves/user_defined) 1172*f0865ec9SKyle Evans 1173*f0865ec9SKyle Evans >These are the definitions of some standard curves (SECP, Brainpool, 1174*f0865ec9SKyle Evans >FRP, ...). 1175*f0865ec9SKyle Evans 1176*f0865ec9SKyle Evans * [6] EC\*DSA signature algorithms: in [src/sig](src/sig/) 1177*f0865ec9SKyle Evans 1178*f0865ec9SKyle Evans >This layer implements the main 1179*f0865ec9SKyle Evans >elliptic curves based signature algorithms (ECSDSA, ECKCDSA, 1180*f0865ec9SKyle Evans >ECFSDSA, ECGDSA, ECRDSA, ECOSDSA). It exposes a sign and 1181*f0865ec9SKyle Evans >verify API with the standard Init/Update/Final logic. 1182*f0865ec9SKyle Evans 1183*f0865ec9SKyle Evans * [7] Hash functions: in [src/hash](src/hash/) 1184*f0865ec9SKyle Evans 1185*f0865ec9SKyle Evans >Hash functions (SHA-2 and SHA-3 based algorithms 1186*f0865ec9SKyle Evans >for now). 1187*f0865ec9SKyle Evans 1188*f0865ec9SKyle Evans * [8] Utils: in [src/utils](src/utils/) 1189*f0865ec9SKyle Evans 1190*f0865ec9SKyle Evans >Various useful libc functions (memcpy, memset, ...) as well as 1191*f0865ec9SKyle Evans >well as pretty printing functions for our NN, Fp and curves layers. 1192*f0865ec9SKyle Evans 1193*f0865ec9SKyle EvansIn addition to the core source code of the library, various resources 1194*f0865ec9SKyle Evansare also present in the source tree. We describe them hereafter. 1195*f0865ec9SKyle Evans 1196*f0865ec9SKyle EvansSome self tests are provided for the signature algorithms over all the curves 1197*f0865ec9SKyle Evansand using all the hash functions [9], as well as tests targeting arithmetic 1198*f0865ec9SKyle Evansoperations over NN and Fp more specifically [10]: 1199*f0865ec9SKyle Evans 1200*f0865ec9SKyle Evans * [9] Sig self tests: in [src/tests](src/tests/) 1201*f0865ec9SKyle Evans 1202*f0865ec9SKyle Evans >Functions to test that the compiled library is 1203*f0865ec9SKyle Evans >properly working with regard to the signature algorithms over 1204*f0865ec9SKyle Evans >the curves statically defined in the library. 1205*f0865ec9SKyle Evans >These tests consiste in known test vectors, random test 1206*f0865ec9SKyle Evans >vectors (i.e. random data sign/verify) as well as performance measurements. 1207*f0865ec9SKyle Evans 1208*f0865ec9SKyle Evans * [10] Arithmetic self tests: in [src/arithmetic](src/arithmetic_tests/) 1209*f0865ec9SKyle Evans 1210*f0865ec9SKyle Evans >Functions to test that the compiled arithmetic library is 1211*f0865ec9SKyle Evans >properly working in its basic operations (addition, subtraction, 1212*f0865ec9SKyle Evans >multiplication, ...). 1213*f0865ec9SKyle Evans 1214*f0865ec9SKyle EvansSome examples to help the user interact with the NN, Fp and cruves layers 1215*f0865ec9SKyle Evansare also provided: 1216*f0865ec9SKyle Evans 1217*f0865ec9SKyle Evans * [11] User examples: in [src/examples](src/examples/) 1218*f0865ec9SKyle Evans 1219*f0865ec9SKyle Evans >User examples for each of the NN, Fp and curves layers. These 1220*f0865ec9SKyle Evans >examples show what are headers to use, and how to interact with 1221*f0865ec9SKyle Evans >the abstract mathematical objects of each layer. Other examples beyond 1222*f0865ec9SKyle Evans >the basic ones (such as RSA signatures, SSS, etc.) are also present there. 1223*f0865ec9SKyle Evans 1224*f0865ec9SKyle EvansThe configuration of the library [13] as well as an external dependencies 1225*f0865ec9SKyle Evansabstraction layer are also provided: 1226*f0865ec9SKyle Evans 1227*f0865ec9SKyle Evans * [12] External dependencies: in [src/external_deps](src/external_deps/) 1228*f0865ec9SKyle Evans 1229*f0865ec9SKyle Evans >These files contain the functions that 1230*f0865ec9SKyle Evans >are considered as external dependencies, meaning that their 1231*f0865ec9SKyle Evans >implementation is platform dependent (this concerns debug 1232*f0865ec9SKyle Evans >output on a console or file, random generation, time measurement). 1233*f0865ec9SKyle Evans >If no C standard library is provided, the user must implement 1234*f0865ec9SKyle Evans >those functions. 1235*f0865ec9SKyle Evans 1236*f0865ec9SKyle Evans * [13] Configuration files: in [include/libecc/lib_ecc_config.h](include/libecc/lib_ecc_config.h) 1237*f0865ec9SKyle Evans 1238*f0865ec9SKyle Evans >These are top C headers that are used for 1239*f0865ec9SKyle Evans >libecc configuration, i.e. activate given hash/curve/signature 1240*f0865ec9SKyle Evans >algorithms at compilation time through ifdefs. 1241*f0865ec9SKyle Evans 1242*f0865ec9SKyle EvansFinally, various useful scripts are provided: 1243*f0865ec9SKyle Evans 1244*f0865ec9SKyle Evans * [14] Scripts: in [scripts](scripts/) 1245*f0865ec9SKyle Evans 1246*f0865ec9SKyle Evans >Tools to expand the libecc with new user defined curves. 1247*f0865ec9SKyle Evans 1248*f0865ec9SKyle EvansHere is a big picture of the library architecture summarizing the links 1249*f0865ec9SKyle Evansbetween the modules previously described: 1250*f0865ec9SKyle Evans 1251*f0865ec9SKyle Evans<pre> 1252*f0865ec9SKyle Evans +-------------------------+ 1253*f0865ec9SKyle Evans |EC*DSA signature | 1254*f0865ec9SKyle Evans |algorithms | <------------------+ 1255*f0865ec9SKyle Evans |(ISO 14888-3) [6] | | 1256*f0865ec9SKyle Evans +-----------+-------------+ | 1257*f0865ec9SKyle Evans ^ | 1258*f0865ec9SKyle Evans | | 1259*f0865ec9SKyle Evans +-----------+-------------+ +----------+------------+ 1260*f0865ec9SKyle Evans |Curves (SECP, Brainpool, | | Hash | 1261*f0865ec9SKyle Evans |FRP, ...) | | functions | 1262*f0865ec9SKyle Evans | [5] | | [7] | 1263*f0865ec9SKyle Evans +-----------+-------------+ +-----------------------+ 1264*f0865ec9SKyle Evans ^ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1265*f0865ec9SKyle Evans | @ {Useful auxiliary modules}@ 1266*f0865ec9SKyle Evans +-----------+-------------+ @ +------------------------+@ 1267*f0865ec9SKyle Evans | Elliptic curves [4] | @ | Utils [8] |@ 1268*f0865ec9SKyle Evans | core (scalar mul, ...) | @ +------------------------+@ 1269*f0865ec9SKyle Evans +-----------+-------------+ @ | Sig Self tests [9] |@ 1270*f0865ec9SKyle Evans ^ @ | Arith Self tests [10] |@ 1271*f0865ec9SKyle Evans | @ | User Examples [11] |@ 1272*f0865ec9SKyle Evans | @ +------------------------+@ 1273*f0865ec9SKyle Evans | @ | External deps [12] |@ 1274*f0865ec9SKyle Evans +-----------+-------------+ @ +------------------------+@ 1275*f0865ec9SKyle Evans | Fp finite fields [3] | @ | LibECC conf files [13] |@ 1276*f0865ec9SKyle Evans | arithmetic | @ +------------------------+@ 1277*f0865ec9SKyle Evans +-----------+-------------+ @ | Scripts [14] |@ 1278*f0865ec9SKyle Evans ^ @ +------------------------+@ 1279*f0865ec9SKyle Evans | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1280*f0865ec9SKyle Evans +-----------+-------------+ +------------------------+ 1281*f0865ec9SKyle Evans | NN natural [2] | <------+ Machine related | 1282*f0865ec9SKyle Evans | numbers arithmetic | | (words, ...) [1] | 1283*f0865ec9SKyle Evans +-------------------------+ +------------------------+ 1284*f0865ec9SKyle Evans 1285*f0865ec9SKyle Evans</pre> 1286*f0865ec9SKyle Evans 1287*f0865ec9SKyle Evans## Integration with hardware acceleration: IPECC 1288*f0865ec9SKyle Evans 1289*f0865ec9SKyle EvansOn the IPECC branch of the libecc repository, there is an integration 1290*f0865ec9SKyle Evanswith the [IPECC](https://github.com/ANSSI-FR/IPECC) hardware accelerator 1291*f0865ec9SKyle Evansproject. This project provides hardware acceleration for ECC points operations 1292*f0865ec9SKyle Evans(addition, doubling, scalar multiplication, etc.) with advanced SCA countermeasures. 1293*f0865ec9SKyle Evans 1294*f0865ec9SKyle EvansIn order to use this accelerator, please follow these steps. First checkout the 1295*f0865ec9SKyle EvansIPECC branch: 1296*f0865ec9SKyle Evans 1297*f0865ec9SKyle Evans<pre> 1298*f0865ec9SKyle Evans $ git clone https://github.com/libecc/libecc 1299*f0865ec9SKyle Evans $ git checkout -b IPECC 1300*f0865ec9SKyle Evans</pre> 1301*f0865ec9SKyle Evans 1302*f0865ec9SKyle EvansThen fetch the dedicated driver on the [IPECC repository](https://github.com/ANSSI-FR/IPECC) 1303*f0865ec9SKyle Evans(this will clone the current repository and place the IPECC drivers in the `src/curve` folder): 1304*f0865ec9SKyle Evans 1305*f0865ec9SKyle Evans<pre> 1306*f0865ec9SKyle Evans $ make install_hw_driver 1307*f0865ec9SKyle Evans</pre> 1308*f0865ec9SKyle Evans 1309*f0865ec9SKyle EvansThen, you can compile the library with hardware acceleration by selecting the underlying platform: 1310*f0865ec9SKyle Evans 1311*f0865ec9SKyle Evans<pre> 1312*f0865ec9SKyle Evans $ make clean && CC=arm-linux-gnueabihf-gcc EXTRA_CFLAGS="-Wall -Wextra -O3 -g3 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -static" VERBOSE=1 USE_EC_HW=1 USE_EC_HW_DEVMEM=1 USE_EC_HW_LOCKING=1 BLINDING=1 make 1313*f0865ec9SKyle Evans</pre> 1314*f0865ec9SKyle Evans 1315*f0865ec9SKyle EvansPlease note that `USE_EC_HW=1` selects the hardware accelerator (this is mandatory to activate the hardware acceleration backend in libecc), 1316*f0865ec9SKyle Evansand `USE_EC_HW_DEVMEM=1` selects the DEVMEM backend (you can use `USE_EC_HW_STANDALONE=1` for the standalone mode, `USE_EC_HW_UIO=1` for UIO, 1317*f0865ec9SKyle Evansand `USE_EC_HW_SOCKET_EMUL=1` for the socket emulation using the Python server). 1318*f0865ec9SKyle EvansWe also override the `CC` compiler to `arm-linux-gnueabihf-gcc` for the Zynq platform (adapt at your will depending on your 1319*f0865ec9SKyle Evanstarget), and add some necessary extra CFLAGS for the platform (as well as a `-static` binary compilation to avoid library dependency issues). 1320*f0865ec9SKyle EvansFinally, `USE_EC_HW_LOCKING=1` is used here for thread safety during hardware access: this flag is necessary for multi-threading. 1321*f0865ec9SKyle Evans 1322*f0865ec9SKyle Evanslibecc has been successfully tested on a [Zynq Arty Z7](https://digilent.com/reference/programmable-logic/arty-z7/start) board with 1323*f0865ec9SKyle Evansa **factor 6** performance improvement compared to pure software on the same platform (with SCA countermeasures): 1324*f0865ec9SKyle Evans 1325*f0865ec9SKyle Evans<pre> 1326*f0865ec9SKyle Evansaz7-ecc-axi:/home/petalinux# ./ec_self_tests_sw perf 1327*f0865ec9SKyle Evans======= Performance test ======================== 1328*f0865ec9SKyle Evans[+] ECDSA-SHA224/FRP256V1 perf: 6 sign/s and 6 verif/s 1329*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP192R1 perf: 9 sign/s and 9 verif/s 1330*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP224R1 perf: 7 sign/s and 7 verif/s 1331*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP256R1 perf: 6 sign/s and 6 verif/s 1332*f0865ec9SKyle Evans... 1333*f0865ec9SKyle Evans 1334*f0865ec9SKyle Evansaz7-ecc-axi:/home/petalinux# ./ec_self_tests_hw perf 1335*f0865ec9SKyle Evans======= Performance test ======================== 1336*f0865ec9SKyle Evans[+] ECDSA-SHA224/FRP256V1 perf: 34 sign/s and 32 verif/s 1337*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP192R1 perf: 57 sign/s and 52 verif/s 1338*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP224R1 perf: 44 sign/s and 39 verif/s 1339*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP256R1 perf: 34 sign/s and 32 verif/s 1340*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP384R1 perf: 16 sign/s and 15 verif/s 1341*f0865ec9SKyle Evans[+] ECDSA-SHA224/SECP521R1 perf: 8 sign/s and 8 verif/s 1342*f0865ec9SKyle Evans[+] ECDSA-SHA224/BRAINPOOLP192R1 perf: 57 sign/s and 52 verif/s 1343*f0865ec9SKyle Evans[+] ECDSA-SHA224/BRAINPOOLP224R1 perf: 44 sign/s and 40 verif/s 1344*f0865ec9SKyle Evans</pre> 1345*f0865ec9SKyle Evans 1346