xref: /freebsd/crypto/libecc/README.md (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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&lowbar;miller&lowbar;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&lowbar;pollard&lowbar;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&lowbar;square&lowbar;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&lowbar;basic&lowbar;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&lowbar;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&lowbar;tests/](src/arithmetic_tests/) folder. More specifically, the tests
352*f0865ec9SKyle Evansare split in two files:
353*f0865ec9SKyle Evans
354*f0865ec9SKyle Evans* [src/arithmetic&lowbar;tests/arithmetic&lowbar;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&lowbar;tests/arithmetic&lowbar;tests&lowbar;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&lowbar;ecc&lowbar;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&lowbar;ecc&lowbar;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&lowbar;ecc&lowbar;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&lowbar;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&lowbar;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&lowbar;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&lowbar;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&lowbar;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&lowbar;params&lowbar;user&lowbar;defined&lowbar;mynewcurve.h' in the [include/libecc/curves/user&lowbar;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&lowbar;list.h](include/libecc/curves/curves_list.h), [src/tests/ec&lowbar;self&lowbar;tests&lowbar;core.h](src/tests/ec_self_tests_core.h),
519*f0865ec9SKyle Evans[include/libecc/lib&lowbar;ecc&lowbar;config.h](include/libecc/lib_ecc_config.h) and [include/libecc/lib&lowbar;ecc&lowbar;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&lowbar;curves&lowbar;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&lowbar;openssl&lowbar;curves&lowbar;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&lowbar;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&lowbar;ecc&lowbar;config.h](include/libecc/lib_ecc_config.h)
596*f0865ec9SKyle Evanswith the `WITH_MY_NEW_HASH` toggle ('my&lowbar;new&lowbar;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&lowbar;algs&lowbar;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&lowbar;ecc&lowbar;config.h](include/libecc/lib_ecc_config.h)
615*f0865ec9SKyle Evanswith the `WITH_MY_NEW_SIGN_ALG` toggle ('my&lowbar;new&lowbar;sign&lowbar;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&lowbar;deps/](src/external_deps), namely:
794*f0865ec9SKyle Evans  * The printing helper in [src/external&lowbar;deps/print.c](src/external_deps/print.c). This helper serves output debugging purposes.
795*f0865ec9SKyle Evans  * The timing helper in [src/external&lowbar;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&lowbar;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&lowbar;deps/print.c](src/external&lowbar;deps/print.c),
1028*f0865ec9SKyle Evans[src/external&lowbar;deps/rand.c](src/external_deps/rand.c) and [src/external&lowbar;deps/time.c](src/external_deps/time.c))
1029*f0865ec9SKyle Evansas well as the two '.c' files [src/tests/ec&lowbar;self&lowbar;tests&lowbar;core.c](src/tests/ec_self_tests_core.c) and
1030*f0865ec9SKyle Evans[src/tests/ec&lowbar;self&lowbar;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&lowbar;self&lowbar;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&lowbar;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&lowbar;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&lowbar;ecc&lowbar;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