ec_curves.c
Go to the documentation of this file.
1 /**
2  * @file ec_curves.c
3  * @brief Elliptic curves
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/crypto.h"
34 #include "ecc/ec_curves.h"
35 #include "encoding/oid.h"
36 #include "debug.h"
37 
38 //Check crypto library configuration
39 #if (EC_SUPPORT == ENABLED)
40 
41 //Macro definition
42 #define CLEAR_WORD32(a, i, n) cryptoMemset((a)->data + i, 0, n * MPI_INT_SIZE);
43 #define COPY_WORD32(a, i, b, j, n) cryptoMemcpy((a)->data + i, (b)->data + j, n * MPI_INT_SIZE);
44 
45 //secp112r1 OID (1.3.132.0.6)
46 const uint8_t SECP112R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x06};
47 //secp112r2 OID (1.3.132.0.7)
48 const uint8_t SECP112R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x07};
49 //secp128r1 OID (1.3.132.0.28)
50 const uint8_t SECP128R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1C};
51 //secp128r2 OID (1.3.132.0.29)
52 const uint8_t SECP128R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1D};
53 //secp160k1 OID (1.3.132.0.9)
54 const uint8_t SECP160K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x09};
55 //secp160r1 OID (1.3.132.0.8)
56 const uint8_t SECP160R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x08};
57 //secp160r2 OID (1.3.132.0.30)
58 const uint8_t SECP160R2_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1E};
59 //secp192k1 OID (1.3.132.0.31)
60 const uint8_t SECP192K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x1F};
61 //secp192r1 OID (1.2.840.10045.3.1.1)
62 const uint8_t SECP192R1_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x01};
63 //secp224k1 OID (1.3.132.0.32)
64 const uint8_t SECP224K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x20};
65 //secp224r1 OID (1.3.132.0.33)
66 const uint8_t SECP224R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x21};
67 //secp256k1 OID (1.3.132.0.10)
68 const uint8_t SECP256K1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x0A};
69 //secp256r1 OID (1.2.840.10045.3.1.7)
70 const uint8_t SECP256R1_OID[8] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07};
71 //secp384r1 OID (1.3.132.0.34)
72 const uint8_t SECP384R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x22};
73 //secp521r1 OID (1.3.132.0.35)
74 const uint8_t SECP521R1_OID[5] = {0x2B, 0x81, 0x04, 0x00, 0x23};
75 //brainpoolP160r1 OID (1.3.36.3.3.2.8.1.1.1)
76 const uint8_t BRAINPOOLP160R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x01};
77 //brainpoolP192r1 OID (1.3.36.3.3.2.8.1.1.3)
78 const uint8_t BRAINPOOLP192R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x03};
79 //brainpoolP224r1 OID (1.3.36.3.3.2.8.1.1.5)
80 const uint8_t BRAINPOOLP224R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05};
81 //brainpoolP256r1 OID (1.3.36.3.3.2.8.1.1.7)
82 const uint8_t BRAINPOOLP256R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07};
83 //brainpoolP320r1 OID (1.3.36.3.3.2.8.1.1.9)
84 const uint8_t BRAINPOOLP320R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x09};
85 //brainpoolP384r1 OID (1.3.36.3.3.2.8.1.1.11)
86 const uint8_t BRAINPOOLP384R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B};
87 //brainpoolP512r1 OID (1.3.36.3.3.2.8.1.1.13)
88 const uint8_t BRAINPOOLP512R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D};
89 //X25519 OID (1.3.101.110)
90 const uint8_t X25519_OID[3] = {0x2B, 0x65, 0x6E};
91 //X448 OID (1.3.101.111)
92 const uint8_t X448_OID[3] = {0x2B, 0x65, 0x6F};
93 //Ed25519 OID (1.3.101.112)
94 const uint8_t ED25519_OID[3] = {0x2B, 0x65, 0x70};
95 //Ed448 OID (1.3.101.113)
96 const uint8_t ED448_OID[3] = {0x2B, 0x65, 0x71};
97 
98 
99 #if (SECP112R1_SUPPORT == ENABLED)
100 
101 /**
102  * @brief secp112r1 elliptic curve
103  **/
104 
106 {
107  //Curve name
108  "secp112r1",
109  //Object identifier
111  sizeof(SECP112R1_OID),
112  //Curve type
114  //Prime modulus p
115  {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x8B},
116  14,
117  //Curve parameter a
118  {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x88},
119  14,
120  //Curve parameter b
121  {0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70, 0x2B, 0x22},
122  14,
123  //x-coordinate of the base point G
124  {0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2, 0xF0, 0x98},
125  14,
126  //y-coordinate of the base point G
127  {0xA8, 0x9C, 0xE5, 0xAF, 0x87, 0x24, 0xC0, 0xA2, 0x3E, 0x0E, 0x0F, 0xF7, 0x75, 0x00},
128  14,
129  //Base point order q
130  {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65, 0x61, 0xC5},
131  14,
132  //Cofactor
133  1,
134  //Fast modular reduction
135  NULL
136 };
137 
138 #endif
139 #if (SECP112R2_SUPPORT == ENABLED)
140 
141 /**
142  * @brief secp112r2 elliptic curve
143  **/
144 
146 {
147  //Curve name
148  "secp112r2",
149  //Object identifier
151  sizeof(SECP112R2_OID),
152  //Curve type
154  //Prime modulus p
155  {0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, 0x20, 0x8B},
156  14,
157  //Curve parameter a
158  {0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E, 0xF0, 0x2C},
159  14,
160  //Curve parameter b
161  {0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85, 0xD7, 0x09},
162  14,
163  //x-coordinate of the base point G
164  {0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92, 0x86, 0x43},
165  14,
166  //y-coordinate of the base point G
167  {0xAD, 0xCD, 0x46, 0xF5, 0x88, 0x2E, 0x37, 0x47, 0xDE, 0xF3, 0x6E, 0x95, 0x6E, 0x97},
168  14,
169  //Base point order q
170  {0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20, 0xD0, 0x4B},
171  14,
172  //Cofactor
173  4,
174  //Fast modular reduction
175  NULL
176 };
177 
178 #endif
179 #if (SECP128R1_SUPPORT == ENABLED)
180 
181 /**
182  * @brief secp128r1 elliptic curve
183  **/
184 
186 {
187  //Curve name
188  "secp128r1",
189  //Object identifier
191  sizeof(SECP128R1_OID),
192  //Curve type
194  //Prime modulus p
195  {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
196  16,
197  //Curve parameter a
198  {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
199  16,
200  //Curve parameter b
201  {0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C, 0x2C, 0xEE, 0x5E, 0xD3},
202  16,
203  //x-coordinate of the base point G
204  {0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C, 0xA5, 0x2C, 0x5B, 0x86},
205  16,
206  //y-coordinate of the base point G
207  {0xCF, 0x5A, 0xC8, 0x39, 0x5B, 0xAF, 0xEB, 0x13, 0xC0, 0x2D, 0xA2, 0x92, 0xDD, 0xED, 0x7A, 0x83},
208  16,
209  //Base point order q
210  {0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B, 0x90, 0x38, 0xA1, 0x15},
211  16,
212  //Cofactor
213  1,
214  //Fast modular reduction
216 };
217 
218 #endif
219 #if (SECP128R2_SUPPORT == ENABLED)
220 
221 /**
222  * @brief secp128r2 elliptic curve
223  **/
224 
226 {
227  //Curve name
228  "secp128r2",
229  //Object identifier
231  sizeof(SECP128R2_OID),
232  //Curve type
234  //Prime modulus p
235  {0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
236  16,
237  //Curve parameter a
238  {0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B, 0xBF, 0xF9, 0xAE, 0xE1},
239  16,
240  //Curve parameter b
241  {0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58, 0xBB, 0x6D, 0x8A, 0x5D},
242  16,
243  //x-coordinate of the base point G
244  {0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7, 0xCD, 0xEB, 0xC1, 0x40},
245  16,
246  //y-coordinate of the base point G
247  {0x27, 0xB6, 0x91, 0x6A, 0x89, 0x4D, 0x3A, 0xEE, 0x71, 0x06, 0xFE, 0x80, 0x5F, 0xC3, 0x4B, 0x44},
248  16,
249  //Base point order q
250  {0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72, 0x06, 0x13, 0xB5, 0xA3},
251  16,
252  //Cofactor
253  4,
254  //Fast modular reduction
256 };
257 
258 #endif
259 #if (SECP160K1_SUPPORT == ENABLED)
260 
261 /**
262  * @brief secp160k1 elliptic curve
263  **/
264 
266 {
267  //Curve name
268  "secp160k1",
269  //Object identifier
271  sizeof(SECP160K1_OID),
272  //Curve type
274  //Prime modulus p
275  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
276  0xFF, 0xFF, 0xAC, 0x73},
277  20,
278  //Curve parameter a
279  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280  0x00, 0x00, 0x00, 0x00},
281  20,
282  //Curve parameter b
283  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284  0x00, 0x00, 0x00, 0x07},
285  20,
286  //x-coordinate of the base point G
287  {0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E, 0x76, 0x30, 0x36, 0xF4, 0xF5,
288  0xDD, 0x4D, 0x7E, 0xBB},
289  20,
290  //y-coordinate of the base point G
291  {0x93, 0x8C, 0xF9, 0x35, 0x31, 0x8F, 0xDC, 0xED, 0x6B, 0xC2, 0x82, 0x86, 0x53, 0x17, 0x33, 0xC3,
292  0xF0, 0x3C, 0x4F, 0xEE},
293  20,
294  //Base point order q
295  {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, 0xFA, 0x16, 0xDF, 0xAB,
296  0x9A, 0xCA, 0x16, 0xB6, 0xB3},
297  21,
298  //Cofactor
299  1,
300  //Fast modular reduction
302 };
303 
304 #endif
305 #if (SECP160R1_SUPPORT == ENABLED)
306 
307 /**
308  * @brief secp160r1 elliptic curve
309  **/
310 
312 {
313  //Curve name
314  "secp160r1",
315  //Object identifier
317  sizeof(SECP160R1_OID),
318  //Curve type
320  //Prime modulus p
321  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
322  0x7F, 0xFF, 0xFF, 0xFF},
323  20,
324  //Curve parameter a
325  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
326  0x7F, 0xFF, 0xFF, 0xFC},
327  20,
328  //Curve parameter b
329  {0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8, 0x9F, 0x81, 0xD4, 0xD4, 0xAD,
330  0xC5, 0x65, 0xFA, 0x45},
331  20,
332  //x-coordinate of the base point G
333  {0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69, 0x89, 0x68, 0xC3, 0x8B, 0xB9,
334  0x13, 0xCB, 0xFC, 0x82},
335  20,
336  //y-coordinate of the base point G
337  {0x23, 0xA6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7D, 0x59, 0xDC, 0xC9, 0x12, 0x04, 0x23, 0x51, 0x37,
338  0x7A, 0xC5, 0xFB, 0x32},
339  20,
340  //Base point order q
341  {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, 0xC8, 0xF9, 0x27, 0xAE,
342  0xD3, 0xCA, 0x75, 0x22, 0x57},
343  21,
344  //Cofactor
345  1,
346  //Fast modular reduction
348 };
349 
350 #endif
351 #if (SECP160R2_SUPPORT == ENABLED)
352 
353 /**
354  * @brief secp160r2 elliptic curve
355  **/
356 
358 {
359  //Curve name
360  "secp160r2",
361  //Object identifier
363  sizeof(SECP160R2_OID),
364  //Curve type
366  //Prime modulus p
367  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
368  0xFF, 0xFF, 0xAC, 0x73},
369  20,
370  //Curve parameter a
371  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
372  0xFF, 0xFF, 0xAC, 0x70},
373  20,
374  //Curve parameter b
375  {0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27, 0x49, 0x04, 0x66, 0x4D, 0x5A,
376  0xF5, 0x03, 0x88, 0xBA},
377  20,
378  //x-coordinate of the base point G
379  {0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1, 0x1B, 0x30, 0xF7, 0x19, 0x9D,
380  0x31, 0x44, 0xCE, 0x6D},
381  20,
382  //y-coordinate of the base point G
383  {0xFE, 0xAF, 0xFE, 0xF2, 0xE3, 0x31, 0xF2, 0x96, 0xE0, 0x71, 0xFA, 0x0D, 0xF9, 0x98, 0x2C, 0xFE,
384  0xA7, 0xD4, 0x3F, 0x2E},
385  20,
386  //Base point order q
387  {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x1E, 0xE7, 0x86, 0xA8,
388  0x18, 0xF3, 0xA1, 0xA1, 0x6B},
389  21,
390  //Cofactor
391  1,
392  //Fast modular reduction
394 };
395 
396 #endif
397 #if (SECP192K1_SUPPORT == ENABLED)
398 
399 /**
400  * @brief secp192k1 elliptic curve
401  **/
402 
404 {
405  //Curve name
406  "secp192k1",
407  //Object identifier
409  sizeof(SECP192K1_OID),
410  //Curve type
412  //Prime modulus p
413  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
414  0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37},
415  24,
416  //Curve parameter a
417  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
419  24,
420  //Curve parameter b
421  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
423  24,
424  //x-coordinate of the base point G
425  {0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02, 0x80, 0xB7, 0xF4, 0x34,
426  0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D},
427  24,
428  //y-coordinate of the base point G
429  {0x9B, 0x2F, 0x2F, 0x6D, 0x9C, 0x56, 0x28, 0xA7, 0x84, 0x41, 0x63, 0xD0, 0x15, 0xBE, 0x86, 0x34,
430  0x40, 0x82, 0xAA, 0x88, 0xD9, 0x5E, 0x2F, 0x9D},
431  24,
432  //Base point order q
433  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x26, 0xF2, 0xFC, 0x17,
434  0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D},
435  24,
436  //Cofactor
437  1,
438  //Fast modular reduction
440 };
441 
442 #endif
443 #if (SECP192R1_SUPPORT == ENABLED)
444 
445 /**
446  * @brief secp192r1 elliptic curve
447  **/
448 
450 {
451  //Curve name
452  "secp192r1",
453  //Object identifier
455  sizeof(SECP192R1_OID),
456  //Curve type
458  //Prime modulus p
459  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
460  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
461  24,
462  //Curve parameter a
463  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
464  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
465  24,
466  //Curve parameter b
467  {0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, 0x72, 0x24, 0x30, 0x49,
468  0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1},
469  24,
470  //x-coordinate of the base point G
471  {0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, 0x43, 0xA1, 0x88, 0x00,
472  0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12},
473  24,
474  //y-coordinate of the base point G
475  {0x07, 0x19, 0x2B, 0x95, 0xFF, 0xC8, 0xDA, 0x78, 0x63, 0x10, 0x11, 0xED, 0x6B, 0x24, 0xCD, 0xD5,
476  0x73, 0xF9, 0x77, 0xA1, 0x1E, 0x79, 0x48, 0x11},
477  24,
478  //Base point order q
479  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0xDE, 0xF8, 0x36,
480  0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31},
481  24,
482  //Cofactor
483  1,
484  //Fast modular reduction
486 };
487 
488 #endif
489 #if (SECP224K1_SUPPORT == ENABLED)
490 
491 /**
492  * @brief secp224k1 elliptic curve
493  **/
494 
496 {
497  //Curve name
498  "secp224k1",
499  //Object identifier
501  sizeof(SECP224K1_OID),
502  //Curve type
504  //Prime modulus p
505  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
506  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE5, 0x6D},
507  28,
508  //Curve parameter a
509  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
511  28,
512  //Curve parameter b
513  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
514  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
515  28,
516  //x-coordinate of the base point G
517  {0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28, 0xA1, 0x69, 0xA4, 0x67, 0xE9,
518  0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65, 0x0E, 0xB6, 0xB7, 0xA4, 0x5C},
519  28,
520  //y-coordinate of the base point G
521  {0x7E, 0x08, 0x9F, 0xED, 0x7F, 0xBA, 0x34, 0x42, 0x82, 0xCA, 0xFB, 0xD6, 0xF7, 0xE3, 0x19, 0xF7,
522  0xC0, 0xB0, 0xBD, 0x59, 0xE2, 0xCA, 0x4B, 0xDB, 0x55, 0x6D, 0x61, 0xA5},
523  28,
524  //Base point order q
525  {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xDC,
526  0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9, 0x71, 0x76, 0x9F, 0xB1, 0xF7},
527  29,
528  //Cofactor
529  1,
530  //Fast modular reduction
532 };
533 
534 #endif
535 #if (SECP224R1_SUPPORT == ENABLED)
536 
537 /**
538  * @brief secp224r1 elliptic curve
539  **/
540 
542 {
543  //Curve name
544  "secp224r1",
545  //Object identifier
547  sizeof(SECP224R1_OID),
548  //Curve type
550  //Prime modulus p
551  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
552  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
553  28,
554  //Curve parameter a
555  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
556  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
557  28,
558  //Curve parameter b
559  {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7,
560  0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
561  28,
562  //x-coordinate of the base point G
563  {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3,
564  0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
565  28,
566  //y-coordinate of the base point G
567  {0xBD, 0x37, 0x63, 0x88, 0xB5, 0xF7, 0x23, 0xFB, 0x4C, 0x22, 0xDF, 0xE6, 0xCD, 0x43, 0x75, 0xA0,
568  0x5A, 0x07, 0x47, 0x64, 0x44, 0xD5, 0x81, 0x99, 0x85, 0x00, 0x7E, 0x34},
569  28,
570  //Base point order q
571  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16, 0xA2,
572  0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, 0x5C, 0x5C, 0x2A, 0x3D},
573  28,
574  //Cofactor
575  1,
576  //Fast modular reduction
578 };
579 
580 #endif
581 #if (SECP256K1_SUPPORT == ENABLED)
582 
583 /**
584  * @brief secp256k1 elliptic curve
585  **/
586 
588 {
589  //Curve name
590  "secp256k1",
591  //Object identifier
593  sizeof(SECP256K1_OID),
594  //Curve type
596  //Prime modulus p
597  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
598  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F},
599  32,
600  //Curve parameter a
601  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
603  32,
604  //Curve parameter b
605  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07},
607  32,
608  //x-coordinate of the base point G
609  {0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, 0x07,
610  0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98},
611  32,
612  //y-coordinate of the base point G
613  {0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, 0xA8,
614  0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, 0xB8},
615  32,
616  //Base point order q
617  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
618  0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41},
619  32,
620  //Cofactor
621  1,
622  //Fast modular reduction
624 };
625 
626 #endif
627 #if (SECP256R1_SUPPORT == ENABLED)
628 
629 /**
630  * @brief secp256r1 elliptic curve
631  **/
632 
634 {
635  //Curve name
636  "secp256r1",
637  //Object identifier
639  sizeof(SECP256R1_OID),
640  //Curve type
642  //Prime modulus p
643  {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
645  32,
646  //Curve parameter a
647  {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC},
649  32,
650  //Curve parameter b
651  {0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 0x76, 0x98, 0x86, 0xBC,
652  0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B},
653  32,
654  //x-coordinate of the base point G
655  {0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 0x63, 0xA4, 0x40, 0xF2,
656  0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96},
657  32,
658  //y-coordinate of the base point G
659  {0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, 0x7C, 0x0F, 0x9E, 0x16,
660  0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5},
661  32,
662  //Base point order q
663  {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
664  0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51},
665  32,
666  //Cofactor
667  1,
668  //Fast modular reduction
670 };
671 
672 #endif
673 #if (SECP384R1_SUPPORT == ENABLED)
674 
675 /**
676  * @brief secp384r1 elliptic curve
677  **/
678 
680 {
681  //Curve name
682  "secp384r1",
683  //Object identifier
685  sizeof(SECP384R1_OID),
686  //Curve type
688  //Prime modulus p
689  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
690  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
691  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
692  48,
693  //Curve parameter a
694  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
695  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
696  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC},
697  48,
698  //Curve parameter b
699  {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, 0xE3, 0xF8, 0x2D, 0x19,
700  0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A,
701  0xC6, 0x56, 0x39, 0x8D, 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF},
702  48,
703  //x-coordinate of the base point G
704  {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 0xF3, 0x20, 0xAD, 0x74,
705  0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38,
706  0x55, 0x02, 0xF2, 0x5D, 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7},
707  48,
708  //y-coordinate of the base point G
709  {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, 0x92, 0x92, 0xDC, 0x29,
710  0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0,
711  0x0A, 0x60, 0xB1, 0xCE, 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F},
712  48,
713  //Base point order q
714  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
715  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF,
716  0x58, 0x1A, 0x0D, 0xB2, 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73},
717  48,
718  //Cofactor
719  1,
720  //Fast modular reduction
722 };
723 
724 #endif
725 #if (SECP521R1_SUPPORT == ENABLED)
726 
727 /**
728  * @brief secp521r1 elliptic curve
729  **/
730 
732 {
733  //Curve name
734  "secp521r1",
735  //Object identifier
737  sizeof(SECP521R1_OID),
738  //Curve type
740  //Prime modulus p
741  {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
742  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
743  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
744  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
745  0xFF, 0xFF},
746  66,
747  //Curve parameter a
748  {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
749  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
750  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
751  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
752  0xFF, 0xFC},
753  66,
754  //Curve parameter b
755  {0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85,
756  0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1,
757  0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
758  0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50,
759  0x3F, 0x00},
760  66,
761  //x-coordinate of the base point G
762  {0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95,
763  0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D,
764  0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
765  0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5,
766  0xBD, 0x66},
767  66,
768  //y-coordinate of the base point G
769  {0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D,
770  0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E,
771  0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD,
772  0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1,
773  0x66, 0x50},
774  66,
775  //Base point order q
776  {0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
777  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
778  0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
779  0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38,
780  0x64, 0x09},
781  66,
782  //Cofactor
783  1,
784  //Fast modular reduction
786 };
787 
788 #endif
789 #if (BRAINPOOLP160R1_SUPPORT == ENABLED)
790 
791 /**
792  * @brief brainpoolP160r1 elliptic curve
793  **/
794 
796 {
797  //Curve name
798  "brainpoolP160r1",
799  //Object identifier
801  sizeof(BRAINPOOLP160R1_OID),
802  //Curve type
804  //Prime modulus p
805  {0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, 0x95, 0xB3, 0xD8, 0x13,
806  0x95, 0x15, 0x62, 0x0F},
807  20,
808  //Curve parameter a
809  {0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, 0x61, 0xBA, 0xDA, 0x74, 0x5D, 0x97,
810  0xE8, 0xF7, 0xC3, 0x00},
811  20,
812  //Curve parameter b
813  {0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, 0xAA, 0x2D, 0xBD, 0xEC, 0x95, 0xC8,
814  0xD8, 0x67, 0x5E, 0x58},
815  20,
816  //x-coordinate of the base point G
817  {0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, 0x8C, 0x46, 0x31, 0xEB, 0x5A, 0xF7,
818  0xBD, 0xBC, 0xDB, 0xC3},
819  20,
820  //y-coordinate of the base point G
821  {0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, 0x47, 0x41, 0x66, 0x9C, 0x97, 0x63,
822  0x16, 0xDA, 0x63, 0x21},
823  20,
824  //Base point order q
825  {0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, 0xD4, 0x50, 0x29, 0x40,
826  0x9E, 0x60, 0xFC, 0x09},
827  20,
828  //Cofactor
829  1,
830  //Fast modular reduction
831  NULL
832 };
833 
834 #endif
835 #if (BRAINPOOLP192R1_SUPPORT == ENABLED)
836 
837 /**
838  * @brief brainpoolP192r1 elliptic curve
839  **/
840 
842 {
843  //Curve name
844  "brainpoolP192r1",
845  //Object identifier
847  sizeof(BRAINPOOLP192R1_OID),
848  //Curve type
850  //Prime modulus p
851  {0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, 0x93, 0xD1, 0x8D, 0xB7,
852  0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97},
853  24,
854  //Curve parameter a
855  {0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, 0xC0, 0x31, 0xFE, 0x86, 0x85, 0xC1,
856  0xCA, 0xE0, 0x40, 0xE5, 0xC6, 0x9A, 0x28, 0xEF},
857  24,
858  //Curve parameter b
859  {0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, 0x1D, 0x04, 0x4F, 0x44, 0x96, 0xBC,
860  0xCA, 0x7E, 0xF4, 0x14, 0x6F, 0xBF, 0x25, 0xC9},
861  24,
862  //x-coordinate of the base point G
863  {0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, 0x33, 0xC5, 0x6C, 0xB0, 0xF0, 0x90,
864  0x0A, 0x2F, 0x5C, 0x48, 0x53, 0x37, 0x5F, 0xD6},
865  24,
866  //y-coordinate of the base point G
867  {0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, 0x48, 0x28, 0xC1, 0x49, 0x00, 0x02,
868  0xE6, 0x77, 0x3F, 0xA2, 0xFA, 0x29, 0x9B, 0x8F},
869  24,
870  //Base point order q
871  {0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, 0x9E, 0x9E, 0x91, 0x6B,
872  0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1},
873  24,
874  //Cofactor
875  1,
876  //Fast modular reduction
877  NULL
878 };
879 
880 #endif
881 #if (BRAINPOOLP224R1_SUPPORT == ENABLED)
882 
883 /**
884  * @brief brainpoolP224r1 elliptic curve
885  **/
886 
888 {
889  //Curve name
890  "brainpoolP224r1",
891  //Object identifier
893  sizeof(BRAINPOOLP224R1_OID),
894  //Curve type
896  //Prime modulus p
897  {0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, 0x75, 0xD1, 0xD7, 0x87,
898  0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, 0x7E, 0xC8, 0xC0, 0xFF},
899  28,
900  //Curve parameter a
901  {0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, 0x03, 0xA6, 0xC1, 0x53, 0x0B, 0x51,
902  0x4E, 0x18, 0x2A, 0xD8, 0xB0, 0x04, 0x2A, 0x59, 0xCA, 0xD2, 0x9F, 0x43},
903  28,
904  //Curve parameter b
905  {0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, 0x13, 0xB1, 0xA9, 0x23, 0x69, 0xE3,
906  0x3E, 0x21, 0x35, 0xD2, 0x66, 0xDB, 0xB3, 0x72, 0x38, 0x6C, 0x40, 0x0B},
907  28,
908  //x-coordinate of the base point G
909  {0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, 0x23, 0xB2, 0xA8, 0x7D, 0xC6, 0x8C,
910  0x9E, 0x4C, 0xE3, 0x17, 0x4C, 0x1E, 0x6E, 0xFD, 0xEE, 0x12, 0xC0, 0x7D},
911  28,
912  //y-coordinate of the base point G
913  {0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, 0xB8, 0x9E, 0x4E, 0xCD, 0xAC, 0x24,
914  0x35, 0x4B, 0x9E, 0x99, 0xCA, 0xA3, 0xF6, 0xD3, 0x76, 0x14, 0x02, 0xCD},
915  28,
916  //Base point order q
917  {0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, 0x75, 0xD0, 0xFB, 0x98,
918  0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, 0xA5, 0xA7, 0x93, 0x9F},
919  28,
920  //Cofactor
921  1,
922  //Fast modular reduction
923  NULL
924 };
925 
926 #endif
927 #if (BRAINPOOLP256R1_SUPPORT == ENABLED)
928 
929 /**
930  * @brief brainpoolP256r1 elliptic curve
931  **/
932 
934 {
935  //Curve name
936  "brainpoolP256r1",
937  //Object identifier
939  sizeof(BRAINPOOLP256R1_OID),
940  //Curve type
942  //Prime modulus p
943  {0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x72,
944  0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77},
945  32,
946  //Curve parameter a
947  {0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30, 0x41, 0x7A, 0xFF, 0xE7,
948  0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9},
949  32,
950  //Curve parameter b
951  {0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, 0xBB, 0xD7, 0x7C, 0xBF,
952  0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6},
953  32,
954  //x-coordinate of the base point G
955  {0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F, 0xFC, 0x81, 0xB7, 0xAF,
956  0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62},
957  32,
958  //y-coordinate of the base point G
959  {0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A, 0x14, 0x61, 0x1D, 0xC9,
960  0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97},
961  32,
962  //Base point order q
963  {0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, 0x9D, 0x83, 0x8D, 0x71,
964  0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7},
965  32,
966  //Cofactor
967  1,
968  //Fast modular reduction
969  NULL
970 };
971 
972 #endif
973 #if (BRAINPOOLP320R1_SUPPORT == ENABLED)
974 
975 /**
976  * @brief brainpoolP320r1 elliptic curve
977  **/
978 
980 {
981  //Curve name
982  "brainpoolP320r1",
983  //Object identifier
985  sizeof(BRAINPOOLP320R1_OID),
986  //Curve type
988  //Prime modulus p
989  {0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65,
990  0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28,
991  0xFC, 0xD4, 0x12, 0xB1, 0xF1, 0xB3, 0x2E, 0x27},
992  40,
993  //Curve parameter a
994  {0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, 0xEB, 0xD4, 0x6D, 0x3F, 0x3B, 0xB8,
995  0xA2, 0xA7, 0x35, 0x13, 0xF5, 0xEB, 0x79, 0xDA, 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF, 0xA9, 0xF4,
996  0x92, 0xF3, 0x75, 0xA9, 0x7D, 0x86, 0x0E, 0xB4},
997  40,
998  //Curve parameter b
999  {0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, 0x19, 0x86, 0x40, 0x68, 0x8A, 0x6F,
1000  0xE1, 0x3F, 0x41, 0x34, 0x95, 0x54, 0xB4, 0x9A, 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45, 0x39, 0x81,
1001  0x6F, 0x5E, 0xB4, 0xAC, 0x8F, 0xB1, 0xF1, 0xA6},
1002  40,
1003  //x-coordinate of the base point G
1004  {0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, 0xBC, 0xC4, 0x8E, 0xE5, 0xBF, 0xE6,
1005  0xF2, 0x01, 0x37, 0xD1, 0x0A, 0x08, 0x7E, 0xB6, 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5, 0x99, 0xC7,
1006  0x10, 0xAF, 0x8D, 0x0D, 0x39, 0xE2, 0x06, 0x11},
1007  40,
1008  //y-coordinate of the base point G
1009  {0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, 0x93, 0x24, 0x7F, 0x77, 0x27, 0x5E,
1010  0x07, 0x43, 0xFF, 0xED, 0x11, 0x71, 0x82, 0xEA, 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC, 0x6A, 0xC7,
1011  0xD3, 0x52, 0x45, 0xD1, 0x69, 0x2E, 0x8E, 0xE1},
1012  40,
1013  //Base point order q
1014  {0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, 0xD2, 0x01, 0xE0, 0x65,
1015  0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9,
1016  0x86, 0x91, 0x55, 0x5B, 0x44, 0xC5, 0x93, 0x11},
1017  40,
1018  //Cofactor
1019  1,
1020  //Fast modular reduction
1021  NULL
1022 };
1023 
1024 #endif
1025 #if (BRAINPOOLP384R1_SUPPORT == ENABLED)
1026 
1027 /**
1028  * @brief brainpoolP384r1 elliptic curve
1029  **/
1030 
1032 {
1033  //Curve name
1034  "brainpoolP384r1",
1035  //Object identifier
1037  sizeof(BRAINPOOLP384R1_OID),
1038  //Curve type
1040  //Prime modulus p
1041  {0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF,
1042  0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23,
1043  0xAC, 0xD3, 0xA7, 0x29, 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53},
1044  48,
1045  //Curve parameter a
1046  {0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A, 0xCE, 0x05, 0xAF, 0xA0,
1047  0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F,
1048  0x8A, 0xA5, 0x81, 0x4A, 0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26},
1049  48,
1050  //Curve parameter b
1051  {0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54, 0x16, 0xF0, 0x44, 0x7C,
1052  0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5,
1053  0x7C, 0xB4, 0x39, 0x02, 0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11},
1054  48,
1055  //x-coordinate of the base point G
1056  {0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81, 0xB7, 0xC1, 0x3F, 0x6B,
1057  0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8,
1058  0xE8, 0x26, 0xE0, 0x34, 0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E},
1059  48,
1060  //y-coordinate of the base point G
1061  {0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E, 0x95, 0xCF, 0xD5, 0x52,
1062  0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28,
1063  0x0E, 0x46, 0x46, 0x21, 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15},
1064  48,
1065  //Base point order q
1066  {0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, 0x50, 0xE6, 0x41, 0xDF,
1067  0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7,
1068  0xCF, 0x3A, 0xB6, 0xAF, 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65},
1069  48,
1070  //Cofactor
1071  1,
1072  //Fast modular reduction
1073  NULL
1074 };
1075 
1076 #endif
1077 #if (BRAINPOOLP512R1_SUPPORT == ENABLED)
1078 
1079 /**
1080  * @brief brainpoolP512r1 elliptic curve
1081  **/
1082 
1084 {
1085  //Curve name
1086  "brainpoolP512r1",
1087  //Object identifier
1089  sizeof(BRAINPOOLP512R1_OID),
1090  //Curve type
1092  //Prime modulus p
1093  {0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07,
1094  0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71,
1095  0x7D, 0x4D, 0x9B, 0x00, 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6,
1096  0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, 0x58, 0x3A, 0x48, 0xF3},
1097  64,
1098  //Curve parameter a
1099  {0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45, 0xAC, 0x23, 0x4C, 0xC5,
1100  0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC,
1101  0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5,
1102  0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA},
1103  64,
1104  //Curve parameter b
1105  {0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A,
1106  0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7,
1107  0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67,
1108  0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63, 0x80, 0x16, 0xF7, 0x23},
1109  64,
1110  //x-coordinate of the base point G
1111  {0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E, 0x9C, 0x4C, 0x6A, 0x93,
1112  0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E,
1113  0xFF, 0x3B, 0x1F, 0x78, 0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F,
1114  0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09, 0xBC, 0xB9, 0xF8, 0x22},
1115  64,
1116  //y-coordinate of the base point G
1117  {0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9, 0xCF, 0x78, 0x22, 0xFD,
1118  0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11,
1119  0xB2, 0xDC, 0xDE, 0x49, 0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE,
1120  0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F, 0x3A, 0xD8, 0x08, 0x92},
1121  64,
1122  //Base point order q
1123  {0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, 0x33, 0xC9, 0xFC, 0x07,
1124  0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70,
1125  0x55, 0x3E, 0x5C, 0x41, 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47,
1126  0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, 0x9C, 0xA9, 0x00, 0x69},
1127  64,
1128  //Cofactor
1129  1,
1130  //Fast modular reduction
1131  NULL
1132 };
1133 
1134 #endif
1135 #if (X25519_SUPPORT == ENABLED)
1136 
1137 /**
1138  * @brief Curve25519 elliptic curve
1139  **/
1140 
1142 {
1143  //Curve name
1144  "Curve22519",
1145  //Object identifier
1146  X25519_OID,
1147  sizeof(X25519_OID),
1148  //Curve type
1150  //Prime modulus p
1151  {0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1152  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED},
1153  32,
1154  //Curve parameter a
1155  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1156  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6D, 0x06},
1157  32,
1158  //Curve parameter b
1159  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1161  32,
1162  //u-coordinate of the base point G
1163  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09},
1165  32,
1166  //v-coordinate of the base point G
1167  {0x20, 0xAE, 0x19, 0xA1, 0xB8, 0xA0, 0x86, 0xB4, 0xE0, 0x1E, 0xDD, 0x2C, 0x77, 0x48, 0xD1, 0x4C,
1168  0x92, 0x3D, 0x4D, 0x7E, 0x6D, 0x7C, 0x61, 0xB2, 0x29, 0xE9, 0xC5, 0xA2, 0x7E, 0xCE, 0xD3, 0xD9},
1169  32,
1170  //Base point order q
1171  {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172  0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED},
1173  32,
1174  //Cofactor
1175  8,
1176  //Fast modular reduction
1177  NULL
1178 };
1179 
1180 #endif
1181 #if (X448_SUPPORT == ENABLED)
1182 
1183 /**
1184  * @brief Curve448 elliptic curve
1185  **/
1186 
1188 {
1189  //Curve name
1190  "Curve448",
1191  //Object identifier
1192  X448_OID,
1193  sizeof(X448_OID),
1194  //Curve type
1196  //Prime modulus p
1197  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1198  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
1199  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1200  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1201  56,
1202  //Curve parameter a
1203  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1204  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1205  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1206  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x62, 0xA6},
1207  56,
1208  //Curve parameter b
1209  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1211  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1213  56,
1214  //u-coordinate of the base point G
1215  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1217  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1218  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
1219  56,
1220  //v-coordinate of the base point G
1221  {0x7D, 0x23, 0x5D, 0x12, 0x95, 0xF5, 0xB1, 0xF6, 0x6C, 0x98, 0xAB, 0x6E, 0x58, 0x32, 0x6F, 0xCE,
1222  0xCB, 0xAE, 0x5D, 0x34, 0xF5, 0x55, 0x45, 0xD0, 0x60, 0xF7, 0x5D, 0xC2, 0x8D, 0xF3, 0xF6, 0xED,
1223  0xB8, 0x02, 0x7E, 0x23, 0x46, 0x43, 0x0D, 0x21, 0x13, 0x12, 0xC4, 0xB1, 0x50, 0x67, 0x7A, 0xF7,
1224  0x6F, 0xD7, 0x22, 0x3D, 0x45, 0x7B, 0x5B, 0x1A},
1225  56,
1226  //Base point order q
1227  {0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1228  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0xCA, 0x23, 0xE9,
1229  0xC4, 0x4E, 0xDB, 0x49, 0xAE, 0xD6, 0x36, 0x90, 0x21, 0x6C, 0xC2, 0x72, 0x8D, 0xC5, 0x8F, 0x55,
1230  0x23, 0x78, 0xC2, 0x92, 0xAB, 0x58, 0x44, 0xF3},
1231  56,
1232  //Cofactor
1233  4,
1234  //Fast modular reduction
1235  NULL
1236 };
1237 
1238 #endif
1239 #if (ED25519_SUPPORT == ENABLED)
1240 
1241 /**
1242  * @brief Ed25519 elliptic curve
1243  **/
1244 
1246 {
1247  //Curve name
1248  "Ed22519",
1249  //Object identifier
1250  ED25519_OID,
1251  sizeof(ED25519_OID),
1252  //Curve type
1254  //Prime modulus p
1255  {0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1256  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED},
1257  32,
1258  //Curve parameter a
1259  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1260  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6D, 0x06},
1261  32,
1262  //Curve parameter b
1263  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1264  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1265  32,
1266  //x-coordinate of the base point G
1267  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09},
1269  32,
1270  //y-coordinate of the base point G
1271  {0x20, 0xAE, 0x19, 0xA1, 0xB8, 0xA0, 0x86, 0xB4, 0xE0, 0x1E, 0xDD, 0x2C, 0x77, 0x48, 0xD1, 0x4C,
1272  0x92, 0x3D, 0x4D, 0x7E, 0x6D, 0x7C, 0x61, 0xB2, 0x29, 0xE9, 0xC5, 0xA2, 0x7E, 0xCE, 0xD3, 0xD9},
1273  32,
1274  //Base point order q
1275  {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276  0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED},
1277  32,
1278  //Cofactor
1279  8,
1280  //Fast modular reduction
1281  NULL
1282 };
1283 
1284 #endif
1285 #if (ED448_SUPPORT == ENABLED)
1286 
1287 /**
1288  * @brief Ed448 elliptic curve
1289  **/
1290 
1292 {
1293  //Curve name
1294  "Ed448",
1295  //Object identifier
1296  ED448_OID,
1297  sizeof(ED448_OID),
1298  //Curve type
1300  //Prime modulus p
1301  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1302  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
1303  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1304  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
1305  56,
1306  //Curve parameter a
1307  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1308  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1309  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x62, 0xA6},
1311  56,
1312  //Curve parameter b
1313  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1315  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1316  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
1317  56,
1318  //x-coordinate of the base point G
1319  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1320  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1321  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05},
1323  56,
1324  //y-coordinate of the base point G
1325  {0x7D, 0x23, 0x5D, 0x12, 0x95, 0xF5, 0xB1, 0xF6, 0x6C, 0x98, 0xAB, 0x6E, 0x58, 0x32, 0x6F, 0xCE,
1326  0xCB, 0xAE, 0x5D, 0x34, 0xF5, 0x55, 0x45, 0xD0, 0x60, 0xF7, 0x5D, 0xC2, 0x8D, 0xF3, 0xF6, 0xED,
1327  0xB8, 0x02, 0x7E, 0x23, 0x46, 0x43, 0x0D, 0x21, 0x13, 0x12, 0xC4, 0xB1, 0x50, 0x67, 0x7A, 0xF7,
1328  0x6F, 0xD7, 0x22, 0x3D, 0x45, 0x7B, 0x5B, 0x1A},
1329  56,
1330  //Base point order q
1331  {0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1332  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0xCA, 0x23, 0xE9,
1333  0xC4, 0x4E, 0xDB, 0x49, 0xAE, 0xD6, 0x36, 0x90, 0x21, 0x6C, 0xC2, 0x72, 0x8D, 0xC5, 0x8F, 0x55,
1334  0x23, 0x78, 0xC2, 0x92, 0xAB, 0x58, 0x44, 0xF3},
1335  56,
1336  //Cofactor
1337  4,
1338  //Fast modular reduction
1339  NULL
1340 };
1341 
1342 #endif
1343 #if (SECP128R1_SUPPORT == ENABLED)
1344 
1345 /**
1346  * @brief Fast modular reduction (secp128r1 curve)
1347  * @param[in,out] a This function accept an integer less than p^2 as
1348  * input and return (a mod p) as output
1349  * @param[in] p Prime modulus
1350  **/
1351 
1353 {
1354  error_t error;
1355  Mpi t;
1356 
1357  //Initialize multiple precision integers
1358  mpiInit(&t);
1359 
1360  //Ajust the size of the integers
1361  MPI_CHECK(mpiGrow(a, 32 / MPI_INT_SIZE));
1362  MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
1363 
1364  //Perform modular reduction
1365  do
1366  {
1367  //Compute T = 0 | 0 | 0 | 0 | A7 | A6 | A5 | A4
1368  COPY_WORD32(&t, 0, a, 4, 4);
1369  CLEAR_WORD32(&t, 4, 4);
1370 
1371  //Clear A7 | A6 | A5 | A4
1372  CLEAR_WORD32(a, 4, 4);
1373 
1374  //Compute A = A + T + (T << 97)
1375  MPI_CHECK(mpiAdd(a, a, &t));
1376  MPI_CHECK(mpiShiftLeft(&t, 97));
1377  MPI_CHECK(mpiAdd(a, a, &t));
1378 
1379  //Check for end condition
1380  } while(mpiComp(a, p) > 0);
1381 
1382 end:
1383  //Release multiple precision integers
1384  mpiFree(&t);
1385 
1386  //Return status code
1387  return error;
1388 }
1389 
1390 #endif
1391 #if (SECP128R2_SUPPORT == ENABLED)
1392 
1393 /**
1394  * @brief Fast modular reduction (secp128r2 curve)
1395  * @param[in,out] a This function accept an integer less than p^2 as
1396  * input and return (a mod p) as output
1397  * @param[in] p Prime modulus
1398  **/
1399 
1401 {
1402  error_t error;
1403  Mpi t;
1404 
1405  //Initialize multiple precision integers
1406  mpiInit(&t);
1407 
1408  //Ajust the size of the integers
1409  MPI_CHECK(mpiGrow(a, 32 / MPI_INT_SIZE));
1410  MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
1411 
1412  //Perform modular reduction
1413  do
1414  {
1415  //Compute T = 0 | 0 | 0 | 0 | A7 | A6 | A5 | A4
1416  COPY_WORD32(&t, 0, a, 4, 4);
1417  CLEAR_WORD32(&t, 4, 4);
1418 
1419  //Clear A7 | A6 | A5 | A4
1420  CLEAR_WORD32(a, 4, 4);
1421 
1422  //Compute A = A + T + (T << 97)
1423  MPI_CHECK(mpiAdd(a, a, &t));
1424  MPI_CHECK(mpiShiftLeft(&t, 97));
1425  MPI_CHECK(mpiAdd(a, a, &t));
1426 
1427  //Check for end condition
1428  } while(mpiComp(a, p) > 0);
1429 
1430 end:
1431  //Release multiple precision integers
1432  mpiFree(&t);
1433 
1434  //Return status code
1435  return error;
1436 }
1437 
1438 #endif
1439 #if (SECP160K1_SUPPORT == ENABLED)
1440 
1441 /**
1442  * @brief Fast modular reduction (secp160k1 curve)
1443  * @param[in,out] a This function accept an integer less than p^2 as
1444  * input and return (a mod p) as output
1445  * @param[in] p Prime modulus
1446  **/
1447 
1449 {
1450  error_t error;
1451  Mpi t;
1452 
1453  //Initialize multiple precision integers
1454  mpiInit(&t);
1455 
1456  //Ajust the size of the integers
1457  MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE));
1458  MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
1459 
1460  //Perform modular reduction
1461  do
1462  {
1463  //Compute T = A9 | A8 | A7 | A6 | A5 | 0
1464  CLEAR_WORD32(&t, 0, 1);
1465  COPY_WORD32(&t, 1, a, 5, 5);
1466 
1467  //Clear A9 | A8 | A7 | A6 | A5
1468  CLEAR_WORD32(a, 5, 5);
1469 
1470  //Compute A = A + T
1471  MPI_CHECK(mpiAdd(a, a, &t));
1472  //Compute T = T >> 32
1473  MPI_CHECK(mpiShiftRight(&t, 32));
1474  //Compute A = A + (21389 * T)
1475  MPI_CHECK(mpiMulInt(&t, &t, 21389));
1476  MPI_CHECK(mpiAdd(a, a, &t));
1477 
1478  //Check for end condition
1479  } while(mpiComp(a, p) > 0);
1480 
1481 end:
1482  //Release multiple precision integers
1483  mpiFree(&t);
1484 
1485  //Return status code
1486  return error;
1487 }
1488 
1489 #endif
1490 #if (SECP160R1_SUPPORT == ENABLED)
1491 
1492 /**
1493  * @brief Fast modular reduction (secp160r1 curve)
1494  * @param[in,out] a This function accept an integer less than p^2 as
1495  * input and return (a mod p) as output
1496  * @param[in] p Prime modulus
1497  **/
1498 
1500 {
1501  error_t error;
1502  Mpi t;
1503 
1504  //Initialize multiple precision integers
1505  mpiInit(&t);
1506 
1507  //Ajust the size of the integers
1508  MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE));
1509  MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
1510 
1511  //Perform modular reduction
1512  do
1513  {
1514  //Compute T = 0 | A9 | A8 | A7 | A6 | A5
1515  COPY_WORD32(&t, 0, a, 5, 5);
1516  CLEAR_WORD32(&t, 5, 1);
1517 
1518  //Clear A9 | A8 | A7 | A6 | A5
1519  CLEAR_WORD32(a, 5, 5);
1520 
1521  //Compute A = A + T + (T << 31)
1522  MPI_CHECK(mpiAdd(a, a, &t));
1523  MPI_CHECK(mpiShiftLeft(&t, 31));
1524  MPI_CHECK(mpiAdd(a, a, &t));
1525 
1526  //Check for end condition
1527  } while(mpiComp(a, p) > 0);
1528 
1529 end:
1530  //Release multiple precision integers
1531  mpiFree(&t);
1532 
1533  //Return status code
1534  return error;
1535 }
1536 
1537 #endif
1538 #if (SECP160R2_SUPPORT == ENABLED)
1539 
1540 /**
1541  * @brief Fast modular reduction (secp160r2 curve)
1542  * @param[in,out] a This function accept an integer less than p^2 as
1543  * input and return (a mod p) as output
1544  * @param[in] p Prime modulus
1545  **/
1546 
1548 {
1549  error_t error;
1550  Mpi t;
1551 
1552  //Initialize multiple precision integers
1553  mpiInit(&t);
1554 
1555  //Ajust the size of the integers
1556  MPI_CHECK(mpiGrow(a, 40 / MPI_INT_SIZE));
1557  MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
1558 
1559  //Perform modular reduction
1560  do
1561  {
1562  //Compute T = A9 | A8 | A7 | A6 | A5 | 0
1563  CLEAR_WORD32(&t, 0, 1);
1564  COPY_WORD32(&t, 1, a, 5, 5);
1565 
1566  //Clear A9 | A8 | A7 | A6 | A5
1567  CLEAR_WORD32(a, 5, 5);
1568 
1569  //Compute A = A + T
1570  MPI_CHECK(mpiAdd(a, a, &t));
1571  //Compute T = T >> 32
1572  MPI_CHECK(mpiShiftRight(&t, 32));
1573  //Compute A = A + (21389 * T)
1574  MPI_CHECK(mpiMulInt(&t, &t, 21389));
1575  MPI_CHECK(mpiAdd(a, a, &t));
1576 
1577  //Check for end condition
1578  } while(mpiComp(a, p) > 0);
1579 
1580 end:
1581  //Release multiple precision integers
1582  mpiFree(&t);
1583 
1584  //Return status code
1585  return error;
1586 }
1587 
1588 #endif
1589 #if (SECP192K1_SUPPORT == ENABLED)
1590 
1591 /**
1592  * @brief Fast modular reduction (secp192k1 curve)
1593  * @param[in,out] a This function accept an integer less than p^2 as
1594  * input and return (a mod p) as output
1595  * @param[in] p Prime modulus
1596  **/
1597 
1599 {
1600  error_t error;
1601  Mpi t;
1602 
1603  //Initialize multiple precision integers
1604  mpiInit(&t);
1605 
1606  //Ajust the size of the integers
1607  MPI_CHECK(mpiGrow(a, 48 / MPI_INT_SIZE));
1608  MPI_CHECK(mpiGrow(&t, 28 / MPI_INT_SIZE));
1609 
1610  //Perform modular reduction
1611  do
1612  {
1613  //Compute T = A11 | A10 | A9 | A8 | A7 | A6 | 0
1614  CLEAR_WORD32(&t, 0, 1);
1615  COPY_WORD32(&t, 1, a, 6, 6);
1616 
1617  //Clear A11 | A10 | A9 | A8 | A7 | A6
1618  CLEAR_WORD32(a, 6, 6);
1619 
1620  //Compute A = A + T
1621  MPI_CHECK(mpiAdd(a, a, &t));
1622  //Compute T = T >> 32
1623  MPI_CHECK(mpiShiftRight(&t, 32));
1624  //Compute A = A + (4553 * T)
1625  MPI_CHECK(mpiMulInt(&t, &t, 4553));
1626  MPI_CHECK(mpiAdd(a, a, &t));
1627 
1628  //Check for end condition
1629  } while(mpiComp(a, p) > 0);
1630 
1631 end:
1632  //Release multiple precision integers
1633  mpiFree(&t);
1634 
1635  //Return status code
1636  return error;
1637 }
1638 
1639 #endif
1640 #if (SECP192R1_SUPPORT == ENABLED)
1641 
1642 /**
1643  * @brief Fast modular reduction (secp192r1 curve)
1644  * @param[in,out] a This function accept an integer less than p^2 as
1645  * input and return (a mod p) as output
1646  * @param[in] p Prime modulus
1647  **/
1648 
1650 {
1651  error_t error;
1652  Mpi s;
1653  Mpi t;
1654 
1655  //Initialize multiple precision integers
1656  mpiInit(&s);
1657  mpiInit(&t);
1658 
1659  //Ajust the size of the integers
1660  MPI_CHECK(mpiGrow(a, 48 / MPI_INT_SIZE));
1661  MPI_CHECK(mpiGrow(&s, 24 / MPI_INT_SIZE));
1662  MPI_CHECK(mpiGrow(&t, 24 / MPI_INT_SIZE));
1663 
1664  //Compute T = A5 | A4 | A3 | A2 | A1 | A0
1665  COPY_WORD32(&t, 0, a, 0, 6);
1666 
1667  //Compute S1 = 0 | 0 | A7 | A6 | A7 | A6
1668  COPY_WORD32(&s, 0, a, 6, 2);
1669  COPY_WORD32(&s, 2, a, 6, 2);
1670  CLEAR_WORD32(&s, 4, 2);
1671  //Compute T = T + S1
1672  MPI_CHECK(mpiAdd(&t, &t, &s));
1673 
1674  //Compute S2 = A9 | A8 | A9 | A8 | 0 | 0
1675  CLEAR_WORD32(&s, 0, 2);
1676  COPY_WORD32(&s, 2, a, 8, 2);
1677  COPY_WORD32(&s, 4, a, 8, 2);
1678  //Compute T = T + S2
1679  MPI_CHECK(mpiAdd(&t, &t, &s));
1680 
1681  //Compute S3 = A11 | A10 | A11 | A10 | A11 | A10
1682  COPY_WORD32(&s, 0, a, 10, 2);
1683  COPY_WORD32(&s, 2, a, 10, 2);
1684  COPY_WORD32(&s, 4, a, 10, 2);
1685  //Compute T = T + S3
1686  MPI_CHECK(mpiAdd(&t, &t, &s));
1687 
1688  //Compute (T + S1 + S2 + S3) mod p
1689  while(mpiComp(&t, p) >= 0)
1690  {
1691  MPI_CHECK(mpiSub(&t, &t, p));
1692  }
1693 
1694  //Save result
1695  MPI_CHECK(mpiCopy(a, &t));
1696 
1697 end:
1698  //Release multiple precision integers
1699  mpiFree(&s);
1700  mpiFree(&t);
1701 
1702  //Return status code
1703  return error;
1704 }
1705 
1706 #endif
1707 #if (SECP224K1_SUPPORT == ENABLED)
1708 
1709 /**
1710  * @brief Fast modular reduction (secp224k1 curve)
1711  * @param[in,out] a This function accept an integer less than p^2 as
1712  * input and return (a mod p) as output
1713  * @param[in] p Prime modulus
1714  **/
1715 
1717 {
1718  error_t error;
1719  Mpi t;
1720 
1721  //Initialize multiple precision integers
1722  mpiInit(&t);
1723 
1724  //Ajust the size of the integers
1725  MPI_CHECK(mpiGrow(a, 56 / MPI_INT_SIZE));
1726  MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
1727 
1728  //Perform modular reduction
1729  do
1730  {
1731  //Compute T = A13 | A12 | A11 | A10 | A9 | A8 | A7 | 0
1732  CLEAR_WORD32(&t, 0, 1);
1733  COPY_WORD32(&t, 1, a, 7, 7);
1734 
1735  //Clear A13 | A12 | A11 | A10 | A9 | A8 | A7
1736  CLEAR_WORD32(a, 7, 7);
1737 
1738  //Compute A = A + T
1739  MPI_CHECK(mpiAdd(a, a, &t));
1740  //Compute T = T >> 32
1741  MPI_CHECK(mpiShiftRight(&t, 32));
1742  //Compute A = A + (6803 * T)
1743  MPI_CHECK(mpiMulInt(&t, &t, 6803));
1744  MPI_CHECK(mpiAdd(a, a, &t));
1745 
1746  //Check for end condition
1747  } while(mpiComp(a, p) > 0);
1748 
1749 end:
1750  //Release multiple precision integers
1751  mpiFree(&t);
1752 
1753  //Return status code
1754  return error;
1755 }
1756 
1757 #endif
1758 #if (SECP224R1_SUPPORT == ENABLED)
1759 
1760 /**
1761  * @brief Fast modular reduction (secp224r1 curve)
1762  * @param[in,out] a This function accept an integer less than p^2 as
1763  * input and return (a mod p) as output
1764  * @param[in] p Prime modulus
1765  **/
1766 
1768 {
1769  error_t error;
1770  Mpi s;
1771  Mpi t;
1772 
1773  //Initialize multiple precision integers
1774  mpiInit(&s);
1775  mpiInit(&t);
1776 
1777  //Ajust the size of the integers
1778  MPI_CHECK(mpiGrow(a, 56 / MPI_INT_SIZE));
1779  MPI_CHECK(mpiGrow(&s, 28 / MPI_INT_SIZE));
1780  MPI_CHECK(mpiGrow(&t, 28 / MPI_INT_SIZE));
1781 
1782  //Compute T = A6 | A5 | A4 | A3 | A2 | A1 | A0
1783  COPY_WORD32(&t, 0, a, 0, 7);
1784 
1785  //Compute S1 = A10 | A9 | A8 | A7 | 0 | 0 | 0
1786  CLEAR_WORD32(&s, 0, 3);
1787  COPY_WORD32(&s, 3, a, 7, 4);
1788  //Compute T = T + S1
1789  MPI_CHECK(mpiAdd(&t, &t, &s));
1790 
1791  //Compute S2 = 0 | A13 | A12 | A11 | 0 | 0 | 0
1792  CLEAR_WORD32(&s, 0, 3);
1793  COPY_WORD32(&s, 3, a, 11, 3);
1794  CLEAR_WORD32(&s, 6, 1);
1795  //Compute T = T + S2
1796  MPI_CHECK(mpiAdd(&t, &t, &s));
1797 
1798  //Compute D1 = A13 | A12 | A11 | A10 | A9 | A8 | A7
1799  COPY_WORD32(&s, 0, a, 7, 7);
1800  //Compute T = T - D1
1801  MPI_CHECK(mpiSub(&t, &t, &s));
1802 
1803  //Compute D2 = 0 | 0 | 0 | 0 | A13 | A12 | A11
1804  COPY_WORD32(&s, 0, a, 11, 3);
1805  CLEAR_WORD32(&s, 3, 4);
1806  //Compute T = T - D2
1807  MPI_CHECK(mpiSub(&t, &t, &s));
1808 
1809  //Compute (T + S1 + S2 - D1 - D2) mod p
1810  while(mpiComp(&t, p) >= 0)
1811  {
1812  MPI_CHECK(mpiSub(&t, &t, p));
1813  }
1814 
1815  while(mpiCompInt(&t, 0) < 0)
1816  {
1817  MPI_CHECK(mpiAdd(&t, &t, p));
1818  }
1819 
1820  //Save result
1821  MPI_CHECK(mpiCopy(a, &t));
1822 
1823 end:
1824  //Release multiple precision integers
1825  mpiFree(&s);
1826  mpiFree(&t);
1827 
1828  //Return status code
1829  return error;
1830 }
1831 
1832 #endif
1833 #if (SECP256K1_SUPPORT == ENABLED)
1834 
1835 /**
1836  * @brief Fast modular reduction (secp256k1 curve)
1837  * @param[in,out] a This function accept an integer less than p^2 as
1838  * input and return (a mod p) as output
1839  * @param[in] p Prime modulus
1840  **/
1841 
1843 {
1844  error_t error;
1845  Mpi t;
1846 
1847  //Initialize multiple precision integers
1848  mpiInit(&t);
1849 
1850  //Ajust the size of the integers
1851  MPI_CHECK(mpiGrow(a, 64 / MPI_INT_SIZE));
1852  MPI_CHECK(mpiGrow(&t, 36 / MPI_INT_SIZE));
1853 
1854  //Perform modular reduction
1855  do
1856  {
1857  //Compute T = A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 | 0
1858  CLEAR_WORD32(&t, 0, 1);
1859  COPY_WORD32(&t, 1, a, 8, 8);
1860 
1861  //Clear A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8
1862  CLEAR_WORD32(a, 8, 8);
1863 
1864  //Compute A = A + T
1865  MPI_CHECK(mpiAdd(a, a, &t));
1866  //Compute T = T >> 32
1867  MPI_CHECK(mpiShiftRight(&t, 32));
1868  //Compute A = A + (977 * T)
1869  MPI_CHECK(mpiMulInt(&t, &t, 977));
1870  MPI_CHECK(mpiAdd(a, a, &t));
1871 
1872  //Check for end condition
1873  } while(mpiComp(a, p) > 0);
1874 
1875 end:
1876  //Release multiple precision integers
1877  mpiFree(&t);
1878 
1879  //Return status code
1880  return error;
1881 }
1882 
1883 #endif
1884 #if (SECP256R1_SUPPORT == ENABLED)
1885 
1886 /**
1887  * @brief Fast modular reduction (secp256r1 curve)
1888  * @param[in,out] a This function accept an integer less than p^2 as
1889  * input and return (a mod p) as output
1890  * @param[in] p Prime modulus
1891  **/
1892 
1894 {
1895  error_t error;
1896  Mpi s;
1897  Mpi t;
1898  Mpi b;
1899 
1900  //Initialize multiple precision integers
1901  mpiInit(&s);
1902  mpiInit(&t);
1903  mpiInit(&b);
1904 
1905  //Ajust the size of the integers
1906  MPI_CHECK(mpiGrow(a, 64 / MPI_INT_SIZE));
1907  MPI_CHECK(mpiGrow(&s, 32 / MPI_INT_SIZE));
1908  MPI_CHECK(mpiGrow(&t, 32 / MPI_INT_SIZE));
1909 
1910  //Compute T = A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0
1911  COPY_WORD32(&t, 0, a, 0, 8);
1912 
1913  //Compute S1 = A15 | A14 | A13 | A12 | A11 | 0 | 0 | 0
1914  CLEAR_WORD32(&s, 0, 3);
1915  COPY_WORD32(&s, 3, a, 11, 5);
1916  //Compute T = T + 2 * S1
1917  MPI_CHECK(mpiAdd(&t, &t, &s));
1918  MPI_CHECK(mpiAdd(&t, &t, &s));
1919 
1920  //Compute S2 = 0 | A15 | A14 | A13 | A12 | 0 | 0 | 0
1921  CLEAR_WORD32(&s, 0, 3);
1922  COPY_WORD32(&s, 3, a, 12, 4);
1923  CLEAR_WORD32(&s, 7, 1);
1924  //Compute T = T + 2 * S2
1925  MPI_CHECK(mpiAdd(&t, &t, &s));
1926  MPI_CHECK(mpiAdd(&t, &t, &s));
1927 
1928  //Compute S3 = A15 | A14 | 0 | 0 | 0 | A10 | A9 | A8
1929  COPY_WORD32(&s, 0, a, 8, 3);
1930  CLEAR_WORD32(&s, 3, 3);
1931  COPY_WORD32(&s, 6, a, 14, 2);
1932  //Compute T = T + S3
1933  MPI_CHECK(mpiAdd(&t, &t, &s));
1934 
1935  //Compute S4 = A8 | A13 | A15 | A14 | A13 | A11 | A10 | A9
1936  COPY_WORD32(&s, 0, a, 9, 3);
1937  COPY_WORD32(&s, 3, a, 13, 3);
1938  COPY_WORD32(&s, 6, a, 13, 1);
1939  COPY_WORD32(&s, 7, a, 8, 1);
1940  //Compute T = T + S4
1941  MPI_CHECK(mpiAdd(&t, &t, &s));
1942 
1943  //Compute D1 = A10 | A8 | 0 | 0 | 0 | A13 | A12 | A11
1944  COPY_WORD32(&s, 0, a, 11, 3);
1945  CLEAR_WORD32(&s, 3, 3);
1946  COPY_WORD32(&s, 6, a, 8, 1);
1947  COPY_WORD32(&s, 7, a, 10, 1);
1948  //Compute T = T - D1
1949  MPI_CHECK(mpiSub(&t, &t, &s));
1950 
1951  //Compute D2 = A11 | A9 | 0 | 0 | A15 | A14 | A13 | A12
1952  COPY_WORD32(&s, 0, a, 12, 4);
1953  CLEAR_WORD32(&s, 4, 2);
1954  COPY_WORD32(&s, 6, a, 9, 1);
1955  COPY_WORD32(&s, 7, a, 11, 1);
1956  //Compute T = T - D2
1957  MPI_CHECK(mpiSub(&t, &t, &s));
1958 
1959  //Compute D3 = A12 | 0 | A10 | A9 | A8 | A15 | A14 | A13
1960  COPY_WORD32(&s, 0, a, 13, 3);
1961  COPY_WORD32(&s, 3, a, 8, 3);
1962  CLEAR_WORD32(&s, 6, 1);
1963  COPY_WORD32(&s, 7, a, 12, 1);
1964  //Compute T = T - D3
1965  MPI_CHECK(mpiSub(&t, &t, &s));
1966 
1967  //Compute D4 = A13 | 0 | A11 | A10 | A9 | 0 | A15 | A14
1968  COPY_WORD32(&s, 0, a, 14, 2);
1969  CLEAR_WORD32(&s, 2, 1);
1970  COPY_WORD32(&s, 3, a, 9, 3);
1971  CLEAR_WORD32(&s, 6, 1);
1972  COPY_WORD32(&s, 7, a, 13, 1);
1973  //Compute T = T - D4
1974  MPI_CHECK(mpiSub(&t, &t, &s));
1975 
1976  //Compute (T + 2 * S1 + 2 * S2 + S3 + S4 - D1 - D2 - D3 - D4) mod p
1977  while(mpiComp(&t, p) >= 0)
1978  {
1979  MPI_CHECK(mpiSub(&t, &t, p));
1980  }
1981 
1982  while(mpiCompInt(&t, 0) < 0)
1983  {
1984  MPI_CHECK(mpiAdd(&t, &t, p));
1985  }
1986 
1987  //Save result
1988  MPI_CHECK(mpiCopy(a, &t));
1989 
1990 end:
1991  //Release multiple precision integers
1992  mpiFree(&s);
1993  mpiFree(&t);
1994 
1995  //Return status code
1996  return error;
1997 }
1998 
1999 #endif
2000 #if (SECP384R1_SUPPORT == ENABLED)
2001 
2002 /**
2003  * @brief Fast modular reduction (secp384r1 curve)
2004  * @param[in,out] a This function accept an integer less than p^2 as
2005  * input and return (a mod p) as output
2006  * @param[in] p Prime modulus
2007  **/
2008 
2010 {
2011  error_t error;
2012  Mpi s;
2013  Mpi t;
2014 
2015  //Initialize multiple precision integers
2016  mpiInit(&s);
2017  mpiInit(&t);
2018 
2019  //Ajust the size of the integers
2020  MPI_CHECK(mpiGrow(a, 96 / MPI_INT_SIZE));
2021  MPI_CHECK(mpiGrow(&s, 48 / MPI_INT_SIZE));
2022  MPI_CHECK(mpiGrow(&t, 48 / MPI_INT_SIZE));
2023 
2024  //Compute T = A11 | A10 | A9 | A8 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0
2025  COPY_WORD32(&t, 0, a, 0, 12);
2026 
2027  //Compute S1 = 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | 0 | 0 | 0 | 0
2028  CLEAR_WORD32(&s, 0, 4);
2029  COPY_WORD32(&s, 4, a, 21, 3);
2030  CLEAR_WORD32(&s, 7, 5);
2031  //Compute T = T + 2 * S1
2032  MPI_CHECK(mpiAdd(&t, &t, &s));
2033  MPI_CHECK(mpiAdd(&t, &t, &s));
2034 
2035  //Compute S2 = A23 | A22 | A21 | A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12
2036  COPY_WORD32(&s, 0, a, 12, 12);
2037  //Compute T = T + S2
2038  MPI_CHECK(mpiAdd(&t, &t, &s));
2039 
2040  //Compute S3 = A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A23| A22 | A21
2041  COPY_WORD32(&s, 0, a, 21, 3);
2042  COPY_WORD32(&s, 3, a, 12, 9);
2043  //Compute T = T + S3
2044  MPI_CHECK(mpiAdd(&t, &t, &s));
2045 
2046  //Compute S4 = A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A20 | 0 | A23 | 0
2047  CLEAR_WORD32(&s, 0, 1);
2048  COPY_WORD32(&s, 1, a, 23, 1);
2049  CLEAR_WORD32(&s, 2, 1);
2050  COPY_WORD32(&s, 3, a, 20, 1);
2051  COPY_WORD32(&s, 4, a, 12, 8);
2052  //Compute T = T + S4
2053  MPI_CHECK(mpiAdd(&t, &t, &s));
2054 
2055  //Compute S5 = 0 | 0 | 0 | 0 | A23 | A22 | A21 | A20 | 0 | 0 | 0 | 0
2056  CLEAR_WORD32(&s, 0, 4);
2057  COPY_WORD32(&s, 4, a, 20, 4);
2058  CLEAR_WORD32(&s, 8, 4);
2059  //Compute T = T + S5
2060  MPI_CHECK(mpiAdd(&t, &t, &s));
2061 
2062  //Compute S6 = 0 | 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | 0 | 0 | A20
2063  COPY_WORD32(&s, 0, a, 20, 1);
2064  CLEAR_WORD32(&s, 1, 2);
2065  COPY_WORD32(&s, 3, a, 21, 3);
2066  CLEAR_WORD32(&s, 6, 6);
2067  //Compute T = T + S6
2068  MPI_CHECK(mpiAdd(&t, &t, &s));
2069 
2070  //Compute D1 = A22 | A21 | A20 | A19 | A18 | A17 | A16 | A15 | A14 | A13 | A12 | A23
2071  COPY_WORD32(&s, 0, a, 23, 1);
2072  COPY_WORD32(&s, 1, a, 12, 11);
2073  //Compute T = T - D1
2074  MPI_CHECK(mpiSub(&t, &t, &s));
2075 
2076  //Compute D2 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | A23 | A22 | A21 | A20 | 0
2077  CLEAR_WORD32(&s, 0, 1);
2078  COPY_WORD32(&s, 1, a, 20, 4);
2079  CLEAR_WORD32(&s, 5, 7);
2080  //Compute T = T - D2
2081  MPI_CHECK(mpiSub(&t, &t, &s));
2082 
2083  //Compute D3 = 0 | 0 | 0 | 0 | 0 | 0 | 0 | A23 | A23 | 0 | 0 | 0
2084  CLEAR_WORD32(&s, 0, 3);
2085  COPY_WORD32(&s, 3, a, 23, 1);
2086  COPY_WORD32(&s, 4, a, 23, 1);
2087  CLEAR_WORD32(&s, 5, 7);
2088  //Compute T = T - D3
2089  MPI_CHECK(mpiSub(&t, &t, &s));
2090 
2091  //Compute (T + 2 * S1 + S2 + S3 + S4 + S5 + S6 - D1 - D2 - D3) mod p
2092  while(mpiComp(&t, p) >= 0)
2093  {
2094  MPI_CHECK(mpiSub(&t, &t, p));
2095  }
2096 
2097  while(mpiCompInt(&t, 0) < 0)
2098  {
2099  MPI_CHECK(mpiAdd(&t, &t, p));
2100  }
2101 
2102  //Save result
2103  MPI_CHECK(mpiCopy(a, &t));
2104 
2105 end:
2106  //Release multiple precision integers
2107  mpiFree(&s);
2108  mpiFree(&t);
2109 
2110  //Return status code
2111  return error;
2112 }
2113 
2114 #endif
2115 #if (SECP521R1_SUPPORT == ENABLED)
2116 
2117 /**
2118  * @brief Fast modular reduction (secp521r1 curve)
2119  * @param[in,out] a This function accept an integer less than p^2 as
2120  * input and return (a mod p) as output
2121  * @param[in] p Prime modulus
2122  **/
2123 
2125 {
2126  error_t error;
2127  Mpi t;
2128 
2129  //Initialize multiple precision integer
2130  mpiInit(&t);
2131 
2132  //Ajust the size of the integers
2133  MPI_CHECK(mpiGrow(a, 132 / MPI_INT_SIZE));
2134  MPI_CHECK(mpiGrow(&t, 68 / MPI_INT_SIZE));
2135 
2136  //Compute A0
2137  COPY_WORD32(&t, 0, a, 0, 17);
2138  t.data[16] &= 0x000001FF;
2139 
2140  //Compute A1
2141  MPI_CHECK(mpiShiftRight(a, 521));
2142 
2143  //Compute A0 + A1
2144  MPI_CHECK(mpiAdd(a, a, &t));
2145 
2146  //Compute (A0 + A1) mod p
2147  while(mpiComp(a, p) >= 0)
2148  {
2149  MPI_CHECK(mpiSub(a, a, p));
2150  }
2151 
2152 end:
2153  //Release multiple precision integer
2154  mpiFree(&t);
2155 
2156  //Return status code
2157  return error;
2158 }
2159 
2160 #endif
2161 
2162 
2163 /**
2164  * @brief Get the elliptic curve that matches the specified OID
2165  * @param[in] oid Object identifier
2166  * @param[in] length OID length
2167  * @return Elliptic curve domain parameters
2168  **/
2169 
2170 const EcCurveInfo *ecGetCurveInfo(const uint8_t *oid, size_t length)
2171 {
2172  const EcCurveInfo *curveInfo;
2173 
2174  //Invalid parameters?
2175  if(oid == NULL || length == 0)
2176  {
2177  curveInfo = NULL;
2178  }
2179 #if (SECP112R1_SUPPORT == ENABLED)
2180  //secp112r1 elliptic curve?
2181  else if(!oidComp(oid, length, SECP112R1_OID, sizeof(SECP112R1_OID)))
2182  {
2183  curveInfo = SECP112R1_CURVE;
2184  }
2185 #endif
2186 #if (SECP112R2_SUPPORT == ENABLED)
2187  //secp112r2 elliptic curve?
2188  else if(!oidComp(oid, length, SECP112R2_OID, sizeof(SECP112R2_OID)))
2189  {
2190  curveInfo = SECP112R2_CURVE;
2191  }
2192 #endif
2193 #if (SECP128R1_SUPPORT == ENABLED)
2194  //secp128r1 elliptic curve?
2195  else if(!oidComp(oid, length, SECP128R1_OID, sizeof(SECP128R1_OID)))
2196  {
2197  curveInfo = SECP128R1_CURVE;
2198  }
2199 #endif
2200 #if (SECP128R2_SUPPORT == ENABLED)
2201  //secp128r2 elliptic curve?
2202  else if(!oidComp(oid, length, SECP128R2_OID, sizeof(SECP128R2_OID)))
2203  {
2204  curveInfo = SECP128R2_CURVE;
2205  }
2206 #endif
2207 #if (SECP160K1_SUPPORT == ENABLED)
2208  //secp160k1 elliptic curve?
2209  else if(!oidComp(oid, length, SECP160K1_OID, sizeof(SECP160K1_OID)))
2210  {
2211  curveInfo = SECP160K1_CURVE;
2212  }
2213 #endif
2214 #if (SECP160R1_SUPPORT == ENABLED)
2215  //secp160r1 elliptic curve?
2216  else if(!oidComp(oid, length, SECP160R1_OID, sizeof(SECP160R1_OID)))
2217  {
2218  curveInfo = SECP160R1_CURVE;
2219  }
2220 #endif
2221 #if (SECP160R2_SUPPORT == ENABLED)
2222  //secp160r2 elliptic curve?
2223  else if(!oidComp(oid, length, SECP160R2_OID, sizeof(SECP160R2_OID)))
2224  {
2225  curveInfo = SECP160R2_CURVE;
2226  }
2227 #endif
2228 #if (SECP192K1_SUPPORT == ENABLED)
2229  //secp192k1 elliptic curve?
2230  else if(!oidComp(oid, length, SECP192K1_OID, sizeof(SECP192K1_OID)))
2231  {
2232  curveInfo = SECP192K1_CURVE;
2233  }
2234 #endif
2235 #if (SECP192R1_SUPPORT == ENABLED)
2236  //secp192r1 elliptic curve?
2237  else if(!oidComp(oid, length, SECP192R1_OID, sizeof(SECP192R1_OID)))
2238  {
2239  curveInfo = SECP192R1_CURVE;
2240  }
2241 #endif
2242 #if (SECP224K1_SUPPORT == ENABLED)
2243  //secp224k1 elliptic curve?
2244  else if(!oidComp(oid, length, SECP224K1_OID, sizeof(SECP224K1_OID)))
2245  {
2246  curveInfo = SECP224K1_CURVE;
2247  }
2248 #endif
2249 #if (SECP224R1_SUPPORT == ENABLED)
2250  //secp224r1 elliptic curve?
2251  else if(!oidComp(oid, length, SECP224R1_OID, sizeof(SECP224R1_OID)))
2252  {
2253  curveInfo = SECP224R1_CURVE;
2254  }
2255 #endif
2256 #if (SECP256K1_SUPPORT == ENABLED)
2257  //secp256k1 elliptic curve?
2258  else if(!oidComp(oid, length, SECP256K1_OID, sizeof(SECP256K1_OID)))
2259  {
2260  curveInfo = SECP256K1_CURVE;
2261  }
2262 #endif
2263 #if (SECP256R1_SUPPORT == ENABLED)
2264  //secp256r1 elliptic curve?
2265  else if(!oidComp(oid, length, SECP256R1_OID, sizeof(SECP256R1_OID)))
2266  {
2267  curveInfo = SECP256R1_CURVE;
2268  }
2269 #endif
2270 #if (SECP384R1_SUPPORT == ENABLED)
2271  //secp384r1 elliptic curve?
2272  else if(!oidComp(oid, length, SECP384R1_OID, sizeof(SECP384R1_OID)))
2273  {
2274  curveInfo = SECP384R1_CURVE;
2275  }
2276 #endif
2277 #if (SECP521R1_SUPPORT == ENABLED)
2278  //secp521r1 elliptic curve?
2279  else if(!oidComp(oid, length, SECP521R1_OID, sizeof(SECP521R1_OID)))
2280  {
2281  curveInfo = SECP521R1_CURVE;
2282  }
2283 #endif
2284 #if (BRAINPOOLP160R1_SUPPORT == ENABLED)
2285  //brainpoolP160r1 elliptic curve?
2287  {
2288  curveInfo = BRAINPOOLP160R1_CURVE;
2289  }
2290 #endif
2291 #if (BRAINPOOLP192R1_SUPPORT == ENABLED)
2292  //brainpoolP192r1 elliptic curve?
2294  {
2295  curveInfo = BRAINPOOLP192R1_CURVE;
2296  }
2297 #endif
2298 #if (BRAINPOOLP224R1_SUPPORT == ENABLED)
2299  //brainpoolP224r1 elliptic curve?
2301  {
2302  curveInfo = BRAINPOOLP224R1_CURVE;
2303  }
2304 #endif
2305 #if (BRAINPOOLP256R1_SUPPORT == ENABLED)
2306  //brainpoolP256r1 elliptic curve?
2308  {
2309  curveInfo = BRAINPOOLP256R1_CURVE;
2310  }
2311 #endif
2312 #if (BRAINPOOLP320R1_SUPPORT == ENABLED)
2313  //brainpoolP320r1 elliptic curve?
2315  {
2316  curveInfo = BRAINPOOLP320R1_CURVE;
2317  }
2318 #endif
2319 #if (BRAINPOOLP384R1_SUPPORT == ENABLED)
2320  //brainpoolP384r1 elliptic curve?
2322  {
2323  curveInfo = BRAINPOOLP384R1_CURVE;
2324  }
2325 #endif
2326 #if (BRAINPOOLP512R1_SUPPORT == ENABLED)
2327  //brainpoolP512r1 elliptic curve?
2329  {
2330  curveInfo = BRAINPOOLP512R1_CURVE;
2331  }
2332 #endif
2333 #if (X25519_SUPPORT == ENABLED)
2334  //Curve25519 elliptic curve?
2335  else if(!oidComp(oid, length, X25519_OID, sizeof(X25519_OID)))
2336  {
2337  curveInfo = X25519_CURVE;
2338  }
2339 #endif
2340 #if (X448_SUPPORT == ENABLED)
2341  //Curve448 elliptic curve?
2342  else if(!oidComp(oid, length, X448_OID, sizeof(X448_OID)))
2343  {
2344  curveInfo = X448_CURVE;
2345  }
2346 #endif
2347 #if (ED25519_SUPPORT == ENABLED)
2348  //Ed25519 elliptic curve?
2349  else if(!oidComp(oid, length, ED25519_OID, sizeof(ED25519_OID)))
2350  {
2351  curveInfo = ED25519_CURVE;
2352  }
2353 #endif
2354 #if (ED448_SUPPORT == ENABLED)
2355  //Ed448 elliptic curve?
2356  else if(!oidComp(oid, length, ED448_OID, sizeof(ED448_OID)))
2357  {
2358  curveInfo = ED448_CURVE;
2359  }
2360 #endif
2361  //Unknown identifier?
2362  else
2363  {
2364  curveInfo = NULL;
2365  }
2366 
2367  //Return the elliptic curve domain parameters, if any
2368  return curveInfo;
2369 }
2370 
2371 #endif
const uint8_t X25519_OID[3]
Definition: ec_curves.c:90
error_t secp160k1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp160k1 curve)
Definition: ec_curves.c:1448
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:747
const EcCurveInfo secp224r1Curve
secp224r1 elliptic curve
Definition: ec_curves.c:541
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:60
Arbitrary precision integer.
Definition: mpi.h:67
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
#define X25519_CURVE
Definition: ec_curves.h:245
#define X448_CURVE
Definition: ec_curves.h:246
error_t secp521r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp521r1 curve)
Definition: ec_curves.c:2124
Debugging facilities.
const EcCurveInfo x448Curve
Curve448 elliptic curve.
Definition: ec_curves.c:1187
error_t secp256k1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp256k1 curve)
Definition: ec_curves.c:1842
uint8_t p
Definition: ndp.h:295
const EcCurveInfo brainpoolP384r1Curve
brainpoolP384r1 elliptic curve
Definition: ec_curves.c:1031
const uint8_t SECP256K1_OID[5]
Definition: ec_curves.c:68
General definitions for cryptographic algorithms.
Elliptic curve parameters.
Definition: ec_curves.h:290
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:287
const EcCurveInfo brainpoolP224r1Curve
brainpoolP224r1 elliptic curve
Definition: ec_curves.c:887
const EcCurveInfo secp521r1Curve
secp521r1 elliptic curve
Definition: ec_curves.c:731
const uint8_t BRAINPOOLP160R1_OID[9]
Definition: ec_curves.c:76
const uint8_t SECP112R1_OID[5]
Definition: ec_curves.c:46
#define MPI_CHECK(f)
Definition: mpi.h:40
#define SECP160K1_CURVE
Definition: ec_curves.h:223
const uint8_t SECP160K1_OID[5]
Definition: ec_curves.c:54
const uint8_t SECP224K1_OID[5]
Definition: ec_curves.c:64
error_t secp224r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp224r1 curve)
Definition: ec_curves.c:1767
const uint8_t SECP224R1_OID[5]
Definition: ec_curves.c:66
const EcCurveInfo secp160k1Curve
secp160k1 elliptic curve
Definition: ec_curves.c:265
const EcCurveInfo secp256r1Curve
secp256r1 elliptic curve
Definition: ec_curves.c:633
const EcCurveInfo secp160r1Curve
secp160r1 elliptic curve
Definition: ec_curves.c:311
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:74
const uint8_t BRAINPOOLP384R1_OID[9]
Definition: ec_curves.c:86
uint8_t a
Definition: ndp.h:407
OID (Object Identifier)
Elliptic curves.
#define BRAINPOOLP192R1_CURVE
Definition: ec_curves.h:237
#define SECP256R1_CURVE
Definition: ec_curves.h:231
const uint8_t BRAINPOOLP320R1_OID[9]
Definition: ec_curves.c:84
const EcCurveInfo secp256k1Curve
secp256k1 elliptic curve
Definition: ec_curves.c:587
const EcCurveInfo secp192r1Curve
secp192r1 elliptic curve
Definition: ec_curves.c:449
#define SECP192R1_CURVE
Definition: ec_curves.h:227
const uint8_t SECP192K1_OID[5]
Definition: ec_curves.c:60
#define SECP224R1_CURVE
Definition: ec_curves.h:229
#define BRAINPOOLP160R1_CURVE
Definition: ec_curves.h:236
#define SECP521R1_CURVE
Definition: ec_curves.h:233
const EcCurveInfo secp112r1Curve
secp112r1 elliptic curve
Definition: ec_curves.c:105
const EcCurveInfo secp112r2Curve
secp112r2 elliptic curve
Definition: ec_curves.c:145
const EcCurveInfo ed25519Curve
Ed25519 elliptic curve.
Definition: ec_curves.c:1245
error_t secp224k1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp224k1 curve)
Definition: ec_curves.c:1716
const EcCurveInfo ed448Curve
Ed448 elliptic curve.
Definition: ec_curves.c:1291
const uint8_t ED448_OID[3]
Definition: ec_curves.c:96
error_t mpiCopy(Mpi *r, const Mpi *a)
Copy a multiple precision integer.
Definition: mpi.c:392
#define SECP112R2_CURVE
Definition: ec_curves.h:220
#define COPY_WORD32(a, i, b, j, n)
Definition: ec_curves.c:43
const EcCurveInfo secp160r2Curve
secp160r2 elliptic curve
Definition: ec_curves.c:357
const uint8_t BRAINPOOLP192R1_OID[9]
Definition: ec_curves.c:78
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:674
error_t secp256r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp256r1 curve)
Definition: ec_curves.c:1893
const uint8_t SECP128R2_OID[5]
Definition: ec_curves.c:52
const uint8_t X448_OID[3]
Definition: ec_curves.c:92
const EcCurveInfo secp128r2Curve
secp128r2 elliptic curve
Definition: ec_curves.c:225
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:99
uint8_t s
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:94
const uint8_t SECP160R1_OID[5]
Definition: ec_curves.c:56
#define SECP384R1_CURVE
Definition: ec_curves.h:232
uint_t * data
Definition: mpi.h:71
error_t mpiMulInt(Mpi *r, const Mpi *a, int_t b)
Multiply a multiple precision integer by an integer.
Definition: mpi.c:1167
error_t
Error codes.
Definition: error.h:40
#define SECP112R1_CURVE
Definition: ec_curves.h:219
int_t mpiCompInt(const Mpi *a, int_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:331
error_t secp192r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp192r1 curve)
Definition: ec_curves.c:1649
const EcCurveInfo secp192k1Curve
secp192k1 elliptic curve
Definition: ec_curves.c:403
const uint8_t SECP160R2_OID[5]
Definition: ec_curves.c:58
#define BRAINPOOLP320R1_CURVE
Definition: ec_curves.h:240
const uint8_t SECP192R1_OID[8]
Definition: ec_curves.c:62
#define BRAINPOOLP256R1_CURVE
Definition: ec_curves.h:239
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
error_t secp160r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp160r1 curve)
Definition: ec_curves.c:1499
const EcCurveInfo secp224k1Curve
secp224k1 elliptic curve
Definition: ec_curves.c:495
#define CLEAR_WORD32(a, i, n)
Definition: ec_curves.c:42
const uint8_t SECP112R2_OID[5]
Definition: ec_curves.c:48
const EcCurveInfo brainpoolP320r1Curve
brainpoolP320r1 elliptic curve
Definition: ec_curves.c:979
const uint8_t BRAINPOOLP224R1_OID[9]
Definition: ec_curves.c:80
error_t mpiShiftLeft(Mpi *r, uint_t n)
Left shift operation.
Definition: mpi.c:986
error_t secp192k1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp192k1 curve)
Definition: ec_curves.c:1598
const EcCurveInfo brainpoolP192r1Curve
brainpoolP192r1 elliptic curve
Definition: ec_curves.c:841
#define ED25519_CURVE
Definition: ec_curves.h:249
const EcCurveInfo brainpoolP160r1Curve
brainpoolP160r1 elliptic curve
Definition: ec_curves.c:795
#define MPI_INT_SIZE
Definition: mpi.h:37
const EcCurveInfo * ecGetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:2170
const EcCurveInfo brainpoolP512r1Curve
brainpoolP512r1 elliptic curve
Definition: ec_curves.c:1083
#define BRAINPOOLP512R1_CURVE
Definition: ec_curves.h:242
#define SECP192K1_CURVE
Definition: ec_curves.h:226
#define BRAINPOOLP224R1_CURVE
Definition: ec_curves.h:238
#define SECP160R1_CURVE
Definition: ec_curves.h:224
#define SECP160R2_CURVE
Definition: ec_curves.h:225
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:83
const EcCurveInfo secp128r1Curve
secp128r1 elliptic curve
Definition: ec_curves.c:185
const uint8_t SECP128R1_OID[5]
Definition: ec_curves.c:50
#define SECP128R1_CURVE
Definition: ec_curves.h:221
error_t secp160r2Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp160r2 curve)
Definition: ec_curves.c:1547
error_t secp128r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp128r1 curve)
Definition: ec_curves.c:1352
error_t secp384r1Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp384r1 curve)
Definition: ec_curves.c:2009
const EcCurveInfo secp384r1Curve
secp384r1 elliptic curve
Definition: ec_curves.c:679
uint8_t length
Definition: dtls_misc.h:140
const uint8_t BRAINPOOLP256R1_OID[9]
Definition: ec_curves.c:82
#define ED448_CURVE
Definition: ec_curves.h:250
uint8_t oid[1]
Definition: mib_common.h:184
const EcCurveInfo x25519Curve
Curve25519 elliptic curve.
Definition: ec_curves.c:1141
const EcCurveInfo brainpoolP256r1Curve
brainpoolP256r1 elliptic curve
Definition: ec_curves.c:933
#define SECP224K1_CURVE
Definition: ec_curves.h:228
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:46
#define BRAINPOOLP384R1_CURVE
Definition: ec_curves.h:241
error_t secp128r2Mod(Mpi *a, const Mpi *p)
Fast modular reduction (secp128r2 curve)
Definition: ec_curves.c:1400
#define SECP128R2_CURVE
Definition: ec_curves.h:222
const uint8_t BRAINPOOLP512R1_OID[9]
Definition: ec_curves.c:88
uint8_t b[6]
Definition: dtls_misc.h:130
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1041
#define SECP256K1_CURVE
Definition: ec_curves.h:230