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-2025 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.5.0
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.h"
37 #include "ecc/ec_curves.h"
38 #include "ecc/ec_misc.h"
39 #include "encoding/oid.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (EC_SUPPORT == ENABLED)
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 //brainpoolP160t1 OID (1.3.36.3.3.2.8.1.1.2)
78 const uint8_t BRAINPOOLP160T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x02};
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 //brainpoolP192t1 OID (1.3.36.3.3.2.8.1.1.4)
82 const uint8_t BRAINPOOLP192T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x04};
83 //brainpoolP224r1 OID (1.3.36.3.3.2.8.1.1.5)
84 const uint8_t BRAINPOOLP224R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05};
85 //brainpoolP224t1 OID (1.3.36.3.3.2.8.1.1.6)
86 const uint8_t BRAINPOOLP224T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x06};
87 //brainpoolP256r1 OID (1.3.36.3.3.2.8.1.1.7)
88 const uint8_t BRAINPOOLP256R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07};
89 //brainpoolP256t1 OID (1.3.36.3.3.2.8.1.1.8)
90 const uint8_t BRAINPOOLP256T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x08};
91 //brainpoolP320r1 OID (1.3.36.3.3.2.8.1.1.9)
92 const uint8_t BRAINPOOLP320R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x09};
93 //brainpoolP320t1 OID (1.3.36.3.3.2.8.1.1.10)
94 const uint8_t BRAINPOOLP320T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0A};
95 //brainpoolP384r1 OID (1.3.36.3.3.2.8.1.1.11)
96 const uint8_t BRAINPOOLP384R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B};
97 //brainpoolP384t1 OID (1.3.36.3.3.2.8.1.1.12)
98 const uint8_t BRAINPOOLP384T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0C};
99 //brainpoolP512r1 OID (1.3.36.3.3.2.8.1.1.13)
100 const uint8_t BRAINPOOLP512R1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D};
101 //brainpoolP512t1 OID (1.3.36.3.3.2.8.1.1.14)
102 const uint8_t BRAINPOOLP512T1_OID[9] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0E};
103 //FRP256v1 OID (1.2.250.1.223.101.256.1)
104 const uint8_t FRP256V1_OID[10] = {0x2A, 0x81, 0x7A, 0x01, 0x81, 0x5F, 0x65, 0x82, 0x00, 0x01};
105 //SM2 OID (1.2.156.10197.1.301)
106 const uint8_t SM2_OID[8] = {0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D};
107 //X25519 OID (1.3.101.110)
108 const uint8_t X25519_OID[3] = {0x2B, 0x65, 0x6E};
109 //X448 OID (1.3.101.111)
110 const uint8_t X448_OID[3] = {0x2B, 0x65, 0x6F};
111 //Ed25519 OID (1.3.101.112)
112 const uint8_t ED25519_OID[3] = {0x2B, 0x65, 0x70};
113 //Ed448 OID (1.3.101.113)
114 const uint8_t ED448_OID[3] = {0x2B, 0x65, 0x71};
115 
116 
117 #if (SECP112R1_SUPPORT == ENABLED)
118 
119 /**
120  * @brief secp112r1 elliptic curve
121  **/
122 
124 {
125  //Curve name
126  "secp112r1",
127  //Object identifier
129  sizeof(SECP112R1_OID),
130  //Curve type
132  //Field size, in bits
133  112,
134  //Order size, in bits
135  112,
136  //Prime modulus p
137  {0xBEAD208B, 0x5E668076, 0x2ABF62E3, 0x0000DB7C},
138  //Pre-computed value mu
139  {0},
140  //Curve parameter a
141  {0xBEAD2088, 0x5E668076, 0x2ABF62E3, 0x0000DB7C},
142  //Curve parameter b
143  {0x11702B22, 0x16EEDE89, 0xF8BA0439, 0x0000659E},
144  //Base point G
145  {
146  //x-coordinate
147  {0xF9C2F098, 0x5EE76B55, 0x7239995A, 0x00000948},
148  //y-coordinate
149  {0x0FF77500, 0xC0A23E0E, 0xE5AF8724, 0x0000A89C},
150  //z-coordinate
151  {0x00000001}
152  },
153  //Base point order q
154  {0xAC6561C5, 0x5E7628DF, 0x2ABF62E3, 0x0000DB7C},
155  //Pre-computed value mu
156  {0x46B3447E, 0xFFEAB2EA, 0xFFFFFFFF, 0x00012A96},
157  //Cofactor
158  1,
159  //Field modular reduction
161  //Field modular inversion
162  NULL,
163  //Scalar modular reduction
165  //Scalar modular inversion
166  NULL,
167 };
168 
169 #endif
170 #if (SECP112R2_SUPPORT == ENABLED)
171 
172 /**
173  * @brief secp112r2 elliptic curve
174  **/
175 
177 {
178  //Curve name
179  "secp112r2",
180  //Object identifier
182  sizeof(SECP112R2_OID),
183  //Curve type
185  //Field size, in bits
186  112,
187  //Order size, in bits
188  110,
189  //Prime modulus p
190  {0xBEAD208B, 0x5E668076, 0x2ABF62E3, 0x0000DB7C},
191  //Pre-computed value mu
192  {0},
193  //Curve parameter a
194  {0x5C0EF02C, 0x8A0AAAF6, 0xC24C05F3, 0x00006127},
195  //Curve parameter b
196  {0x4C85D709, 0xED74FCC3, 0xF1815DB5, 0x000051DE},
197  //Base point G
198  {
199  //x-coordinate
200  {0xD0928643, 0xB4E1649D, 0x0AB5E892, 0x00004BA3},
201  //y-coordinate
202  {0x6E956E97, 0x3747DEF3, 0x46F5882E, 0x0000ADCD},
203  //z-coordinate
204  {0x00000001}
205  },
206  //Base point order q
207  {0x0520D04B, 0xD7597CA1, 0x0AAFD8B8, 0x000036DF},
208  //Pre-computed value mu
209  {0x95D6F3F0, 0x015D0500, 0x00000000, 0x00012A97},
210  //Cofactor
211  4,
212  //Field modular reduction
214  //Field modular inversion
215  NULL,
216  //Scalar modular reduction
218  //Scalar modular inversion
219  NULL,
220 };
221 
222 #endif
223 #if (SECP128R1_SUPPORT == ENABLED)
224 
225 /**
226  * @brief secp128r1 elliptic curve
227  **/
228 
230 {
231  //Curve name
232  "secp128r1",
233  //Object identifier
235  sizeof(SECP128R1_OID),
236  //Curve type
238  //Field size, in bits
239  128,
240  //Order size, in bits
241  128,
242  //Prime modulus p
243  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD},
244  //Pre-computed value mu
245  {0},
246  //Curve parameter a
247  {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD},
248  //Curve parameter b
249  {0x2CEE5ED3, 0xD824993C, 0x1079F43D, 0xE87579C1},
250  //Base point G
251  {
252  //x-coordinate
253  {0xA52C5B86, 0x0C28607C, 0x8B899B2D, 0x161FF752},
254  //y-coordinate
255  {0xDDED7A83, 0xC02DA292, 0x5BAFEB13, 0xCF5AC839},
256  //z-coordinate
257  {0x00000001}
258  },
259  //Base point order q
260  {0x9038A115, 0x75A30D1B, 0x00000000, 0xFFFFFFFE},
261  //Pre-computed value mu
262  {0x993B2A87, 0x8A5CF2EA, 0x00000003, 0x00000002, 0x00000001},
263  //Cofactor
264  1,
265  //Field modular reduction
267  //Field modular inversion
269  //Scalar modular reduction
271  //Scalar modular inversion
272  NULL,
273 };
274 
275 #endif
276 #if (SECP128R2_SUPPORT == ENABLED)
277 
278 /**
279  * @brief secp128r2 elliptic curve
280  **/
281 
283 {
284  //Curve name
285  "secp128r2",
286  //Object identifier
288  sizeof(SECP128R2_OID),
289  //Curve type
291  //Field size, in bits
292  128,
293  //Order size, in bits
294  126,
295  //Prime modulus p
296  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD},
297  //Pre-computed value mu
298  {0},
299  //Curve parameter a
300  {0xBFF9AEE1, 0xBF59CC9B, 0xD1B3BBFE, 0xD6031998},
301  //Curve parameter b
302  {0xBB6D8A5D, 0xDC2C6558, 0x80D02919, 0x5EEEFCA3},
303  //Base point G
304  {
305  //x-coordinate
306  {0xCDEBC140, 0xE6FB32A7, 0x5E572983, 0x7B6AA5D8},
307  //y-coordinate
308  {0x5FC34B44, 0x7106FE80, 0x894D3AEE, 0x27B6916A},
309  //z-coordinate
310  {0x00000001}
311  },
312  //Base point order q
313  {0x0613B5A3, 0xBE002472, 0x7FFFFFFF, 0x3FFFFFFF},
314  //Pre-computed value mu
315  {0x07AEE271, 0x07FF6E44, 0x00000005, 0x00000002, 0x00000001},
316  //Cofactor
317  4,
318  //Field modular reduction
320  //Field modular inversion
322  //Scalar modular reduction
324  //Scalar modular inversion
325  NULL,
326 };
327 
328 #endif
329 #if (SECP160K1_SUPPORT == ENABLED)
330 
331 /**
332  * @brief secp160k1 elliptic curve
333  **/
334 
336 {
337  //Curve name
338  "secp160k1",
339  //Object identifier
341  sizeof(SECP160K1_OID),
342  //Curve type
344  //Field size, in bits
345  160,
346  //Order size, in bits
347  161,
348  //Prime modulus p
349  {0xFFFFAC73, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
350  //Pre-computed value mu
351  {0},
352  //Curve parameter a
353  {0x00000000},
354  //Curve parameter b
355  {0x00000007},
356  //Base point G
357  {
358  //x-coordinate
359  {0xDD4D7EBB, 0x3036F4F5, 0xA4019E76, 0xE37AA192, 0x3B4C382C},
360  //y-coordinate
361  {0xF03C4FEE, 0x531733C3, 0x6BC28286, 0x318FDCED, 0x938CF935},
362  //z-coordinate
363  {0x00000001}
364  },
365  //Base point order q
366  {0xCA16B6B3, 0x16DFAB9A, 0x0001B8FA, 0x00000000, 0x00000000, 0x00000001},
367  //Pre-computed value mu
368  {0x929FEF39, 0xA8CA6BD2, 0x8E0BD240, 0xFFFFFFFC, 0xFFFFFFFF, 0x0001FFFF},
369  //Cofactor
370  1,
371  //Field modular reduction
373  //Field modular inversion
375  //Scalar modular reduction
377  //Scalar modular inversion
378  NULL,
379 };
380 
381 #endif
382 #if (SECP160R1_SUPPORT == ENABLED)
383 
384 /**
385  * @brief secp160r1 elliptic curve
386  **/
387 
389 {
390  //Curve name
391  "secp160r1",
392  //Object identifier
394  sizeof(SECP160R1_OID),
395  //Curve type
397  //Field size, in bits
398  160,
399  //Order size, in bits
400  161,
401  //Prime modulus p
402  {0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
403  //Pre-computed value mu
404  {0},
405  //Curve parameter a
406  {0x7FFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
407  //Curve parameter b
408  {0xC565FA45, 0x81D4D4AD, 0x65ACF89F, 0x54BD7A8B, 0x1C97BEFC},
409  //Base point G
410  {
411  //x-coordinate
412  {0x13CBFC82, 0x68C38BB9, 0x46646989, 0x8EF57328, 0x4A96B568},
413  //y-coordinate
414  {0x7AC5FB32, 0x04235137, 0x59DCC912, 0x3168947D, 0x23A62855},
415  //z-coordinate
416  {0x00000001}
417  },
418  //Base point order q
419  {0xCA752257, 0xF927AED3, 0x0001F4C8, 0x00000000, 0x00000000, 0x00000001},
420  //Pre-computed value mu
421  {0xBB59A743, 0xA2586B15, 0x166E0DB0, 0xFFFFFFFC, 0xFFFFFFFF, 0x0001FFFF},
422  //Cofactor
423  1,
424  //Field modular reduction
426  //Field modular inversion
428  //Scalar modular reduction
430  //Scalar modular inversion
431  NULL,
432 };
433 
434 #endif
435 #if (SECP160R2_SUPPORT == ENABLED)
436 
437 /**
438  * @brief secp160r2 elliptic curve
439  **/
440 
442 {
443  //Curve name
444  "secp160r2",
445  //Object identifier
447  sizeof(SECP160R2_OID),
448  //Curve type
450  //Field size, in bits
451  160,
452  //Order size, in bits
453  161,
454  //Prime modulus p
455  {0xFFFFAC73, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
456  //Pre-computed value mu
457  {0},
458  //Curve parameter a
459  {0xFFFFAC70, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
460  //Curve parameter b
461  {0xF50388BA, 0x04664D5A, 0xAB572749, 0xFB59EB8B, 0xB4E134D3},
462  //Base point G
463  {
464  //x-coordinate
465  {0x3144CE6D, 0x30F7199D, 0x1F4FF11B, 0x293A117E, 0x52DCB034},
466  //y-coordinate
467  {0xA7D43F2E, 0xF9982CFE, 0xE071FA0D, 0xE331F296, 0xFEAFFEF2},
468  //z-coordinate
469  {0x00000001}
470  },
471  //Base point order q
472  {0xF3A1A16B, 0xE786A818, 0x0000351E, 0x00000000, 0x00000000, 0x00000001},
473  //Pre-computed value mu
474  {0xBD2A160B, 0xAFCE18BC, 0x95C230F2, 0xFFFFFFFF, 0xFFFFFFFF, 0x0001FFFF},
475  //Cofactor
476  1,
477  //Field modular reduction
479  //Field modular inversion
481  //Scalar modular reduction
483  //Scalar modular inversion
484  NULL,
485 };
486 
487 #endif
488 #if (SECP192K1_SUPPORT == ENABLED)
489 
490 /**
491  * @brief secp192k1 elliptic curve
492  **/
493 
495 {
496  //Curve name
497  "secp192k1",
498  //Object identifier
500  sizeof(SECP192K1_OID),
501  //Curve type
503  //Field size, in bits
504  192,
505  //Order size, in bits
506  192,
507  //Prime modulus p
508  {0xFFFFEE37, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
509  //Pre-computed value mu
510  {0},
511  //Curve parameter a
512  {0x00000000},
513  //Curve parameter b
514  {0x00000003},
515  //Base point G
516  {
517  //x-coordinate
518  {0xEAE06C7D, 0x1DA5D1B1, 0x80B7F434, 0x26B07D02, 0xC057E9AE, 0xDB4FF10E},
519  //y-coordinate
520  {0xD95E2F9D, 0x4082AA88, 0x15BE8634, 0x844163D0, 0x9C5628A7, 0x9B2F2F6D},
521  //z-coordinate
522  {0x00000001}
523  },
524  //Base point order q
525  {0x74DEFD8D, 0x0F69466A, 0x26F2FC17, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF},
526  //Pre-computed value mu
527  {0x8B210276, 0xF096B995, 0xD90D03E8, 0x00000001, 0x00000000, 0x00000000, 0x00000001},
528  //Cofactor
529  1,
530  //Field modular reduction
532  //Field modular inversion
534  //Scalar modular reduction
536  //Scalar modular inversion
537  NULL,
538 };
539 
540 #endif
541 #if (SECP192R1_SUPPORT == ENABLED)
542 
543 /**
544  * @brief secp192r1 elliptic curve
545  **/
546 
548 {
549  //Curve name
550  "secp192r1",
551  //Object identifier
553  sizeof(SECP192R1_OID),
554  //Curve type
556  //Field size, in bits
557  192,
558  //Order size, in bits
559  192,
560  //Prime modulus p
561  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
562  //Pre-computed value mu
563  {0},
564  //Curve parameter a
565  {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
566  //Curve parameter b
567  {0xC146B9B1, 0xFEB8DEEC, 0x72243049, 0x0FA7E9AB, 0xE59C80E7, 0x64210519},
568  //Base point G
569  {
570  //x-coordinate
571  {0x82FF1012, 0xF4FF0AFD, 0x43A18800, 0x7CBF20EB, 0xB03090F6, 0x188DA80E},
572  //y-coordinate
573  {0x1E794811, 0x73F977A1, 0x6B24CDD5, 0x631011ED, 0xFFC8DA78, 0x07192B95},
574  //z-coordinate
575  {0x00000001}
576  },
577  //Base point order q
578  {0xB4D22831, 0x146BC9B1, 0x99DEF836, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
579  //Pre-computed value mu
580  {0x4B2DD7CF, 0xEB94364E, 0x662107C9, 0x00000000, 0x00000000, 0x00000000, 0x00000001},
581  //Cofactor
582  1,
583  //Field modular reduction
585  //Field modular inversion
587  //Scalar modular reduction
589  //Scalar modular inversion
590  NULL,
591 };
592 
593 #endif
594 #if (SECP224K1_SUPPORT == ENABLED)
595 
596 /**
597  * @brief secp224k1 elliptic curve
598  **/
599 
601 {
602  //Curve name
603  "secp224k1",
604  //Object identifier
606  sizeof(SECP224K1_OID),
607  //Curve type
609  //Field size, in bits
610  224,
611  //Order size, in bits
612  225,
613  //Prime modulus p
614  {0xFFFFE56D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
615  //Pre-computed value mu
616  {0},
617  //Curve parameter a
618  {0x00000000},
619  //Curve parameter b
620  {0x00000005},
621  //Base point G
622  {
623  //x-coordinate
624  {0xB6B7A45C, 0x0F7E650E, 0xE47075A9, 0x69A467E9, 0x30FC28A1, 0x4DF099DF, 0xA1455B33},
625  //y-coordinate
626  {0x556D61A5, 0xE2CA4BDB, 0xC0B0BD59, 0xF7E319F7, 0x82CAFBD6, 0x7FBA3442, 0x7E089FED},
627  //z-coordinate
628  {0x00000001}
629  },
630  //Base point order q
631  {0x769FB1F7, 0xCAF0A971, 0xD2EC6184, 0x0001DCE8, 0x00000000, 0x00000000, 0x00000000, 0x00000001},
632  //Pre-computed value mu
633  {0x9C18F0E5, 0xAD1D12C0, 0x3CF66A1E, 0x462E5A27, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x0001FFFF},
634  //Cofactor
635  1,
636  //Field modular reduction
638  //Field modular inversion
640  //Scalar modular reduction
642  //Scalar modular inversion
643  NULL,
644 };
645 
646 #endif
647 #if (SECP224R1_SUPPORT == ENABLED)
648 
649 /**
650  * @brief secp224r1 elliptic curve
651  **/
652 
654 {
655  //Curve name
656  "secp224r1",
657  //Object identifier
659  sizeof(SECP224R1_OID),
660  //Curve type
662  //Field size, in bits
663  224,
664  //Order size, in bits
665  224,
666  //Prime modulus p
667  {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
668  //Pre-computed value mu
669  {0},
670  //Curve parameter a
671  {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
672  //Curve parameter b
673  {0x2355FFB4, 0x270B3943, 0xD7BFD8BA, 0x5044B0B7, 0xF5413256, 0x0C04B3AB, 0xB4050A85},
674  //Base point G
675  {
676  //x-coordinate
677  {0x115C1D21, 0x343280D6, 0x56C21122, 0x4A03C1D3, 0x321390B9, 0x6BB4BF7F, 0xB70E0CBD},
678  //y-coordinate
679  {0x85007E34, 0x44D58199, 0x5A074764, 0xCD4375A0, 0x4C22DFE6, 0xB5F723FB, 0xBD376388},
680  //z-coordinate
681  {0x00000001}
682  },
683  //Base point order q
684  {0x5C5C2A3D, 0x13DD2945, 0xE0B8F03E, 0xFFFF16A2, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
685  //Pre-computed value mu
686  {0xA3A3D5C3, 0xEC22D6BA, 0x1F470FC1, 0x0000E95D, 0x00000000, 0x00000000, 0x00000000, 0x00000001},
687  //Cofactor
688  1,
689  //Field modular reduction
691  //Field modular inversion
693  //Scalar modular reduction
695  //Scalar modular inversion
696  NULL,
697 };
698 
699 #endif
700 #if (SECP256K1_SUPPORT == ENABLED)
701 
702 /**
703  * @brief secp256k1 elliptic curve
704  **/
705 
707 {
708  //Curve name
709  "secp256k1",
710  //Object identifier
712  sizeof(SECP256K1_OID),
713  //Curve type
715  //Field size, in bits
716  256,
717  //Order size, in bits
718  256,
719  //Prime modulus p
720  {0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
721  //Pre-computed value mu
722  {0},
723  //Curve parameter a
724  {0x00000000},
725  //Curve parameter b
726  {0x00000007},
727  //Base point G
728  {
729  //x-coordinate
730  {0x16F81798, 0x59F2815B, 0x2DCE28D9, 0x029BFCDB, 0xCE870B07, 0x55A06295, 0xF9DCBBAC, 0x79BE667E},
731  //y-coordinate
732  {0xFB10D4B8, 0x9C47D08F, 0xA6855419, 0xFD17B448, 0x0E1108A8, 0x5DA4FBFC, 0x26A3C465, 0x483ADA77},
733  //z-coordinate
734  {0x00000001}
735  },
736  //Base point order q
737  {0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
738  //Pre-computed value mu
739  {0x2FC9BEC0, 0x402DA173, 0x50B75FC4, 0x45512319, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
740  0x00000001},
741  //Cofactor
742  1,
743  //Field modular reduction
745  //Field modular inversion
747  //Scalar modular reduction
749  //Scalar modular inversion
750  NULL,
751 };
752 
753 #endif
754 #if (SECP256R1_SUPPORT == ENABLED)
755 
756 /**
757  * @brief secp256r1 elliptic curve
758  **/
759 
761 {
762  //Curve name
763  "secp256r1",
764  //Object identifier
766  sizeof(SECP256R1_OID),
767  //Curve type
769  //Field size, in bits
770  256,
771  //Order size, in bits
772  256,
773  //Prime modulus p
774  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
775  //Pre-computed value mu
776  {0},
777  //Curve parameter a
778  {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
779  //Curve parameter b
780  {0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8},
781  //Base point G
782  {
783  //x-coordinate
784  {0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81, 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2},
785  //y-coordinate
786  {0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357, 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2},
787  //z-coordinate
788  {0x00000001}
789  },
790  //Base point order q
791  {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF},
792  //Pre-computed value mu
793  {0xEEDF9BFE, 0x012FFD85, 0xDF1A6C21, 0x43190552, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000,
794  0x00000001},
795  //Cofactor
796  1,
797  //Field modular reduction
799  //Field modular inversion
801  //Scalar modular reduction
803  //Scalar modular inversion
805 };
806 
807 #endif
808 #if (SECP384R1_SUPPORT == ENABLED)
809 
810 /**
811  * @brief secp384r1 elliptic curve
812  **/
813 
815 {
816  //Curve name
817  "secp384r1",
818  //Object identifier
820  sizeof(SECP384R1_OID),
821  //Curve type
823  //Field size, in bits
824  384,
825  //Order size, in bits
826  384,
827  //Prime modulus p
828  {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
829  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
830  //Pre-computed value mu
831  {0},
832  //Curve parameter a
833  {0xFFFFFFFC, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
834  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
835  //Curve parameter b
836  {0xD3EC2AEF, 0x2A85C8ED, 0x8A2ED19D, 0xC656398D, 0x5013875A, 0x0314088F, 0xFE814112, 0x181D9C6E,
837  0xE3F82D19, 0x988E056B, 0xE23EE7E4, 0xB3312FA7},
838  //Base point G
839  {
840  //x-coordinate
841  {0x72760AB7, 0x3A545E38, 0xBF55296C, 0x5502F25D, 0x82542A38, 0x59F741E0, 0x8BA79B98, 0x6E1D3B62,
842  0xF320AD74, 0x8EB1C71E, 0xBE8B0537, 0xAA87CA22},
843  //y-coordinate
844  {0x90EA0E5F, 0x7A431D7C, 0x1D7E819D, 0x0A60B1CE, 0xB5F0B8C0, 0xE9DA3113, 0x289A147C, 0xF8F41DBD,
845  0x9292DC29, 0x5D9E98BF, 0x96262C6F, 0x3617DE4A},
846  //z-coordinate
847  {0x00000001}
848  },
849  //Base point order q
850  {0xCCC52973, 0xECEC196A, 0x48B0A77A, 0x581A0DB2, 0xF4372DDF, 0xC7634D81, 0xFFFFFFFF, 0xFFFFFFFF,
851  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
852  //Pre-computed value mu
853  {0x333AD68D, 0x1313E695, 0xB74F5885, 0xA7E5F24D, 0x0BC8D220, 0x389CB27E, 0x00000000, 0x00000000,
854  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001},
855  //Cofactor
856  1,
857  //Field modular reduction
859  //Field modular inversion
861  //Scalar modular reduction
863  //Scalar modular inversion
865 };
866 
867 #endif
868 #if (SECP521R1_SUPPORT == ENABLED)
869 
870 /**
871  * @brief secp521r1 elliptic curve
872  **/
873 
875 {
876  //Curve name
877  "secp521r1",
878  //Object identifier
880  sizeof(SECP521R1_OID),
881  //Curve type
883  //Field size, in bits
884  521,
885  //Order size, in bits
886  521,
887  //Prime modulus p
888  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
889  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
890  0x000001FF},
891  //Pre-computed value mu
892  {0},
893  //Curve parameter a
894  {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
895  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
896  0x000001FF},
897  //Curve parameter b
898  {0x6B503F00, 0xEF451FD4, 0x3D2C34F1, 0x3573DF88, 0x3BB1BF07, 0x1652C0BD, 0xEC7E937B, 0x56193951,
899  0x8EF109E1, 0xB8B48991, 0x99B315F3, 0xA2DA725B, 0xB68540EE, 0x929A21A0, 0x8E1C9A1F, 0x953EB961,
900  0x00000051},
901  //Base point G
902  {
903  //x-coordinate
904  {0xC2E5BD66, 0xF97E7E31, 0x856A429B, 0x3348B3C1, 0xA2FFA8DE, 0xFE1DC127, 0xEFE75928, 0xA14B5E77,
905  0x6B4D3DBA, 0xF828AF60, 0x053FB521, 0x9C648139, 0x2395B442, 0x9E3ECB66, 0x0404E9CD, 0x858E06B7,
906  0x000000C6},
907  //y-coordinate
908  {0x9FD16650, 0x88BE9476, 0xA272C240, 0x353C7086, 0x3FAD0761, 0xC550B901, 0x5EF42640, 0x97EE7299,
909  0x273E662C, 0x17AFBD17, 0x579B4468, 0x98F54449, 0x2C7D1BD9, 0x5C8A5FB4, 0x9A3BC004, 0x39296A78,
910  0x00000118},
911  //z-coordinate
912  {0x00000001}
913  },
914  //Base point order q
915  {0x91386409, 0xBB6FB71E, 0x899C47AE, 0x3BB5C9B8, 0xF709A5D0, 0x7FCC0148, 0xBF2F966B, 0x51868783,
916  0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
917  0x000001FF},
918  //Pre-computed value mu
919  {0x63CDFB88, 0x482470B7, 0x31DC28A2, 0x251B23BB, 0x7B2D17E2, 0x19FF5B84, 0x6834CA40, 0x3CBC3E20,
920  0x000002D7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
921  0x00010000},
922  //Cofactor
923  1,
924  //Field modular reduction
926  //Field modular inversion
928  //Scalar modular reduction
930  //Scalar modular inversion
932 };
933 
934 #endif
935 #if (BRAINPOOLP160R1_SUPPORT == ENABLED)
936 
937 /**
938  * @brief brainpoolP160r1 elliptic curve
939  **/
940 
942 {
943  //Curve name
944  "brainpoolP160r1",
945  //Object identifier
947  sizeof(BRAINPOOLP160R1_OID),
948  //Curve type
950  //Field size, in bits
951  160,
952  //Order size, in bits
953  160,
954  //Prime modulus p
955  {0x9515620F, 0x95B3D813, 0x60DFC7AD, 0x737059DC, 0xE95E4A5F},
956  //Pre-computed value mu
957  {0xC26FB1EF, 0xA5D79737, 0xF1269FF8, 0x86396600, 0x18D392ED, 0x00000001},
958  //Curve parameter a
959  {0xE8F7C300, 0xDA745D97, 0xE2BE61BA, 0xA280EB74, 0x340E7BE2},
960  //Curve parameter b
961  {0xD8675E58, 0xBDEC95C8, 0x134FAA2D, 0x95423412, 0x1E589A85},
962  //Base point G
963  {
964  //x-coordinate
965  {0xBDBCDBC3, 0x31EB5AF7, 0x62938C46, 0xEA3F6A4F, 0xBED5AF16},
966  //y-coordinate
967  {0x16DA6321, 0x669C9763, 0x38F94741, 0x7A1A8EC3, 0x1667CB47},
968  //z-coordinate
969  {0x00000001}
970  },
971  //Base point order q
972  {0x9E60FC09, 0xD4502940, 0x60DF5991, 0x737059DC, 0xE95E4A5F},
973  //Pre-computed value mu
974  {0x033BC7E6, 0xB54E9909, 0xF1272478, 0x86396600, 0x18D392ED, 0x00000001},
975  //Cofactor
976  1,
977  //Field modular reduction
979  //Field modular inversion
980  NULL,
981  //Scalar modular reduction
983  //Scalar modular inversion
984  NULL,
985 };
986 
987 #endif
988 #if (BRAINPOOLP160T1_SUPPORT == ENABLED)
989 
990 /**
991  * @brief brainpoolP160t1 elliptic curve
992  **/
993 
995 {
996  //Curve name
997  "brainpoolP160t1",
998  //Object identifier
1000  sizeof(BRAINPOOLP160T1_OID),
1001  //Curve type
1003  //Field size, in bits
1004  160,
1005  //Order size, in bits
1006  160,
1007  //Prime modulus p
1008  {0x9515620F, 0x95B3D813, 0x60DFC7AD, 0x737059DC, 0xE95E4A5F},
1009  //Pre-computed value mu
1010  {0xC26FB1EF, 0xA5D79737, 0xF1269FF8, 0x86396600, 0x18D392ED, 0x00000001},
1011  //Curve parameter a
1012  {0x9515620C, 0x95B3D813, 0x60DFC7AD, 0x737059DC, 0xE95E4A5F},
1013  //Curve parameter b
1014  {0x5C55F380, 0x7DAA7A0B, 0x51ED2C4D, 0xAE535B7B, 0x7A556B6D},
1015  //Base point G
1016  {
1017  //x-coordinate
1018  {0x65FF2378, 0xEB05ACC2, 0x397E64BA, 0x9B34EFC1, 0xB199B13B},
1019  //y-coordinate
1020  {0x52C9E0AD, 0x24437721, 0xF0991B84, 0x7C7C1961, 0xADD6718B},
1021  //z-coordinate
1022  {0x00000001}
1023  },
1024  //Base point order q
1025  {0x9E60FC09, 0xD4502940, 0x60DF5991, 0x737059DC, 0xE95E4A5F},
1026  //Pre-computed value mu
1027  {0x033BC7E6, 0xB54E9909, 0xF1272478, 0x86396600, 0x18D392ED, 0x00000001},
1028  //Cofactor
1029  1,
1030  //Field modular reduction
1032  //Field modular inversion
1033  NULL,
1034  //Scalar modular reduction
1036  //Scalar modular inversion
1037  NULL,
1038 };
1039 
1040 #endif
1041 #if (BRAINPOOLP192R1_SUPPORT == ENABLED)
1042 
1043 /**
1044  * @brief brainpoolP192r1 elliptic curve
1045  **/
1046 
1048 {
1049  //Curve name
1050  "brainpoolP192r1",
1051  //Object identifier
1053  sizeof(BRAINPOOLP192R1_OID),
1054  //Curve type
1056  //Field size, in bits
1057  192,
1058  //Order size, in bits
1059  192,
1060  //Prime modulus p
1061  {0xE1A86297, 0x8FCE476D, 0x93D18DB7, 0xA7A34630, 0x932A36CD, 0xC302F41D},
1062  //Pre-computed value mu
1063  {0x10B1AC0A, 0x6639FECF, 0xC2462077, 0x675BC2FD, 0xFF1728C8, 0x500FEA39, 0x00000001},
1064  //Curve parameter a
1065  {0xC69A28EF, 0xCAE040E5, 0xFE8685C1, 0x9C39C031, 0x76B1E0E1, 0x6A911740},
1066  //Curve parameter b
1067  {0x6FBF25C9, 0xCA7EF414, 0x4F4496BC, 0xDC721D04, 0x7C28CCA3, 0x469A28EF},
1068  //Base point G
1069  {
1070  //x-coordinate
1071  {0x53375FD6, 0x0A2F5C48, 0x6CB0F090, 0x53B033C5, 0xAAB6A487, 0xC0A0647E},
1072  //y-coordinate
1073  {0xFA299B8F, 0xE6773FA2, 0xC1490002, 0x8B5F4828, 0x6ABD5BB8, 0x14B69086},
1074  //z-coordinate
1075  {0x00000001}
1076  },
1077  //Base point order q
1078  {0x9AC4ACC1, 0x5BE8F102, 0x9E9E916B, 0xA7A3462F, 0x932A36CD, 0xC302F41D},
1079  //Pre-computed value mu
1080  {0x5E71F108, 0x3A674578, 0x68D2F9A8, 0x675BC2FF, 0xFF1728C8, 0x500FEA39, 0x00000001},
1081  //Cofactor
1082  1,
1083  //Field modular reduction
1085  //Field modular inversion
1086  NULL,
1087  //Scalar modular reduction
1089  //Scalar modular inversion
1090  NULL,
1091 };
1092 
1093 #endif
1094 #if (BRAINPOOLP192T1_SUPPORT == ENABLED)
1095 
1096 /**
1097  * @brief brainpoolP192t1 elliptic curve
1098  **/
1099 
1101 {
1102  //Curve name
1103  "brainpoolP192t1",
1104  //Object identifier
1106  sizeof(BRAINPOOLP192T1_OID),
1107  //Curve type
1109  //Field size, in bits
1110  192,
1111  //Order size, in bits
1112  192,
1113  //Prime modulus p
1114  {0xE1A86297, 0x8FCE476D, 0x93D18DB7, 0xA7A34630, 0x932A36CD, 0xC302F41D},
1115  //Pre-computed value mu
1116  {0x10B1AC0A, 0x6639FECF, 0xC2462077, 0x675BC2FD, 0xFF1728C8, 0x500FEA39, 0x00000001},
1117  //Curve parameter a
1118  {0xE1A86294, 0x8FCE476D, 0x93D18DB7, 0xA7A34630, 0x932A36CD, 0xC302F41D},
1119  //Curve parameter b
1120  {0x27897B79, 0xFB68542E, 0x3B35BEC2, 0x68F9DEB4, 0xEC78681E, 0x13D56FFA},
1121  //Base point G
1122  {
1123  //x-coordinate
1124  {0xF4618129, 0x2C446AF6, 0xBBF43FA7, 0x282E1FE7, 0x82F63C30, 0x3AE9E58C},
1125  //y-coordinate
1126  {0x7CCC01C9, 0xB7E5B3DE, 0x449D0084, 0x902AB5CA, 0x67C2223A, 0x097E2C56},
1127  //z-coordinate
1128  {0x00000001}
1129  },
1130  //Base point order q
1131  {0x9AC4ACC1, 0x5BE8F102, 0x9E9E916B, 0xA7A3462F, 0x932A36CD, 0xC302F41D},
1132  //Pre-computed value mu
1133  {0x5E71F108, 0x3A674578, 0x68D2F9A8, 0x675BC2FF, 0xFF1728C8, 0x500FEA39, 0x00000001},
1134  //Cofactor
1135  1,
1136  //Field modular reduction
1138  //Field modular inversion
1139  NULL,
1140  //Scalar modular reduction
1142  //Scalar modular inversion
1143  NULL,
1144 };
1145 
1146 #endif
1147 #if (BRAINPOOLP224R1_SUPPORT == ENABLED)
1148 
1149 /**
1150  * @brief brainpoolP224r1 elliptic curve
1151  **/
1152 
1154 {
1155  //Curve name
1156  "brainpoolP224r1",
1157  //Object identifier
1159  sizeof(BRAINPOOLP224R1_OID),
1160  //Curve type
1162  //Field size, in bits
1163  224,
1164  //Order size, in bits
1165  224,
1166  //Prime modulus p
1167  {0x7EC8C0FF, 0x97DA89F5, 0xB09F0757, 0x75D1D787, 0x2A183025, 0x26436686, 0xD7C134AA},
1168  //Pre-computed value mu
1169  {0xB36F5F4F, 0xEF60DC4D, 0x33DA784F, 0x603DE8FD, 0x4E1D543F, 0x8FD22299, 0x2FC099F7, 0x00000001},
1170  //Curve parameter a
1171  {0xCAD29F43, 0xB0042A59, 0x4E182AD8, 0xC1530B51, 0x299803A6, 0xA9CE6C1C, 0x68A5E62C},
1172  //Curve parameter b
1173  {0x386C400B, 0x66DBB372, 0x3E2135D2, 0xA92369E3, 0x870713B1, 0xCFE44138, 0x2580F63C},
1174  //Base point G
1175  {
1176  //x-coordinate
1177  {0xEE12C07D, 0x4C1E6EFD, 0x9E4CE317, 0xA87DC68C, 0x340823B2, 0x2C7E5CF4, 0x0D9029AD},
1178  //y-coordinate
1179  {0x761402CD, 0xCAA3F6D3, 0x354B9E99, 0x4ECDAC24, 0x24C6B89E, 0x72C0726F, 0x58AA56F7},
1180  //z-coordinate
1181  {0x00000001}
1182  },
1183  //Base point order q
1184  {0xA5A7939F, 0x6DDEBCA3, 0xD116BC4B, 0x75D0FB98, 0x2A183025, 0x26436686, 0xD7C134AA},
1185  //Pre-computed value mu
1186  {0x1C8A5BA1, 0x590A94D3, 0xBEE15BC3, 0x603F1E9F, 0x4E1D543F, 0x8FD22299, 0x2FC099F7, 0x00000001},
1187  //Cofactor
1188  1,
1189  //Field modular reduction
1191  //Field modular inversion
1192  NULL,
1193  //Scalar modular reduction
1195  //Scalar modular inversion
1196  NULL,
1197 };
1198 
1199 #endif
1200 #if (BRAINPOOLP224T1_SUPPORT == ENABLED)
1201 
1202 /**
1203  * @brief brainpoolP224t1 elliptic curve
1204  **/
1205 
1207 {
1208  //Curve name
1209  "brainpoolP224t1",
1210  //Object identifier
1212  sizeof(BRAINPOOLP224T1_OID),
1213  //Curve type
1215  //Field size, in bits
1216  224,
1217  //Order size, in bits
1218  224,
1219  //Prime modulus p
1220  {0x7EC8C0FF, 0x97DA89F5, 0xB09F0757, 0x75D1D787, 0x2A183025, 0x26436686, 0xD7C134AA},
1221  //Pre-computed value mu
1222  {0xB36F5F4F, 0xEF60DC4D, 0x33DA784F, 0x603DE8FD, 0x4E1D543F, 0x8FD22299, 0x2FC099F7, 0x00000001},
1223  //Curve parameter a
1224  {0x7EC8C0FC, 0x97DA89F5, 0xB09F0757, 0x75D1D787, 0x2A183025, 0x26436686, 0xD7C134AA},
1225  //Curve parameter b
1226  {0x8A60888D, 0xB3BB64F1, 0x0DA14C08, 0x0CED1ED2, 0xEF271BF6, 0x4104CD7B, 0x4B337D93},
1227  //Base point G
1228  {
1229  //x-coordinate
1230  {0x29B4D580, 0x8AC0C760, 0xCB49F892, 0xFE14762E, 0x96424E7F, 0xCE25FF38, 0x6AB1E344},
1231  //y-coordinate
1232  {0x1A46DB4C, 0x1C6ABD5F, 0x41C8CC0D, 0x7C0D4B1E, 0xD23F3F4D, 0x143E568C, 0x0374E9F5},
1233  //z-coordinate
1234  {0x00000001}
1235  },
1236  //Base point order q
1237  {0xA5A7939F, 0x6DDEBCA3, 0xD116BC4B, 0x75D0FB98, 0x2A183025, 0x26436686, 0xD7C134AA},
1238  //Pre-computed value mu
1239  {0x1C8A5BA1, 0x590A94D3, 0xBEE15BC3, 0x603F1E9F, 0x4E1D543F, 0x8FD22299, 0x2FC099F7, 0x00000001},
1240  //Cofactor
1241  1,
1242  //Field modular reduction
1244  //Field modular inversion
1245  NULL,
1246  //Scalar modular reduction
1248  //Scalar modular inversion
1249  NULL,
1250 };
1251 
1252 #endif
1253 #if (BRAINPOOLP256R1_SUPPORT == ENABLED)
1254 
1255 /**
1256  * @brief brainpoolP256r1 elliptic curve
1257  **/
1258 
1260 {
1261  //Curve name
1262  "brainpoolP256r1",
1263  //Object identifier
1265  sizeof(BRAINPOOLP256R1_OID),
1266  //Curve type
1268  //Field size, in bits
1269  256,
1270  //Order size, in bits
1271  256,
1272  //Prime modulus p
1273  {0x1F6E5377, 0x2013481D, 0xD5262028, 0x6E3BF623, 0x9D838D72, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB},
1274  //Pre-computed value mu
1275  {0x1180DD0C, 0xB62AE630, 0xFF6A2FA9, 0x9B4F54A0, 0x322A7BF2, 0xBB73ABA8, 0xA1C55B7E, 0x818C1131,
1276  0x00000001},
1277  //Curve parameter a
1278  {0xF330B5D9, 0xE94A4B44, 0x26DC5C6C, 0xFB8055C1, 0x417AFFE7, 0xEEF67530, 0xFC2C3057, 0x7D5A0975},
1279  //Curve parameter b
1280  {0xFF8C07B6, 0x6BCCDC18, 0x5CF7E1CE, 0x95841629, 0xBBD77CBF, 0xF330B5D9, 0xE94A4B44, 0x26DC5C6C},
1281  //Base point G
1282  {
1283  //x-coordinate
1284  {0x9ACE3262, 0x3A4453BD, 0xE3BD23C2, 0xB9DE27E1, 0xFC81B7AF, 0x2C4B482F, 0xCB7E57CB, 0x8BD2AEB9},
1285  //y-coordinate
1286  {0x2F046997, 0x5C1D54C7, 0x2DED8E54, 0xC2774513, 0x14611DC9, 0x97F8461A, 0xC3DAC4FD, 0x547EF835},
1287  //z-coordinate
1288  {0x00000001}
1289  },
1290  //Base point order q
1291  {0x974856A7, 0x901E0E82, 0xB561A6F7, 0x8C397AA3, 0x9D838D71, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB},
1292  //Pre-computed value mu
1293  {0xCCD10716, 0x50D73B46, 0x5FDF55EA, 0x9BF0088C, 0x322A7BF4, 0xBB73ABA8, 0xA1C55B7E, 0x818C1131,
1294  0x00000001},
1295  //Cofactor
1296  1,
1297  //Field modular reduction
1299  //Field modular inversion
1300  NULL,
1301  //Scalar modular reduction
1303  //Scalar modular inversion
1304  NULL,
1305 };
1306 
1307 #endif
1308 #if (BRAINPOOLP256T1_SUPPORT == ENABLED)
1309 
1310 /**
1311  * @brief brainpoolP256t1 elliptic curve
1312  **/
1313 
1315 {
1316  //Curve name
1317  "brainpoolP256t1",
1318  //Object identifier
1320  sizeof(BRAINPOOLP256T1_OID),
1321  //Curve type
1323  //Field size, in bits
1324  256,
1325  //Order size, in bits
1326  256,
1327  //Prime modulus p
1328  {0x1F6E5377, 0x2013481D, 0xD5262028, 0x6E3BF623, 0x9D838D72, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB},
1329  //Pre-computed value mu
1330  {0x1180DD0C, 0xB62AE630, 0xFF6A2FA9, 0x9B4F54A0, 0x322A7BF2, 0xBB73ABA8, 0xA1C55B7E, 0x818C1131,
1331  0x00000001},
1332  //Curve parameter a
1333  {0x1F6E5374, 0x2013481D, 0xD5262028, 0x6E3BF623, 0x9D838D72, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB},
1334  //Curve parameter b
1335  {0xFEE92B04, 0x6AE58101, 0xAF2F4925, 0xBF93EBC4, 0x3D0B76B7, 0xFE66A773, 0x30D84EA4, 0x662C61C4},
1336  //Base point G
1337  {
1338  //x-coordinate
1339  {0x2E1305F4, 0x79A19156, 0x7AAFBC2B, 0xAFA142C4, 0x3A656149, 0x732213B2, 0xC1CFE7B7, 0xA3E8EB3C},
1340  //y-coordinate
1341  {0x5B25C9BE, 0x1DABE8F3, 0x39D02700, 0x69BCB6DE, 0x4644417E, 0x7F7B22E1, 0x3439C56D, 0x2D996C82},
1342  //z-coordinate
1343  {0x00000001}
1344  },
1345  //Base point order q
1346  {0x974856A7, 0x901E0E82, 0xB561A6F7, 0x8C397AA3, 0x9D838D71, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB},
1347  //Pre-computed value mu
1348  {0xCCD10716, 0x50D73B46, 0x5FDF55EA, 0x9BF0088C, 0x322A7BF4, 0xBB73ABA8, 0xA1C55B7E, 0x818C1131,
1349  0x00000001},
1350  //Cofactor
1351  1,
1352  //Field modular reduction
1354  //Field modular inversion
1355  NULL,
1356  //Scalar modular reduction
1358  //Scalar modular inversion
1359  NULL,
1360 };
1361 
1362 #endif
1363 #if (BRAINPOOLP320R1_SUPPORT == ENABLED)
1364 
1365 /**
1366  * @brief brainpoolP320r1 elliptic curve
1367  **/
1368 
1370 {
1371  //Curve name
1372  "brainpoolP320r1",
1373  //Object identifier
1375  sizeof(BRAINPOOLP320R1_OID),
1376  //Curve type
1378  //Field size, in bits
1379  320,
1380  //Order size, in bits
1381  320,
1382  //Prime modulus p
1383  {0xF1B32E27, 0xFCD412B1, 0x7893EC28, 0x4F92B9EC, 0xF6F40DEF, 0xF98FCFA6, 0xD201E065, 0xE13C785E,
1384  0x36BC4FB7, 0xD35E4720},
1385  //Pre-computed value mu
1386  {0xDDC4B621, 0x2D8C7CAF, 0x3D5AB45A, 0x55D42A20, 0x2237985C, 0x22B851A5, 0x89AD9837, 0x4195C155,
1387  0xAF1AA120, 0x360E55A5, 0x00000001},
1388  //Curve parameter a
1389  {0x7D860EB4, 0x92F375A9, 0x85FFA9F4, 0x66190EB0, 0xF5EB79DA, 0xA2A73513, 0x6D3F3BB8, 0x83CCEBD4,
1390  0x8FBAB0F8, 0x3EE30B56},
1391  //Curve parameter b
1392  {0x8FB1F1A6, 0x6F5EB4AC, 0x88453981, 0xCC31DCCD, 0x9554B49A, 0xE13F4134, 0x40688A6F, 0xD3AD1986,
1393  0x9DFDBC42, 0x52088394},
1394  //Base point G
1395  {
1396  //x-coordinate
1397  {0x39E20611, 0x10AF8D0D, 0x10A599C7, 0xE7871E2A, 0x0A087EB6, 0xF20137D1, 0x8EE5BFE6, 0x5289BCC4,
1398  0xFB53D8B8, 0x43BD7E9A},
1399  //y-coordinate
1400  {0x692E8EE1, 0xD35245D1, 0xAAAC6AC7, 0xA9C77877, 0x117182EA, 0x0743FFED, 0x7F77275E, 0xAB409324,
1401  0x45EC1CC8, 0x14FDD055},
1402  //z-coordinate
1403  {0x00000001}
1404  },
1405  //Base point order q
1406  {0x44C59311, 0x8691555B, 0xEE8658E9, 0x2D482EC7, 0xB68F12A3, 0xF98FCFA5, 0xD201E065, 0xE13C785E,
1407  0x36BC4FB7, 0xD35E4720},
1408  //Pre-computed value mu
1409  {0xAFA14203, 0x059081EA, 0xA154E856, 0x80461C1B, 0xF8341FE6, 0x22B851A6, 0x89AD9837, 0x4195C155,
1410  0xAF1AA120, 0x360E55A5, 0x00000001},
1411  //Cofactor
1412  1,
1413  //Field modular reduction
1415  //Field modular inversion
1416  NULL,
1417  //Scalar modular reduction
1419  //Scalar modular inversion
1420  NULL,
1421 };
1422 
1423 #endif
1424 #if (BRAINPOOLP320T1_SUPPORT == ENABLED)
1425 
1426 /**
1427  * @brief brainpoolP320t1 elliptic curve
1428  **/
1429 
1431 {
1432  //Curve name
1433  "brainpoolP320t1",
1434  //Object identifier
1436  sizeof(BRAINPOOLP320T1_OID),
1437  //Curve type
1439  //Field size, in bits
1440  320,
1441  //Order size, in bits
1442  320,
1443  //Prime modulus p
1444  {0xF1B32E27, 0xFCD412B1, 0x7893EC28, 0x4F92B9EC, 0xF6F40DEF, 0xF98FCFA6, 0xD201E065, 0xE13C785E,
1445  0x36BC4FB7, 0xD35E4720},
1446  //Pre-computed value mu
1447  {0xDDC4B621, 0x2D8C7CAF, 0x3D5AB45A, 0x55D42A20, 0x2237985C, 0x22B851A5, 0x89AD9837, 0x4195C155,
1448  0xAF1AA120, 0x360E55A5, 0x00000001},
1449  //Curve parameter a
1450  {0xF1B32E24, 0xFCD412B1, 0x7893EC28, 0x4F92B9EC, 0xF6F40DEF, 0xF98FCFA6, 0xD201E065, 0xE13C785E,
1451  0x36BC4FB7, 0xD35E4720},
1452  //Curve parameter b
1453  {0x22340353, 0xB5B4FEF4, 0xB8A547CE, 0x80AAF77F, 0x7ED27C67, 0x064C19F2, 0xDB782013, 0x60B3D147,
1454  0x38EB1ED5, 0xA7F561E0},
1455  //Base point G
1456  {
1457  //x-coordinate
1458  {0xA21BED52, 0x3357F624, 0xCC136FFF, 0x7EE07868, 0x6C4F09CB, 0x3408AB10, 0x90010F81, 0x4D3E7D49,
1459  0x01AFC6FB, 0x925BE9FB},
1460  //y-coordinate
1461  {0x5FB0D2C3, 0x1B9BC045, 0x9D1EE71B, 0x42A5A098, 0xA0B077AD, 0xEE084E58, 0x7ABB30EB, 0x6671DBEF,
1462  0x27483EBF, 0x63BA3A7A},
1463  //z-coordinate
1464  {0x00000001}
1465  },
1466  //Base point order q
1467  {0x44C59311, 0x8691555B, 0xEE8658E9, 0x2D482EC7, 0xB68F12A3, 0xF98FCFA5, 0xD201E065, 0xE13C785E,
1468  0x36BC4FB7, 0xD35E4720},
1469  //Pre-computed value mu
1470  {0xAFA14203, 0x059081EA, 0xA154E856, 0x80461C1B, 0xF8341FE6, 0x22B851A6, 0x89AD9837, 0x4195C155,
1471  0xAF1AA120, 0x360E55A5, 0x00000001},
1472  //Cofactor
1473  1,
1474  //Field modular reduction
1476  //Field modular inversion
1477  NULL,
1478  //Scalar modular reduction
1480  //Scalar modular inversion
1481  NULL,
1482 };
1483 
1484 #endif
1485 #if (BRAINPOOLP384R1_SUPPORT == ENABLED)
1486 
1487 /**
1488  * @brief brainpoolP384r1 elliptic curve
1489  **/
1490 
1492 {
1493  //Curve name
1494  "brainpoolP384r1",
1495  //Object identifier
1497  sizeof(BRAINPOOLP384R1_OID),
1498  //Curve type
1500  //Field size, in bits
1501  384,
1502  //Order size, in bits
1503  384,
1504  //Prime modulus p
1505  {0x3107EC53, 0x87470013, 0x901D1A71, 0xACD3A729, 0x7FB71123, 0x12B1DA19, 0xED5456B4, 0x152F7109,
1506  0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82},
1507  //Pre-computed value mu
1508  {0x84A26716, 0x10A03BF6, 0x7A71566F, 0x9047BCE0, 0xF1C4D721, 0x9ED590CE, 0xCAE56EDE, 0xDDA2C449,
1509  0x3CC6FA65, 0xFF25ADFD, 0x6D8EC6B8, 0xD1B575B1, 0x00000001},
1510  //Curve parameter a
1511  {0x22CE2826, 0x04A8C7DD, 0x503AD4EB, 0x8AA5814A, 0xBA91F90F, 0x139165EF, 0x4FB22787, 0xC2BEA28E,
1512  0xCE05AFA0, 0x3C72080A, 0x3D8C150C, 0x7BC382C6},
1513  //Curve parameter b
1514  {0xFA504C11, 0x3AB78696, 0x95DBC994, 0x7CB43902, 0x3EEB62D5, 0x2E880EA5, 0x07DCD2A6, 0x2FB77DE1,
1515  0x16F0447C, 0x8B39B554, 0x22CE2826, 0x04A8C7DD},
1516  //Base point G
1517  {
1518  //x-coordinate
1519  {0x47D4AF1E, 0xEF87B2E2, 0x36D646AA, 0xE826E034, 0x0CBD10E8, 0xDB7FCAFE, 0x7EF14FE3, 0x8847A3E7,
1520  0xB7C13F6B, 0xA2A63A81, 0x68CF45FF, 0x1D1C64F0},
1521  //y-coordinate
1522  {0x263C5315, 0x42820341, 0x77918111, 0x0E464621, 0xF9912928, 0xE19C054F, 0xFEEC5864, 0x62B70B29,
1523  0x95CFD552, 0x5CB1EB8E, 0x20F9C2A4, 0x8ABE1D75},
1524  //z-coordinate
1525  {0x00000001}
1526  },
1527  //Base point order q
1528  {0xE9046565, 0x3B883202, 0x6B7FC310, 0xCF3AB6AF, 0xAC0425A7, 0x1F166E6C, 0xED5456B3, 0x152F7109,
1529  0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82},
1530  //Pre-computed value mu
1531  {0xF8A71F8A, 0x600ADCCC, 0x7A652109, 0x189FDB46, 0x165031E7, 0xC506F2FE, 0xCAE56EE1, 0xDDA2C449,
1532  0x3CC6FA65, 0xFF25ADFD, 0x6D8EC6B8, 0xD1B575B1, 0x00000001},
1533  //Cofactor
1534  1,
1535  //Field modular reduction
1537  //Field modular inversion
1538  NULL,
1539  //Scalar modular reduction
1541  //Scalar modular inversion
1542  NULL,
1543 };
1544 
1545 #endif
1546 #if (BRAINPOOLP384T1_SUPPORT == ENABLED)
1547 
1548 /**
1549  * @brief brainpoolP384t1 elliptic curve
1550  **/
1551 
1553 {
1554  //Curve name
1555  "brainpoolP384t1",
1556  //Object identifier
1558  sizeof(BRAINPOOLP384T1_OID),
1559  //Curve type
1561  //Field size, in bits
1562  384,
1563  //Order size, in bits
1564  384,
1565  //Prime modulus p
1566  {0x3107EC53, 0x87470013, 0x901D1A71, 0xACD3A729, 0x7FB71123, 0x12B1DA19, 0xED5456B4, 0x152F7109,
1567  0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82},
1568  //Pre-computed value mu
1569  {0x84A26716, 0x10A03BF6, 0x7A71566F, 0x9047BCE0, 0xF1C4D721, 0x9ED590CE, 0xCAE56EDE, 0xDDA2C449,
1570  0x3CC6FA65, 0xFF25ADFD, 0x6D8EC6B8, 0xD1B575B1, 0x00000001},
1571  //Curve parameter a
1572  {0x3107EC50, 0x87470013, 0x901D1A71, 0xACD3A729, 0x7FB71123, 0x12B1DA19, 0xED5456B4, 0x152F7109,
1573  0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82},
1574  //Curve parameter b
1575  {0x33B471EE, 0xED70355A, 0x3B88805C, 0x2074AA26, 0x756DCE1D, 0x4B1ABD11, 0x8CCDC64E, 0x4B9346ED,
1576  0x47910F8C, 0xD826DBA6, 0xA7BDA81B, 0x7F519EAD},
1577  //Base point G
1578  {
1579  //x-coordinate
1580  {0x418808CC, 0xD8D0AA2F, 0x946A5F54, 0xC4FF191B, 0x462AABFF, 0x2476FECD, 0xEBD65317, 0x9B80AB12,
1581  0x35F72A81, 0xF2AFCD72, 0x2DB9A306, 0x18DE98B0},
1582  //y-coordinate
1583  {0x9E582928, 0x2675BF5B, 0x4DC2B291, 0x46940858, 0xA208CCFE, 0x3B88F2B6, 0x5B7A1FCA, 0x747F9347,
1584  0x755AD336, 0xA114AFD2, 0x62D30651, 0x25AB0569},
1585  //z-coordinate
1586  {0x00000001}
1587  },
1588  //Base point order q
1589  {0xE9046565, 0x3B883202, 0x6B7FC310, 0xCF3AB6AF, 0xAC0425A7, 0x1F166E6C, 0xED5456B3, 0x152F7109,
1590  0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82},
1591  //Pre-computed value mu
1592  {0xF8A71F8A, 0x600ADCCC, 0x7A652109, 0x189FDB46, 0x165031E7, 0xC506F2FE, 0xCAE56EE1, 0xDDA2C449,
1593  0x3CC6FA65, 0xFF25ADFD, 0x6D8EC6B8, 0xD1B575B1, 0x00000001},
1594  //Cofactor
1595  1,
1596  //Field modular reduction
1598  //Field modular inversion
1599  NULL,
1600  //Scalar modular reduction
1602  //Scalar modular inversion
1603  NULL,
1604 };
1605 
1606 #endif
1607 #if (BRAINPOOLP512R1_SUPPORT == ENABLED)
1608 
1609 /**
1610  * @brief brainpoolP512r1 elliptic curve
1611  **/
1612 
1614 {
1615  //Curve name
1616  "brainpoolP512r1",
1617  //Object identifier
1619  sizeof(BRAINPOOLP512R1_OID),
1620  //Curve type
1622  //Field size, in bits
1623  512,
1624  //Order size, in bits
1625  512,
1626  //Prime modulus p
1627  {0x583A48F3, 0x28AA6056, 0x2D82C685, 0x2881FF2F, 0xE6A380E6, 0xAECDA12A, 0x9BC66842, 0x7D4D9B00,
1628  0x70330871, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3, 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8},
1629  //Pre-computed value mu
1630  {0xE911E8D9, 0x17E2CF84, 0x603556D1, 0x71D621C4, 0x4E73EA8C, 0xE47D9303, 0x823152C5, 0x42FF2B38,
1631  0xF5BF92F5, 0x666AD8F2, 0xCC44EF09, 0x8373AF60, 0x03461E1E, 0x15D5EA2F, 0xD6DAEB8A, 0x7F8D7F4E,
1632  0x00000001},
1633  //Curve parameter a
1634  {0x77FC94CA, 0xE7C1AC4D, 0x2BF2C7B9, 0x7F1117A7, 0x8B9AC8B5, 0x0A2EF1C9, 0xA8253AA1, 0x2DED5D5A,
1635  0xEA9863BC, 0xA83441CA, 0x3DF91610, 0x94CBDD8D, 0xAC234CC5, 0xE2327145, 0x8B603B89, 0x7830A331},
1636  //Curve parameter b
1637  {0x8016F723, 0x2809BD63, 0x5EBAE5DD, 0x984050B7, 0xDC083E67, 0x77FC94CA, 0xE7C1AC4D, 0x2BF2C7B9,
1638  0x7F1117A7, 0x8B9AC8B5, 0x0A2EF1C9, 0xA8253AA1, 0x2DED5D5A, 0xEA9863BC, 0xA83441CA, 0x3DF91610},
1639  //Base point G
1640  {
1641  //x-coordinate
1642  {0xBCB9F822, 0x8B352209, 0x406A5E68, 0x7C6D5047, 0x93B97D5F, 0x50D1687B, 0xE2D0D48D, 0xFF3B1F78,
1643  0xF4D0098E, 0xB43B62EE, 0xB5D916C1, 0x85ED9F70, 0x9C4C6A93, 0x5A21322E, 0xD82ED964, 0x81AEE4BD},
1644  //y-coordinate
1645  {0x3AD80892, 0x78CD1E0F, 0xA8F05406, 0xD1CA2B2F, 0x8A2763AE, 0x5BCA4BD8, 0x4A5F485E, 0xB2DCDE49,
1646  0x881F8111, 0xA000C55B, 0x24A57B1A, 0xF209F700, 0xCF7822FD, 0xC0EABFA9, 0x566332EC, 0x7DDE385D},
1647  //z-coordinate
1648  {0x00000001}
1649  },
1650  //Base point order q
1651  {0x9CA90069, 0xB5879682, 0x085DDADD, 0x1DB1D381, 0x7FAC1047, 0x41866119, 0x4CA92619, 0x553E5C41,
1652  0x70330870, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3, 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8},
1653  //Pre-computed value mu
1654  {0xDB57DB37, 0x2FAFAC64, 0x15D5C4CE, 0x0EAF0D90, 0x59EE4710, 0x9FF38F5F, 0x1A235D44, 0xDB9470C6,
1655  0xF5BF92F7, 0x666AD8F2, 0xCC44EF09, 0x8373AF60, 0x03461E1E, 0x15D5EA2F, 0xD6DAEB8A, 0x7F8D7F4E,
1656  0x00000001},
1657  //Cofactor
1658  1,
1659  //Field modular reduction
1661  //Field modular inversion
1662  NULL,
1663  //Scalar modular reduction
1665  //Scalar modular inversion
1666  NULL,
1667 };
1668 
1669 #endif
1670 #if (BRAINPOOLP512T1_SUPPORT == ENABLED)
1671 
1672 /**
1673  * @brief brainpoolP512t1 elliptic curve
1674  **/
1675 
1677 {
1678  //Curve name
1679  "brainpoolP512t1",
1680  //Object identifier
1682  sizeof(BRAINPOOLP512T1_OID),
1683  //Curve type
1685  //Field size, in bits
1686  512,
1687  //Order size, in bits
1688  512,
1689  //Prime modulus p
1690  {0x583A48F3, 0x28AA6056, 0x2D82C685, 0x2881FF2F, 0xE6A380E6, 0xAECDA12A, 0x9BC66842, 0x7D4D9B00,
1691  0x70330871, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3, 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8},
1692  //Pre-computed value mu
1693  {0xE911E8D9, 0x17E2CF84, 0x603556D1, 0x71D621C4, 0x4E73EA8C, 0xE47D9303, 0x823152C5, 0x42FF2B38,
1694  0xF5BF92F5, 0x666AD8F2, 0xCC44EF09, 0x8373AF60, 0x03461E1E, 0x15D5EA2F, 0xD6DAEB8A, 0x7F8D7F4E,
1695  0x00000001},
1696  //Curve parameter a
1697  {0x583A48F0, 0x28AA6056, 0x2D82C685, 0x2881FF2F, 0xE6A380E6, 0xAECDA12A, 0x9BC66842, 0x7D4D9B00,
1698  0x70330871, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3, 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8},
1699  //Curve parameter b
1700  {0x1867423E, 0x180EA257, 0x65763689, 0xC22553B4, 0xF2DAE145, 0xF6450085, 0x04976540, 0x2BCDFA23,
1701  0xEC3E36A6, 0x7897504B, 0xCB498152, 0x21F70C0B, 0x6884EAE3, 0x6E1890E4, 0x441CFAB7, 0x7CBBBCF9},
1702  //Base point G
1703  {
1704  //x-coordinate
1705  {0xFA9035DA, 0x1BAA2696, 0xE26F06B5, 0xF7A3F25F, 0xD6943A64, 0x99AA77A7, 0x5CDB3EA4, 0x82BA5173,
1706  0x39C0313D, 0x9DB1758D, 0x58C56DDE, 0xBA858424, 0xCBC2A6FE, 0xB9C1BA06, 0x12788717, 0x640ECE5C},
1707  //y-coordinate
1708  {0x00F8B332, 0xE198B61E, 0x6DBB8BAC, 0x306ECFF9, 0xDF86A627, 0xD71DF2DA, 0xBEEF216B, 0xD9932184,
1709  0xAE03CEE9, 0x1131159C, 0xB71634C0, 0xBB4E3019, 0x6C84ACE1, 0xA2C89237, 0x95F5AF0F, 0x5B534BD5},
1710  //z-coordinate
1711  {0x00000001}
1712  },
1713  //Base point order q
1714  {0x9CA90069, 0xB5879682, 0x085DDADD, 0x1DB1D381, 0x7FAC1047, 0x41866119, 0x4CA92619, 0x553E5C41,
1715  0x70330870, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3, 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8},
1716  //Pre-computed value mu
1717  {0xDB57DB37, 0x2FAFAC64, 0x15D5C4CE, 0x0EAF0D90, 0x59EE4710, 0x9FF38F5F, 0x1A235D44, 0xDB9470C6,
1718  0xF5BF92F7, 0x666AD8F2, 0xCC44EF09, 0x8373AF60, 0x03461E1E, 0x15D5EA2F, 0xD6DAEB8A, 0x7F8D7F4E,
1719  0x00000001},
1720  //Cofactor
1721  1,
1722  //Field modular reduction
1724  //Field modular inversion
1725  NULL,
1726  //Scalar modular reduction
1728  //Scalar modular inversion
1729  NULL,
1730 };
1731 
1732 #endif
1733 #if (FRP256V1_SUPPORT == ENABLED)
1734 
1735 /**
1736  * @brief FRP256v1 elliptic curve
1737  **/
1738 
1740 {
1741  //Curve name
1742  "FRP256v1",
1743  //Object identifier
1744  FRP256V1_OID,
1745  sizeof(FRP256V1_OID),
1746  //Curve type
1748  //Field size, in bits
1749  256,
1750  //Order size, in bits
1751  256,
1752  //Prime modulus p
1753  {0xD86E9C03, 0xE8FCF353, 0xABC8CA6D, 0x3961ADBC, 0xCE42435B, 0x10126DE8, 0x0B3AD58F, 0xF1FD178C},
1754  //Pre-computed value mu
1755  {0x9002424F, 0x6ABA3ABF, 0xC20522AE, 0x07B58508, 0x8851C193, 0xF36AF7F5, 0xC7D2B040, 0x0ED297DC,
1756  0x00000001},
1757  //Curve parameter a
1758  {0xD86E9C00, 0xE8FCF353, 0xABC8CA6D, 0x3961ADBC, 0xCE42435B, 0x10126DE8, 0x0B3AD58F, 0xF1FD178C},
1759  //Curve parameter b
1760  {0x7B7BB73F, 0x3075ED96, 0xE4B1A180, 0xDFEC0C9A, 0x4A44C00F, 0x0D4ABA75, 0x5428A930, 0xEE353FCA},
1761  //Base point G
1762  {
1763  //x-coordinate
1764  {0xD98F5CFF, 0x64C97A2D, 0xAF98B701, 0x8C27D2DC, 0x49D42395, 0x31183D47, 0x56C139EB, 0xB6B3D4C3},
1765  //y-coordinate
1766  {0x54062CFB, 0x83115A15, 0xE8E4C9E1, 0x2701C307, 0xF3ECEF8C, 0x1F9271F0, 0xC8B20491, 0x6142E0F7},
1767  //z-coordinate
1768  {0x00000001}
1769  },
1770  //Base point order q
1771  {0xC6D655E1, 0x1FFDD459, 0x40D2BF94, 0x53DC67E1, 0xCE42435B, 0x10126DE8, 0x0B3AD58F, 0xF1FD178C},
1772  //Pre-computed value mu
1773  {0xE02F4C13, 0xC7CFD1DA, 0xCEAD1E3F, 0xEA1313F7, 0x8851C192, 0xF36AF7F5, 0xC7D2B040, 0x0ED297DC,
1774  0x00000001},
1775  //Cofactor
1776  1,
1777  //Field modular reduction
1779  //Field modular inversion
1780  NULL,
1781  //Scalar modular reduction
1783  //Scalar modular inversion
1784  NULL,
1785 };
1786 
1787 #endif
1788 #if (SM2_SUPPORT == ENABLED)
1789 
1790 /**
1791  * @brief SM2 elliptic curve
1792  **/
1793 
1795 {
1796  //Curve name
1797  "curveSM2",
1798  //Object identifier
1799  SM2_OID,
1800  sizeof(SM2_OID),
1801  //Curve type
1803  //Field size, in bits
1804  256,
1805  //Order size, in bits
1806  256,
1807  //Prime modulus p
1808  {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE},
1809  //Pre-computed value mu
1810  {0},
1811  //Curve parameter a
1812  {0xFFFFFFFC, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE},
1813  //Curve parameter b
1814  {0x4D940E93, 0xDDBCBD41, 0x15AB8F92, 0xF39789F5, 0xCF6509A7, 0x4D5A9E4B, 0x9D9F5E34, 0x28E9FA9E},
1815  //Base point G
1816  {
1817  //x-coordinate
1818  {0x334C74C7, 0x715A4589, 0xF2660BE1, 0x8FE30BBF, 0x6A39C994, 0x5F990446, 0x1F198119, 0x32C4AE2C},
1819  //y-coordinate
1820  {0x2139F0A0, 0x02DF32E5, 0xC62A4740, 0xD0A9877C, 0x6B692153, 0x59BDCEE3, 0xF4F6779C, 0xBC3736A2},
1821  //z-coordinate
1822  {0x00000001}
1823  },
1824  //Base point order q
1825  {0x39D54123, 0x53BBF409, 0x21C6052B, 0x7203DF6B, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE},
1826  //Pre-computed value mu
1827  {0xF15149A0, 0x12AC6361, 0xFA323C01, 0x8DFC2096, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
1828  0x00000001},
1829  //Cofactor
1830  1,
1831  //Field modular reduction
1832  sm2FieldMod,
1833  //Field modular inversion
1834  sm2FieldInv,
1835  //Scalar modular reduction
1836  sm2ScalarMod,
1837  //Scalar modular inversion
1838  NULL,
1839 };
1840 
1841 #endif
1842 #if (X25519_SUPPORT == ENABLED)
1843 
1844 /**
1845  * @brief Curve25519 elliptic curve
1846  **/
1847 
1849 {
1850  //Curve name
1851  "curve25519",
1852  //Object identifier
1853  X25519_OID,
1854  sizeof(X25519_OID),
1855  //Curve type
1857  //Field size, in bits
1858  255,
1859  //Order size, in bits
1860  253,
1861  //Prime modulus p
1862  {0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF},
1863  //Pre-computed value mu
1864  {0},
1865  //Curve parameter a
1866  {0x00076D06},
1867  //Curve parameter b
1868  {0x00000001},
1869  //Base point G
1870  {
1871  //x-coordinate
1872  {0x00000009},
1873  //y-coordinate
1874  {0x7ECED3D9, 0x29E9C5A2, 0x6D7C61B2, 0x923D4D7E, 0x7748D14C, 0xE01EDD2C, 0xB8A086B4, 0x20AE19A1},
1875  //z-coordinate
1876  {0x00000001}
1877  },
1878  //Base point order q
1879  {0x5CF5D3ED, 0x5812631A, 0xA2F79CD6, 0x14DEF9DE, 0x00000000, 0x00000000, 0x00000000, 0x10000000},
1880  //Pre-computed value mu
1881  {0},
1882  //Cofactor
1883  8,
1884  //Field modular reduction
1885  NULL,
1886  //Field modular inversion
1887  NULL,
1888  //Scalar modular reduction
1889  NULL,
1890  //Scalar modular inversion
1891  NULL,
1892 };
1893 
1894 #endif
1895 #if (X448_SUPPORT == ENABLED)
1896 
1897 /**
1898  * @brief Curve448 elliptic curve
1899  **/
1900 
1902 {
1903  //Curve name
1904  "curve448",
1905  //Object identifier
1906  X448_OID,
1907  sizeof(X448_OID),
1908  //Curve type
1910  //Field size, in bits
1911  448,
1912  //Order size, in bits
1913  446,
1914  //Prime modulus p
1915  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE,
1916  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
1917  //Pre-computed value mu
1918  {0},
1919  //Curve parameter a
1920  {0x000262A6},
1921  //Curve parameter b
1922  {0x00000001},
1923  //Base point G
1924  {
1925  //x-coordinate
1926  {0x00000005},
1927  //y-coordinate
1928  {0x457B5B1A, 0x6FD7223D, 0x50677AF7, 0x1312C4B1, 0x46430D21, 0xB8027E23, 0x8DF3F6ED, 0x60F75DC2,
1929  0xF55545D0, 0xCBAE5D34, 0x58326FCE, 0x6C98AB6E, 0x95F5B1F6, 0x7D235D12},
1930  //z-coordinate
1931  {0x00000001}
1932  },
1933  //Base point order q
1934  {0xAB5844F3, 0x2378C292, 0x8DC58F55, 0x216CC272, 0xAED63690, 0xC44EDB49, 0x7CCA23E9, 0xFFFFFFFF,
1935  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x3FFFFFFF},
1936  //Pre-computed value mu
1937  {0},
1938  //Cofactor
1939  4,
1940  //Field modular reduction
1941  NULL,
1942  //Field modular inversion
1943  NULL,
1944  //Scalar modular reduction
1945  NULL,
1946  //Scalar modular inversion
1947  NULL,
1948 };
1949 
1950 #endif
1951 #if (ED25519_SUPPORT == ENABLED)
1952 
1953 /**
1954  * @brief Ed25519 elliptic curve
1955  **/
1956 
1958 {
1959  //Curve name
1960  "Ed25519",
1961  //Object identifier
1962  ED25519_OID,
1963  sizeof(ED25519_OID),
1964  //Curve type
1966  //Field size, in bits
1967  255,
1968  //Order size, in bits
1969  253,
1970  //Prime modulus p
1971  {0xFFFFFFED, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF},
1972  //Pre-computed value mu
1973  {0},
1974  //Curve parameter a
1975  {0xFFFFFFEC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF},
1976  //Curve parameter d
1977  {0x135978A3, 0x75EB4DCA, 0x4141D8AB, 0x00700A4D, 0x7779E898, 0x8CC74079, 0x2B6FFE73, 0x52036CEE},
1978  //Base point G
1979  {
1980  //x-coordinate
1981  {0x8F25D51A, 0xC9562D60, 0x9525A7B2, 0x692CC760, 0xFDD6DC5C, 0xC0A4E231, 0xCD6E53FE, 0x216936D3},
1982  //y-coordinate
1983  {0x66666658, 0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666666, 0x66666666},
1984  //z-coordinate
1985  {0x00000001}
1986  },
1987  //Base point order q
1988  {0x5CF5D3ED, 0x5812631A, 0xA2F79CD6, 0x14DEF9DE, 0x00000000, 0x00000000, 0x00000000, 0x10000000},
1989  //Pre-computed value mu
1990  {0},
1991  //Cofactor
1992  8,
1993  //Field modular reduction
1994  NULL,
1995  //Field modular inversion
1996  NULL,
1997  //Scalar modular reduction
1998  NULL,
1999  //Scalar modular inversion
2000  NULL,
2001 };
2002 
2003 #endif
2004 #if (ED448_SUPPORT == ENABLED)
2005 
2006 /**
2007  * @brief Ed448 elliptic curve
2008  **/
2009 
2011 {
2012  //Curve name
2013  "Ed448",
2014  //Object identifier
2015  ED448_OID,
2016  sizeof(ED448_OID),
2017  //Curve type
2019  //Field size, in bits
2020  448,
2021  //Order size, in bits
2022  446,
2023  //Prime modulus p
2024  {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE,
2025  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
2026  //Pre-computed value mu
2027  {0},
2028  //Curve parameter a
2029  {0x0000001},
2030  //Curve parameter d
2031  {0xBAA156B9, 0x243CC32D, 0x58FB61C4, 0xD0809970, 0x264CFE9A, 0x9CCC9C81, 0x412A12E7, 0x809B1DA3,
2032  0x42A50F37, 0xAD461572, 0x9373A2CC, 0xF24F38C2, 0x7F0DAF19, 0xD78B4BDC},
2033  //Base point G
2034  {
2035  //x-coordinate
2036  {0x3E9C04FC, 0x69871309, 0x8496CD11, 0x9DE732F3, 0xED697224, 0xE21F7787, 0x728BDC93, 0x0C25A07D,
2037  0xC9296924, 0x1128751A, 0x16C792C6, 0xAE7C9DF4, 0x70400553, 0x79A70B2B},
2038  //y-coordinate
2039  {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xFFFFFFFF,
2040  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF},
2041  //z-coordinate
2042  {0x00000001}
2043  },
2044  //Base point order q
2045  {0xAB5844F3, 0x2378C292, 0x8DC58F55, 0x216CC272, 0xAED63690, 0xC44EDB49, 0x7CCA23E9, 0xFFFFFFFF,
2046  0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x3FFFFFFF},
2047  //Pre-computed value mu
2048  {0},
2049  //Cofactor
2050  4,
2051  //Field modular reduction
2052  NULL,
2053  //Field modular inversion
2054  NULL,
2055  //Scalar modular reduction
2056  NULL,
2057  //Scalar modular inversion
2058  NULL,
2059 };
2060 
2061 #endif
2062 #if (SECP112R1_SUPPORT == ENABLED)
2063 
2064 /**
2065  * @brief Field modular reduction (secp112r1 curve)
2066  * @param[in] curve Elliptic curve parameters
2067  * @param[out] r Resulting integer R = A mod p
2068  * @param[in] a An integer such as 0 <= A < p^2
2069  **/
2070 
2071 void secp112r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2072 {
2073  uint32_t c;
2074  uint64_t temp;
2075  uint32_t u[4];
2076  uint32_t v[4];
2077 
2078  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2079  temp = (uint64_t) a[3] * 76439;
2080  temp >>= 32;
2081  temp += (uint64_t) a[4] * 76439;
2082  u[0] = (uint32_t) temp;
2083  temp >>= 32;
2084  temp += (uint64_t) a[5] * 76439;
2085  u[1] = (uint32_t) temp;
2086  temp >>= 32;
2087  temp += (uint64_t) a[6] * 76439;
2088  u[2] = (uint32_t) temp;
2089  temp >>= 32;
2090  u[3] = (uint32_t) temp;
2091 
2092  //Compute v = u * p mod b^(k + 1)
2093  ecScalarMul(v, NULL, u, curve->p, 4);
2094 
2095  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2096  //If u < 0, then u = u + b^(k + 1)
2097  ecScalarSub(u, a, v, 4);
2098 
2099  //This estimation implies that at most two subtractions of p are required to
2100  //obtain the correct remainder r
2101  c = ecScalarSub(v, u, curve->p, 4);
2102  ecScalarSelect(u, v, u, c, 4);
2103  c = ecScalarSub(v, u, curve->p, 4);
2104  ecScalarSelect(r, v, u, c, 4);
2105 }
2106 
2107 
2108 /**
2109  * @brief Scalar modular reduction (secp112r1 curve)
2110  * @param[in] curve Elliptic curve parameters
2111  * @param[out] r Resulting integer R = A mod q
2112  * @param[in] a An integer such as 0 <= A < q^2
2113  **/
2114 
2115 void secp112r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2116 {
2117  uint32_t c;
2118  uint32_t u[4];
2119  uint32_t v[4];
2120 
2121  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2122  ecScalarMul(NULL, u, a + 3, curve->qmu, 4);
2123  //Compute v = u * q mod b^(k + 1)
2124  ecScalarMul(v, NULL, u, curve->q, 4);
2125 
2126  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2127  //If u < 0, then u = u + b^(k + 1)
2128  ecScalarSub(u, a, v, 4);
2129 
2130  //This estimation implies that at most two subtractions of q are required to
2131  //obtain the correct remainder r
2132  c = ecScalarSub(v, u, curve->q, 4);
2133  ecScalarSelect(u, v, u, c, 4);
2134  c = ecScalarSub(v, u, curve->q, 4);
2135  ecScalarSelect(r, v, u, c, 4);
2136 }
2137 
2138 #endif
2139 #if (SECP112R2_SUPPORT == ENABLED)
2140 
2141 /**
2142  * @brief Field modular reduction (secp112r2 curve)
2143  * @param[in] curve Elliptic curve parameters
2144  * @param[out] r Resulting integer R = A mod p
2145  * @param[in] a An integer such as 0 <= A < p^2
2146  **/
2147 
2148 void secp112r2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2149 {
2150  uint32_t c;
2151  uint64_t temp;
2152  uint32_t u[4];
2153  uint32_t v[4];
2154 
2155  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2156  temp = (uint64_t) a[3] * 76439;
2157  temp >>= 32;
2158  temp += (uint64_t) a[4] * 76439;
2159  u[0] = (uint32_t) temp;
2160  temp >>= 32;
2161  temp += (uint64_t) a[5] * 76439;
2162  u[1] = (uint32_t) temp;
2163  temp >>= 32;
2164  temp += (uint64_t) a[6] * 76439;
2165  u[2] = (uint32_t) temp;
2166  temp >>= 32;
2167  u[3] = (uint32_t) temp;
2168 
2169  //Compute v = u * p mod b^(k + 1)
2170  ecScalarMul(v, NULL, u, curve->p, 4);
2171 
2172  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2173  //If u < 0, then u = u + b^(k + 1)
2174  ecScalarSub(u, a, v, 4);
2175 
2176  //This estimation implies that at most two subtractions of p are required to
2177  //obtain the correct remainder r
2178  c = ecScalarSub(v, u, curve->p, 4);
2179  ecScalarSelect(u, v, u, c, 4);
2180  c = ecScalarSub(v, u, curve->p, 4);
2181  ecScalarSelect(r, v, u, c, 4);
2182 }
2183 
2184 
2185 /**
2186  * @brief Scalar modular reduction (secp112r2 curve)
2187  * @param[in] curve Elliptic curve parameters
2188  * @param[out] r Resulting integer R = A mod q
2189  * @param[in] a An integer such as 0 <= A < q^2
2190  **/
2191 
2192 void secp112r2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2193 {
2194  uint32_t c;
2195  uint32_t a2[7];
2196  uint32_t q2[4];
2197  uint32_t u[4];
2198  uint32_t v[4];
2199 
2200  //Compute a = a << 2
2201  ecScalarShiftLeft(a2, a, 2, 7);
2202  //Compute q = q << 2
2203  ecScalarShiftLeft(q2, curve->q, 2, 4);
2204 
2205  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2206  ecScalarMul(NULL, u, a2 + 3, curve->qmu, 4);
2207  //Compute v = u * q mod b^(k + 1)
2208  ecScalarMul(v, NULL, u, q2, 4);
2209 
2210  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2211  //If u < 0, then u = u + b^(k + 1)
2212  ecScalarSub(u, a2, v, 4);
2213 
2214  //This estimation implies that at most two subtractions of q are required to
2215  //obtain the correct remainder r
2216  c = ecScalarSub(v, u, q2, 4);
2217  ecScalarSelect(u, v, u, c, 4);
2218  c = ecScalarSub(v, u, q2, 4);
2219  ecScalarSelect(u, v, u, c, 4);
2220 
2221  //Compute a = u >> 2
2222  ecScalarShiftRight(r, u, 2, 4);
2223 }
2224 
2225 #endif
2226 #if (SECP128R1_SUPPORT == ENABLED)
2227 
2228 /**
2229  * @brief Field modular reduction (secp128r1 curve)
2230  * @param[in] curve Elliptic curve parameters
2231  * @param[out] r Resulting integer R = A mod p
2232  * @param[in] a An integer such as 0 <= A < p^2
2233  **/
2234 
2235 void secp128r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2236 {
2237  uint64_t c;
2238  uint64_t temp;
2239 
2240  //First pass
2241  temp = (uint64_t) a[0] + a[4] + a[5] + a[5];
2242  temp += (uint64_t) a[6] << 2;
2243  temp += (uint64_t) a[7] << 3;
2244  r[0] = (uint32_t) temp;
2245  temp >>= 32;
2246  temp += (uint64_t) a[1] + a[5] + a[6] + a[6];
2247  temp += (uint64_t) a[7] << 2;
2248  r[1] = (uint32_t) temp;
2249  temp >>= 32;
2250  temp += (uint64_t) a[2] + a[6] + a[7] + a[7];
2251  r[2] = (uint32_t) temp;
2252  temp >>= 32;
2253  temp += (uint64_t) a[3] + a[4] + a[4] + a[7];
2254  temp += (uint64_t) a[5] << 2;
2255  temp += (uint64_t) a[6] << 3;
2256  temp += (uint64_t) a[7] << 4;
2257  r[3] = (uint32_t) temp;
2258  c = temp >> 32;
2259 
2260  //Second pass
2261  temp = (uint64_t) r[0] + c;
2262  r[0] = (uint32_t) temp;
2263  temp >>= 32;
2264  temp += (uint64_t) r[1];
2265  r[1] = (uint32_t) temp;
2266  temp >>= 32;
2267  temp += (uint64_t) r[2];
2268  r[2] = (uint32_t) temp;
2269  temp >>= 32;
2270  temp += (uint64_t) r[3] + c + c;
2271  r[3] = (uint32_t) temp;
2272  c = temp >> 32;
2273 
2274  //Third pass
2275  temp = (uint64_t) r[0] + c;
2276  r[0] = (uint32_t) temp;
2277  temp >>= 32;
2278  temp += (uint64_t) r[1];
2279  r[1] = (uint32_t) temp;
2280  temp >>= 32;
2281  temp += (uint64_t) r[2];
2282  r[2] = (uint32_t) temp;
2283  temp >>= 32;
2284  temp += (uint64_t) r[3] + c + c;
2285  r[3] = (uint32_t) temp;
2286 
2287  //Reduce non-canonical values
2288  ecFieldCanonicalize(curve, r, r);
2289 }
2290 
2291 
2292 /**
2293  * @brief Field modular inversion (secp128r1 curve)
2294  * @param[in] curve Elliptic curve parameters
2295  * @param[out] r Resulting integer R = A^-1 mod p
2296  * @param[in] a An integer such as 0 <= A < p
2297  **/
2298 
2299 void secp128r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2300 {
2301  uint32_t u[4];
2302  uint32_t v[4];
2303 
2304  //Since GF(p) is a prime field, the Fermat's little theorem can be
2305  //used to find the multiplicative inverse of A modulo p
2306  ecFieldSqrMod(curve, u, a);
2307  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
2308  ecFieldSqrMod(curve, u, u);
2309  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
2310  ecFieldPwr2Mod(curve, v, u, 3);
2311  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
2312  ecFieldSqrMod(curve, u, u);
2313  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
2314  ecFieldPwr2Mod(curve, v, u, 7);
2315  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
2316  ecFieldSqrMod(curve, u, u);
2317  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
2318  ecFieldPwr2Mod(curve, v, u, 15);
2319  ecFieldMulMod(curve, v, u, v); //A^(2^30 - 1)
2320  ecFieldPwr2Mod(curve, u, v, 31);
2321  ecFieldMulMod(curve, u, u, v); //A^(2^61 - 2^30 - 1)
2322  ecFieldPwr2Mod(curve, u, u, 30);
2323  ecFieldMulMod(curve, u, u, v); //A^(2^91 - 2^60 - 1)
2324  ecFieldPwr2Mod(curve, u, u, 30);
2325  ecFieldMulMod(curve, u, u, v); //A^(2^121 - 2^90 - 1)
2326  ecFieldSqrMod(curve, u, u);
2327  ecFieldMulMod(curve, u, u, a); //A^(2^122 - 2^91 - 1)
2328  ecFieldSqrMod(curve, u, u);
2329  ecFieldMulMod(curve, u, u, a); //A^(2^123 - 2^92 - 1)
2330  ecFieldSqrMod(curve, u, u);
2331  ecFieldMulMod(curve, u, u, a); //A^(2^124 - 2^93 - 1)
2332  ecFieldSqrMod(curve, u, u);
2333  ecFieldMulMod(curve, u, u, a); //A^(2^125 - 2^94 - 1)
2334  ecFieldSqrMod(curve, u, u);
2335  ecFieldMulMod(curve, u, u, a); //A^(2^126 - 2^95 - 1)
2336  ecFieldPwr2Mod(curve, u, u, 2);
2337  ecFieldMulMod(curve, r, u, a); //A^(2^128 - 2^97 - 3)
2338 }
2339 
2340 
2341 /**
2342  * @brief Scalar modular reduction (secp128r1 curve)
2343  * @param[in] curve Elliptic curve parameters
2344  * @param[out] r Resulting integer R = A mod q
2345  * @param[in] a An integer such as 0 <= A < q^2
2346  **/
2347 
2348 void secp128r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2349 {
2350  uint32_t c;
2351  uint32_t u[9];
2352  uint32_t v[9];
2353 
2354  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2355  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
2356  //Compute v = u * q mod b^(k + 1)
2357  ecScalarMul(v, NULL, u, curve->q, 9);
2358 
2359  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2360  //If u < 0, then u = u + b^(k + 1)
2361  ecScalarSub(u, a, v, 9);
2362 
2363  //This estimation implies that at most two subtractions of q are required to
2364  //obtain the correct remainder r
2365  c = ecScalarSub(v, u, curve->q, 9);
2366  ecScalarSelect(u, v, u, c, 9);
2367  c = ecScalarSub(v, u, curve->q, 9);
2368  ecScalarSelect(r, v, u, c, 8);
2369 }
2370 
2371 #endif
2372 #if (SECP128R2_SUPPORT == ENABLED)
2373 
2374 /**
2375  * @brief Field modular reduction (secp128r2 curve)
2376  * @param[in] curve Elliptic curve parameters
2377  * @param[out] r Resulting integer R = A mod p
2378  * @param[in] a An integer such as 0 <= A < p^2
2379  **/
2380 
2381 void secp128r2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2382 {
2383  uint64_t c;
2384  uint64_t temp;
2385 
2386  //First pass
2387  temp = (uint64_t) a[0] + a[4] + a[5] + a[5];
2388  temp += (uint64_t) a[6] << 2;
2389  temp += (uint64_t) a[7] << 3;
2390  r[0] = (uint32_t) temp;
2391  temp >>= 32;
2392  temp += (uint64_t) a[1] + a[5] + a[6] + a[6];
2393  temp += (uint64_t) a[7] << 2;
2394  r[1] = (uint32_t) temp;
2395  temp >>= 32;
2396  temp += (uint64_t) a[2] + a[6] + a[7] + a[7];
2397  r[2] = (uint32_t) temp;
2398  temp >>= 32;
2399  temp += (uint64_t) a[3] + a[4] + a[4] + a[7];
2400  temp += (uint64_t) a[5] << 2;
2401  temp += (uint64_t) a[6] << 3;
2402  temp += (uint64_t) a[7] << 4;
2403  r[3] = (uint32_t) temp;
2404  c = temp >> 32;
2405 
2406  //Second pass
2407  temp = (uint64_t) r[0] + c;
2408  r[0] = (uint32_t) temp;
2409  temp >>= 32;
2410  temp += (uint64_t) r[1];
2411  r[1] = (uint32_t) temp;
2412  temp >>= 32;
2413  temp += (uint64_t) r[2];
2414  r[2] = (uint32_t) temp;
2415  temp >>= 32;
2416  temp += (uint64_t) r[3] + c + c;
2417  r[3] = (uint32_t) temp;
2418  c = temp >> 32;
2419 
2420  //Third pass
2421  temp = (uint64_t) r[0] + c;
2422  r[0] = (uint32_t) temp;
2423  temp >>= 32;
2424  temp += (uint64_t) r[1];
2425  r[1] = (uint32_t) temp;
2426  temp >>= 32;
2427  temp += (uint64_t) r[2];
2428  r[2] = (uint32_t) temp;
2429  temp >>= 32;
2430  temp += (uint64_t) r[3] + c + c;
2431  r[3] = (uint32_t) temp;
2432 
2433  //Reduce non-canonical values
2434  ecFieldCanonicalize(curve, r, r);
2435 }
2436 
2437 
2438 /**
2439  * @brief Field modular inversion (secp128r2 curve)
2440  * @param[in] curve Elliptic curve parameters
2441  * @param[out] r Resulting integer R = A^-1 mod p
2442  * @param[in] a An integer such as 0 <= A < p
2443  **/
2444 
2445 void secp128r2FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2446 {
2447  uint32_t u[4];
2448  uint32_t v[4];
2449 
2450  //Since GF(p) is a prime field, the Fermat's little theorem can be
2451  //used to find the multiplicative inverse of A modulo p
2452  ecFieldSqrMod(curve, u, a);
2453  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
2454  ecFieldSqrMod(curve, u, u);
2455  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
2456  ecFieldPwr2Mod(curve, v, u, 3);
2457  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
2458  ecFieldSqrMod(curve, u, u);
2459  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
2460  ecFieldPwr2Mod(curve, v, u, 7);
2461  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
2462  ecFieldSqrMod(curve, u, u);
2463  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
2464  ecFieldPwr2Mod(curve, v, u, 15);
2465  ecFieldMulMod(curve, v, u, v); //A^(2^30 - 1)
2466  ecFieldPwr2Mod(curve, u, v, 31);
2467  ecFieldMulMod(curve, u, u, v); //A^(2^61 - 2^30 - 1)
2468  ecFieldPwr2Mod(curve, u, u, 30);
2469  ecFieldMulMod(curve, u, u, v); //A^(2^91 - 2^60 - 1)
2470  ecFieldPwr2Mod(curve, u, u, 30);
2471  ecFieldMulMod(curve, u, u, v); //A^(2^121 - 2^90 - 1)
2472  ecFieldSqrMod(curve, u, u);
2473  ecFieldMulMod(curve, u, u, a); //A^(2^122 - 2^91 - 1)
2474  ecFieldSqrMod(curve, u, u);
2475  ecFieldMulMod(curve, u, u, a); //A^(2^123 - 2^92 - 1)
2476  ecFieldSqrMod(curve, u, u);
2477  ecFieldMulMod(curve, u, u, a); //A^(2^124 - 2^93 - 1)
2478  ecFieldSqrMod(curve, u, u);
2479  ecFieldMulMod(curve, u, u, a); //A^(2^125 - 2^94 - 1)
2480  ecFieldSqrMod(curve, u, u);
2481  ecFieldMulMod(curve, u, u, a); //A^(2^126 - 2^95 - 1)
2482  ecFieldPwr2Mod(curve, u, u, 2);
2483  ecFieldMulMod(curve, r, u, a); //A^(2^128 - 2^97 - 3)
2484 }
2485 
2486 
2487 /**
2488  * @brief Scalar modular reduction (secp128r2 curve)
2489  * @param[in] curve Elliptic curve parameters
2490  * @param[out] r Resulting integer R = A mod q
2491  * @param[in] a An integer such as 0 <= A < q^2
2492  **/
2493 
2494 void secp128r2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2495 {
2496  uint32_t c;
2497  uint32_t a2[9];
2498  uint32_t q2[5];
2499  uint32_t u[5];
2500  uint32_t v[5];
2501 
2502  //Compute a = a << 2
2503  ecScalarShiftLeft(a2, a, 2, 9);
2504  //Compute q = q << 2
2505  ecScalarShiftLeft(q2, curve->q, 2, 5);
2506 
2507  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2508  ecScalarMul(NULL, u, a2 + 4, curve->qmu, 5);
2509  //Compute v = u * q mod b^(k + 1)
2510  ecScalarMul(v, NULL, u, q2, 5);
2511 
2512  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2513  //If u < 0, then u = u + b^(k + 1)
2514  ecScalarSub(u, a2, v, 5);
2515 
2516  //This estimation implies that at most two subtractions of q are required to
2517  //obtain the correct remainder r
2518  c = ecScalarSub(v, u, q2, 5);
2519  ecScalarSelect(u, v, u, c, 5);
2520  c = ecScalarSub(v, u, q2, 5);
2521  ecScalarSelect(u, v, u, c, 5);
2522 
2523  //Compute a = u >> 2
2524  ecScalarShiftRight(r, u, 2, 5);
2525 }
2526 
2527 #endif
2528 #if (SECP160K1_SUPPORT == ENABLED)
2529 
2530 /**
2531  * @brief Field modular reduction (secp160k1 curve)
2532  * @param[in] curve Elliptic curve parameters
2533  * @param[out] r Resulting integer R = A mod p
2534  * @param[in] a An integer such as 0 <= A < p^2
2535  **/
2536 
2537 void secp160k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2538 {
2539  uint64_t c;
2540  uint64_t temp;
2541 
2542  //First pass
2543  temp = (uint64_t) a[0];
2544  temp += (uint64_t) a[5] * 21389;
2545  temp += (uint64_t) a[9] * 21389;
2546  r[0] = (uint32_t) temp;
2547  temp >>= 32;
2548  temp += (uint64_t) a[1] + a[5] + a[9];
2549  temp += (uint64_t) a[6] * 21389;
2550  r[1] = (uint32_t) temp;
2551  temp >>= 32;
2552  temp += (uint64_t) a[2] + a[6];
2553  temp += (uint64_t) a[7] * 21389;
2554  r[2] = (uint32_t) temp;
2555  temp >>= 32;
2556  temp += (uint64_t) a[3] + a[7];
2557  temp += (uint64_t) a[8] * 21389;
2558  r[3] = (uint32_t) temp;
2559  temp >>= 32;
2560  temp += (uint64_t) a[4] + a[8];
2561  temp += (uint64_t) a[9] * 21389;
2562  r[4] = (uint32_t) temp;
2563  c = temp >> 32;
2564 
2565  //Second pass
2566  temp = (uint64_t) r[0] + c * 21389;
2567  r[0] = (uint32_t) temp;
2568  temp >>= 32;
2569  temp += (uint64_t) r[1] + c;
2570  r[1] = (uint32_t) temp;
2571  temp >>= 32;
2572  temp += (uint64_t) r[2];
2573  r[2] = (uint32_t) temp;
2574  temp >>= 32;
2575  temp += (uint64_t) r[3];
2576  r[3] = (uint32_t) temp;
2577  c = temp >> 32;
2578 
2579  //Third pass
2580  temp = (uint64_t) r[0] + c * 21389;
2581  r[0] = (uint32_t) temp;
2582  temp >>= 32;
2583  temp += (uint64_t) r[1] + c;
2584  r[1] = (uint32_t) temp;
2585  temp >>= 32;
2586  temp += (uint64_t) r[2];
2587  r[2] = (uint32_t) temp;
2588  temp >>= 32;
2589  temp += (uint64_t) r[3];
2590  r[3] = (uint32_t) temp;
2591 
2592  //Reduce non-canonical values
2593  ecFieldCanonicalize(curve, r, r);
2594 }
2595 
2596 
2597 /**
2598  * @brief Field modular inversion (secp160k1 curve)
2599  * @param[in] curve Elliptic curve parameters
2600  * @param[out] r Resulting integer R = A^-1 mod p
2601  * @param[in] a An integer such as 0 <= A < p
2602  **/
2603 
2604 void secp160k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2605 {
2606  uint32_t u[5];
2607  uint32_t v[5];
2608  uint32_t w[5];
2609 
2610  //Since GF(p) is a prime field, the Fermat's little theorem can be
2611  //used to find the multiplicative inverse of A modulo p
2612  ecFieldSqrMod(curve, u, a);
2613  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
2614  ecFieldSqrMod(curve, u, u);
2615  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
2616  ecFieldPwr2Mod(curve, v, u, 3);
2617  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
2618  ecFieldSqrMod(curve, u, u);
2619  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
2620  ecFieldPwr2Mod(curve, v, u, 7);
2621  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
2622  ecFieldSqrMod(curve, u, u);
2623  ecFieldMulMod(curve, w, u, a); //A^(2^15 - 1)
2624  ecFieldPwr2Mod(curve, u, w, 15);
2625  ecFieldMulMod(curve, u, u, w); //A^(2^30 - 1)
2626  ecFieldSqrMod(curve, u, u);
2627  ecFieldMulMod(curve, u, u, a); //A^(2^31 - 1)
2628  ecFieldPwr2Mod(curve, v, u, 31);
2629  ecFieldMulMod(curve, u, u, v); //A^(2^62 - 1)
2630  ecFieldSqrMod(curve, u, u);
2631  ecFieldMulMod(curve, u, u, a); //A^(2^63 - 1)
2632  ecFieldPwr2Mod(curve, v, u, 63);
2633  ecFieldMulMod(curve, u, u, v); //A^(2^126 - 1)
2634  ecFieldSqrMod(curve, u, u);
2635  ecFieldMulMod(curve, u, u, a); //A^(2^127 - 1)
2636  ecFieldPwr2Mod(curve, u, u, 16);
2637  ecFieldMulMod(curve, u, u, w); //A^(2^143 - 2^15 - 1)
2638  ecFieldSqrMod(curve, u, u);
2639  ecFieldMulMod(curve, u, u, a); //A^(2^144 - 2^16 - 1)
2640  ecFieldSqrMod(curve, u, u);
2641  ecFieldMulMod(curve, u, u, a); //A^(2^145 - 2^17 - 1)
2642  ecFieldPwr2Mod(curve, u, u, 2);
2643  ecFieldMulMod(curve, u, u, a); //A^(2^147 - 2^19 - 2^1 - 1)
2644  ecFieldPwr2Mod(curve, u, u, 2);
2645  ecFieldMulMod(curve, u, u, a); //A^(2^149 - 2^21 - 2^3 - 2^1 - 1)
2646  ecFieldSqrMod(curve, u, u);
2647  ecFieldMulMod(curve, u, u, a); //A^(2^150 - 2^22 - 2^4 - 2^2 - 1)
2648  ecFieldPwr2Mod(curve, u, u, 4);
2649  ecFieldMulMod(curve, u, u, a); //A^(2^154 - 2^26 - 2^8 - 2^6 - 2^3 - 2^2 - 2^1 - 1)
2650  ecFieldSqrMod(curve, u, u);
2651  ecFieldMulMod(curve, u, u, a); //A^(2^155 - 2^27 - 2^9 - 2^7 - 2^4 - 2^3 - 2^2 - 1)
2652  ecFieldSqrMod(curve, u, u);
2653  ecFieldMulMod(curve, u, u, a); //A^(2^156 - 2^28 - 2^10 - 2^8 - 2^5 - 2^4 - 2^3 - 1)
2654  ecFieldPwr2Mod(curve, u, u, 4);
2655  ecFieldMulMod(curve, r, u, a); //A^(2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 3)
2656 }
2657 
2658 
2659 /**
2660  * @brief Scalar modular reduction (secp160k1 curve)
2661  * @param[in] curve Elliptic curve parameters
2662  * @param[out] r Resulting integer R = A mod q
2663  * @param[in] a An integer such as 0 <= A < q^2
2664  **/
2665 
2666 void secp160k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2667 {
2668  uint32_t c;
2669  uint32_t a2[11];
2670  uint32_t q2[6];
2671  uint32_t u[6];
2672  uint32_t v[6];
2673 
2674  //Compute a = a << 15
2675  ecScalarShiftLeft(a2, a, 15, 11);
2676  //Compute q = q << 15
2677  ecScalarShiftLeft(q2, curve->q, 15, 6);
2678 
2679  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2680  ecScalarMul(NULL, u, a2 + 5, curve->qmu, 6);
2681  //Compute v = u * q mod b^(k + 1)
2682  ecScalarMul(v, NULL, u, q2, 6);
2683 
2684  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2685  //If u < 0, then u = u + b^(k + 1)
2686  ecScalarSub(u, a2, v, 6);
2687 
2688  //This estimation implies that at most two subtractions of q are required to
2689  //obtain the correct remainder r
2690  c = ecScalarSub(v, u, q2, 6);
2691  ecScalarSelect(u, v, u, c, 6);
2692  c = ecScalarSub(v, u, q2, 6);
2693  ecScalarSelect(u, v, u, c, 6);
2694 
2695  //Compute a = u >> 15
2696  ecScalarShiftRight(r, u, 15, 6);
2697 }
2698 
2699 #endif
2700 #if (SECP160R1_SUPPORT == ENABLED)
2701 
2702 /**
2703  * @brief Field modular reduction (secp160r1 curve)
2704  * @param[in] curve Elliptic curve parameters
2705  * @param[out] r Resulting integer R = A mod p
2706  * @param[in] a An integer such as 0 <= A < p^2
2707  **/
2708 
2709 void secp160r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2710 {
2711  uint64_t c;
2712  uint64_t temp;
2713 
2714  //First pass
2715  temp = (uint64_t) a[0] + a[5];
2716  temp += (uint64_t) a[5] << 31;
2717  r[0] = (uint32_t) temp;
2718  temp >>= 32;
2719  temp += (uint64_t) a[1] + a[6];
2720  temp += (uint64_t) a[6] << 31;
2721  r[1] = (uint32_t) temp;
2722  temp >>= 32;
2723  temp += (uint64_t) a[2] + a[7];
2724  temp += (uint64_t) a[7] << 31;
2725  r[2] = (uint32_t) temp;
2726  temp >>= 32;
2727  temp += (uint64_t) a[3] + a[8];
2728  temp += (uint64_t) a[8] << 31;
2729  r[3] = (uint32_t) temp;
2730  temp >>= 32;
2731  temp += (uint64_t) a[4] + a[9];
2732  temp += (uint64_t) a[9] << 31;
2733  r[4] = (uint32_t) temp;
2734  c = temp >> 32;
2735 
2736  //Second pass
2737  temp = (uint64_t) r[0] + c + (c << 31);
2738  r[0] = (uint32_t) temp;
2739  temp >>= 32;
2740  temp += (uint64_t) r[1];
2741  r[1] = (uint32_t) temp;
2742  temp >>= 32;
2743  temp += (uint64_t) r[2];
2744  r[2] = (uint32_t) temp;
2745  temp >>= 32;
2746  temp += (uint64_t) r[3];
2747  r[3] = (uint32_t) temp;
2748  c = temp >> 32;
2749 
2750  //Third pass
2751  temp = (uint64_t) r[0] + c + (c << 31);
2752  r[0] = (uint32_t) temp;
2753  temp >>= 32;
2754  temp += (uint64_t) r[1];
2755  r[1] = (uint32_t) temp;
2756  temp >>= 32;
2757  temp += (uint64_t) r[2];
2758  r[2] = (uint32_t) temp;
2759  temp >>= 32;
2760  temp += (uint64_t) r[3];
2761  r[3] = (uint32_t) temp;
2762 
2763  //Reduce non-canonical values
2764  ecFieldCanonicalize(curve, r, r);
2765 }
2766 
2767 
2768 /**
2769  * @brief Field modular inversion (secp160r1 curve)
2770  * @param[in] curve Elliptic curve parameters
2771  * @param[out] r Resulting integer R = A^-1 mod p
2772  * @param[in] a An integer such as 0 <= A < p
2773  **/
2774 
2775 void secp160r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2776 {
2777  uint32_t u[5];
2778  uint32_t v[5];
2779  uint32_t w[5];
2780 
2781  //Since GF(p) is a prime field, the Fermat's little theorem can be
2782  //used to find the multiplicative inverse of A modulo p
2783  ecFieldSqrMod(curve, u, a);
2784  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
2785  ecFieldSqrMod(curve, u, u);
2786  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
2787  ecFieldPwr2Mod(curve, v, u, 3);
2788  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
2789  ecFieldSqrMod(curve, u, u);
2790  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
2791  ecFieldPwr2Mod(curve, v, u, 7);
2792  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
2793  ecFieldPwr2Mod(curve, v, u, 14);
2794  ecFieldMulMod(curve, u, u, v); //A^(2^28 - 1)
2795  ecFieldSqrMod(curve, u, u);
2796  ecFieldMulMod(curve, w, u, a); //A^(2^29 - 1)
2797  ecFieldSqrMod(curve, u, w);
2798  ecFieldMulMod(curve, u, u, a); //A^(2^30 - 1)
2799  ecFieldSqrMod(curve, u, u);
2800  ecFieldMulMod(curve, u, u, a); //A^(2^31 - 1)
2801  ecFieldSqrMod(curve, u, u);
2802  ecFieldMulMod(curve, u, u, a); //A^(2^32 - 1)
2803  ecFieldPwr2Mod(curve, v, u, 32);
2804  ecFieldMulMod(curve, u, u, v); //A^(2^64 - 1)
2805  ecFieldPwr2Mod(curve, v, u, 64);
2806  ecFieldMulMod(curve, u, u, v); //A^(2^128 - 1)
2807  ecFieldPwr2Mod(curve, u, u, 30);
2808  ecFieldMulMod(curve, u, u, w); //A^(2^158 - 2^29 - 1)
2809  ecFieldPwr2Mod(curve, u, u, 2);
2810  ecFieldMulMod(curve, r, u, a); //A^(2^160 - 2^31 - 3)
2811 }
2812 
2813 
2814 /**
2815  * @brief Scalar modular reduction (secp160r1 curve)
2816  * @param[in] curve Elliptic curve parameters
2817  * @param[out] r Resulting integer R = A mod q
2818  * @param[in] a An integer such as 0 <= A < q^2
2819  **/
2820 
2821 void secp160r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2822 {
2823  uint32_t c;
2824  uint32_t a2[11];
2825  uint32_t q2[6];
2826  uint32_t u[6];
2827  uint32_t v[6];
2828 
2829  //Compute a = a << 15
2830  ecScalarShiftLeft(a2, a, 15, 11);
2831  //Compute q = q << 15
2832  ecScalarShiftLeft(q2, curve->q, 15, 6);
2833 
2834  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
2835  ecScalarMul(NULL, u, a2 + 5, curve->qmu, 6);
2836  //Compute v = u * q mod b^(k + 1)
2837  ecScalarMul(v, NULL, u, q2, 6);
2838 
2839  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
2840  //If u < 0, then u = u + b^(k + 1)
2841  ecScalarSub(u, a2, v, 6);
2842 
2843  //This estimation implies that at most two subtractions of q are required to
2844  //obtain the correct remainder r
2845  c = ecScalarSub(v, u, q2, 6);
2846  ecScalarSelect(u, v, u, c, 6);
2847  c = ecScalarSub(v, u, q2, 6);
2848  ecScalarSelect(u, v, u, c, 6);
2849 
2850  //Compute a = u >> 15
2851  ecScalarShiftRight(r, u, 15, 6);
2852 }
2853 
2854 #endif
2855 #if (SECP160R2_SUPPORT == ENABLED)
2856 
2857 /**
2858  * @brief Field modular reduction (secp160r2 curve)
2859  * @param[in] curve Elliptic curve parameters
2860  * @param[out] r Resulting integer R = A mod p
2861  * @param[in] a An integer such as 0 <= A < p^2
2862  **/
2863 
2864 void secp160r2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2865 {
2866  uint64_t c;
2867  uint64_t temp;
2868 
2869  //First pass
2870  temp = (uint64_t) a[0];
2871  temp += (uint64_t) a[5] * 21389;
2872  temp += (uint64_t) a[9] * 21389;
2873  r[0] = (uint32_t) temp;
2874  temp >>= 32;
2875  temp += (uint64_t) a[1] + a[5] + a[9];
2876  temp += (uint64_t) a[6] * 21389;
2877  r[1] = (uint32_t) temp;
2878  temp >>= 32;
2879  temp += (uint64_t) a[2] + a[6];
2880  temp += (uint64_t) a[7] * 21389;
2881  r[2] = (uint32_t) temp;
2882  temp >>= 32;
2883  temp += (uint64_t) a[3] + a[7];
2884  temp += (uint64_t) a[8] * 21389;
2885  r[3] = (uint32_t) temp;
2886  temp >>= 32;
2887  temp += (uint64_t) a[4] + a[8];
2888  temp += (uint64_t) a[9] * 21389;
2889  r[4] = (uint32_t) temp;
2890  c = temp >> 32;
2891 
2892  //Second pass
2893  temp = (uint64_t) r[0] + c * 21389;
2894  r[0] = (uint32_t) temp;
2895  temp >>= 32;
2896  temp += (uint64_t) r[1] + c;
2897  r[1] = (uint32_t) temp;
2898  temp >>= 32;
2899  temp += (uint64_t) r[2];
2900  r[2] = (uint32_t) temp;
2901  temp >>= 32;
2902  temp += (uint64_t) r[3];
2903  r[3] = (uint32_t) temp;
2904  c = temp >> 32;
2905 
2906  //Third pass
2907  temp = (uint64_t) r[0] + c * 21389;
2908  r[0] = (uint32_t) temp;
2909  temp >>= 32;
2910  temp += (uint64_t) r[1] + c;
2911  r[1] = (uint32_t) temp;
2912  temp >>= 32;
2913  temp += (uint64_t) r[2];
2914  r[2] = (uint32_t) temp;
2915  temp >>= 32;
2916  temp += (uint64_t) r[3];
2917  r[3] = (uint32_t) temp;
2918 
2919  //Reduce non-canonical values
2920  ecFieldCanonicalize(curve, r, r);
2921 }
2922 
2923 
2924 /**
2925  * @brief Field modular inversion (secp160r2 curve)
2926  * @param[in] curve Elliptic curve parameters
2927  * @param[out] r Resulting integer R = A^-1 mod p
2928  * @param[in] a An integer such as 0 <= A < p
2929  **/
2930 
2931 void secp160r2FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2932 {
2933  uint32_t u[5];
2934  uint32_t v[5];
2935  uint32_t w[5];
2936 
2937  //Since GF(p) is a prime field, the Fermat's little theorem can be
2938  //used to find the multiplicative inverse of A modulo p
2939  ecFieldSqrMod(curve, u, a);
2940  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
2941  ecFieldSqrMod(curve, u, u);
2942  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
2943  ecFieldPwr2Mod(curve, v, u, 3);
2944  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
2945  ecFieldSqrMod(curve, u, u);
2946  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
2947  ecFieldPwr2Mod(curve, v, u, 7);
2948  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
2949  ecFieldSqrMod(curve, u, u);
2950  ecFieldMulMod(curve, w, u, a); //A^(2^15 - 1)
2951  ecFieldPwr2Mod(curve, u, w, 15);
2952  ecFieldMulMod(curve, u, u, w); //A^(2^30 - 1)
2953  ecFieldSqrMod(curve, u, u);
2954  ecFieldMulMod(curve, u, u, a); //A^(2^31 - 1)
2955  ecFieldPwr2Mod(curve, v, u, 31);
2956  ecFieldMulMod(curve, u, u, v); //A^(2^62 - 1)
2957  ecFieldSqrMod(curve, u, u);
2958  ecFieldMulMod(curve, u, u, a); //A^(2^63 - 1)
2959  ecFieldPwr2Mod(curve, v, u, 63);
2960  ecFieldMulMod(curve, u, u, v); //A^(2^126 - 1)
2961  ecFieldSqrMod(curve, u, u);
2962  ecFieldMulMod(curve, u, u, a); //A^(2^127 - 1)
2963  ecFieldPwr2Mod(curve, u, u, 16);
2964  ecFieldMulMod(curve, u, u, w); //A^(2^143 - 2^15 - 1)
2965  ecFieldSqrMod(curve, u, u);
2966  ecFieldMulMod(curve, u, u, a); //A^(2^144 - 2^16 - 1)
2967  ecFieldSqrMod(curve, u, u);
2968  ecFieldMulMod(curve, u, u, a); //A^(2^145 - 2^17 - 1)
2969  ecFieldPwr2Mod(curve, u, u, 2);
2970  ecFieldMulMod(curve, u, u, a); //A^(2^147 - 2^19 - 2^1 - 1)
2971  ecFieldPwr2Mod(curve, u, u, 2);
2972  ecFieldMulMod(curve, u, u, a); //A^(2^149 - 2^21 - 2^3 - 2^1 - 1)
2973  ecFieldSqrMod(curve, u, u);
2974  ecFieldMulMod(curve, u, u, a); //A^(2^150 - 2^22 - 2^4 - 2^2 - 1)
2975  ecFieldPwr2Mod(curve, u, u, 4);
2976  ecFieldMulMod(curve, u, u, a); //A^(2^154 - 2^26 - 2^8 - 2^6 - 2^3 - 2^2 - 2^1 - 1)
2977  ecFieldSqrMod(curve, u, u);
2978  ecFieldMulMod(curve, u, u, a); //A^(2^155 - 2^27 - 2^9 - 2^7 - 2^4 - 2^3 - 2^2 - 1)
2979  ecFieldSqrMod(curve, u, u);
2980  ecFieldMulMod(curve, u, u, a); //A^(2^156 - 2^28 - 2^10 - 2^8 - 2^5 - 2^4 - 2^3 - 1)
2981  ecFieldPwr2Mod(curve, u, u, 4);
2982  ecFieldMulMod(curve, r, u, a); //A^(2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 3)
2983 }
2984 
2985 
2986 /**
2987  * @brief Scalar modular reduction (secp160r2 curve)
2988  * @param[in] curve Elliptic curve parameters
2989  * @param[out] r Resulting integer R = A mod q
2990  * @param[in] a An integer such as 0 <= A < q^2
2991  **/
2992 
2993 void secp160r2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
2994 {
2995  uint32_t c;
2996  uint32_t a2[11];
2997  uint32_t q2[6];
2998  uint32_t u[6];
2999  uint32_t v[6];
3000 
3001  //Compute a = a << 15
3002  ecScalarShiftLeft(a2, a, 15, 11);
3003  //Compute q = q << 15
3004  ecScalarShiftLeft(q2, curve->q, 15, 6);
3005 
3006  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
3007  ecScalarMul(NULL, u, a2 + 5, curve->qmu, 6);
3008  //Compute v = u * q mod b^(k + 1)
3009  ecScalarMul(v, NULL, u, q2, 6);
3010 
3011  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
3012  //If u < 0, then u = u + b^(k + 1)
3013  ecScalarSub(u, a2, v, 6);
3014 
3015  //This estimation implies that at most two subtractions of q are required to
3016  //obtain the correct remainder r
3017  c = ecScalarSub(v, u, q2, 6);
3018  ecScalarSelect(u, v, u, c, 6);
3019  c = ecScalarSub(v, u, q2, 6);
3020  ecScalarSelect(u, v, u, c, 6);
3021 
3022  //Compute a = u >> 15
3023  ecScalarShiftRight(r, u, 15, 6);
3024 }
3025 
3026 #endif
3027 #if (SECP192K1_SUPPORT == ENABLED)
3028 
3029 /**
3030  * @brief Field modular reduction (secp192k1 curve)
3031  * @param[in] curve Elliptic curve parameters
3032  * @param[out] r Resulting integer R = A mod p
3033  * @param[in] a An integer such as 0 <= A < p^2
3034  **/
3035 
3036 void secp192k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3037 {
3038  uint64_t c;
3039  uint64_t temp;
3040 
3041  //First pass
3042  temp = (uint64_t) a[0];
3043  temp += (uint64_t) a[6] * 4553;
3044  temp += (uint64_t) a[11] * 4553;
3045  r[0] = (uint32_t) temp;
3046  temp >>= 32;
3047  temp += (uint64_t) a[1] + a[6] + a[11];
3048  temp += (uint64_t) a[7] * 4553;
3049  r[1] = (uint32_t) temp;
3050  temp >>= 32;
3051  temp += (uint64_t) a[2] + a[7];
3052  temp += (uint64_t) a[8] * 4553;
3053  r[2] = (uint32_t) temp;
3054  temp >>= 32;
3055  temp += (uint64_t) a[3] + a[8];
3056  temp += (uint64_t) a[9] * 4553;
3057  r[3] = (uint32_t) temp;
3058  temp >>= 32;
3059  temp += (uint64_t) a[4] + a[9];
3060  temp += (uint64_t) a[10] * 4553;
3061  r[4] = (uint32_t) temp;
3062  temp >>= 32;
3063  temp += (uint64_t) a[5] + a[10];
3064  temp += (uint64_t) a[11] * 4553;
3065  r[5] = (uint32_t) temp;
3066  c = temp >> 32;
3067 
3068  //Second pass
3069  temp = (uint64_t) r[0] + c * 4553;
3070  r[0] = (uint32_t) temp;
3071  temp >>= 32;
3072  temp += (uint64_t) r[1] + c;
3073  r[1] = (uint32_t) temp;
3074  temp >>= 32;
3075  temp += (uint64_t) r[2];
3076  r[2] = (uint32_t) temp;
3077  temp >>= 32;
3078  temp += (uint64_t) r[3];
3079  r[3] = (uint32_t) temp;
3080  temp >>= 32;
3081  temp += (uint64_t) r[4];
3082  r[4] = (uint32_t) temp;
3083  temp >>= 32;
3084  temp += (uint64_t) r[5];
3085  r[5] = (uint32_t) temp;
3086  c = temp >> 32;
3087 
3088  //Third pass
3089  temp = (uint64_t) r[0] + c * 4553;
3090  r[0] = (uint32_t) temp;
3091  temp >>= 32;
3092  temp += (uint64_t) r[1] + c;
3093  r[1] = (uint32_t) temp;
3094  temp >>= 32;
3095  temp += (uint64_t) r[2];
3096  r[2] = (uint32_t) temp;
3097  temp >>= 32;
3098  temp += (uint64_t) r[3];
3099  r[3] = (uint32_t) temp;
3100  temp >>= 32;
3101  temp += (uint64_t) r[4];
3102  r[4] = (uint32_t) temp;
3103  temp >>= 32;
3104  temp += (uint64_t) r[5];
3105  r[5] = (uint32_t) temp;
3106 
3107  //Reduce non-canonical values
3108  ecFieldCanonicalize(curve, r, r);
3109 }
3110 
3111 
3112 /**
3113  * @brief Field modular inversion (secp192k1 curve)
3114  * @param[in] curve Elliptic curve parameters
3115  * @param[out] r Resulting integer R = A^-1 mod p
3116  * @param[in] a An integer such as 0 <= A < p
3117  **/
3118 
3119 void secp192k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3120 {
3121  uint32_t u[6];
3122  uint32_t v[6];
3123  uint32_t w[6];
3124 
3125  //Since GF(p) is a prime field, the Fermat's little theorem can be
3126  //used to find the multiplicative inverse of A modulo p
3127  ecFieldSqrMod(curve, u, a);
3128  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
3129  ecFieldPwr2Mod(curve, v, u, 2);
3130  ecFieldMulMod(curve, u, u, v); //A^(2^4 - 1)
3131  ecFieldPwr2Mod(curve, v, u, 4);
3132  ecFieldMulMod(curve, u, u, v); //A^(2^8 - 1)
3133  ecFieldSqrMod(curve, u, u);
3134  ecFieldMulMod(curve, u, u, a); //A^(2^9 - 1)
3135  ecFieldPwr2Mod(curve, v, u, 9);
3136  ecFieldMulMod(curve, u, u, v); //A^(2^18 - 1)
3137  ecFieldSqrMod(curve, u, u);
3138  ecFieldMulMod(curve, w, u, a); //A^(2^19 - 1)
3139  ecFieldPwr2Mod(curve, u, w, 19);
3140  ecFieldMulMod(curve, u, u, w); //A^(2^38 - 1)
3141  ecFieldSqrMod(curve, u, u);
3142  ecFieldMulMod(curve, u, u, a); //A^(2^39 - 1)
3143  ecFieldPwr2Mod(curve, v, u, 39);
3144  ecFieldMulMod(curve, u, u, v); //A^(2^78 - 1)
3145  ecFieldSqrMod(curve, u, u);
3146  ecFieldMulMod(curve, u, u, a); //A^(2^79 - 1)
3147  ecFieldPwr2Mod(curve, v, u, 79);
3148  ecFieldMulMod(curve, u, u, v); //A^(2^158 - 1)
3149  ecFieldSqrMod(curve, u, u);
3150  ecFieldMulMod(curve, u, u, a); //A^(2^159 - 1)
3151  ecFieldPwr2Mod(curve, u, u, 20);
3152  ecFieldMulMod(curve, u, u, w); //A^(2^179 - 2^19 - 1)
3153  ecFieldPwr2Mod(curve, u, u, 2);
3154  ecFieldMulMod(curve, u, u, a); //A^(2^181 - 2^21 - 2^1 - 1)
3155  ecFieldSqrMod(curve, u, u);
3156  ecFieldMulMod(curve, u, u, a); //A^(2^182 - 2^22 - 2^2 - 1)
3157  ecFieldSqrMod(curve, u, u);
3158  ecFieldMulMod(curve, u, u, a); //A^(2^183 - 2^23 - 2^3 - 1)
3159  ecFieldPwr2Mod(curve, u, u, 4);
3160  ecFieldMulMod(curve, u, u, a); //A^(2^187 - 2^27 - 2^7 - 2^3 - 2^2 - 2^1 - 1)
3161  ecFieldSqrMod(curve, u, u);
3162  ecFieldMulMod(curve, u, u, a); //A^(2^188 - 2^28 - 2^8 - 2^4 - 2^3 - 2^2 - 1)
3163  ecFieldPwr2Mod(curve, u, u, 2);
3164  ecFieldMulMod(curve, u, u, a); //A^(2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1 - 1)
3165  ecFieldPwr2Mod(curve, u, u, 2);
3166  ecFieldMulMod(curve, r, u, a); //A^(2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 3)
3167 }
3168 
3169 
3170 /**
3171  * @brief Scalar modular reduction (secp192k1 curve)
3172  * @param[in] curve Elliptic curve parameters
3173  * @param[out] r Resulting integer R = A mod q
3174  * @param[in] a An integer such as 0 <= A < q^2
3175  **/
3176 
3177 void secp192k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3178 {
3179  uint32_t c;
3180  uint32_t u[7];
3181  uint32_t v[7];
3182 
3183  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
3184  ecScalarMul(NULL, u, a + 5, curve->qmu, 7);
3185  //Compute v = u * q mod b^(k + 1)
3186  ecScalarMul(v, NULL, u, curve->q, 7);
3187 
3188  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
3189  //If u < 0, then u = u + b^(k + 1)
3190  ecScalarSub(u, a, v, 7);
3191 
3192  //This estimation implies that at most two subtractions of q are required to
3193  //obtain the correct remainder r
3194  c = ecScalarSub(v, u, curve->q, 7);
3195  ecScalarSelect(u, v, u, c, 7);
3196  c = ecScalarSub(v, u, curve->q, 7);
3197  ecScalarSelect(r, v, u, c, 6);
3198 }
3199 
3200 #endif
3201 #if (SECP192R1_SUPPORT == ENABLED)
3202 
3203 /**
3204  * @brief Field modular reduction (secp192r1 curve)
3205  * @param[in] curve Elliptic curve parameters
3206  * @param[out] r Resulting integer R = A mod p
3207  * @param[in] a An integer such as 0 <= A < p^2
3208  **/
3209 
3210 void secp192r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3211 {
3212  uint64_t c;
3213  uint64_t temp;
3214 
3215  //First pass
3216  temp = (uint64_t) a[0] + a[6] + a[10];
3217  r[0] = (uint32_t) temp;
3218  temp >>= 32;
3219  temp += (uint64_t) a[1] + a[7] + a[11];
3220  r[1] = (uint32_t) temp;
3221  temp >>= 32;
3222  temp += (uint64_t) a[2] + a[6] + a[8] + a[10];
3223  r[2] = (uint32_t) temp;
3224  temp >>= 32;
3225  temp += (uint64_t) a[3] + a[7] + a[9] + a[11];
3226  r[3] = (uint32_t) temp;
3227  temp >>= 32;
3228  temp += (uint64_t) a[4] + a[8] + a[10];
3229  r[4] = (uint32_t) temp;
3230  temp >>= 32;
3231  temp += (uint64_t) a[5] + a[9] + a[11];
3232  r[5] = (uint32_t) temp;
3233  c = temp >> 32;
3234 
3235  //Second pass
3236  temp = (uint64_t) r[0] + c;
3237  r[0] = (uint32_t) temp;
3238  temp >>= 32;
3239  temp += (uint64_t) r[1];
3240  r[1] = (uint32_t) temp;
3241  temp >>= 32;
3242  temp += (uint64_t) r[2] + c;
3243  r[2] = (uint32_t) temp;
3244  temp >>= 32;
3245  temp += (uint64_t) r[3];
3246  r[3] = (uint32_t) temp;
3247  temp >>= 32;
3248  temp += (uint64_t) r[4];
3249  r[4] = (uint32_t) temp;
3250  temp >>= 32;
3251  temp += (uint64_t) r[5];
3252  r[5] = (uint32_t) temp;
3253  c = temp >> 32;
3254 
3255  //Third pass
3256  temp = (uint64_t) r[0] + c;
3257  r[0] = (uint32_t) temp;
3258  temp >>= 32;
3259  temp += (uint64_t) r[1];
3260  r[1] = (uint32_t) temp;
3261  temp >>= 32;
3262  temp += (uint64_t) r[2] + c;
3263  r[2] = (uint32_t) temp;
3264  temp >>= 32;
3265  temp += (uint64_t) r[3];
3266  r[3] = (uint32_t) temp;
3267  temp >>= 32;
3268  temp += (uint64_t) r[4];
3269  r[4] = (uint32_t) temp;
3270  temp >>= 32;
3271  temp += (uint64_t) r[5];
3272  r[5] = (uint32_t) temp;
3273 
3274  //Reduce non-canonical values
3275  ecFieldCanonicalize(curve, r, r);
3276 }
3277 
3278 
3279 /**
3280  * @brief Field modular inversion (secp192r1 curve)
3281  * @param[in] curve Elliptic curve parameters
3282  * @param[out] r Resulting integer R = A^-1 mod p
3283  * @param[in] a An integer such as 0 <= A < p
3284  **/
3285 
3286 void secp192r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3287 {
3288  uint32_t u[6];
3289  uint32_t v[6];
3290 
3291  //Since GF(p) is a prime field, the Fermat's little theorem can be
3292  //used to find the multiplicative inverse of A modulo p
3293  ecFieldSqrMod(curve, u, a);
3294  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
3295  ecFieldSqrMod(curve, u, u);
3296  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
3297  ecFieldPwr2Mod(curve, v, u, 3);
3298  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
3299  ecFieldSqrMod(curve, u, u);
3300  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
3301  ecFieldPwr2Mod(curve, v, u, 7);
3302  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
3303  ecFieldSqrMod(curve, u, u);
3304  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
3305  ecFieldPwr2Mod(curve, v, u, 15);
3306  ecFieldMulMod(curve, u, u, v); //A^(2^30 - 1)
3307  ecFieldSqrMod(curve, u, u);
3308  ecFieldMulMod(curve, v, u, a); //A^(2^31 - 1)
3309  ecFieldSqrMod(curve, u, v);
3310  ecFieldMulMod(curve, u, u, a); //A^(2^32 - 1)
3311  ecFieldPwr2Mod(curve, u, u, 31);
3312  ecFieldMulMod(curve, u, u, v); //A^(2^63 - 1)
3313  ecFieldSqrMod(curve, u, u);
3314  ecFieldMulMod(curve, u, u, a); //A^(2^64 - 1)
3315  ecFieldPwr2Mod(curve, u, u, 31);
3316  ecFieldMulMod(curve, u, u, v); //A^(2^95 - 1)
3317  ecFieldSqrMod(curve, u, u);
3318  ecFieldMulMod(curve, u, u, a); //A^(2^96 - 1)
3319  ecFieldPwr2Mod(curve, u, u, 31);
3320  ecFieldMulMod(curve, u, u, v); //A^(2^127 - 1)
3321  ecFieldPwr2Mod(curve, u, u, 32);
3322  ecFieldMulMod(curve, u, u, v); //A^(2^159 - 2^31 - 1)
3323  ecFieldPwr2Mod(curve, u, u, 31);
3324  ecFieldMulMod(curve, u, u, v); //A^(2^190 - 2^62 - 1)
3325  ecFieldPwr2Mod(curve, u, u, 2);
3326  ecFieldMulMod(curve, r, u, a); //A^(2^192 - 2^64 - 3)
3327 }
3328 
3329 
3330 /**
3331  * @brief Scalar modular reduction (secp192r1 curve)
3332  * @param[in] curve Elliptic curve parameters
3333  * @param[out] r Resulting integer R = A mod q
3334  * @param[in] a An integer such as 0 <= A < q^2
3335  **/
3336 
3337 void secp192r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3338 {
3339  uint32_t c;
3340  uint32_t u[7];
3341  uint32_t v[7];
3342 
3343  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
3344  ecScalarMul(NULL, u, a + 5, curve->qmu, 7);
3345  //Compute v = u * q mod b^(k + 1)
3346  ecScalarMul(v, NULL, u, curve->q, 7);
3347 
3348  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
3349  //If u < 0, then u = u + b^(k + 1)
3350  ecScalarSub(u, a, v, 7);
3351 
3352  //This estimation implies that at most two subtractions of q are required to
3353  //obtain the correct remainder r
3354  c = ecScalarSub(v, u, curve->q, 7);
3355  ecScalarSelect(u, v, u, c, 7);
3356  c = ecScalarSub(v, u, curve->q, 7);
3357  ecScalarSelect(r, v, u, c, 6);
3358 }
3359 
3360 #endif
3361 #if (SECP224K1_SUPPORT == ENABLED)
3362 
3363 /**
3364  * @brief Field modular reduction (secp224k1 curve)
3365  * @param[in] curve Elliptic curve parameters
3366  * @param[out] r Resulting integer R = A mod p
3367  * @param[in] a An integer such as 0 <= A < p^2
3368  **/
3369 
3370 void secp224k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3371 {
3372  uint64_t c;
3373  uint64_t temp;
3374 
3375  //First pass
3376  temp = (uint64_t) a[0];
3377  temp += (uint64_t) a[7] * 6803;
3378  temp += (uint64_t) a[13] * 6803;
3379  r[0] = (uint32_t) temp;
3380  temp >>= 32;
3381  temp += (uint64_t) a[1] + a[7] + a[13];
3382  temp += (uint64_t) a[8] * 6803;
3383  r[1] = (uint32_t) temp;
3384  temp >>= 32;
3385  temp += (uint64_t) a[2] + a[8];
3386  temp += (uint64_t) a[9] * 6803;
3387  r[2] = (uint32_t) temp;
3388  temp >>= 32;
3389  temp += (uint64_t) a[3] + a[9];
3390  temp += (uint64_t) a[10] * 6803;
3391  r[3] = (uint32_t) temp;
3392  temp >>= 32;
3393  temp += (uint64_t) a[4] + a[10];
3394  temp += (uint64_t) a[11] * 6803;
3395  r[4] = (uint32_t) temp;
3396  temp >>= 32;
3397  temp += (uint64_t) a[5] + a[11];
3398  temp += (uint64_t) a[12] * 6803;
3399  r[5] = (uint32_t) temp;
3400  temp >>= 32;
3401  temp += (uint64_t) a[6] + a[12];
3402  temp += (uint64_t) a[13] * 6803;
3403  r[6] = (uint32_t) temp;
3404  c = temp >> 32;
3405 
3406  //Second pass
3407  temp = (uint64_t) r[0] + c * 6803;
3408  r[0] = (uint32_t) temp;
3409  temp >>= 32;
3410  temp += (uint64_t) r[1] + c;
3411  r[1] = (uint32_t) temp;
3412  temp >>= 32;
3413  temp += (uint64_t) r[2];
3414  r[2] = (uint32_t) temp;
3415  temp >>= 32;
3416  temp += (uint64_t) r[3];
3417  r[3] = (uint32_t) temp;
3418  temp >>= 32;
3419  temp += (uint64_t) r[4];
3420  r[4] = (uint32_t) temp;
3421  temp >>= 32;
3422  temp += (uint64_t) r[5];
3423  r[5] = (uint32_t) temp;
3424  temp >>= 32;
3425  temp += (uint64_t) r[6];
3426  r[6] = (uint32_t) temp;
3427  c = temp >> 32;
3428 
3429  //Third pass
3430  temp = (uint64_t) r[0] + c * 6803;
3431  r[0] = (uint32_t) temp;
3432  temp >>= 32;
3433  temp += (uint64_t) r[1] + c;
3434  r[1] = (uint32_t) temp;
3435  temp >>= 32;
3436  temp += (uint64_t) r[2];
3437  r[2] = (uint32_t) temp;
3438  temp >>= 32;
3439  temp += (uint64_t) r[3];
3440  r[3] = (uint32_t) temp;
3441  temp >>= 32;
3442  temp += (uint64_t) r[4];
3443  r[4] = (uint32_t) temp;
3444  temp >>= 32;
3445  temp += (uint64_t) r[5];
3446  r[5] = (uint32_t) temp;
3447  temp >>= 32;
3448  temp += (uint64_t) r[6];
3449  r[6] = (uint32_t) temp;
3450 
3451  //Reduce non-canonical values
3452  ecFieldCanonicalize(curve, r, r);
3453 }
3454 
3455 
3456 /**
3457  * @brief Field modular inversion (secp224k1 curve)
3458  * @param[in] curve Elliptic curve parameters
3459  * @param[out] r Resulting integer R = A^-1 mod p
3460  * @param[in] a An integer such as 0 <= A < p
3461  **/
3462 
3463 void secp224k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3464 {
3465  uint32_t u[7];
3466  uint32_t v[7];
3467  uint32_t w[7];
3468 
3469  //Since GF(p) is a prime field, the Fermat's little theorem can be
3470  //used to find the multiplicative inverse of A modulo p
3471  ecFieldSqrMod(curve, u, a);
3472  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
3473  ecFieldPwr2Mod(curve, v, u, 2);
3474  ecFieldMulMod(curve, u, u, v); //A^(2^4 - 1)
3475  ecFieldPwr2Mod(curve, v, u, 4);
3476  ecFieldMulMod(curve, u, u, v); //A^(2^8 - 1)
3477  ecFieldSqrMod(curve, u, u);
3478  ecFieldMulMod(curve, u, u, a); //A^(2^9 - 1)
3479  ecFieldPwr2Mod(curve, v, u, 9);
3480  ecFieldMulMod(curve, u, u, v); //A^(2^18 - 1)
3481  ecFieldSqrMod(curve, u, u);
3482  ecFieldMulMod(curve, w, u, a); //A^(2^19 - 1)
3483  ecFieldPwr2Mod(curve, u, w, 19);
3484  ecFieldMulMod(curve, u, u, w); //A^(2^38 - 1)
3485  ecFieldPwr2Mod(curve, v, u, 38);
3486  ecFieldMulMod(curve, u, u, v); //A^(2^76 - 1)
3487  ecFieldPwr2Mod(curve, v, u, 76);
3488  ecFieldMulMod(curve, u, u, v); //A^(2^152 - 1)
3489  ecFieldPwr2Mod(curve, u, u, 19);
3490  ecFieldMulMod(curve, u, u, w); //A^(2^171 - 1)
3491  ecFieldPwr2Mod(curve, u, u, 19);
3492  ecFieldMulMod(curve, u, u, w); //A^(2^190 - 1)
3493  ecFieldSqrMod(curve, u, u);
3494  ecFieldMulMod(curve, u, u, a); //A^(2^191 - 1)
3495  ecFieldPwr2Mod(curve, u, u, 20);
3496  ecFieldMulMod(curve, u, u, w); //A^(2^211 - 2^19 - 1)
3497  ecFieldPwr2Mod(curve, u, u, 3);
3498  ecFieldMulMod(curve, u, u, a); //A^(2^214 - 2^22 - 2^2 - 2^1 - 1)
3499  ecFieldPwr2Mod(curve, u, u, 2);
3500  ecFieldMulMod(curve, u, u, a); //A^(2^216 - 2^24 - 2^4 - 2^3 - 2^1 - 1)
3501  ecFieldPwr2Mod(curve, u, u, 2);
3502  ecFieldMulMod(curve, u, u, a); //A^(2^218 - 2^26 - 2^6 - 2^5 - 2^3 - 2^1 - 1)
3503  ecFieldSqrMod(curve, u, u);
3504  ecFieldMulMod(curve, u, u, a); //A^(2^219 - 2^27 - 2^7 - 2^6 - 2^4 - 2^2 - 1)
3505  ecFieldPwr2Mod(curve, u, u, 2);
3506  ecFieldMulMod(curve, u, u, a); //A^(2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 - 1)
3507  ecFieldPwr2Mod(curve, u, u, 2);
3508  ecFieldMulMod(curve, u, u, a); //A^(2^223 - 2^31 - 2^11 - 2^10 - 2^8 - 2^6 - 2^3 - 2^1 - 1)
3509  ecFieldSqrMod(curve, u, u);
3510  ecFieldMulMod(curve, r, u, a); //A^(2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2^2 - 1)
3511 }
3512 
3513 
3514 /**
3515  * @brief Scalar modular reduction (secp224k1 curve)
3516  * @param[in] curve Elliptic curve parameters
3517  * @param[out] r Resulting integer R = A mod q
3518  * @param[in] a An integer such as 0 <= A < q^2
3519  **/
3520 
3521 void secp224k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3522 {
3523  uint32_t c;
3524  uint32_t a2[15];
3525  uint32_t q2[8];
3526  uint32_t u[8];
3527  uint32_t v[8];
3528 
3529  //Compute a = a << 15
3530  ecScalarShiftLeft(a2, a, 15, 15);
3531  //Compute q = q << 15
3532  ecScalarShiftLeft(q2, curve->q, 15, 8);
3533 
3534  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
3535  ecScalarMul(NULL, u, a2 + 7, curve->qmu, 8);
3536  //Compute v = u * q mod b^(k + 1)
3537  ecScalarMul(v, NULL, u, q2, 8);
3538 
3539  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
3540  //If u < 0, then u = u + b^(k + 1)
3541  ecScalarSub(u, a2, v, 8);
3542 
3543  //This estimation implies that at most two subtractions of q are required to
3544  //obtain the correct remainder r
3545  c = ecScalarSub(v, u, q2, 8);
3546  ecScalarSelect(u, v, u, c, 8);
3547  c = ecScalarSub(v, u, q2, 8);
3548  ecScalarSelect(u, v, u, c, 8);
3549 
3550  //Compute a = u >> 15
3551  ecScalarShiftRight(r, u, 15, 8);
3552 }
3553 
3554 #endif
3555 #if (SECP224R1_SUPPORT == ENABLED)
3556 
3557 /**
3558  * @brief Field modular reduction (secp224r1 curve)
3559  * @param[in] curve Elliptic curve parameters
3560  * @param[out] r Resulting integer R = A mod p
3561  * @param[in] a An integer such as 0 <= A < p^2
3562  **/
3563 
3564 void secp224r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3565 {
3566  int64_t c;
3567  int64_t temp;
3568 
3569  //First pass
3570  temp = (int64_t) a[0];
3571  temp -= (int64_t) a[7] + a[11];
3572  r[0] = (uint32_t) temp;
3573  temp >>= 32;
3574  temp += (int64_t) a[1];
3575  temp -= (int64_t) a[8] + a[12];
3576  r[1] = (uint32_t) temp;
3577  temp >>= 32;
3578  temp += (int64_t) a[2];
3579  temp -= (int64_t) a[9] + a[13];
3580  r[2] = (uint32_t) temp;
3581  temp >>= 32;
3582  temp += (int64_t) a[3] + a[7] + a[11];
3583  temp -= (int64_t) a[10];
3584  r[3] = (uint32_t) temp;
3585  temp >>= 32;
3586  temp += (int64_t) a[4] + a[8] + a[12];
3587  temp -= (int64_t) a[11];
3588  r[4] = (uint32_t) temp;
3589  temp >>= 32;
3590  temp += (int64_t) a[5] + a[9] + a[13];
3591  temp -= (int64_t) a[12];
3592  r[5] = (uint32_t) temp;
3593  temp >>= 32;
3594  temp += (int64_t) a[6] + a[10];
3595  temp -= (int64_t) a[13];
3596  r[6] = (uint32_t) temp;
3597  c = temp >> 32;
3598 
3599  //Second pass
3600  temp = (int64_t) r[0] - c;
3601  r[0] = (uint32_t) temp;
3602  temp >>= 32;
3603  temp += (int64_t) r[1];
3604  r[1] = (uint32_t) temp;
3605  temp >>= 32;
3606  temp += (int64_t) r[2];
3607  r[2] = (uint32_t) temp;
3608  temp >>= 32;
3609  temp += (int64_t) r[3] + c;
3610  r[3] = (uint32_t) temp;
3611  temp >>= 32;
3612  temp += (int64_t) r[4];
3613  r[4] = (uint32_t) temp;
3614  temp >>= 32;
3615  temp += (int64_t) r[5];
3616  r[5] = (uint32_t) temp;
3617  temp >>= 32;
3618  temp += (int64_t) r[6];
3619  r[6] = (uint32_t) temp;
3620  c = temp >> 32;
3621 
3622  //Third pass
3623  temp = (int64_t) r[0] - c;
3624  r[0] = (uint32_t) temp;
3625  temp >>= 32;
3626  temp += (int64_t) r[1];
3627  r[1] = (uint32_t) temp;
3628  temp >>= 32;
3629  temp += (int64_t) r[2];
3630  r[2] = (uint32_t) temp;
3631  temp >>= 32;
3632  temp += (int64_t) r[3] + c;
3633  r[3] = (uint32_t) temp;
3634  temp >>= 32;
3635  temp += (int64_t) r[4];
3636  r[4] = (uint32_t) temp;
3637  temp >>= 32;
3638  temp += (int64_t) r[5];
3639  r[5] = (uint32_t) temp;
3640  temp >>= 32;
3641  temp += (int64_t) r[6];
3642  r[6] = (uint32_t) temp;
3643 
3644  //Reduce non-canonical values
3645  ecFieldCanonicalize(curve, r, r);
3646 }
3647 
3648 
3649 /**
3650  * @brief Field modular inversion (secp224r1 curve)
3651  * @param[in] curve Elliptic curve parameters
3652  * @param[out] r Resulting integer R = A^-1 mod p
3653  * @param[in] a An integer such as 0 <= A < p
3654  **/
3655 
3656 void secp224r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3657 {
3658  uint32_t u[7];
3659  uint32_t v[7];
3660 
3661  //Since GF(p) is a prime field, the Fermat's little theorem can be
3662  //used to find the multiplicative inverse of A modulo p
3663  ecFieldSqrMod(curve, u, a);
3664  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
3665  ecFieldSqrMod(curve, u, u);
3666  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
3667  ecFieldPwr2Mod(curve, v, u, 3);
3668  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
3669  ecFieldSqrMod(curve, u, u);
3670  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
3671  ecFieldPwr2Mod(curve, v, u, 7);
3672  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
3673  ecFieldSqrMod(curve, u, u);
3674  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
3675  ecFieldPwr2Mod(curve, v, u, 15);
3676  ecFieldMulMod(curve, u, u, v); //A^(2^30 - 1)
3677  ecFieldSqrMod(curve, u, u);
3678  ecFieldMulMod(curve, v, u, a); //A^(2^31 - 1)
3679  ecFieldSqrMod(curve, u, v);
3680  ecFieldMulMod(curve, u, u, a); //A^(2^32 - 1)
3681  ecFieldPwr2Mod(curve, u, u, 31);
3682  ecFieldMulMod(curve, u, u, v); //A^(2^63 - 1)
3683  ecFieldSqrMod(curve, u, u);
3684  ecFieldMulMod(curve, u, u, a); //A^(2^64 - 1)
3685  ecFieldPwr2Mod(curve, u, u, 31);
3686  ecFieldMulMod(curve, u, u, v); //A^(2^95 - 1)
3687  ecFieldSqrMod(curve, u, u);
3688  ecFieldMulMod(curve, u, u, a); //A^(2^96 - 1)
3689  ecFieldPwr2Mod(curve, u, u, 31);
3690  ecFieldMulMod(curve, u, u, v); //A^(2^127 - 1)
3691  ecFieldPwr2Mod(curve, u, u, 32);
3692  ecFieldMulMod(curve, u, u, v); //A^(2^159 - 2^31 - 1)
3693  ecFieldSqrMod(curve, u, u);
3694  ecFieldMulMod(curve, u, u, a); //A^(2^160 - 2^32 - 1)
3695  ecFieldPwr2Mod(curve, u, u, 31);
3696  ecFieldMulMod(curve, u, u, v); //A^(2^191 - 2^63 - 1)
3697  ecFieldSqrMod(curve, u, u);
3698  ecFieldMulMod(curve, u, u, a); //A^(2^192 - 2^64 - 1)
3699  ecFieldPwr2Mod(curve, u, u, 31);
3700  ecFieldMulMod(curve, u, u, v); //A^(2^223 - 2^95 - 1)
3701  ecFieldSqrMod(curve, u, u);
3702  ecFieldMulMod(curve, r, u, a); //A^(2^224 - 2^96 - 1)
3703 }
3704 
3705 
3706 /**
3707  * @brief Scalar modular reduction (secp224r1 curve)
3708  * @param[in] curve Elliptic curve parameters
3709  * @param[out] r Resulting integer R = A mod q
3710  * @param[in] a An integer such as 0 <= A < q^2
3711  **/
3712 
3713 void secp224r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3714 {
3715  uint32_t c;
3716  uint32_t u[8];
3717  uint32_t v[8];
3718 
3719  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
3720  ecScalarMul(NULL, u, a + 6, curve->qmu, 8);
3721  //Compute v = u * q mod b^(k + 1)
3722  ecScalarMul(v, NULL, u, curve->q, 8);
3723 
3724  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
3725  //If u < 0, then u = u + b^(k + 1)
3726  ecScalarSub(u, a, v, 8);
3727 
3728  //This estimation implies that at most two subtractions of q are required to
3729  //obtain the correct remainder r
3730  c = ecScalarSub(v, u, curve->q, 8);
3731  ecScalarSelect(u, v, u, c, 8);
3732  c = ecScalarSub(v, u, curve->q, 8);
3733  ecScalarSelect(r, v, u, c, 7);
3734 }
3735 
3736 #endif
3737 #if (SECP256K1_SUPPORT == ENABLED)
3738 
3739 /**
3740  * @brief Field modular reduction (secp256k1 curve)
3741  * @param[in] curve Elliptic curve parameters
3742  * @param[out] r Resulting integer R = A mod p
3743  * @param[in] a An integer such as 0 <= A < p^2
3744  **/
3745 
3746 void secp256k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3747 {
3748  uint64_t c;
3749  uint64_t temp;
3750 
3751  //First pass
3752  temp = (uint64_t) a[0];
3753  temp += (uint64_t) a[8] * 977;
3754  temp += (uint64_t) a[15] * 977;
3755  r[0] = (uint32_t) temp;
3756  temp >>= 32;
3757  temp += (uint64_t) a[1] + a[8] + a[15];
3758  temp += (uint64_t) a[9] * 977;
3759  r[1] = (uint32_t) temp;
3760  temp >>= 32;
3761  temp += (uint64_t) a[2] + a[9];
3762  temp += (uint64_t) a[10] * 977;
3763  r[2] = (uint32_t) temp;
3764  temp >>= 32;
3765  temp += (uint64_t) a[3] + a[10];
3766  temp += (uint64_t) a[11] * 977;
3767  r[3] = (uint32_t) temp;
3768  temp >>= 32;
3769  temp += (uint64_t) a[4] + a[11];
3770  temp += (uint64_t) a[12] * 977;
3771  r[4] = (uint32_t) temp;
3772  temp >>= 32;
3773  temp += (uint64_t) a[5] + a[12];
3774  temp += (uint64_t) a[13] * 977;
3775  r[5] = (uint32_t) temp;
3776  temp >>= 32;
3777  temp += (uint64_t) a[6] + a[13];
3778  temp += (uint64_t) a[14] * 977;
3779  r[6] = (uint32_t) temp;
3780  temp >>= 32;
3781  temp += (uint64_t) a[7] + a[14];
3782  temp += (uint64_t) a[15] * 977;
3783  r[7] = (uint32_t) temp;
3784  c = temp >> 32;
3785 
3786  //Second pass
3787  temp = (uint64_t) r[0] + c * 977;
3788  r[0] = (uint32_t) temp;
3789  temp >>= 32;
3790  temp += (uint64_t) r[1] + c;
3791  r[1] = (uint32_t) temp;
3792  temp >>= 32;
3793  temp += (uint64_t) r[2];
3794  r[2] = (uint32_t) temp;
3795  temp >>= 32;
3796  temp += (uint64_t) r[3];
3797  r[3] = (uint32_t) temp;
3798  temp >>= 32;
3799  temp += (uint64_t) r[4];
3800  r[4] = (uint32_t) temp;
3801  temp >>= 32;
3802  temp += (uint64_t) r[5];
3803  r[5] = (uint32_t) temp;
3804  temp >>= 32;
3805  temp += (uint64_t) r[6];
3806  r[6] = (uint32_t) temp;
3807  temp >>= 32;
3808  temp += (uint64_t) r[7];
3809  r[7] = (uint32_t) temp;
3810  c = temp >> 32;
3811 
3812  //Third pass
3813  temp = (uint64_t) r[0] + c * 977;
3814  r[0] = (uint32_t) temp;
3815  temp >>= 32;
3816  temp += (uint64_t) r[1] + c;
3817  r[1] = (uint32_t) temp;
3818  temp >>= 32;
3819  temp += (uint64_t) r[2];
3820  r[2] = (uint32_t) temp;
3821  temp >>= 32;
3822  temp += (uint64_t) r[3];
3823  r[3] = (uint32_t) temp;
3824  temp >>= 32;
3825  temp += (uint64_t) r[4];
3826  r[4] = (uint32_t) temp;
3827  temp >>= 32;
3828  temp += (uint64_t) r[5];
3829  r[5] = (uint32_t) temp;
3830  temp >>= 32;
3831  temp += (uint64_t) r[6];
3832  r[6] = (uint32_t) temp;
3833  temp >>= 32;
3834  temp += (uint64_t) r[7];
3835  r[7] = (uint32_t) temp;
3836 
3837  //Reduce non-canonical values
3838  ecFieldCanonicalize(curve, r, r);
3839 }
3840 
3841 
3842 /**
3843  * @brief Field modular inversion (secp256k1 curve)
3844  * @param[in] curve Elliptic curve parameters
3845  * @param[out] r Resulting integer R = A^-1 mod p
3846  * @param[in] a An integer such as 0 <= A < p
3847  **/
3848 
3849 void secp256k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3850 {
3851  uint32_t u[8];
3852  uint32_t v[8];
3853  uint32_t w[8];
3854 
3855  //Since GF(p) is a prime field, the Fermat's little theorem can be
3856  //used to find the multiplicative inverse of A modulo p
3857  ecFieldSqrMod(curve, u, a);
3858  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
3859  ecFieldPwr2Mod(curve, v, u, 2);
3860  ecFieldMulMod(curve, u, u, v); //A^(2^4 - 1)
3861  ecFieldSqrMod(curve, u, u);
3862  ecFieldMulMod(curve, u, u, a); //A^(2^5 - 1)
3863  ecFieldPwr2Mod(curve, v, u, 5);
3864  ecFieldMulMod(curve, u, u, v); //A^(2^10 - 1)
3865  ecFieldSqrMod(curve, u, u);
3866  ecFieldMulMod(curve, u, u, a); //A^(2^11 - 1)
3867  ecFieldPwr2Mod(curve, v, u, 11);
3868  ecFieldMulMod(curve, w, u, v); //A^(2^22 - 1)
3869  ecFieldPwr2Mod(curve, u, w, 22);
3870  ecFieldMulMod(curve, u, u, w); //A^(2^44 - 1)
3871  ecFieldPwr2Mod(curve, v, u, 44);
3872  ecFieldMulMod(curve, u, u, v); //A^(2^88 - 1)
3873  ecFieldPwr2Mod(curve, u, u, 22);
3874  ecFieldMulMod(curve, u, u, w); //A^(2^110 - 1)
3875  ecFieldSqrMod(curve, u, u);
3876  ecFieldMulMod(curve, u, u, a); //A^(2^111 - 1)
3877  ecFieldPwr2Mod(curve, v, u, 111);
3878  ecFieldMulMod(curve, u, u, v); //A^(2^222 - 1)
3879  ecFieldSqrMod(curve, u, u);
3880  ecFieldMulMod(curve, u, u, a); //A^(2^223 - 1)
3881  ecFieldPwr2Mod(curve, u, u, 23);
3882  ecFieldMulMod(curve, u, u, w); //A^(2^246 - 2^22 - 1)
3883  ecFieldPwr2Mod(curve, u, u, 5);
3884  ecFieldMulMod(curve, u, u, a); //A^(2^251 - 2^27 - 2^4 - 2^3 - 2^2 - 2^1 - 1)
3885  ecFieldPwr2Mod(curve, u, u, 2);
3886  ecFieldMulMod(curve, u, u, a); //A^(2^253 - 2^29 - 2^6 - 2^5 - 2^4 - 2^3 - 2^1 - 1)
3887  ecFieldSqrMod(curve, u, u);
3888  ecFieldMulMod(curve, u, u, a); //A^(2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2 - 1)
3889  ecFieldPwr2Mod(curve, u, u, 2);
3890  ecFieldMulMod(curve, r, u, a); //A^(2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 3)
3891 }
3892 
3893 
3894 /**
3895  * @brief Scalar modular reduction (secp256k1 curve)
3896  * @param[in] curve Elliptic curve parameters
3897  * @param[out] r Resulting integer R = A mod q
3898  * @param[in] a An integer such as 0 <= A < q^2
3899  **/
3900 
3901 void secp256k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3902 {
3903  uint32_t c;
3904  uint32_t u[9];
3905  uint32_t v[9];
3906 
3907  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
3908  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
3909  //Compute v = u * q mod b^(k + 1)
3910  ecScalarMul(v, NULL, u, curve->q, 9);
3911 
3912  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
3913  //If u < 0, then u = u + b^(k + 1)
3914  ecScalarSub(u, a, v, 9);
3915 
3916  //This estimation implies that at most two subtractions of q are required to
3917  //obtain the correct remainder r
3918  c = ecScalarSub(v, u, curve->q, 9);
3919  ecScalarSelect(u, v, u, c, 9);
3920  c = ecScalarSub(v, u, curve->q, 9);
3921  ecScalarSelect(r, v, u, c, 8);
3922 }
3923 
3924 #endif
3925 #if (SECP256R1_SUPPORT == ENABLED)
3926 
3927 /**
3928  * @brief Field modular reduction (secp256r1 curve)
3929  * @param[in] curve Elliptic curve parameters
3930  * @param[out] r Resulting integer R = A mod p
3931  * @param[in] a An integer such as 0 <= A < p^2
3932  **/
3933 
3934 void secp256r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
3935 {
3936  int64_t c;
3937  int64_t temp;
3938 
3939  //First pass
3940  temp = (int64_t) a[0] + a[8] + a[9];
3941  temp -= (int64_t) a[11] + a[12] + a[13] + a[14];
3942  r[0] = (uint32_t) temp;
3943  temp >>= 32;
3944  temp += (int64_t) a[1] + a[9] + a[10];
3945  temp -= (int64_t) a[12] + a[13] + a[14] + a[15];
3946  r[1] = (uint32_t) temp;
3947  temp >>= 32;
3948  temp += (int64_t) a[2] + a[10] + a[11];
3949  temp -= (int64_t) a[13] + a[14] + a[15];
3950  r[2] = (uint32_t) temp;
3951  temp >>= 32;
3952  temp += (int64_t) a[3] + a[11] + a[11] + a[12] + a[12] + a[13];
3953  temp -= (int64_t) a[8] + a[9] + a[15];
3954  r[3] = (uint32_t) temp;
3955  temp >>= 32;
3956  temp += (int64_t) a[4] + a[12] + a[12] + a[13] + a[13] + a[14];
3957  temp -= (int64_t) a[9] + a[10];
3958  r[4] = (uint32_t) temp;
3959  temp >>= 32;
3960  temp += (int64_t) a[5] + a[13] + a[13] + a[14] + a[14] + a[15];
3961  temp -= (int64_t) a[10] + a[11];
3962  r[5] = (uint32_t) temp;
3963  temp >>= 32;
3964  temp += (int64_t) a[6] + a[13] + a[14] + a[14] + a[14] + a[15] + a[15];
3965  temp -= (int64_t) a[8] + a[9];
3966  r[6] = (uint32_t) temp;
3967  temp >>= 32;
3968  temp += (int64_t) a[7] + a[8] + a[15] + a[15] + a[15];
3969  temp -= (int64_t) a[10] + a[11] + a[12] + a[13];
3970  r[7] = (uint32_t) temp;
3971  c = temp >> 32;
3972 
3973  //Second pass
3974  temp = (int64_t) r[0] + c;
3975  r[0] = (uint32_t) temp;
3976  temp >>= 32;
3977  temp += (int64_t) r[1];
3978  r[1] = (uint32_t) temp;
3979  temp >>= 32;
3980  temp += (int64_t) r[2];
3981  r[2] = (uint32_t) temp;
3982  temp >>= 32;
3983  temp += (int64_t) r[3] - c;
3984  r[3] = (uint32_t) temp;
3985  temp >>= 32;
3986  temp += (int64_t) r[4];
3987  r[4] = (uint32_t) temp;
3988  temp >>= 32;
3989  temp += (int64_t) r[5];
3990  r[5] = (uint32_t) temp;
3991  temp >>= 32;
3992  temp += (int64_t) r[6] - c;
3993  r[6] = (uint32_t) temp;
3994  temp >>= 32;
3995  temp += (int64_t) r[7] + c;
3996  r[7] = (uint32_t) temp;
3997  c = temp >> 32;
3998 
3999  //Third pass
4000  temp = (int64_t) r[0] + c;
4001  r[0] = (uint32_t) temp;
4002  temp >>= 32;
4003  temp += (int64_t) r[1];
4004  r[1] = (uint32_t) temp;
4005  temp >>= 32;
4006  temp += (int64_t) r[2];
4007  r[2] = (uint32_t) temp;
4008  temp >>= 32;
4009  temp += (int64_t) r[3] - c;
4010  r[3] = (uint32_t) temp;
4011  temp >>= 32;
4012  temp += (int64_t) r[4];
4013  r[4] = (uint32_t) temp;
4014  temp >>= 32;
4015  temp += (int64_t) r[5];
4016  r[5] = (uint32_t) temp;
4017  temp >>= 32;
4018  temp += (int64_t) r[6] - c;
4019  r[6] = (uint32_t) temp;
4020  temp >>= 32;
4021  temp += (int64_t) r[7] + c;
4022  r[7] = (uint32_t) temp;
4023 
4024  //Reduce non-canonical values
4025  ecFieldCanonicalize(curve, r, r);
4026 }
4027 
4028 
4029 /**
4030  * @brief Field modular inversion (secp256r1 curve)
4031  * @param[in] curve Elliptic curve parameters
4032  * @param[out] r Resulting integer R = A^-1 mod p
4033  * @param[in] a An integer such as 0 <= A < p
4034  **/
4035 
4036 void secp256r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4037 {
4038  uint32_t u[8];
4039  uint32_t v[8];
4040 
4041  //Since GF(p) is a prime field, the Fermat's little theorem can be
4042  //used to find the multiplicative inverse of A modulo p
4043  ecFieldSqrMod(curve, u, a);
4044  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
4045  ecFieldSqrMod(curve, u, u);
4046  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
4047  ecFieldPwr2Mod(curve, v, u, 3);
4048  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
4049  ecFieldSqrMod(curve, u, u);
4050  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
4051  ecFieldPwr2Mod(curve, v, u, 7);
4052  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
4053  ecFieldSqrMod(curve, u, u);
4054  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
4055  ecFieldPwr2Mod(curve, v, u, 15);
4056  ecFieldMulMod(curve, u, u, v); //A^(2^30 - 1)
4057  ecFieldSqrMod(curve, u, u);
4058  ecFieldMulMod(curve, v, u, a); //A^(2^31 - 1)
4059  ecFieldSqrMod(curve, u, v);
4060  ecFieldMulMod(curve, u, u, a); //A^(2^32 - 1)
4061  ecFieldPwr2Mod(curve, u, u, 32);
4062  ecFieldMulMod(curve, u, u, a); //A^(2^64 - 2^32 + 1)
4063  ecFieldPwr2Mod(curve, u, u, 127);
4064  ecFieldMulMod(curve, u, u, v); //A^(2^191 - 2^159 + 2^127 + 2^31 - 1)
4065  ecFieldPwr2Mod(curve, u, u, 31);
4066  ecFieldMulMod(curve, u, u, v); //A^(2^222 - 2^190 + 2^158 + 2^62 - 1)
4067  ecFieldPwr2Mod(curve, u, u, 31);
4068  ecFieldMulMod(curve, u, u, v); //A^(2^253 - 2^221 + 2^189 + 2^93 - 1)
4069  ecFieldSqrMod(curve, u, u);
4070  ecFieldMulMod(curve, u, u, a); //A^(2^254 - 2^222 + 2^190 + 2^94 - 1)
4071  ecFieldPwr2Mod(curve, u, u, 2);
4072  ecFieldMulMod(curve, r, u, a); //A^(2^256 - 2^224 + 2^192 + 2^96 - 3)
4073 }
4074 
4075 
4076 /**
4077  * @brief Scalar modular reduction (secp256r1 curve)
4078  * @param[in] curve Elliptic curve parameters
4079  * @param[out] r Resulting integer R = A mod q
4080  * @param[in] a An integer such as 0 <= A < q^2
4081  **/
4082 
4083 void secp256r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4084 {
4085  uint32_t c;
4086  uint32_t u[9];
4087  uint32_t v[9];
4088 
4089  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4090  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
4091  //Compute v = u * q mod b^(k + 1)
4092  ecScalarMul(v, NULL, u, curve->q, 9);
4093 
4094  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4095  //If u < 0, then u = u + b^(k + 1)
4096  ecScalarSub(u, a, v, 9);
4097 
4098  //This estimation implies that at most two subtractions of q are required to
4099  //obtain the correct remainder r
4100  c = ecScalarSub(v, u, curve->q, 9);
4101  ecScalarSelect(u, v, u, c, 9);
4102  c = ecScalarSub(v, u, curve->q, 9);
4103  ecScalarSelect(r, v, u, c, 8);
4104 }
4105 
4106 
4107 /**
4108  * @brief Scalar modular inversion (secp256r1 curve)
4109  * @param[in] curve Elliptic curve parameters
4110  * @param[out] r Resulting integer R = A^-1 mod q
4111  * @param[in] a An integer such as 0 <= A < q
4112  **/
4113 
4114 void secp256r1ScalarInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4115 {
4116  int_t i;
4117  uint32_t u[13];
4118  uint32_t v[13];
4119 
4120  //Process bits 255...128
4121  ecScalarSqrMod(curve, u, a);
4122  ecScalarMulMod(curve, u, u, a); //A^(2^2 - 1)
4123  ecScalarPwr2Mod(curve, v, u, 2);
4124  ecScalarMulMod(curve, u, u, v); //A^(2^4 - 1)
4125  ecScalarPwr2Mod(curve, v, u, 4);
4126  ecScalarMulMod(curve, u, u, v); //A^(2^8 - 1)
4127  ecScalarPwr2Mod(curve, v, u, 8);
4128  ecScalarMulMod(curve, u, u, v); //A^(2^16 - 1)
4129  ecScalarPwr2Mod(curve, v, u, 16);
4130  ecScalarMulMod(curve, v, u, v); //A^(2^32 - 1)
4131  ecScalarPwr2Mod(curve, u, v, 64);
4132  ecScalarMulMod(curve, u, u, v);
4133  ecScalarPwr2Mod(curve, u, u, 32);
4134  ecScalarMulMod(curve, u, u, v);
4135 
4136  //Process bits 127..5
4137  for(i = 127; i >= 5; i--)
4138  {
4139  //Calculate U = U^2
4140  ecScalarSqrMod(curve, u, u);
4141 
4142  //Check the value of q(i)
4143  if(((curve->q[i / 32] >> (i % 32)) & 1) != 0)
4144  {
4145  //Calculate U = U * A
4146  ecScalarMulMod(curve, u, u, a);
4147  }
4148  }
4149 
4150  //Process bits 4..0
4151  ecScalarSqrMod(curve, u, u);
4152  ecScalarSqrMod(curve, u, u);
4153  ecScalarMulMod(curve, u, u, a);
4154  ecScalarSqrMod(curve, u, u);
4155  ecScalarMulMod(curve, u, u, a);
4156  ecScalarSqrMod(curve, u, u);
4157  ecScalarMulMod(curve, u, u, a);
4158  ecScalarSqrMod(curve, u, u);
4159  ecScalarMulMod(curve, r, u, a);
4160 }
4161 
4162 #endif
4163 #if (SECP384R1_SUPPORT == ENABLED)
4164 
4165 /**
4166  * @brief Field modular reduction (secp384r1 curve)
4167  * @param[in] curve Elliptic curve parameters
4168  * @param[out] r Resulting integer R = A mod p
4169  * @param[in] a An integer such as 0 <= A < p^2
4170  **/
4171 
4172 void secp384r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4173 {
4174  int64_t c;
4175  int64_t temp;
4176 
4177  //First pass
4178  temp = (int64_t) a[0] + a[12] + a[20] + a[21];
4179  temp -= (int64_t) a[23];
4180  r[0] = (uint32_t) temp;
4181  temp >>= 32;
4182  temp += (int64_t) a[1] + a[13] + a[22] + a[23];
4183  temp -= (int64_t) a[12] + a[20];
4184  r[1] = (uint32_t) temp;
4185  temp >>= 32;
4186  temp += (int64_t) a[2] + a[14] + a[23];
4187  temp -= (int64_t) a[13] + a[21];
4188  r[2] = (uint32_t) temp;
4189  temp >>= 32;
4190  temp += (int64_t) a[3] + a[12] + a[15] + a[20] + a[21];
4191  temp -= (int64_t) a[14] + a[22] + a[23];
4192  r[3] = (uint32_t) temp;
4193  temp >>= 32;
4194  temp += (int64_t) a[4] + a[12] + a[13] + a[16] + a[20] + a[21] + a[21] + a[22];
4195  temp -= (int64_t) a[15] + a[23] + a[23];
4196  r[4] = (uint32_t) temp;
4197  temp >>= 32;
4198  temp += (int64_t) a[5] + a[13] + a[14] + a[17] + a[21] + a[22] + a[22] + a[23];
4199  temp -= (int64_t) a[16];
4200  r[5] = (uint32_t) temp;
4201  temp >>= 32;
4202  temp += (int64_t) a[6] + a[14] + a[15] + a[18] + a[22] + a[23] + a[23];
4203  temp -= (int64_t) a[17];
4204  r[6] = (uint32_t) temp;
4205  temp >>= 32;
4206  temp += (int64_t) a[7] + a[15] + a[16] + a[19] + a[23];
4207  temp -= (int64_t) a[18];
4208  r[7] = (uint32_t) temp;
4209  temp >>= 32;
4210  temp += (int64_t) a[8] + a[16] + a[17] + a[20];
4211  temp -= (int64_t) a[19];
4212  r[8] = (uint32_t) temp;
4213  temp >>= 32;
4214  temp += (int64_t) a[9] + a[17] + a[18] + a[21];
4215  temp -= (int64_t) a[20];
4216  r[9] = (uint32_t) temp;
4217  temp >>= 32;
4218  temp += (int64_t) a[10] + a[18] + a[19] + a[22];
4219  temp -= (int64_t) a[21];
4220  r[10] = (uint32_t) temp;
4221  temp >>= 32;
4222  temp += (int64_t) a[11] + a[19] + a[20] + a[23];
4223  temp -= (int64_t) a[22];
4224  r[11] = (uint32_t) temp;
4225  c = temp >> 32;
4226 
4227  //Second pass
4228  temp = (int64_t) r[0] + c;
4229  r[0] = (uint32_t) temp;
4230  temp >>= 32;
4231  temp += (int64_t) r[1] - c;
4232  r[1] = (uint32_t) temp;
4233  temp >>= 32;
4234  temp += (int64_t) r[2];
4235  r[2] = (uint32_t) temp;
4236  temp >>= 32;
4237  temp += (int64_t) r[3] + c;
4238  r[3] = (uint32_t) temp;
4239  temp >>= 32;
4240  temp += (int64_t) r[4] + c;
4241  r[4] = (uint32_t) temp;
4242  temp >>= 32;
4243  temp += (int64_t) r[5];
4244  r[5] = (uint32_t) temp;
4245  temp >>= 32;
4246  temp += (int64_t) r[6];
4247  r[6] = (uint32_t) temp;
4248  temp >>= 32;
4249  temp += (int64_t) r[7];
4250  r[7] = (uint32_t) temp;
4251  temp >>= 32;
4252  temp += (int64_t) r[8];
4253  r[8] = (uint32_t) temp;
4254  temp >>= 32;
4255  temp += (int64_t) r[9];
4256  r[9] = (uint32_t) temp;
4257  temp >>= 32;
4258  temp += (int64_t) r[10];
4259  r[10] = (uint32_t) temp;
4260  temp >>= 32;
4261  temp += (int64_t) r[11];
4262  r[11] = (uint32_t) temp;
4263  c = temp >> 32;
4264 
4265  //Third pass
4266  temp = (int64_t) r[0] + c;
4267  r[0] = (uint32_t) temp;
4268  temp >>= 32;
4269  temp += (int64_t) r[1] - c;
4270  r[1] = (uint32_t) temp;
4271  temp >>= 32;
4272  temp += (int64_t) r[2];
4273  r[2] = (uint32_t) temp;
4274  temp >>= 32;
4275  temp += (int64_t) r[3] + c;
4276  r[3] = (uint32_t) temp;
4277  temp >>= 32;
4278  temp += (int64_t) r[4] + c;
4279  r[4] = (uint32_t) temp;
4280  temp >>= 32;
4281  temp += (int64_t) r[5];
4282  r[5] = (uint32_t) temp;
4283  temp >>= 32;
4284  temp += (int64_t) r[6];
4285  r[6] = (uint32_t) temp;
4286  temp >>= 32;
4287  temp += (int64_t) r[7];
4288  r[7] = (uint32_t) temp;
4289  temp >>= 32;
4290  temp += (int64_t) r[8];
4291  r[8] = (uint32_t) temp;
4292  temp >>= 32;
4293  temp += (int64_t) r[9];
4294  r[9] = (uint32_t) temp;
4295  temp >>= 32;
4296  temp += (int64_t) r[10];
4297  r[10] = (uint32_t) temp;
4298  temp >>= 32;
4299  temp += (int64_t) r[11];
4300  r[11] = (uint32_t) temp;
4301 
4302  //Reduce non-canonical values
4303  ecFieldCanonicalize(curve, r, r);
4304 }
4305 
4306 
4307 /**
4308  * @brief Field modular inversion (secp384r1 curve)
4309  * @param[in] curve Elliptic curve parameters
4310  * @param[out] r Resulting integer R = A^-1 mod p
4311  * @param[in] a An integer such as 0 <= A < p
4312  **/
4313 
4314 void secp384r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4315 {
4316  uint32_t u[12];
4317  uint32_t v[12];
4318  uint32_t w[12];
4319 
4320  //Since GF(p) is a prime field, the Fermat's little theorem can be
4321  //used to find the multiplicative inverse of A modulo p
4322  ecFieldSqrMod(curve, u, a);
4323  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
4324  ecFieldSqrMod(curve, u, u);
4325  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
4326  ecFieldPwr2Mod(curve, v, u, 3);
4327  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
4328  ecFieldSqrMod(curve, u, u);
4329  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
4330  ecFieldPwr2Mod(curve, v, u, 7);
4331  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
4332  ecFieldSqrMod(curve, u, u);
4333  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
4334  ecFieldPwr2Mod(curve, v, u, 15);
4335  ecFieldMulMod(curve, w, u, v); //A^(2^30 - 1)
4336  ecFieldSqrMod(curve, u, w);
4337  ecFieldMulMod(curve, u, u, a); //A^(2^31 - 1)
4338  ecFieldPwr2Mod(curve, v, u, 31);
4339  ecFieldMulMod(curve, u, u, v); //A^(2^62 - 1)
4340  ecFieldSqrMod(curve, u, u);
4341  ecFieldMulMod(curve, u, u, a); //A^(2^63 - 1)
4342  ecFieldPwr2Mod(curve, v, u, 63);
4343  ecFieldMulMod(curve, u, u, v); //A^(2^126 - 1)
4344  ecFieldSqrMod(curve, u, u);
4345  ecFieldMulMod(curve, u, u, a); //A^(2^127 - 1)
4346  ecFieldPwr2Mod(curve, v, u, 127);
4347  ecFieldMulMod(curve, u, u, v); //A^(2^254 - 1)
4348  ecFieldSqrMod(curve, u, u);
4349  ecFieldMulMod(curve, u, u, a); //A^(2^255 - 1)
4350  ecFieldPwr2Mod(curve, u, u, 31);
4351  ecFieldMulMod(curve, u, u, w); //A^(2^286 - 2^30 - 1)
4352  ecFieldSqrMod(curve, u, u);
4353  ecFieldMulMod(curve, u, u, a); //A^(2^287 - 2^31 - 1)
4354  ecFieldSqrMod(curve, u, u);
4355  ecFieldMulMod(curve, u, u, a); //A^(2^288 - 2^32 - 1)
4356  ecFieldPwr2Mod(curve, u, u, 94);
4357  ecFieldMulMod(curve, u, u, w); //A^(2^382 - 2^126 - 2^94 + 2^30 - 1)
4358  ecFieldPwr2Mod(curve, u, u, 2);
4359  ecFieldMulMod(curve, r, u, a); //A^(2^384 - 2^128 - 2^96 + 2^32 - 3)
4360 }
4361 
4362 
4363 /**
4364  * @brief Scalar modular reduction (secp384r1 curve)
4365  * @param[in] curve Elliptic curve parameters
4366  * @param[out] r Resulting integer R = A mod q
4367  * @param[in] a An integer such as 0 <= A < q^2
4368  **/
4369 
4370 void secp384r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4371 {
4372  uint32_t c;
4373  uint32_t u[13];
4374  uint32_t v[13];
4375 
4376  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4377  ecScalarMul(NULL, u, a + 11, curve->qmu, 13);
4378  //Compute v = u * q mod b^(k + 1)
4379  ecScalarMul(v, NULL, u, curve->q, 13);
4380 
4381  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4382  //If u < 0, then u = u + b^(k + 1)
4383  ecScalarSub(u, a, v, 13);
4384 
4385  //This estimation implies that at most two subtractions of q are required to
4386  //obtain the correct remainder r
4387  c = ecScalarSub(v, u, curve->q, 13);
4388  ecScalarSelect(u, v, u, c, 13);
4389  c = ecScalarSub(v, u, curve->q, 13);
4390  ecScalarSelect(r, v, u, c, 12);
4391 }
4392 
4393 
4394 /**
4395  * @brief Scalar modular inversion (secp384r1 curve)
4396  * @param[in] curve Elliptic curve parameters
4397  * @param[out] r Resulting integer R = A^-1 mod q
4398  * @param[in] a An integer such as 0 <= A < q
4399  **/
4400 
4401 void secp384r1ScalarInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4402 {
4403  int_t i;
4404  uint32_t u[13];
4405  uint32_t v[13];
4406 
4407  //Process bits 383...190
4408  ecScalarSqrMod(curve, u, a);
4409  ecScalarMulMod(curve, u, u, a); //A^(2^2 - 1)
4410  ecScalarSqrMod(curve, u, u);
4411  ecScalarMulMod(curve, u, u, a); //A^(2^3 - 1)
4412  ecScalarPwr2Mod(curve, v, u, 3);
4413  ecScalarMulMod(curve, u, u, v); //A^(2^6 - 1)
4414  ecScalarPwr2Mod(curve, v, u, 6);
4415  ecScalarMulMod(curve, u, u, v); //A^(2^12 - 1)
4416  ecScalarPwr2Mod(curve, v, u, 12);
4417  ecScalarMulMod(curve, u, u, v); //A^(2^24 - 1)
4418  ecScalarPwr2Mod(curve, v, u, 24);
4419  ecScalarMulMod(curve, u, u, v); //A^(2^48 - 1)
4420  ecScalarPwr2Mod(curve, v, u, 48);
4421  ecScalarMulMod(curve, u, u, v); //A^(2^96 - 1)
4422  ecScalarSqrMod(curve, u, u);
4423  ecScalarMulMod(curve, u, u, a); //A^(2^97 - 1)
4424  ecScalarPwr2Mod(curve, v, u, 97);
4425  ecScalarMulMod(curve, u, u, v); //A^(2^194 - 1)
4426 
4427  //Process bits 189..2
4428  for(i = 189; i >= 2; i--)
4429  {
4430  //Calculate U = U^2
4431  ecScalarSqrMod(curve, u, u);
4432 
4433  //Check the value of q(i)
4434  if(((curve->q[i / 32] >> (i % 32)) & 1) != 0)
4435  {
4436  //Calculate U = U * A
4437  ecScalarMulMod(curve, u, u, a);
4438  }
4439  }
4440 
4441  //Process bits 1..0
4442  ecScalarSqrMod(curve, u, u);
4443  ecScalarSqrMod(curve, u, u);
4444  ecScalarMulMod(curve, r, u, a);
4445 }
4446 
4447 #endif
4448 #if (SECP521R1_SUPPORT == ENABLED)
4449 
4450 /**
4451  * @brief Field modular reduction (secp521r1 curve)
4452  * @param[in] curve Elliptic curve parameters
4453  * @param[out] r Resulting integer R = A mod p
4454  * @param[in] a An integer such as 0 <= A < p^2
4455  **/
4456 
4457 void secp521r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4458 {
4459  uint64_t c;
4460  uint64_t temp;
4461 
4462  //First pass
4463  temp = (uint64_t) a[0];
4464  temp += (uint64_t) a[16] >> 9;
4465  temp += (uint64_t) a[17] << 23;
4466  r[0] = (uint32_t) temp;
4467  temp >>= 32;
4468  temp += (uint64_t) a[1];
4469  temp += (uint64_t) a[18] << 23;
4470  r[1] = (uint32_t) temp;
4471  temp >>= 32;
4472  temp += (uint64_t) a[2];
4473  temp += (uint64_t) a[19] << 23;
4474  r[2] = (uint32_t) temp;
4475  temp >>= 32;
4476  temp += (uint64_t) a[3];
4477  temp += (uint64_t) a[20] << 23;
4478  r[3] = (uint32_t) temp;
4479  temp >>= 32;
4480  temp += (uint64_t) a[4];
4481  temp += (uint64_t) a[21] << 23;
4482  r[4] = (uint32_t) temp;
4483  temp >>= 32;
4484  temp += (uint64_t) a[5];
4485  temp += (uint64_t) a[22] << 23;
4486  r[5] = (uint32_t) temp;
4487  temp >>= 32;
4488  temp += (uint64_t) a[6];
4489  temp += (uint64_t) a[23] << 23;
4490  r[6] = (uint32_t) temp;
4491  temp >>= 32;
4492  temp += (uint64_t) a[7];
4493  temp += (uint64_t) a[24] << 23;
4494  r[7] = (uint32_t) temp;
4495  temp >>= 32;
4496  temp += (uint64_t) a[8];
4497  temp += (uint64_t) a[25] << 23;
4498  r[8] = (uint32_t) temp;
4499  temp >>= 32;
4500  temp += (uint64_t) a[9];
4501  temp += (uint64_t) a[26] << 23;
4502  r[9] = (uint32_t) temp;
4503  temp >>= 32;
4504  temp += (uint64_t) a[10];
4505  temp += (uint64_t) a[27] << 23;
4506  r[10] = (uint32_t) temp;
4507  temp >>= 32;
4508  temp += (uint64_t) a[11];
4509  temp += (uint64_t) a[28] << 23;
4510  r[11] = (uint32_t) temp;
4511  temp >>= 32;
4512  temp += (uint64_t) a[12];
4513  temp += (uint64_t) a[29] << 23;
4514  r[12] = (uint32_t) temp;
4515  temp >>= 32;
4516  temp += (uint64_t) a[13];
4517  temp += (uint64_t) a[30] << 23;
4518  r[13] = (uint32_t) temp;
4519  temp >>= 32;
4520  temp += (uint64_t) a[14];
4521  temp += (uint64_t) a[31] << 23;
4522  r[14] = (uint32_t) temp;
4523  temp >>= 32;
4524  temp += (uint64_t) a[15];
4525  temp += (uint64_t) a[32] << 23;
4526  r[15] = (uint32_t) temp;
4527  temp >>= 32;
4528  temp += (uint64_t) a[16] & 0x1FF;
4529  r[16] = (uint32_t) temp & 0x1FF;
4530  c = temp >> 9;
4531 
4532  //Second pass
4533  temp = (uint64_t) r[0] + c;
4534  r[0] = (uint32_t) temp;
4535  temp >>= 32;
4536  temp += (uint64_t) r[1];
4537  r[1] = (uint32_t) temp;
4538  temp >>= 32;
4539  temp += (uint64_t) r[2];
4540  r[2] = (uint32_t) temp;
4541  temp >>= 32;
4542  temp += (uint64_t) r[3];
4543  r[3] = (uint32_t) temp;
4544  temp >>= 32;
4545  temp += (uint64_t) r[4];
4546  r[4] = (uint32_t) temp;
4547  temp >>= 32;
4548  temp += (uint64_t) r[5];
4549  r[5] = (uint32_t) temp;
4550  temp >>= 32;
4551  temp += (uint64_t) r[6];
4552  r[6] = (uint32_t) temp;
4553  temp >>= 32;
4554  temp += (uint64_t) r[7];
4555  r[7] = (uint32_t) temp;
4556  temp >>= 32;
4557  temp += (uint64_t) r[8];
4558  r[8] = (uint32_t) temp;
4559  temp >>= 32;
4560  temp += (uint64_t) r[9];
4561  r[9] = (uint32_t) temp;
4562  temp >>= 32;
4563  temp += (uint64_t) r[10];
4564  r[10] = (uint32_t) temp;
4565  temp >>= 32;
4566  temp += (uint64_t) r[11];
4567  r[11] = (uint32_t) temp;
4568  temp >>= 32;
4569  temp += (uint64_t) r[12];
4570  r[12] = (uint32_t) temp;
4571  temp >>= 32;
4572  temp += (uint64_t) r[13];
4573  r[13] = (uint32_t) temp;
4574  temp >>= 32;
4575  temp += (uint64_t) r[14];
4576  r[14] = (uint32_t) temp;
4577  temp >>= 32;
4578  temp += (uint64_t) r[15];
4579  r[15] = (uint32_t) temp;
4580  temp >>= 32;
4581  temp += (uint64_t) r[16] & 0x1FF;
4582  r[16] = (uint32_t) temp & 0x1FF;
4583 
4584  //Reduce non-canonical values
4585  ecFieldCanonicalize(curve, r, r);
4586 }
4587 
4588 
4589 /**
4590  * @brief Field modular inversion (secp521r1 curve)
4591  * @param[in] curve Elliptic curve parameters
4592  * @param[out] r Resulting integer R = A^-1 mod p
4593  * @param[in] a An integer such as 0 <= A < p
4594  **/
4595 
4596 void secp521r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4597 {
4598  uint32_t u[17];
4599  uint32_t v[17];
4600 
4601  //Since GF(p) is a prime field, the Fermat's little theorem can be
4602  //used to find the multiplicative inverse of A modulo p
4603  ecFieldSqrMod(curve, u, a);
4604  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
4605  ecFieldPwr2Mod(curve, v, u, 2);
4606  ecFieldMulMod(curve, u, u, v); //A^(2^4 - 1)
4607  ecFieldPwr2Mod(curve, v, u, 4);
4608  ecFieldMulMod(curve, u, u, v); //A^(2^8 - 1)
4609  ecFieldPwr2Mod(curve, v, u, 8);
4610  ecFieldMulMod(curve, u, u, v); //A^(2^16 - 1)
4611  ecFieldPwr2Mod(curve, v, u, 16);
4612  ecFieldMulMod(curve, u, u, v); //A^(2^32 - 1)
4613  ecFieldPwr2Mod(curve, v, u, 32);
4614  ecFieldMulMod(curve, u, u, v); //A^(2^64 - 1)
4615  ecFieldPwr2Mod(curve, v, u, 64);
4616  ecFieldMulMod(curve, u, u, v); //A^(2^128 - 1)
4617  ecFieldSqrMod(curve, u, u);
4618  ecFieldMulMod(curve, u, u, a); //A^(2^129 - 1)
4619  ecFieldPwr2Mod(curve, v, u, 129);
4620  ecFieldMulMod(curve, u, u, v); //A^(2^258 - 1)
4621  ecFieldSqrMod(curve, u, u);
4622  ecFieldMulMod(curve, u, u, a); //A^(2^259 - 1)
4623  ecFieldPwr2Mod(curve, v, u, 259);
4624  ecFieldMulMod(curve, u, u, v); //A^(2^518 - 1)
4625  ecFieldSqrMod(curve, u, u);
4626  ecFieldMulMod(curve, u, u, a); //A^(2^519 - 1)
4627  ecFieldPwr2Mod(curve, u, u, 2);
4628  ecFieldMulMod(curve, r, u, a); //A^(2^521 - 3)
4629 }
4630 
4631 
4632 /**
4633  * @brief Scalar modular reduction (secp521r1 curve)
4634  * @param[in] curve Elliptic curve parameters
4635  * @param[out] r Resulting integer R = A mod q
4636  * @param[in] a An integer such as 0 <= A < q^2
4637  **/
4638 
4639 void secp521r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4640 {
4641  uint32_t c;
4642  uint32_t a2[33];
4643  uint32_t q2[17];
4644  uint32_t u[17];
4645  uint32_t v[17];
4646 
4647  //Compute a = a << 7
4648  ecScalarShiftLeft(a2, a, 7, 33);
4649  //Compute q = q << 7
4650  ecScalarShiftLeft(q2, curve->q, 7, 17);
4651 
4652  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4653  ecScalarMul(NULL, u, a2 + 16, curve->qmu, 17);
4654  //Compute v = u * q mod b^(k + 1)
4655  ecScalarMul(v, NULL, u, q2, 17);
4656 
4657  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4658  //If u < 0, then u = u + b^(k + 1)
4659  ecScalarSub(u, a2, v, 17);
4660 
4661  //This estimation implies that at most two subtractions of q are required to
4662  //obtain the correct remainder r
4663  c = ecScalarSub(v, u, q2, 17);
4664  ecScalarSelect(u, v, u, c, 17);
4665  c = ecScalarSub(v, u, q2, 17);
4666  ecScalarSelect(u, v, u, c, 17);
4667 
4668  //Compute a = u >> 7
4669  ecScalarShiftRight(r, u, 7, 17);
4670 }
4671 
4672 
4673 /**
4674  * @brief Scalar modular inversion (secp521r1 curve)
4675  * @param[in] curve Elliptic curve parameters
4676  * @param[out] r Resulting integer R = A^-1 mod q
4677  * @param[in] a An integer such as 0 <= A < q
4678  **/
4679 
4680 void secp521r1ScalarInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4681 {
4682  int_t i;
4683  uint32_t u[17];
4684  uint32_t v[17];
4685 
4686  //Process bits 520...259
4687  ecScalarSqrMod(curve, u, a);
4688  ecScalarMulMod(curve, u, u, a); //A^(2^2 - 1)
4689  ecScalarPwr2Mod(curve, v, u, 2);
4690  ecScalarMulMod(curve, u, u, v); //A^(2^4 - 1)
4691  ecScalarPwr2Mod(curve, v, u, 4);
4692  ecScalarMulMod(curve, u, u, v); //A^(2^8 - 1)
4693  ecScalarPwr2Mod(curve, v, u, 8);
4694  ecScalarMulMod(curve, u, u, v); //A^(2^16 - 1)
4695  ecScalarPwr2Mod(curve, v, u, 16);
4696  ecScalarMulMod(curve, u, u, v); //A^(2^32 - 1)
4697  ecScalarPwr2Mod(curve, v, u, 32);
4698  ecScalarMulMod(curve, u, u, v); //A^(2^64 - 1)
4699  ecScalarSqrMod(curve, u, u);
4700  ecScalarMulMod(curve, u, u, a); //A^(2^65 - 1)
4701  ecScalarPwr2Mod(curve, v, u, 65);
4702  ecScalarMulMod(curve, u, u, v); //A^(2^130 - 1)
4703  ecScalarSqrMod(curve, u, u);
4704  ecScalarMulMod(curve, u, u, a); //A^(2^131 - 1)
4705  ecScalarPwr2Mod(curve, v, u, 131);
4706  ecScalarMulMod(curve, u, u, v); //A^(2^262 - 1)
4707 
4708  //Process bits 258..4
4709  for(i = 258; i >= 4; i--)
4710  {
4711  //Calculate U = U^2
4712  ecScalarSqrMod(curve, u, u);
4713 
4714  //Check the value of q(i)
4715  if(((curve->q[i / 32] >> (i % 32)) & 1) != 0)
4716  {
4717  //Calculate U = U * A
4718  ecScalarMulMod(curve, u, u, a);
4719  }
4720  }
4721 
4722  //Process bits 3..0
4723  ecScalarSqrMod(curve, u, u);
4724  ecScalarSqrMod(curve, u, u);
4725  ecScalarMulMod(curve, u, u, a);
4726  ecScalarSqrMod(curve, u, u);
4727  ecScalarMulMod(curve, u, u, a);
4728  ecScalarSqrMod(curve, u, u);
4729  ecScalarMulMod(curve, r, u, a);
4730 }
4731 
4732 #endif
4733 #if (BRAINPOOLP160R1_SUPPORT == ENABLED)
4734 
4735 /**
4736  * @brief Field modular reduction (brainpoolP160r1 curve)
4737  * @param[in] curve Elliptic curve parameters
4738  * @param[out] r Resulting integer R = A mod p
4739  * @param[in] a An integer such as 0 <= A < p^2
4740  **/
4741 
4742 void brainpoolP160r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4743 {
4744  uint32_t c;
4745  uint32_t u[6];
4746  uint32_t v[6];
4747 
4748  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4749  ecScalarMul(NULL, u, a + 4, curve->pmu, 6);
4750  //Compute v = u * p mod b^(k + 1)
4751  ecScalarMul(v, NULL, u, curve->p, 6);
4752 
4753  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4754  //If u < 0, then u = u + b^(k + 1)
4755  ecScalarSub(u, a, v, 6);
4756 
4757  //This estimation implies that at most two subtractions of p are required to
4758  //obtain the correct remainder r
4759  c = ecScalarSub(v, u, curve->p, 6);
4760  ecScalarSelect(u, v, u, c, 6);
4761  c = ecScalarSub(v, u, curve->p, 6);
4762  ecScalarSelect(r, v, u, c, 5);
4763 }
4764 
4765 
4766 /**
4767  * @brief Scalar modular reduction (brainpoolP160r1 curve)
4768  * @param[in] curve Elliptic curve parameters
4769  * @param[out] r Resulting integer R = A mod q
4770  * @param[in] a An integer such as 0 <= A < q^2
4771  **/
4772 
4773 void brainpoolP160r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4774 {
4775  uint32_t c;
4776  uint32_t u[6];
4777  uint32_t v[6];
4778 
4779  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4780  ecScalarMul(NULL, u, a + 4, curve->qmu, 6);
4781  //Compute v = u * q mod b^(k + 1)
4782  ecScalarMul(v, NULL, u, curve->q, 6);
4783 
4784  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4785  //If u < 0, then u = u + b^(k + 1)
4786  ecScalarSub(u, a, v, 6);
4787 
4788  //This estimation implies that at most two subtractions of q are required to
4789  //obtain the correct remainder r
4790  c = ecScalarSub(v, u, curve->q, 6);
4791  ecScalarSelect(u, v, u, c, 6);
4792  c = ecScalarSub(v, u, curve->q, 6);
4793  ecScalarSelect(r, v, u, c, 5);
4794 }
4795 
4796 #endif
4797 #if (BRAINPOOLP160T1_SUPPORT == ENABLED)
4798 
4799 /**
4800  * @brief Field modular reduction (brainpoolP160t1 curve)
4801  * @param[in] curve Elliptic curve parameters
4802  * @param[out] r Resulting integer R = A mod p
4803  * @param[in] a An integer such as 0 <= A < p^2
4804  **/
4805 
4806 void brainpoolP160t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4807 {
4808  uint32_t c;
4809  uint32_t u[6];
4810  uint32_t v[6];
4811 
4812  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4813  ecScalarMul(NULL, u, a + 4, curve->pmu, 6);
4814  //Compute v = u * p mod b^(k + 1)
4815  ecScalarMul(v, NULL, u, curve->p, 6);
4816 
4817  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4818  //If u < 0, then u = u + b^(k + 1)
4819  ecScalarSub(u, a, v, 6);
4820 
4821  //This estimation implies that at most two subtractions of p are required to
4822  //obtain the correct remainder r
4823  c = ecScalarSub(v, u, curve->p, 6);
4824  ecScalarSelect(u, v, u, c, 6);
4825  c = ecScalarSub(v, u, curve->p, 6);
4826  ecScalarSelect(r, v, u, c, 5);
4827 }
4828 
4829 
4830 /**
4831  * @brief Scalar modular reduction (brainpoolP160t1 curve)
4832  * @param[in] curve Elliptic curve parameters
4833  * @param[out] r Resulting integer R = A mod q
4834  * @param[in] a An integer such as 0 <= A < q^2
4835  **/
4836 
4837 void brainpoolP160t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4838 {
4839  uint32_t c;
4840  uint32_t u[6];
4841  uint32_t v[6];
4842 
4843  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4844  ecScalarMul(NULL, u, a + 4, curve->qmu, 6);
4845  //Compute v = u * q mod b^(k + 1)
4846  ecScalarMul(v, NULL, u, curve->q, 6);
4847 
4848  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4849  //If u < 0, then u = u + b^(k + 1)
4850  ecScalarSub(u, a, v, 6);
4851 
4852  //This estimation implies that at most two subtractions of q are required to
4853  //obtain the correct remainder r
4854  c = ecScalarSub(v, u, curve->q, 6);
4855  ecScalarSelect(u, v, u, c, 6);
4856  c = ecScalarSub(v, u, curve->q, 6);
4857  ecScalarSelect(r, v, u, c, 5);
4858 }
4859 
4860 #endif
4861 #if (BRAINPOOLP192R1_SUPPORT == ENABLED)
4862 
4863 /**
4864  * @brief Field modular reduction (brainpoolP192r1 curve)
4865  * @param[in] curve Elliptic curve parameters
4866  * @param[out] r Resulting integer R = A mod p
4867  * @param[in] a An integer such as 0 <= A < p^2
4868  **/
4869 
4870 void brainpoolP192r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4871 {
4872  uint32_t c;
4873  uint32_t u[7];
4874  uint32_t v[7];
4875 
4876  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4877  ecScalarMul(NULL, u, a + 5, curve->pmu, 7);
4878  //Compute v = u * p mod b^(k + 1)
4879  ecScalarMul(v, NULL, u, curve->p, 7);
4880 
4881  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4882  //If u < 0, then u = u + b^(k + 1)
4883  ecScalarSub(u, a, v, 7);
4884 
4885  //This estimation implies that at most two subtractions of p are required to
4886  //obtain the correct remainder r
4887  c = ecScalarSub(v, u, curve->p, 7);
4888  ecScalarSelect(u, v, u, c, 7);
4889  c = ecScalarSub(v, u, curve->p, 7);
4890  ecScalarSelect(r, v, u, c, 6);
4891 }
4892 
4893 
4894 /**
4895  * @brief Scalar modular reduction (brainpoolP192r1 curve)
4896  * @param[in] curve Elliptic curve parameters
4897  * @param[out] r Resulting integer R = A mod q
4898  * @param[in] a An integer such as 0 <= A < q^2
4899  **/
4900 
4901 void brainpoolP192r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4902 {
4903  uint32_t c;
4904  uint32_t u[7];
4905  uint32_t v[7];
4906 
4907  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4908  ecScalarMul(NULL, u, a + 5, curve->qmu, 7);
4909  //Compute v = u * q mod b^(k + 1)
4910  ecScalarMul(v, NULL, u, curve->q, 7);
4911 
4912  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4913  //If u < 0, then u = u + b^(k + 1)
4914  ecScalarSub(u, a, v, 7);
4915 
4916  //This estimation implies that at most two subtractions of q are required to
4917  //obtain the correct remainder r
4918  c = ecScalarSub(v, u, curve->q, 7);
4919  ecScalarSelect(u, v, u, c, 7);
4920  c = ecScalarSub(v, u, curve->q, 7);
4921  ecScalarSelect(r, v, u, c, 6);
4922 }
4923 
4924 #endif
4925 #if (BRAINPOOLP192T1_SUPPORT == ENABLED)
4926 
4927 /**
4928  * @brief Field modular reduction (brainpoolP192t1 curve)
4929  * @param[in] curve Elliptic curve parameters
4930  * @param[out] r Resulting integer R = A mod p
4931  * @param[in] a An integer such as 0 <= A < p^2
4932  **/
4933 
4934 void brainpoolP192t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4935 {
4936  uint32_t c;
4937  uint32_t u[7];
4938  uint32_t v[7];
4939 
4940  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4941  ecScalarMul(NULL, u, a + 5, curve->pmu, 7);
4942  //Compute v = u * p mod b^(k + 1)
4943  ecScalarMul(v, NULL, u, curve->p, 7);
4944 
4945  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4946  //If u < 0, then u = u + b^(k + 1)
4947  ecScalarSub(u, a, v, 7);
4948 
4949  //This estimation implies that at most two subtractions of p are required to
4950  //obtain the correct remainder r
4951  c = ecScalarSub(v, u, curve->p, 7);
4952  ecScalarSelect(u, v, u, c, 7);
4953  c = ecScalarSub(v, u, curve->p, 7);
4954  ecScalarSelect(r, v, u, c, 6);
4955 }
4956 
4957 
4958 /**
4959  * @brief Scalar modular reduction (brainpoolP192t1 curve)
4960  * @param[in] curve Elliptic curve parameters
4961  * @param[out] r Resulting integer R = A mod q
4962  * @param[in] a An integer such as 0 <= A < q^2
4963  **/
4964 
4965 void brainpoolP192t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4966 {
4967  uint32_t c;
4968  uint32_t u[7];
4969  uint32_t v[7];
4970 
4971  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
4972  ecScalarMul(NULL, u, a + 5, curve->qmu, 7);
4973  //Compute v = u * q mod b^(k + 1)
4974  ecScalarMul(v, NULL, u, curve->q, 7);
4975 
4976  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
4977  //If u < 0, then u = u + b^(k + 1)
4978  ecScalarSub(u, a, v, 7);
4979 
4980  //This estimation implies that at most two subtractions of q are required to
4981  //obtain the correct remainder r
4982  c = ecScalarSub(v, u, curve->q, 7);
4983  ecScalarSelect(u, v, u, c, 7);
4984  c = ecScalarSub(v, u, curve->q, 7);
4985  ecScalarSelect(r, v, u, c, 6);
4986 }
4987 
4988 #endif
4989 #if (BRAINPOOLP224R1_SUPPORT == ENABLED)
4990 
4991 /**
4992  * @brief Field modular reduction (brainpoolP224r1 curve)
4993  * @param[in] curve Elliptic curve parameters
4994  * @param[out] r Resulting integer R = A mod p
4995  * @param[in] a An integer such as 0 <= A < p^2
4996  **/
4997 
4998 void brainpoolP224r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
4999 {
5000  uint32_t c;
5001  uint32_t u[8];
5002  uint32_t v[8];
5003 
5004  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5005  ecScalarMul(NULL, u, a + 6, curve->pmu, 8);
5006  //Compute v = u * p mod b^(k + 1)
5007  ecScalarMul(v, NULL, u, curve->p, 8);
5008 
5009  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5010  //If u < 0, then u = u + b^(k + 1)
5011  ecScalarSub(u, a, v, 8);
5012 
5013  //This estimation implies that at most two subtractions of p are required to
5014  //obtain the correct remainder r
5015  c = ecScalarSub(v, u, curve->p, 8);
5016  ecScalarSelect(u, v, u, c, 8);
5017  c = ecScalarSub(v, u, curve->p, 8);
5018  ecScalarSelect(r, v, u, c, 7);
5019 }
5020 
5021 
5022 /**
5023  * @brief Scalar modular reduction (brainpoolP224r1 curve)
5024  * @param[in] curve Elliptic curve parameters
5025  * @param[out] r Resulting integer R = A mod q
5026  * @param[in] a An integer such as 0 <= A < q^2
5027  **/
5028 
5029 void brainpoolP224r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5030 {
5031  uint32_t c;
5032  uint32_t u[8];
5033  uint32_t v[8];
5034 
5035  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5036  ecScalarMul(NULL, u, a + 6, curve->qmu, 8);
5037  //Compute v = u * q mod b^(k + 1)
5038  ecScalarMul(v, NULL, u, curve->q, 8);
5039 
5040  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5041  //If u < 0, then u = u + b^(k + 1)
5042  ecScalarSub(u, a, v, 8);
5043 
5044  //This estimation implies that at most two subtractions of q are required to
5045  //obtain the correct remainder r
5046  c = ecScalarSub(v, u, curve->q, 8);
5047  ecScalarSelect(u, v, u, c, 8);
5048  c = ecScalarSub(v, u, curve->q, 8);
5049  ecScalarSelect(r, v, u, c, 7);
5050 }
5051 
5052 #endif
5053 #if (BRAINPOOLP224T1_SUPPORT == ENABLED)
5054 
5055 /**
5056  * @brief Field modular reduction (brainpoolP224t1 curve)
5057  * @param[in] curve Elliptic curve parameters
5058  * @param[out] r Resulting integer R = A mod p
5059  * @param[in] a An integer such as 0 <= A < p^2
5060  **/
5061 
5062 void brainpoolP224t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5063 {
5064  uint32_t c;
5065  uint32_t u[8];
5066  uint32_t v[8];
5067 
5068  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5069  ecScalarMul(NULL, u, a + 6, curve->pmu, 8);
5070  //Compute v = u * p mod b^(k + 1)
5071  ecScalarMul(v, NULL, u, curve->p, 8);
5072 
5073  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5074  //If u < 0, then u = u + b^(k + 1)
5075  ecScalarSub(u, a, v, 8);
5076 
5077  //This estimation implies that at most two subtractions of p are required to
5078  //obtain the correct remainder r
5079  c = ecScalarSub(v, u, curve->p, 8);
5080  ecScalarSelect(u, v, u, c, 8);
5081  c = ecScalarSub(v, u, curve->p, 8);
5082  ecScalarSelect(r, v, u, c, 7);
5083 }
5084 
5085 
5086 /**
5087  * @brief Scalar modular reduction (brainpoolP224t1 curve)
5088  * @param[in] curve Elliptic curve parameters
5089  * @param[out] r Resulting integer R = A mod q
5090  * @param[in] a An integer such as 0 <= A < q^2
5091  **/
5092 
5093 void brainpoolP224t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5094 {
5095  uint32_t c;
5096  uint32_t u[8];
5097  uint32_t v[8];
5098 
5099  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5100  ecScalarMul(NULL, u, a + 6, curve->qmu, 8);
5101  //Compute v = u * q mod b^(k + 1)
5102  ecScalarMul(v, NULL, u, curve->q, 8);
5103 
5104  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5105  //If u < 0, then u = u + b^(k + 1)
5106  ecScalarSub(u, a, v, 8);
5107 
5108  //This estimation implies that at most two subtractions of q are required to
5109  //obtain the correct remainder r
5110  c = ecScalarSub(v, u, curve->q, 8);
5111  ecScalarSelect(u, v, u, c, 8);
5112  c = ecScalarSub(v, u, curve->q, 8);
5113  ecScalarSelect(r, v, u, c, 7);
5114 }
5115 
5116 #endif
5117 #if (BRAINPOOLP256R1_SUPPORT == ENABLED)
5118 
5119 /**
5120  * @brief Field modular reduction (brainpoolP256r1 curve)
5121  * @param[in] curve Elliptic curve parameters
5122  * @param[out] r Resulting integer R = A mod p
5123  * @param[in] a An integer such as 0 <= A < p^2
5124  **/
5125 
5126 void brainpoolP256r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5127 {
5128  uint32_t c;
5129  uint32_t u[9];
5130  uint32_t v[9];
5131 
5132  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5133  ecScalarMul(NULL, u, a + 7, curve->pmu, 9);
5134  //Compute v = u * p mod b^(k + 1)
5135  ecScalarMul(v, NULL, u, curve->p, 9);
5136 
5137  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5138  //If u < 0, then u = u + b^(k + 1)
5139  ecScalarSub(u, a, v, 9);
5140 
5141  //This estimation implies that at most two subtractions of p are required to
5142  //obtain the correct remainder r
5143  c = ecScalarSub(v, u, curve->p, 9);
5144  ecScalarSelect(u, v, u, c, 9);
5145  c = ecScalarSub(v, u, curve->p, 9);
5146  ecScalarSelect(r, v, u, c, 8);
5147 }
5148 
5149 
5150 /**
5151  * @brief Scalar modular reduction (brainpoolP256r1 curve)
5152  * @param[in] curve Elliptic curve parameters
5153  * @param[out] r Resulting integer R = A mod q
5154  * @param[in] a An integer such as 0 <= A < q^2
5155  **/
5156 
5157 void brainpoolP256r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5158 {
5159  uint32_t c;
5160  uint32_t u[9];
5161  uint32_t v[9];
5162 
5163  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5164  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
5165  //Compute v = u * q mod b^(k + 1)
5166  ecScalarMul(v, NULL, u, curve->q, 9);
5167 
5168  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5169  //If u < 0, then u = u + b^(k + 1)
5170  ecScalarSub(u, a, v, 9);
5171 
5172  //This estimation implies that at most two subtractions of q are required to
5173  //obtain the correct remainder r
5174  c = ecScalarSub(v, u, curve->q, 9);
5175  ecScalarSelect(u, v, u, c, 9);
5176  c = ecScalarSub(v, u, curve->q, 9);
5177  ecScalarSelect(r, v, u, c, 8);
5178 }
5179 
5180 #endif
5181 #if (BRAINPOOLP256T1_SUPPORT == ENABLED)
5182 
5183 /**
5184  * @brief Field modular reduction (brainpoolP256t1 curve)
5185  * @param[in] curve Elliptic curve parameters
5186  * @param[out] r Resulting integer R = A mod p
5187  * @param[in] a An integer such as 0 <= A < p^2
5188  **/
5189 
5190 void brainpoolP256t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5191 {
5192  uint32_t c;
5193  uint32_t u[9];
5194  uint32_t v[9];
5195 
5196  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5197  ecScalarMul(NULL, u, a + 7, curve->pmu, 9);
5198  //Compute v = u * p mod b^(k + 1)
5199  ecScalarMul(v, NULL, u, curve->p, 9);
5200 
5201  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5202  //If u < 0, then u = u + b^(k + 1)
5203  ecScalarSub(u, a, v, 9);
5204 
5205  //This estimation implies that at most two subtractions of p are required to
5206  //obtain the correct remainder r
5207  c = ecScalarSub(v, u, curve->p, 9);
5208  ecScalarSelect(u, v, u, c, 9);
5209  c = ecScalarSub(v, u, curve->p, 9);
5210  ecScalarSelect(r, v, u, c, 8);
5211 }
5212 
5213 
5214 /**
5215  * @brief Scalar modular reduction (brainpoolP256t1 curve)
5216  * @param[in] curve Elliptic curve parameters
5217  * @param[out] r Resulting integer R = A mod q
5218  * @param[in] a An integer such as 0 <= A < q^2
5219  **/
5220 
5221 void brainpoolP256t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5222 {
5223  uint32_t c;
5224  uint32_t u[9];
5225  uint32_t v[9];
5226 
5227  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5228  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
5229  //Compute v = u * q mod b^(k + 1)
5230  ecScalarMul(v, NULL, u, curve->q, 9);
5231 
5232  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5233  //If u < 0, then u = u + b^(k + 1)
5234  ecScalarSub(u, a, v, 9);
5235 
5236  //This estimation implies that at most two subtractions of q are required to
5237  //obtain the correct remainder r
5238  c = ecScalarSub(v, u, curve->q, 9);
5239  ecScalarSelect(u, v, u, c, 9);
5240  c = ecScalarSub(v, u, curve->q, 9);
5241  ecScalarSelect(r, v, u, c, 8);
5242 }
5243 
5244 #endif
5245 #if (BRAINPOOLP320R1_SUPPORT == ENABLED)
5246 
5247 /**
5248  * @brief Field modular reduction (brainpoolP320r1 curve)
5249  * @param[in] curve Elliptic curve parameters
5250  * @param[out] r Resulting integer R = A mod p
5251  * @param[in] a An integer such as 0 <= A < p^2
5252  **/
5253 
5254 void brainpoolP320r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5255 {
5256  uint32_t c;
5257  uint32_t u[11];
5258  uint32_t v[11];
5259 
5260  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5261  ecScalarMul(NULL, u, a + 9, curve->pmu, 11);
5262  //Compute v = u * p mod b^(k + 1)
5263  ecScalarMul(v, NULL, u, curve->p, 11);
5264 
5265  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5266  //If u < 0, then u = u + b^(k + 1)
5267  ecScalarSub(u, a, v, 11);
5268 
5269  //This estimation implies that at most two subtractions of p are required to
5270  //obtain the correct remainder r
5271  c = ecScalarSub(v, u, curve->p, 11);
5272  ecScalarSelect(u, v, u, c, 11);
5273  c = ecScalarSub(v, u, curve->p, 11);
5274  ecScalarSelect(r, v, u, c, 10);
5275 }
5276 
5277 
5278 /**
5279  * @brief Scalar modular reduction (brainpoolP320r1 curve)
5280  * @param[in] curve Elliptic curve parameters
5281  * @param[out] r Resulting integer R = A mod q
5282  * @param[in] a An integer such as 0 <= A < q^2
5283  **/
5284 
5285 void brainpoolP320r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5286 {
5287  uint32_t c;
5288  uint32_t u[11];
5289  uint32_t v[11];
5290 
5291  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5292  ecScalarMul(NULL, u, a + 9, curve->qmu, 11);
5293  //Compute v = u * q mod b^(k + 1)
5294  ecScalarMul(v, NULL, u, curve->q, 11);
5295 
5296  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5297  //If u < 0, then u = u + b^(k + 1)
5298  ecScalarSub(u, a, v, 11);
5299 
5300  //This estimation implies that at most two subtractions of q are required to
5301  //obtain the correct remainder r
5302  c = ecScalarSub(v, u, curve->q, 11);
5303  ecScalarSelect(u, v, u, c, 11);
5304  c = ecScalarSub(v, u, curve->q, 11);
5305  ecScalarSelect(r, v, u, c, 10);
5306 }
5307 
5308 #endif
5309 #if (BRAINPOOLP320T1_SUPPORT == ENABLED)
5310 
5311 /**
5312  * @brief Field modular reduction (brainpoolP320t1 curve)
5313  * @param[in] curve Elliptic curve parameters
5314  * @param[out] r Resulting integer R = A mod p
5315  * @param[in] a An integer such as 0 <= A < p^2
5316  **/
5317 
5318 void brainpoolP320t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5319 {
5320  uint32_t c;
5321  uint32_t u[11];
5322  uint32_t v[11];
5323 
5324  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5325  ecScalarMul(NULL, u, a + 9, curve->pmu, 11);
5326  //Compute v = u * p mod b^(k + 1)
5327  ecScalarMul(v, NULL, u, curve->p, 11);
5328 
5329  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5330  //If u < 0, then u = u + b^(k + 1)
5331  ecScalarSub(u, a, v, 11);
5332 
5333  //This estimation implies that at most two subtractions of p are required to
5334  //obtain the correct remainder r
5335  c = ecScalarSub(v, u, curve->p, 11);
5336  ecScalarSelect(u, v, u, c, 11);
5337  c = ecScalarSub(v, u, curve->p, 11);
5338  ecScalarSelect(r, v, u, c, 10);
5339 }
5340 
5341 
5342 /**
5343  * @brief Scalar modular reduction (brainpoolP320t1 curve)
5344  * @param[in] curve Elliptic curve parameters
5345  * @param[out] r Resulting integer R = A mod q
5346  * @param[in] a An integer such as 0 <= A < q^2
5347  **/
5348 
5349 void brainpoolP320t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5350 {
5351  uint32_t c;
5352  uint32_t u[11];
5353  uint32_t v[11];
5354 
5355  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5356  ecScalarMul(NULL, u, a + 9, curve->qmu, 11);
5357  //Compute v = u * q mod b^(k + 1)
5358  ecScalarMul(v, NULL, u, curve->q, 11);
5359 
5360  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5361  //If u < 0, then u = u + b^(k + 1)
5362  ecScalarSub(u, a, v, 11);
5363 
5364  //This estimation implies that at most two subtractions of q are required to
5365  //obtain the correct remainder r
5366  c = ecScalarSub(v, u, curve->q, 11);
5367  ecScalarSelect(u, v, u, c, 11);
5368  c = ecScalarSub(v, u, curve->q, 11);
5369  ecScalarSelect(r, v, u, c, 10);
5370 }
5371 
5372 #endif
5373 #if (BRAINPOOLP384R1_SUPPORT == ENABLED)
5374 
5375 /**
5376  * @brief Field modular reduction (brainpoolP384r1 curve)
5377  * @param[in] curve Elliptic curve parameters
5378  * @param[out] r Resulting integer R = A mod p
5379  * @param[in] a An integer such as 0 <= A < p^2
5380  **/
5381 
5382 void brainpoolP384r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5383 {
5384  uint32_t c;
5385  uint32_t u[13];
5386  uint32_t v[13];
5387 
5388  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5389  ecScalarMul(NULL, u, a + 11, curve->pmu, 13);
5390  //Compute v = u * p mod b^(k + 1)
5391  ecScalarMul(v, NULL, u, curve->p, 13);
5392 
5393  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5394  //If u < 0, then u = u + b^(k + 1)
5395  ecScalarSub(u, a, v, 13);
5396 
5397  //This estimation implies that at most two subtractions of p are required to
5398  //obtain the correct remainder r
5399  c = ecScalarSub(v, u, curve->p, 13);
5400  ecScalarSelect(u, v, u, c, 13);
5401  c = ecScalarSub(v, u, curve->p, 13);
5402  ecScalarSelect(r, v, u, c, 12);
5403 }
5404 
5405 
5406 /**
5407  * @brief Scalar modular reduction (brainpoolP384r1 curve)
5408  * @param[in] curve Elliptic curve parameters
5409  * @param[out] r Resulting integer R = A mod q
5410  * @param[in] a An integer such as 0 <= A < q^2
5411  **/
5412 
5413 void brainpoolP384r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5414 {
5415  uint32_t c;
5416  uint32_t u[13];
5417  uint32_t v[13];
5418 
5419  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5420  ecScalarMul(NULL, u, a + 11, curve->qmu, 13);
5421  //Compute v = u * q mod b^(k + 1)
5422  ecScalarMul(v, NULL, u, curve->q, 13);
5423 
5424  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5425  //If u < 0, then u = u + b^(k + 1)
5426  ecScalarSub(u, a, v, 13);
5427 
5428  //This estimation implies that at most two subtractions of q are required to
5429  //obtain the correct remainder r
5430  c = ecScalarSub(v, u, curve->q, 13);
5431  ecScalarSelect(u, v, u, c, 13);
5432  c = ecScalarSub(v, u, curve->q, 13);
5433  ecScalarSelect(r, v, u, c, 12);
5434 }
5435 
5436 #endif
5437 #if (BRAINPOOLP384T1_SUPPORT == ENABLED)
5438 
5439 /**
5440  * @brief Field modular reduction (brainpoolP384t1 curve)
5441  * @param[in] curve Elliptic curve parameters
5442  * @param[out] r Resulting integer R = A mod p
5443  * @param[in] a An integer such as 0 <= A < p^2
5444  **/
5445 
5446 void brainpoolP384t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5447 {
5448  uint32_t c;
5449  uint32_t u[13];
5450  uint32_t v[13];
5451 
5452  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5453  ecScalarMul(NULL, u, a + 11, curve->pmu, 13);
5454  //Compute v = u * p mod b^(k + 1)
5455  ecScalarMul(v, NULL, u, curve->p, 13);
5456 
5457  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5458  //If u < 0, then u = u + b^(k + 1)
5459  ecScalarSub(u, a, v, 13);
5460 
5461  //This estimation implies that at most two subtractions of p are required to
5462  //obtain the correct remainder r
5463  c = ecScalarSub(v, u, curve->p, 13);
5464  ecScalarSelect(u, v, u, c, 13);
5465  c = ecScalarSub(v, u, curve->p, 13);
5466  ecScalarSelect(r, v, u, c, 12);
5467 }
5468 
5469 
5470 /**
5471  * @brief Scalar modular reduction (brainpoolP384t1 curve)
5472  * @param[in] curve Elliptic curve parameters
5473  * @param[out] r Resulting integer R = A mod q
5474  * @param[in] a An integer such as 0 <= A < q^2
5475  **/
5476 
5477 void brainpoolP384t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5478 {
5479  uint32_t c;
5480  uint32_t u[13];
5481  uint32_t v[13];
5482 
5483  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5484  ecScalarMul(NULL, u, a + 11, curve->qmu, 13);
5485  //Compute v = u * q mod b^(k + 1)
5486  ecScalarMul(v, NULL, u, curve->q, 13);
5487 
5488  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5489  //If u < 0, then u = u + b^(k + 1)
5490  ecScalarSub(u, a, v, 13);
5491 
5492  //This estimation implies that at most two subtractions of q are required to
5493  //obtain the correct remainder r
5494  c = ecScalarSub(v, u, curve->q, 13);
5495  ecScalarSelect(u, v, u, c, 13);
5496  c = ecScalarSub(v, u, curve->q, 13);
5497  ecScalarSelect(r, v, u, c, 12);
5498 }
5499 
5500 #endif
5501 #if (BRAINPOOLP512R1_SUPPORT == ENABLED)
5502 
5503 /**
5504  * @brief Field modular reduction (brainpoolP512r1 curve)
5505  * @param[in] curve Elliptic curve parameters
5506  * @param[out] r Resulting integer R = A mod p
5507  * @param[in] a An integer such as 0 <= A < p^2
5508  **/
5509 
5510 void brainpoolP512r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5511 {
5512  uint32_t c;
5513  uint32_t u[17];
5514  uint32_t v[17];
5515 
5516  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5517  ecScalarMul(NULL, u, a + 15, curve->pmu, 17);
5518  //Compute v = u * p mod b^(k + 1)
5519  ecScalarMul(v, NULL, u, curve->p, 17);
5520 
5521  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5522  //If u < 0, then u = u + b^(k + 1)
5523  ecScalarSub(u, a, v, 17);
5524 
5525  //This estimation implies that at most two subtractions of p are required to
5526  //obtain the correct remainder r
5527  c = ecScalarSub(v, u, curve->p, 17);
5528  ecScalarSelect(u, v, u, c, 17);
5529  c = ecScalarSub(v, u, curve->p, 17);
5530  ecScalarSelect(r, v, u, c, 16);
5531 }
5532 
5533 
5534 /**
5535  * @brief Scalar modular reduction (brainpoolP512r1 curve)
5536  * @param[in] curve Elliptic curve parameters
5537  * @param[out] r Resulting integer R = A mod q
5538  * @param[in] a An integer such as 0 <= A < q^2
5539  **/
5540 
5541 void brainpoolP512r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5542 {
5543  uint32_t c;
5544  uint32_t u[17];
5545  uint32_t v[17];
5546 
5547  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5548  ecScalarMul(NULL, u, a + 15, curve->qmu, 17);
5549  //Compute v = u * q mod b^(k + 1)
5550  ecScalarMul(v, NULL, u, curve->q, 17);
5551 
5552  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5553  //If u < 0, then u = u + b^(k + 1)
5554  ecScalarSub(u, a, v, 17);
5555 
5556  //This estimation implies that at most two subtractions of q are required to
5557  //obtain the correct remainder r
5558  c = ecScalarSub(v, u, curve->q, 17);
5559  ecScalarSelect(u, v, u, c, 17);
5560  c = ecScalarSub(v, u, curve->q, 17);
5561  ecScalarSelect(r, v, u, c, 16);
5562 }
5563 
5564 #endif
5565 #if (BRAINPOOLP512T1_SUPPORT == ENABLED)
5566 
5567 /**
5568  * @brief Field modular reduction (brainpoolP512t1 curve)
5569  * @param[in] curve Elliptic curve parameters
5570  * @param[out] r Resulting integer R = A mod p
5571  * @param[in] a An integer such as 0 <= A < p^2
5572  **/
5573 
5574 void brainpoolP512t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5575 {
5576  uint32_t c;
5577  uint32_t u[17];
5578  uint32_t v[17];
5579 
5580  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5581  ecScalarMul(NULL, u, a + 15, curve->pmu, 17);
5582  //Compute v = u * p mod b^(k + 1)
5583  ecScalarMul(v, NULL, u, curve->p, 17);
5584 
5585  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5586  //If u < 0, then u = u + b^(k + 1)
5587  ecScalarSub(u, a, v, 17);
5588 
5589  //This estimation implies that at most two subtractions of p are required to
5590  //obtain the correct remainder r
5591  c = ecScalarSub(v, u, curve->p, 17);
5592  ecScalarSelect(u, v, u, c, 17);
5593  c = ecScalarSub(v, u, curve->p, 17);
5594  ecScalarSelect(r, v, u, c, 16);
5595 }
5596 
5597 
5598 /**
5599  * @brief Scalar modular reduction (brainpoolP512t1 curve)
5600  * @param[in] curve Elliptic curve parameters
5601  * @param[out] r Resulting integer R = A mod q
5602  * @param[in] a An integer such as 0 <= A < q^2
5603  **/
5604 
5605 void brainpoolP512t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5606 {
5607  uint32_t c;
5608  uint32_t u[17];
5609  uint32_t v[17];
5610 
5611  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5612  ecScalarMul(NULL, u, a + 15, curve->qmu, 17);
5613  //Compute v = u * q mod b^(k + 1)
5614  ecScalarMul(v, NULL, u, curve->q, 17);
5615 
5616  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5617  //If u < 0, then u = u + b^(k + 1)
5618  ecScalarSub(u, a, v, 17);
5619 
5620  //This estimation implies that at most two subtractions of q are required to
5621  //obtain the correct remainder r
5622  c = ecScalarSub(v, u, curve->q, 17);
5623  ecScalarSelect(u, v, u, c, 17);
5624  c = ecScalarSub(v, u, curve->q, 17);
5625  ecScalarSelect(r, v, u, c, 16);
5626 }
5627 
5628 #endif
5629 #if (FRP256V1_SUPPORT == ENABLED)
5630 
5631 /**
5632  * @brief Field modular reduction (FRP256v1 curve)
5633  * @param[in] curve Elliptic curve parameters
5634  * @param[out] r Resulting integer R = A mod p
5635  * @param[in] a An integer such as 0 <= A < p^2
5636  **/
5637 
5638 void frp256v1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5639 {
5640  uint32_t c;
5641  uint32_t u[9];
5642  uint32_t v[9];
5643 
5644  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5645  ecScalarMul(NULL, u, a + 7, curve->pmu, 9);
5646  //Compute v = u * p mod b^(k + 1)
5647  ecScalarMul(v, NULL, u, curve->p, 9);
5648 
5649  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5650  //If u < 0, then u = u + b^(k + 1)
5651  ecScalarSub(u, a, v, 9);
5652 
5653  //This estimation implies that at most two subtractions of p are required to
5654  //obtain the correct remainder r
5655  c = ecScalarSub(v, u, curve->p, 9);
5656  ecScalarSelect(u, v, u, c, 9);
5657  c = ecScalarSub(v, u, curve->p, 9);
5658  ecScalarSelect(r, v, u, c, 8);
5659 }
5660 
5661 
5662 /**
5663  * @brief Scalar modular reduction (FRP256v1 curve)
5664  * @param[in] curve Elliptic curve parameters
5665  * @param[out] r Resulting integer R = A mod q
5666  * @param[in] a An integer such as 0 <= A < q^2
5667  **/
5668 
5669 void frp256v1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5670 {
5671  uint32_t c;
5672  uint32_t u[9];
5673  uint32_t v[9];
5674 
5675  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5676  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
5677  //Compute v = u * q mod b^(k + 1)
5678  ecScalarMul(v, NULL, u, curve->q, 9);
5679 
5680  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5681  //If u < 0, then u = u + b^(k + 1)
5682  ecScalarSub(u, a, v, 9);
5683 
5684  //This estimation implies that at most two subtractions of q are required to
5685  //obtain the correct remainder r
5686  c = ecScalarSub(v, u, curve->q, 9);
5687  ecScalarSelect(u, v, u, c, 9);
5688  c = ecScalarSub(v, u, curve->q, 9);
5689  ecScalarSelect(r, v, u, c, 8);
5690 }
5691 
5692 #endif
5693 #if (SM2_SUPPORT == ENABLED)
5694 
5695 /**
5696  * @brief Field modular reduction (SM2 curve)
5697  * @param[in] curve Elliptic curve parameters
5698  * @param[out] r Resulting integer R = A mod p
5699  * @param[in] a An integer such as 0 <= A < p^2
5700  **/
5701 
5702 void sm2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5703 {
5704  int64_t c;
5705  int64_t temp;
5706 
5707  //First pass
5708  temp = (int64_t) a[0] + a[8] + a[9] + a[10] + a[11] + a[12] + a[13] + a[13];
5709  temp += (int64_t) a[14] + a[14] + a[15] + a[15];
5710  r[0] = (uint32_t) temp;
5711  temp >>= 32;
5712  temp += (int64_t) a[1] + a[9] + a[10] + a[11] + a[12] + a[13] + a[14] + a[14];
5713  temp += (int64_t) a[15] + a[15];
5714  r[1] = (uint32_t) temp;
5715  temp >>= 32;
5716  temp += (int64_t) a[2];
5717  temp -= (int64_t) a[8] + a[9] + a[13] + a[14];
5718  r[2] = (uint32_t) temp;
5719  temp >>= 32;
5720  temp += (int64_t) a[3] + a[8] + a[11] + a[12] + a[13] + a[13] + a[14] + a[15];
5721  r[3] = (uint32_t) temp;
5722  temp >>= 32;
5723  temp += (int64_t) a[4] + a[9] + a[12] + a[13] + a[14] + a[14] + a[15];
5724  r[4] = (uint32_t) temp;
5725  temp >>= 32;
5726  temp += (int64_t) a[5] + a[10] + a[13] + a[14] + a[15] + a[15];
5727  r[5] = (uint32_t) temp;
5728  temp >>= 32;
5729  temp += (int64_t) a[6] + a[11] + a[14] + a[15];
5730  r[6] = (uint32_t) temp;
5731  temp >>= 32;
5732  temp += (int64_t) a[7] + a[8] + a[9] + a[10] + a[11] + a[12] + a[12] + a[13];
5733  temp += (int64_t) a[13] + a[14] + a[14] + a[15] + a[15] + a[15];
5734  r[7] = (uint32_t) temp;
5735  c = temp >> 32;
5736 
5737  //Second pass
5738  temp = (int64_t) r[0] + c;
5739  r[0] = (uint32_t) temp;
5740  temp >>= 32;
5741  temp += (int64_t) r[1];
5742  r[1] = (uint32_t) temp;
5743  temp >>= 32;
5744  temp += (int64_t) r[2] - c;
5745  r[2] = (uint32_t) temp;
5746  temp >>= 32;
5747  temp += (int64_t) r[3] + c;
5748  r[3] = (uint32_t) temp;
5749  temp >>= 32;
5750  temp += (int64_t) r[4];
5751  r[4] = (uint32_t) temp;
5752  temp >>= 32;
5753  temp += (int64_t) r[5];
5754  r[5] = (uint32_t) temp;
5755  temp >>= 32;
5756  temp += (int64_t) r[6];
5757  r[6] = (uint32_t) temp;
5758  temp >>= 32;
5759  temp += (int64_t) r[7] + c;
5760  r[7] = (uint32_t) temp;
5761  c = temp >> 32;
5762 
5763  //Third pass
5764  temp = (int64_t) r[0] + c;
5765  r[0] = (uint32_t) temp;
5766  temp >>= 32;
5767  temp += (int64_t) r[1];
5768  r[1] = (uint32_t) temp;
5769  temp >>= 32;
5770  temp += (int64_t) r[2] - c;
5771  r[2] = (uint32_t) temp;
5772  temp >>= 32;
5773  temp += (int64_t) r[3] + c;
5774  r[3] = (uint32_t) temp;
5775  temp >>= 32;
5776  temp += (int64_t) r[4];
5777  r[4] = (uint32_t) temp;
5778  temp >>= 32;
5779  temp += (int64_t) r[5];
5780  r[5] = (uint32_t) temp;
5781  temp >>= 32;
5782  temp += (int64_t) r[6];
5783  r[6] = (uint32_t) temp;
5784  temp >>= 32;
5785  temp += (int64_t) r[7] + c;
5786  r[7] = (uint32_t) temp;
5787 
5788  //Reduce non-canonical values
5789  ecFieldCanonicalize(curve, r, r);
5790 }
5791 
5792 
5793 /**
5794  * @brief Field modular inversion (SM2 curve)
5795  * @param[in] curve Elliptic curve parameters
5796  * @param[out] r Resulting integer R = A^-1 mod p
5797  * @param[in] a An integer such as 0 <= A < p
5798  **/
5799 
5800 void sm2FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5801 {
5802  uint32_t u[8];
5803  uint32_t v[8];
5804 
5805  //Since GF(p) is a prime field, the Fermat's little theorem can be
5806  //used to find the multiplicative inverse of A modulo p
5807  ecFieldSqrMod(curve, u, a);
5808  ecFieldMulMod(curve, u, u, a); //A^(2^2 - 1)
5809  ecFieldSqrMod(curve, u, u);
5810  ecFieldMulMod(curve, u, u, a); //A^(2^3 - 1)
5811  ecFieldPwr2Mod(curve, v, u, 3);
5812  ecFieldMulMod(curve, u, u, v); //A^(2^6 - 1)
5813  ecFieldSqrMod(curve, u, u);
5814  ecFieldMulMod(curve, u, u, a); //A^(2^7 - 1)
5815  ecFieldPwr2Mod(curve, v, u, 7);
5816  ecFieldMulMod(curve, u, u, v); //A^(2^14 - 1)
5817  ecFieldSqrMod(curve, u, u);
5818  ecFieldMulMod(curve, u, u, a); //A^(2^15 - 1)
5819  ecFieldPwr2Mod(curve, v, u, 15);
5820  ecFieldMulMod(curve, u, u, v); //A^(2^30 - 1)
5821  ecFieldSqrMod(curve, u, u);
5822  ecFieldMulMod(curve, v, u, a); //A^(2^31 - 1)
5823  ecFieldPwr2Mod(curve, u, v, 32);
5824  ecFieldMulMod(curve, u, u, v); //A^(2^63 - 2^31 - 1)
5825  ecFieldSqrMod(curve, u, u);
5826  ecFieldMulMod(curve, u, u, a); //A^(2^64 - 2^32 - 1)
5827  ecFieldPwr2Mod(curve, u, u, 31);
5828  ecFieldMulMod(curve, u, u, v); //A^(2^95 - 2^63 - 1)
5829  ecFieldSqrMod(curve, u, u);
5830  ecFieldMulMod(curve, u, u, a); //A^(2^96 - 2^64 - 1)
5831  ecFieldPwr2Mod(curve, u, u, 31);
5832  ecFieldMulMod(curve, u, u, v); //A^(2^127 - 2^95 - 1)
5833  ecFieldSqrMod(curve, u, u);
5834  ecFieldMulMod(curve, u, u, a); //A^(2^128 - 2^96 - 1)
5835  ecFieldPwr2Mod(curve, u, u, 31);
5836  ecFieldMulMod(curve, u, u, v); //A^(2^159 - 2^127 - 1)
5837  ecFieldSqrMod(curve, u, u);
5838  ecFieldMulMod(curve, u, u, a); //A^(2^160 - 2^128 - 1)
5839  ecFieldPwr2Mod(curve, u, u, 63);
5840  ecFieldMulMod(curve, u, u, v); //A^(2^223 - 2^191 - 2^63 + 2^31 - 1)
5841  ecFieldPwr2Mod(curve, u, u, 31);
5842  ecFieldMulMod(curve, u, u, v); //A^(2^254 - 2^222 - 2^94 + 2^62 - 1)
5843  ecFieldPwr2Mod(curve, u, u, 2);
5844  ecFieldMulMod(curve, r, u, a); //A^(2^256 - 2^224 - 2^96 + 2^64 - 3)
5845 }
5846 
5847 
5848 /**
5849  * @brief Scalar modular reduction (SM2 curve)
5850  * @param[in] curve Elliptic curve parameters
5851  * @param[out] r Resulting integer R = A mod q
5852  * @param[in] a An integer such as 0 <= A < q^2
5853  **/
5854 
5855 void sm2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
5856 {
5857  uint32_t c;
5858  uint32_t u[9];
5859  uint32_t v[9];
5860 
5861  //Compute the estimate of the quotient u = ((a / b^(k - 1)) * mu) / b^(k + 1)
5862  ecScalarMul(NULL, u, a + 7, curve->qmu, 9);
5863  //Compute v = u * q mod b^(k + 1)
5864  ecScalarMul(v, NULL, u, curve->q, 9);
5865 
5866  //Compute the estimate of the remainder u = a mod b^(k + 1) - v
5867  //If u < 0, then u = u + b^(k + 1)
5868  ecScalarSub(u, a, v, 9);
5869 
5870  //This estimation implies that at most two subtractions of q are required to
5871  //obtain the correct remainder r
5872  c = ecScalarSub(v, u, curve->q, 9);
5873  ecScalarSelect(u, v, u, c, 9);
5874  c = ecScalarSub(v, u, curve->q, 9);
5875  ecScalarSelect(r, v, u, c, 8);
5876 }
5877 
5878 #endif
5879 
5880 
5881 /**
5882  * @brief Get the elliptic curve that matches the specified OID
5883  * @param[in] oid Object identifier
5884  * @param[in] length OID length
5885  * @return Elliptic curve parameters
5886  **/
5887 
5888 const EcCurve *ecGetCurve(const uint8_t *oid, size_t length)
5889 {
5890  const EcCurve *curve;
5891 
5892  //Invalid parameters?
5893  if(oid == NULL || length == 0)
5894  {
5895  curve = NULL;
5896  }
5897 #if (SECP112R1_SUPPORT == ENABLED)
5898  //secp112r1 elliptic curve?
5899  else if(OID_COMP(oid, length, SECP112R1_OID) == 0)
5900  {
5901  curve = SECP112R1_CURVE;
5902  }
5903 #endif
5904 #if (SECP112R2_SUPPORT == ENABLED)
5905  //secp112r2 elliptic curve?
5906  else if(OID_COMP(oid, length, SECP112R2_OID) == 0)
5907  {
5908  curve = SECP112R2_CURVE;
5909  }
5910 #endif
5911 #if (SECP128R1_SUPPORT == ENABLED)
5912  //secp128r1 elliptic curve?
5913  else if(OID_COMP(oid, length, SECP128R1_OID) == 0)
5914  {
5915  curve = SECP128R1_CURVE;
5916  }
5917 #endif
5918 #if (SECP128R2_SUPPORT == ENABLED)
5919  //secp128r2 elliptic curve?
5920  else if(OID_COMP(oid, length, SECP128R2_OID) == 0)
5921  {
5922  curve = SECP128R2_CURVE;
5923  }
5924 #endif
5925 #if (SECP160K1_SUPPORT == ENABLED)
5926  //secp160k1 elliptic curve?
5927  else if(OID_COMP(oid, length, SECP160K1_OID) == 0)
5928  {
5929  curve = SECP160K1_CURVE;
5930  }
5931 #endif
5932 #if (SECP160R1_SUPPORT == ENABLED)
5933  //secp160r1 elliptic curve?
5934  else if(OID_COMP(oid, length, SECP160R1_OID) == 0)
5935  {
5936  curve = SECP160R1_CURVE;
5937  }
5938 #endif
5939 #if (SECP160R2_SUPPORT == ENABLED)
5940  //secp160r2 elliptic curve?
5941  else if(OID_COMP(oid, length, SECP160R2_OID) == 0)
5942  {
5943  curve = SECP160R2_CURVE;
5944  }
5945 #endif
5946 #if (SECP192K1_SUPPORT == ENABLED)
5947  //secp192k1 elliptic curve?
5948  else if(OID_COMP(oid, length, SECP192K1_OID) == 0)
5949  {
5950  curve = SECP192K1_CURVE;
5951  }
5952 #endif
5953 #if (SECP192R1_SUPPORT == ENABLED)
5954  //secp192r1 elliptic curve?
5955  else if(OID_COMP(oid, length, SECP192R1_OID) == 0)
5956  {
5957  curve = SECP192R1_CURVE;
5958  }
5959 #endif
5960 #if (SECP224K1_SUPPORT == ENABLED)
5961  //secp224k1 elliptic curve?
5962  else if(OID_COMP(oid, length, SECP224K1_OID) == 0)
5963  {
5964  curve = SECP224K1_CURVE;
5965  }
5966 #endif
5967 #if (SECP224R1_SUPPORT == ENABLED)
5968  //secp224r1 elliptic curve?
5969  else if(OID_COMP(oid, length, SECP224R1_OID) == 0)
5970  {
5971  curve = SECP224R1_CURVE;
5972  }
5973 #endif
5974 #if (SECP256K1_SUPPORT == ENABLED)
5975  //secp256k1 elliptic curve?
5976  else if(OID_COMP(oid, length, SECP256K1_OID) == 0)
5977  {
5978  curve = SECP256K1_CURVE;
5979  }
5980 #endif
5981 #if (SECP256R1_SUPPORT == ENABLED)
5982  //secp256r1 elliptic curve?
5983  else if(OID_COMP(oid, length, SECP256R1_OID) == 0)
5984  {
5985  curve = SECP256R1_CURVE;
5986  }
5987 #endif
5988 #if (SECP384R1_SUPPORT == ENABLED)
5989  //secp384r1 elliptic curve?
5990  else if(OID_COMP(oid, length, SECP384R1_OID) == 0)
5991  {
5992  curve = SECP384R1_CURVE;
5993  }
5994 #endif
5995 #if (SECP521R1_SUPPORT == ENABLED)
5996  //secp521r1 elliptic curve?
5997  else if(OID_COMP(oid, length, SECP521R1_OID) == 0)
5998  {
5999  curve = SECP521R1_CURVE;
6000  }
6001 #endif
6002 #if (BRAINPOOLP160R1_SUPPORT == ENABLED)
6003  //brainpoolP160r1 elliptic curve?
6004  else if(OID_COMP(oid, length, BRAINPOOLP160R1_OID) == 0)
6005  {
6006  curve = BRAINPOOLP160R1_CURVE;
6007  }
6008 #endif
6009 #if (BRAINPOOLP160T1_SUPPORT == ENABLED)
6010  //brainpoolP160t1 elliptic curve?
6011  else if(OID_COMP(oid, length, BRAINPOOLP160T1_OID) == 0)
6012  {
6013  curve = BRAINPOOLP160T1_CURVE;
6014  }
6015 #endif
6016 #if (BRAINPOOLP192R1_SUPPORT == ENABLED)
6017  //brainpoolP192r1 elliptic curve?
6018  else if(OID_COMP(oid, length, BRAINPOOLP192R1_OID) == 0)
6019  {
6020  curve = BRAINPOOLP192R1_CURVE;
6021  }
6022 #endif
6023 #if (BRAINPOOLP192T1_SUPPORT == ENABLED)
6024  //brainpoolP192t1 elliptic curve?
6025  else if(OID_COMP(oid, length, BRAINPOOLP192T1_OID) == 0)
6026  {
6027  curve = BRAINPOOLP192T1_CURVE;
6028  }
6029 #endif
6030 #if (BRAINPOOLP224R1_SUPPORT == ENABLED)
6031  //brainpoolP224r1 elliptic curve?
6032  else if(OID_COMP(oid, length, BRAINPOOLP224R1_OID) == 0)
6033  {
6034  curve = BRAINPOOLP224R1_CURVE;
6035  }
6036 #endif
6037 #if (BRAINPOOLP224T1_SUPPORT == ENABLED)
6038  //brainpoolP224t1 elliptic curve?
6039  else if(OID_COMP(oid, length, BRAINPOOLP224T1_OID) == 0)
6040  {
6041  curve = BRAINPOOLP224T1_CURVE;
6042  }
6043 #endif
6044 #if (BRAINPOOLP256R1_SUPPORT == ENABLED)
6045  //brainpoolP256r1 elliptic curve?
6046  else if(OID_COMP(oid, length, BRAINPOOLP256R1_OID) == 0)
6047  {
6048  curve = BRAINPOOLP256R1_CURVE;
6049  }
6050 #endif
6051 #if (BRAINPOOLP256T1_SUPPORT == ENABLED)
6052  //brainpoolP256t1 elliptic curve?
6053  else if(OID_COMP(oid, length, BRAINPOOLP256T1_OID) == 0)
6054  {
6055  curve = BRAINPOOLP256T1_CURVE;
6056  }
6057 #endif
6058 #if (BRAINPOOLP320R1_SUPPORT == ENABLED)
6059  //brainpoolP320r1 elliptic curve?
6060  else if(OID_COMP(oid, length, BRAINPOOLP320R1_OID) == 0)
6061  {
6062  curve = BRAINPOOLP320R1_CURVE;
6063  }
6064 #endif
6065 #if (BRAINPOOLP320T1_SUPPORT == ENABLED)
6066  //brainpoolP320t1 elliptic curve?
6067  else if(OID_COMP(oid, length, BRAINPOOLP320T1_OID) == 0)
6068  {
6069  curve = BRAINPOOLP320T1_CURVE;
6070  }
6071 #endif
6072 #if (BRAINPOOLP384R1_SUPPORT == ENABLED)
6073  //brainpoolP384r1 elliptic curve?
6074  else if(OID_COMP(oid, length, BRAINPOOLP384R1_OID) == 0)
6075  {
6076  curve = BRAINPOOLP384R1_CURVE;
6077  }
6078 #endif
6079 #if (BRAINPOOLP384T1_SUPPORT == ENABLED)
6080  //brainpoolP384t1 elliptic curve?
6081  else if(OID_COMP(oid, length, BRAINPOOLP384T1_OID) == 0)
6082  {
6083  curve = BRAINPOOLP384T1_CURVE;
6084  }
6085 #endif
6086 #if (BRAINPOOLP512R1_SUPPORT == ENABLED)
6087  //brainpoolP512r1 elliptic curve?
6088  else if(OID_COMP(oid, length, BRAINPOOLP512R1_OID) == 0)
6089  {
6090  curve = BRAINPOOLP512R1_CURVE;
6091  }
6092 #endif
6093 #if (BRAINPOOLP512T1_SUPPORT == ENABLED)
6094  //brainpoolP512t1 elliptic curve?
6095  else if(OID_COMP(oid, length, BRAINPOOLP512T1_OID) == 0)
6096  {
6097  curve = BRAINPOOLP512T1_CURVE;
6098  }
6099 #endif
6100 #if (FRP256V1_SUPPORT == ENABLED)
6101  //FRP256v1 elliptic curve?
6102  else if(OID_COMP(oid, length, FRP256V1_OID) == 0)
6103  {
6104  curve = FRP256V1_CURVE;
6105  }
6106 #endif
6107 #if (SM2_SUPPORT == ENABLED)
6108  //SM2 elliptic curve?
6109  else if(OID_COMP(oid, length, SM2_OID) == 0)
6110  {
6111  curve = SM2_CURVE;
6112  }
6113 #endif
6114 #if (X25519_SUPPORT == ENABLED)
6115  //Curve25519 elliptic curve?
6116  else if(OID_COMP(oid, length, X25519_OID) == 0)
6117  {
6118  curve = X25519_CURVE;
6119  }
6120 #endif
6121 #if (X448_SUPPORT == ENABLED)
6122  //Curve448 elliptic curve?
6123  else if(OID_COMP(oid, length, X448_OID) == 0)
6124  {
6125  curve = X448_CURVE;
6126  }
6127 #endif
6128 #if (ED25519_SUPPORT == ENABLED)
6129  //Ed25519 elliptic curve?
6130  else if(OID_COMP(oid, length, ED25519_OID) == 0)
6131  {
6132  curve = ED25519_CURVE;
6133  }
6134 #endif
6135 #if (ED448_SUPPORT == ENABLED)
6136  //Ed448 elliptic curve?
6137  else if(OID_COMP(oid, length, ED448_OID) == 0)
6138  {
6139  curve = ED448_CURVE;
6140  }
6141 #endif
6142  //Unknown identifier?
6143  else
6144  {
6145  curve = NULL;
6146  }
6147 
6148  //Return the elliptic curve parameters, if any
6149  return curve;
6150 }
6151 
6152 #endif
#define SECP128R2_CURVE
Definition: ec_curves.h:42
@ EC_CURVE_TYPE_WEIERSTRASS_A3
Definition: ec.h:362
#define BRAINPOOLP192R1_CURVE
Definition: ec_curves.h:56
@ EC_CURVE_TYPE_MONTGOMERY
Definition: ec.h:363
const EcCurve brainpoolP384t1Curve
brainpoolP384t1 elliptic curve
Definition: ec_curves.c:1552
@ EC_CURVE_TYPE_EDWARDS
Definition: ec.h:364
const EcCurve secp192r1Curve
secp192r1 elliptic curve
Definition: ec_curves.c:547
#define SECP521R1_CURVE
Definition: ec_curves.h:53
uint8_t a
Definition: ndp.h:411
const uint8_t X25519_OID[3]
Definition: ec_curves.c:108
const EcCurve secp192k1Curve
secp192k1 elliptic curve
Definition: ec_curves.c:494
const EcCurve secp128r2Curve
secp128r2 elliptic curve
Definition: ec_curves.c:282
signed int int_t
Definition: compiler_port.h:56
#define BRAINPOOLP512T1_CURVE
Definition: ec_curves.h:67
void secp160r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp160r1 curve)
Definition: ec_curves.c:2775
const EcCurve brainpoolP512t1Curve
brainpoolP512t1 elliptic curve
Definition: ec_curves.c:1676
const EcCurve brainpoolP256r1Curve
brainpoolP256r1 elliptic curve
Definition: ec_curves.c:1259
OID (Object Identifier)
void secp256k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp256k1 curve)
Definition: ec_curves.c:3849
#define SECP384R1_CURVE
Definition: ec_curves.h:52
const EcCurve frp256v1Curve
FRP256v1 elliptic curve.
Definition: ec_curves.c:1739
void brainpoolP512t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP512t1 curve)
Definition: ec_curves.c:5605
#define SECP256R1_CURVE
Definition: ec_curves.h:51
void secp224r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp224r1 curve)
Definition: ec_curves.c:3564
const EcCurve secp224r1Curve
secp224r1 elliptic curve
Definition: ec_curves.c:653
const uint8_t BRAINPOOLP512T1_OID[9]
Definition: ec_curves.c:102
void brainpoolP384t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP384t1 curve)
Definition: ec_curves.c:5477
const uint8_t SECP224R1_OID[5]
Definition: ec_curves.c:66
#define SECP192K1_CURVE
Definition: ec_curves.h:46
#define SECP112R2_CURVE
Definition: ec_curves.h:40
const uint8_t BRAINPOOLP512R1_OID[9]
Definition: ec_curves.c:100
void brainpoolP224r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP224r1 curve)
Definition: ec_curves.c:4998
const uint8_t BRAINPOOLP224T1_OID[9]
Definition: ec_curves.c:86
void secp224r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp224r1 curve)
Definition: ec_curves.c:3656
#define ED25519_CURVE
Definition: ec_curves.h:72
const uint8_t SECP160K1_OID[5]
Definition: ec_curves.c:54
void secp192r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp192r1 curve)
Definition: ec_curves.c:3337
void brainpoolP384r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP384r1 curve)
Definition: ec_curves.c:5382
const uint8_t SECP256K1_OID[5]
Definition: ec_curves.c:68
#define ED448_CURVE
Definition: ec_curves.h:73
const uint8_t BRAINPOOLP384R1_OID[9]
Definition: ec_curves.c:96
const EcCurve ed25519Curve
Ed25519 elliptic curve.
Definition: ec_curves.c:1957
void brainpoolP224t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP224t1 curve)
Definition: ec_curves.c:5093
const EcCurve brainpoolP384r1Curve
brainpoolP384r1 elliptic curve
Definition: ec_curves.c:1491
const EcCurve x448Curve
Curve448 elliptic curve.
Definition: ec_curves.c:1901
const uint8_t BRAINPOOLP320R1_OID[9]
Definition: ec_curves.c:92
void ecScalarShiftLeft(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
Left shift operation.
Definition: ec_misc.c:884
const EcCurve brainpoolP320r1Curve
brainpoolP320r1 elliptic curve
Definition: ec_curves.c:1369
void brainpoolP256r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP256r1 curve)
Definition: ec_curves.c:5126
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
uint8_t oid[]
Definition: lldp_tlv.h:300
void secp160k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp160k1 curve)
Definition: ec_curves.c:2537
void secp112r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp112r1 curve)
Definition: ec_curves.c:2115
const uint8_t SECP224K1_OID[5]
Definition: ec_curves.c:64
const uint8_t BRAINPOOLP256T1_OID[9]
Definition: ec_curves.c:90
uint8_t r
Definition: ndp.h:346
void brainpoolP224t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP224t1 curve)
Definition: ec_curves.c:5062
void brainpoolP224r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP224r1 curve)
Definition: ec_curves.c:5029
#define BRAINPOOLP160T1_CURVE
Definition: ec_curves.h:55
#define BRAINPOOLP512R1_CURVE
Definition: ec_curves.h:66
#define BRAINPOOLP384R1_CURVE
Definition: ec_curves.h:64
void brainpoolP160t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP160t1 curve)
Definition: ec_curves.c:4806
const uint8_t SECP112R1_OID[5]
Definition: ec_curves.c:46
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:74
#define BRAINPOOLP224R1_CURVE
Definition: ec_curves.h:58
const EcCurve secp256r1Curve
secp256r1 elliptic curve
Definition: ec_curves.c:760
__weak_func void ecScalarSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular squaring.
Definition: ec_misc.c:1135
const uint8_t BRAINPOOLP160R1_OID[9]
Definition: ec_curves.c:76
void brainpoolP512r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP512r1 curve)
Definition: ec_curves.c:5541
void brainpoolP320t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP320t1 curve)
Definition: ec_curves.c:5318
const EcCurve secp160k1Curve
secp160k1 elliptic curve
Definition: ec_curves.c:335
uint32_t ecScalarSub(uint32_t *r, const uint32_t *a, const uint32_t *b, uint_t n)
Subtraction of two integers.
Definition: ec_misc.c:707
void secp112r2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp112r2 curve)
Definition: ec_curves.c:2192
const EcCurve brainpoolP256t1Curve
brainpoolP256t1 elliptic curve
Definition: ec_curves.c:1314
void brainpoolP320r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP320r1 curve)
Definition: ec_curves.c:5285
#define BRAINPOOLP320R1_CURVE
Definition: ec_curves.h:62
void secp384r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp384r1 curve)
Definition: ec_curves.c:4314
void secp521r1ScalarInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular inversion (secp521r1 curve)
Definition: ec_curves.c:4680
void brainpoolP160t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP160t1 curve)
Definition: ec_curves.c:4837
Helper routines for ECC.
const EcCurve secp160r1Curve
secp160r1 elliptic curve
Definition: ec_curves.c:388
const uint8_t BRAINPOOLP192T1_OID[9]
Definition: ec_curves.c:82
const EcCurve brainpoolP160t1Curve
brainpoolP160t1 elliptic curve
Definition: ec_curves.c:994
const EcCurve brainpoolP224r1Curve
brainpoolP224r1 elliptic curve
Definition: ec_curves.c:1153
#define SECP256K1_CURVE
Definition: ec_curves.h:50
void brainpoolP192r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP192r1 curve)
Definition: ec_curves.c:4870
#define SECP160K1_CURVE
Definition: ec_curves.h:43
void secp256r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp256r1 curve)
Definition: ec_curves.c:4083
void ecScalarPwr2Mod(const EcCurve *curve, uint32_t *r, const uint32_t *a, uint_t n)
Raise an integer to power 2^n.
Definition: ec_misc.c:1158
void secp112r2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp112r2 curve)
Definition: ec_curves.c:2148
void secp128r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp128r1 curve)
Definition: ec_curves.c:2348
General definitions for cryptographic algorithms.
void secp384r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp384r1 curve)
Definition: ec_curves.c:4370
void secp128r2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp128r2 curve)
Definition: ec_curves.c:2494
const EcCurve brainpoolP512r1Curve
brainpoolP512r1 elliptic curve
Definition: ec_curves.c:1613
#define BRAINPOOLP224T1_CURVE
Definition: ec_curves.h:59
void secp112r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp112r1 curve)
Definition: ec_curves.c:2071
#define SECP112R1_CURVE
Definition: ec_curves.h:39
const uint8_t SECP128R2_OID[5]
Definition: ec_curves.c:52
const uint8_t SECP160R1_OID[5]
Definition: ec_curves.c:56
__weak_func void ecFieldSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular squaring.
Definition: ec_misc.c:1308
void secp384r1ScalarInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular inversion (secp384r1 curve)
Definition: ec_curves.c:4401
uint8_t u
Definition: lldp_ext_med.h:213
#define SM2_CURVE
Definition: ec_curves.h:69
void secp192r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp192r1 curve)
Definition: ec_curves.c:3286
void secp192k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp192k1 curve)
Definition: ec_curves.c:3036
#define BRAINPOOLP320T1_CURVE
Definition: ec_curves.h:63
uint8_t length
Definition: tcp.h:375
void sm2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (SM2 curve)
Definition: ec_curves.c:5855
void brainpoolP192r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP192r1 curve)
Definition: ec_curves.c:4901
void ecScalarSelect(uint32_t *r, const uint32_t *a, const uint32_t *b, uint32_t c, uint_t n)
Select an integer.
Definition: ec_misc.c:576
void brainpoolP192t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP192t1 curve)
Definition: ec_curves.c:4965
void sm2FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (SM2 curve)
Definition: ec_curves.c:5800
#define SECP128R1_CURVE
Definition: ec_curves.h:41
const EcCurve secp384r1Curve
secp384r1 elliptic curve
Definition: ec_curves.c:814
void secp256k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp256k1 curve)
Definition: ec_curves.c:3746
void secp192r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp192r1 curve)
Definition: ec_curves.c:3210
#define SECP160R2_CURVE
Definition: ec_curves.h:45
void secp521r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp521r1 curve)
Definition: ec_curves.c:4457
void secp521r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp521r1 curve)
Definition: ec_curves.c:4596
const EcCurve secp160r2Curve
secp160r2 elliptic curve
Definition: ec_curves.c:441
const uint8_t SECP192R1_OID[8]
Definition: ec_curves.c:62
const uint8_t ED448_OID[3]
Definition: ec_curves.c:114
const EcCurve secp256k1Curve
secp256k1 elliptic curve
Definition: ec_curves.c:706
#define SECP224K1_CURVE
Definition: ec_curves.h:48
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
const EcCurve secp112r2Curve
secp112r2 elliptic curve
Definition: ec_curves.c:176
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:112
__weak_func void ecFieldMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Definition: ec_misc.c:1286
const uint8_t X448_OID[3]
Definition: ec_curves.c:110
void secp256k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp256k1 curve)
Definition: ec_curves.c:3901
const uint8_t BRAINPOOLP384T1_OID[9]
Definition: ec_curves.c:98
const uint8_t SECP192K1_OID[5]
Definition: ec_curves.c:60
#define BRAINPOOLP192T1_CURVE
Definition: ec_curves.h:57
void frp256v1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (FRP256v1 curve)
Definition: ec_curves.c:5669
void secp160k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp160k1 curve)
Definition: ec_curves.c:2604
void secp224r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp224r1 curve)
Definition: ec_curves.c:3713
void brainpoolP160r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP160r1 curve)
Definition: ec_curves.c:4773
const EcCurve brainpoolP224t1Curve
brainpoolP224t1 elliptic curve
Definition: ec_curves.c:1206
const uint8_t BRAINPOOLP160T1_OID[9]
Definition: ec_curves.c:78
void brainpoolP160r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP160r1 curve)
Definition: ec_curves.c:4742
void secp160r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp160r1 curve)
Definition: ec_curves.c:2709
void secp256r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp256r1 curve)
Definition: ec_curves.c:4036
const uint8_t SECP112R2_OID[5]
Definition: ec_curves.c:48
void brainpoolP320r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP320r1 curve)
Definition: ec_curves.c:5254
#define FRP256V1_CURVE
Definition: ec_curves.h:68
void brainpoolP256t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP256t1 curve)
Definition: ec_curves.c:5221
const uint8_t BRAINPOOLP320T1_OID[9]
Definition: ec_curves.c:94
#define SECP160R1_CURVE
Definition: ec_curves.h:44
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
void brainpoolP192t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP192t1 curve)
Definition: ec_curves.c:4934
void secp256r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp256r1 curve)
Definition: ec_curves.c:3934
void sm2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (SM2 curve)
Definition: ec_curves.c:5702
void brainpoolP256t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP256t1 curve)
Definition: ec_curves.c:5190
void ecFieldCanonicalize(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Reduce non-canonical value.
Definition: ec_misc.c:1405
void secp128r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp128r1 curve)
Definition: ec_curves.c:2235
void secp256r1ScalarInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular inversion (secp256r1 curve)
Definition: ec_curves.c:4114
const EcCurve sm2Curve
SM2 elliptic curve.
Definition: ec_curves.c:1794
void secp224k1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp224k1 curve)
Definition: ec_curves.c:3370
void secp224k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp224k1 curve)
Definition: ec_curves.c:3521
const EcCurve x25519Curve
Curve25519 elliptic curve.
Definition: ec_curves.c:1848
void secp160r2ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp160r2 curve)
Definition: ec_curves.c:2993
const uint8_t BRAINPOOLP224R1_OID[9]
Definition: ec_curves.c:84
const uint8_t FRP256V1_OID[10]
Definition: ec_curves.c:104
void secp128r2FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp128r2 curve)
Definition: ec_curves.c:2445
const EcCurve brainpoolP192t1Curve
brainpoolP192t1 elliptic curve
Definition: ec_curves.c:1100
void secp128r2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp128r2 curve)
Definition: ec_curves.c:2381
const uint8_t BRAINPOOLP192R1_OID[9]
Definition: ec_curves.c:80
const EcCurve ed448Curve
Ed448 elliptic curve.
Definition: ec_curves.c:2010
void secp160r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp160r1 curve)
Definition: ec_curves.c:2821
void frp256v1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (FRP256v1 curve)
Definition: ec_curves.c:5638
void secp160k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp160k1 curve)
Definition: ec_curves.c:2666
void ecScalarShiftRight(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
Right shift operation.
Definition: ec_misc.c:940
void brainpoolP320t1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP320t1 curve)
Definition: ec_curves.c:5349
#define BRAINPOOLP256R1_CURVE
Definition: ec_curves.h:60
const EcCurve * ecGetCurve(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:5888
const EcCurve secp112r1Curve
secp112r1 elliptic curve
Definition: ec_curves.c:123
const EcCurve brainpoolP160r1Curve
brainpoolP160r1 elliptic curve
Definition: ec_curves.c:941
#define X448_CURVE
Definition: ec_curves.h:71
const uint8_t SECP160R2_OID[5]
Definition: ec_curves.c:58
@ EC_CURVE_TYPE_WEIERSTRASS
Definition: ec.h:360
void brainpoolP512r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP512r1 curve)
Definition: ec_curves.c:5510
void brainpoolP512t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP512t1 curve)
Definition: ec_curves.c:5574
#define SECP224R1_CURVE
Definition: ec_curves.h:49
void secp160r2FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp160r2 curve)
Definition: ec_curves.c:2931
void brainpoolP384t1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (brainpoolP384t1 curve)
Definition: ec_curves.c:5446
void secp128r1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp128r1 curve)
Definition: ec_curves.c:2299
#define BRAINPOOLP384T1_CURVE
Definition: ec_curves.h:65
void secp192k1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp192k1 curve)
Definition: ec_curves.c:3177
#define EcCurve
Definition: ec.h:346
const EcCurve secp521r1Curve
secp521r1 elliptic curve
Definition: ec_curves.c:874
void ecFieldPwr2Mod(const EcCurve *curve, uint32_t *r, const uint32_t *a, uint_t n)
Raise an integer to power 2^n.
Definition: ec_misc.c:1331
void brainpoolP256r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP256r1 curve)
Definition: ec_curves.c:5157
#define BRAINPOOLP256T1_CURVE
Definition: ec_curves.h:61
__weak_func void ecScalarMul(uint32_t *rl, uint32_t *rh, const uint32_t *a, const uint32_t *b, uint_t n)
Multiplication of two integers.
Definition: ec_misc.c:766
void brainpoolP384r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (brainpoolP384r1 curve)
Definition: ec_curves.c:5413
#define BRAINPOOLP160R1_CURVE
Definition: ec_curves.h:54
const EcCurve brainpoolP192r1Curve
brainpoolP192r1 elliptic curve
Definition: ec_curves.c:1047
void secp384r1FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp384r1 curve)
Definition: ec_curves.c:4172
const EcCurve secp128r1Curve
secp128r1 elliptic curve
Definition: ec_curves.c:229
Elliptic curves.
const EcCurve brainpoolP320t1Curve
brainpoolP320t1 elliptic curve
Definition: ec_curves.c:1430
void secp160r2FieldMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular reduction (secp160r2 curve)
Definition: ec_curves.c:2864
void secp521r1ScalarMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Scalar modular reduction (secp521r1 curve)
Definition: ec_curves.c:4639
ECC (Elliptic Curve Cryptography)
void secp224k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp224k1 curve)
Definition: ec_curves.c:3463
const EcCurve secp224k1Curve
secp224k1 elliptic curve
Definition: ec_curves.c:600
__weak_func void ecScalarMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Definition: ec_misc.c:1113
@ EC_CURVE_TYPE_WEIERSTRASS_A0
Definition: ec.h:361
#define SECP192R1_CURVE
Definition: ec_curves.h:47
void secp192k1FieldInv(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Field modular inversion (secp192k1 curve)
Definition: ec_curves.c:3119
uint8_t c
Definition: ndp.h:514
const uint8_t SECP128R1_OID[5]
Definition: ec_curves.c:50
Debugging facilities.
const uint8_t BRAINPOOLP256R1_OID[9]
Definition: ec_curves.c:88
const uint8_t SM2_OID[8]
Definition: ec_curves.c:106
#define X25519_CURVE
Definition: ec_curves.h:70