/src/libecc/include/libecc/nn/nn_config.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2017 - This file is part of libecc project |
3 | | * |
4 | | * Authors: |
5 | | * Ryad BENADJILA <ryadbenadjila@gmail.com> |
6 | | * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> |
7 | | * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> |
8 | | * |
9 | | * Contributors: |
10 | | * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> |
11 | | * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> |
12 | | * |
13 | | * This software is licensed under a dual BSD and GPL v2 license. |
14 | | * See LICENSE file at the root folder of the project. |
15 | | */ |
16 | | #ifndef __NN_CONFIG_H__ |
17 | | #define __NN_CONFIG_H__ |
18 | | #include <libecc/words/words.h> |
19 | | /* |
20 | | * We include the curves list to adapt the maximum NN size to P and Q |
21 | | * (prime and order of the curve). |
22 | | */ |
23 | | #include <libecc/curves/curves_list.h> |
24 | | /* |
25 | | * We also include the hash layer to adapt the maximum NN size to the |
26 | | * maximum digest size as we have to import full digests as NN when dealing |
27 | | * with some signature algorithms. |
28 | | * |
29 | | */ |
30 | | #include <libecc/hash/hash_algs.h> |
31 | | |
32 | | /* |
33 | | * All the big num used in the lib are statically allocated. This constant |
34 | | * must be defined (here or during build) to provide an upper limit on the |
35 | | * size in bits of the numbers the instance of the lib you will build will |
36 | | * handle. Note that this value does not prevent the declaration and use |
37 | | * of smaller numbers. |
38 | | * |
39 | | * Rationale for the default value: the main purpose of the lirary is to |
40 | | * support for an ECC implementation. ATM, a forseeable upper limit for the |
41 | | * numbers that will be dealt with is 521 bits. |
42 | | * |
43 | | * However, the user is allowed to overload the maximum bit length of the |
44 | | * numbers through the USER_NN_BIT_LEN macro definition (see below). A |
45 | | * hard limit 'nn_max' for this size depends on the word size and verifies |
46 | | * the following equation (with w being the word size): |
47 | | * |
48 | | * floor((nn_max + w - 1) / w) * 3 = 255 |
49 | | * |
50 | | * This equation is explained by elements given below, and by the fact that |
51 | | * the length in words of our big numbers are encoded on an u8. This yields |
52 | | * in max sizes of around 5300 bits for 64-bit words, around 2650 bits for |
53 | | * 32-bit words, and around 1300 bits for 16-bit words. |
54 | | * |
55 | | * Among all the functions we have, some need to handle something which |
56 | | * can be seen as a double, so we need twice the amount of bit above. |
57 | | * This is typically the case when two numbers are multiplied. |
58 | | * But then you usually want to divide this product by another number |
59 | | * of the initial size which generically requires shifting by the |
60 | | * original sized, whence the factor 3 below. |
61 | | * |
62 | | * Additionally, all numbers we handled are expected to have a length which |
63 | | * is a multiple of the word size we support, i.e. 64/32/16 bits. Hence the |
64 | | * rounding. |
65 | | */ |
66 | | |
67 | | /* Macro to round a bit length size to a word size */ |
68 | | #define BIT_LEN_ROUNDING(x, w) ((((x) + (w) - 1) / (w)) * (w)) |
69 | | |
70 | | /* |
71 | | * Macro to round a bit length size of a NN value to a word size, and |
72 | | * to a size compatible with the arithmetic operations of the library |
73 | | * (usually 3 times the size of the input numbers, see explanations above). |
74 | | */ |
75 | 23.7G | #define MAX_BIT_LEN_ROUNDING(x, w) (((((x) + (w) - 1) / (w)) * (w)) * 3) |
76 | | |
77 | | #ifndef USER_NN_BIT_LEN |
78 | | /* |
79 | | * The user has not defined a specific bit length: we can infer our maximum |
80 | | * NN bit size from our curves. |
81 | | */ |
82 | | #ifndef NN_MAX_BIT_LEN |
83 | | #if CURVES_MAX_P_BIT_LEN >= CURVES_MAX_CURVE_ORDER_BIT_LEN |
84 | 23.7G | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(CURVES_MAX_P_BIT_LEN, WORD_BITS) |
85 | 17.2k | #define NN_MAX_BASE CURVES_MAX_P_BIT_LEN |
86 | | #else |
87 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(CURVES_MAX_CURVE_ORDER_BIT_LEN, WORD_BITS) |
88 | | #define NN_MAX_BASE CURVES_MAX_CURVE_ORDER_BIT_LEN |
89 | | #endif |
90 | | #endif |
91 | | /****************/ |
92 | | #else |
93 | | /* |
94 | | * If the USER_NN_BIT_LEN flag is defined by the user, we want to be sure that |
95 | | * we can also handle our curves, and we also want to round the size to the |
96 | | * words we have. |
97 | | */ |
98 | | #if CURVES_MAX_P_BIT_LEN >= CURVES_MAX_CURVE_ORDER_BIT_LEN |
99 | | #if USER_NN_BIT_LEN >= CURVES_MAX_P_BIT_LEN |
100 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(USER_NN_BIT_LEN, WORD_BITS) |
101 | | #define NN_MAX_BASE USER_NN_BIT_LEN |
102 | | #else |
103 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(CURVES_MAX_P_BIT_LEN, WORD_BITS) |
104 | | #define NN_MAX_BASE CURVES_MAX_P_BIT_LEN |
105 | | #endif |
106 | | #else |
107 | | #if USER_NN_BIT_LEN >= CURVES_MAX_CURVE_ORDER_BIT_LEN |
108 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(USER_NN_BIT_LEN, WORD_BITS) |
109 | | #define NN_MAX_BASE USER_NN_BIT_LEN |
110 | | #else |
111 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(CURVES_MAX_CURVE_ORDER_BIT_LEN, WORD_BITS) |
112 | | #define NN_MAX_BASE CURVES_MAX_CURVE_ORDER_BIT_LEN |
113 | | #endif |
114 | | #endif |
115 | | #endif |
116 | | |
117 | | /* Now adjust the maximum length with our maximum digest size as we |
118 | | * have to import full digests as big numbers in some signature algorithms. |
119 | | * |
120 | | * The division by 2 here is related to the fact that we usually import hash values |
121 | | * without performing much NN operations on them (immediately reducing them modulo q), so |
122 | | * it is safe to remove some additional space left for multiplications. |
123 | | */ |
124 | | #if NN_MAX_BIT_LEN < MAX_BIT_LEN_ROUNDING(((8 * MAX_DIGEST_SIZE) / 2), WORD_BITS) |
125 | | #undef NN_MAX_BIT_LEN |
126 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING(((8 * MAX_DIGEST_SIZE) / 2), WORD_BITS) |
127 | | #undef NN_MAX_BASE |
128 | | #define NN_MAX_BASE MAX_DIGEST_SIZE_BITS |
129 | | #endif |
130 | | /* |
131 | | * NOTE: the only exception to the rule above (i.e. immediately reducing hash sized |
132 | | * values modulo q) is when we use blinding and EdDSA and there might be not enough |
133 | | * room for our computations. This is actually *specific to EdDSA 25519* as EdDSA 448 |
134 | | * always uses SHAKE256 digest with 114 bytes hash output that has enough room for |
135 | | * computation when compared to the 448-bit size order of the curve. |
136 | | * |
137 | | * This is kind of ugly to have this specific case here, but |
138 | | * being too conservative always using the maximum size adapated to MAX_DIGEST_SIZE |
139 | | * sacrifices *ALL* the sognature performance only for the specific case of EdDSA 25519! |
140 | | * |
141 | | */ |
142 | | #if defined(WITH_SIG_EDDSA25519) && defined(USE_SIG_BLINDING) |
143 | | #if NN_MAX_BIT_LEN < MAX_BIT_LEN_ROUNDING((8 * SHA512_DIGEST_SIZE), WORD_BITS) |
144 | | #undef NN_MAX_BIT_LEN |
145 | | #define NN_MAX_BIT_LEN MAX_BIT_LEN_ROUNDING((8 * SHA512_DIGEST_SIZE), WORD_BITS) |
146 | | #undef NN_MAX_BASE |
147 | | #define NN_MAX_BASE MAX_DIGEST_SIZE_BITS |
148 | | #endif |
149 | | #endif /* defined(WITH_SIG_EDDSA25519) && defined(USE_SIG_BLINDING) */ |
150 | | |
151 | | /************/ |
152 | | /* NN maximum internal lengths to be "safe" in our computations */ |
153 | 23.7G | #define NN_MAX_BYTE_LEN (NN_MAX_BIT_LEN / 8) |
154 | 23.7G | #define NN_MAX_WORD_LEN (NN_MAX_BYTE_LEN / WORD_BYTES) |
155 | | /* Usable maximum sizes, to be used by the end user to be "safe" in |
156 | | * all the computations. |
157 | | */ |
158 | 17.2k | #define NN_USABLE_MAX_BIT_LEN (NN_MAX_BASE) |
159 | | #define NN_USABLE_MAX_BYTE_LEN ((BIT_LEN_ROUNDING(NN_USABLE_MAX_BIT_LEN, 8)) / 8) |
160 | | #define NN_USABLE_MAX_WORD_LEN ((BIT_LEN_ROUNDING(NN_USABLE_MAX_BIT_LEN, WORD_BITS)) / WORD_BITS) |
161 | | |
162 | | /* Sanity checks */ |
163 | | #if (NN_USABLE_MAX_BIT_LEN > NN_MAX_BIT_LEN) || (NN_USABLE_MAX_BYTE_LEN > NN_MAX_BYTE_LEN) || (NN_USABLE_MAX_WORD_LEN > NN_MAX_WORD_LEN) |
164 | | #error "usable maximum length > internal maximum length, this should not happen!" |
165 | | #endif |
166 | | |
167 | | #if (NN_MAX_WORD_LEN > 255) |
168 | | #error "nn.wlen is encoded on an u8. NN_MAX_WORD_LEN cannot be larger than 255!" |
169 | | #endif |
170 | | |
171 | | /* Add a (somehow 'dirty' but working and useful!) way to detect when our .a |
172 | | * library has been compiled with options (WORDSIZE and NN_MAX_BIT_LEN) |
173 | | * inconsistent with the 'final' binary we want to compile linking to the .a |
174 | | * archive. The 'magic' lies in the definition in nn.c of a function (symbol) |
175 | | * in our .a archive, consisting in a concatenation of WORDSIZE and |
176 | | * NN_MAX_BIT_LEN preprocessed values. On the other side, we force the use |
177 | | * of this symbol in other NN .c modules, yielding in a compile time error |
178 | | * if WORDSIZE or NN_MAX_BIT_LEN differ. |
179 | | * Update: we also check here the consistency of using complete formulas |
180 | | * or not. |
181 | | */ |
182 | | #ifdef NO_USE_COMPLETE_FORMULAS |
183 | | #define _LIBECC_CONCATENATE(a, b, c, d, e) a##_##b##_##c##_##d##_##e |
184 | | #define LIBECC_CONCATENATE(a, b, c, d, e) _LIBECC_CONCATENATE(a, b, c, d, e) |
185 | | void LIBECC_CONCATENATE(nn_consistency_check_maxbitlen, NN_MAX_BASE, wordsize, |
186 | | WORDSIZE, MAX_DIGEST_SIZE) (void); |
187 | | #ifdef NN_CONSISTENCY_CHECK |
188 | | ATTRIBUTE_USED void LIBECC_CONCATENATE(nn_consistency_check_maxbitlen, NN_MAX_BASE, |
189 | | wordsize, WORDSIZE, MAX_DIGEST_SIZE) (void) { |
190 | | return; |
191 | | } |
192 | | #else |
193 | | ATTRIBUTE_USED static inline void nn_check_libconsistency(void) |
194 | | { |
195 | | LIBECC_CONCATENATE(nn_consistency_check_maxbitlen, NN_MAX_BASE, wordsize, |
196 | | WORDSIZE, MAX_DIGEST_SIZE) (); |
197 | | return; |
198 | | } |
199 | | #endif |
200 | | #else /* NO_USE_COMPLETE_FORMULAS */ |
201 | 0 | #define _LIBECC_CONCATENATE(a, b, c, d, e, f) a##_##b##_##c##_##d##_##e##_##f |
202 | 0 | #define LIBECC_CONCATENATE(a, b, c, d, e, f) _LIBECC_CONCATENATE(a, b, c, d, e, f) |
203 | | void LIBECC_CONCATENATE(nn_consistency_check_maxbitlen, NN_MAX_BASE, wordsize, |
204 | | WORDSIZE, complete_formulas, MAX_DIGEST_SIZE) (void); |
205 | | #ifdef NN_CONSISTENCY_CHECK |
206 | | ATTRIBUTE_USED void LIBECC_CONCATENATE(nn_consistency_check_maxbitlen, NN_MAX_BASE, |
207 | 0 | wordsize, WORDSIZE, complete_formulas, MAX_DIGEST_SIZE) (void) { |
208 | 0 | return; |
209 | 0 | } |
210 | | #else |
211 | | ATTRIBUTE_USED static inline void nn_check_libconsistency(void) |
212 | 0 | { |
213 | 0 | LIBECC_CONCATENATE(nn_consistency_check_maxbitlen, NN_MAX_BASE, wordsize, |
214 | 0 | WORDSIZE, complete_formulas, MAX_DIGEST_SIZE) (); |
215 | 0 | return; |
216 | 0 | } Unexecuted instantiation: module.cpp:nn_check_libconsistency() Unexecuted instantiation: aff_pt.c:nn_check_libconsistency Unexecuted instantiation: curves.c:nn_check_libconsistency Unexecuted instantiation: ec_key.c:nn_check_libconsistency Unexecuted instantiation: ec_params.c:nn_check_libconsistency Unexecuted instantiation: ec_shortw.c:nn_check_libconsistency Unexecuted instantiation: ecccdh.c:nn_check_libconsistency Unexecuted instantiation: ecdsa.c:nn_check_libconsistency Unexecuted instantiation: ecdsa_common.c:nn_check_libconsistency Unexecuted instantiation: ecgdsa.c:nn_check_libconsistency Unexecuted instantiation: ecrdsa.c:nn_check_libconsistency Unexecuted instantiation: eddsa.c:nn_check_libconsistency Unexecuted instantiation: fp.c:nn_check_libconsistency Unexecuted instantiation: fp_add.c:nn_check_libconsistency Unexecuted instantiation: fp_mul.c:nn_check_libconsistency Unexecuted instantiation: fp_mul_redc1.c:nn_check_libconsistency Unexecuted instantiation: fp_sqrt.c:nn_check_libconsistency Unexecuted instantiation: fuzzing_ecdsa.c:nn_check_libconsistency Unexecuted instantiation: fuzzing_ecgdsa.c:nn_check_libconsistency Unexecuted instantiation: fuzzing_ecrdsa.c:nn_check_libconsistency Unexecuted instantiation: nn_add.c:nn_check_libconsistency Unexecuted instantiation: nn_div.c:nn_check_libconsistency Unexecuted instantiation: nn_logical.c:nn_check_libconsistency Unexecuted instantiation: nn_mod_pow.c:nn_check_libconsistency Unexecuted instantiation: nn_modinv.c:nn_check_libconsistency Unexecuted instantiation: nn_mul.c:nn_check_libconsistency Unexecuted instantiation: nn_mul_redc1.c:nn_check_libconsistency Unexecuted instantiation: nn_rand.c:nn_check_libconsistency Unexecuted instantiation: prj_pt.c:nn_check_libconsistency Unexecuted instantiation: sig_algs.c:nn_check_libconsistency Unexecuted instantiation: sm2.c:nn_check_libconsistency Unexecuted instantiation: x25519_448.c:nn_check_libconsistency Unexecuted instantiation: aff_pt_edwards.c:nn_check_libconsistency Unexecuted instantiation: aff_pt_montgomery.c:nn_check_libconsistency Unexecuted instantiation: bign.c:nn_check_libconsistency Unexecuted instantiation: bign_common.c:nn_check_libconsistency Unexecuted instantiation: bip0340.c:nn_check_libconsistency Unexecuted instantiation: dbign.c:nn_check_libconsistency Unexecuted instantiation: decdsa.c:nn_check_libconsistency Unexecuted instantiation: ec_edwards.c:nn_check_libconsistency Unexecuted instantiation: ec_montgomery.c:nn_check_libconsistency Unexecuted instantiation: ecfsdsa.c:nn_check_libconsistency Unexecuted instantiation: eckcdsa.c:nn_check_libconsistency Unexecuted instantiation: ecosdsa.c:nn_check_libconsistency Unexecuted instantiation: ecsdsa.c:nn_check_libconsistency Unexecuted instantiation: ecsdsa_common.c:nn_check_libconsistency Unexecuted instantiation: fp_montgomery.c:nn_check_libconsistency Unexecuted instantiation: fp_pow.c:nn_check_libconsistency Unexecuted instantiation: fp_rand.c:nn_check_libconsistency |
217 | | #endif |
218 | | #endif /* NO_USE_COMPLETE_FORMULAS */ |
219 | | |
220 | | #endif /* __NN_CONFIG_H__ */ |