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