1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Crypto Component                                                 */
17 /**                                                                       */
18 /**   Elliptic Curve                                                      */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
27 /*                                                                        */
28 /*    nx_crypto_ec.h                                      PORTABLE C      */
29 /*                                                           6.1.12       */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Timothy Stapko, Microsoft Corporation                               */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file defines the symbols, structures and operations for        */
37 /*    Elliptic Curve Crypto.                                              */
38 /*                                                                        */
39 /*  RELEASE HISTORY                                                       */
40 /*                                                                        */
41 /*    DATE              NAME                      DESCRIPTION             */
42 /*                                                                        */
43 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
44 /*  09-30-2020     Timothy Stapko           Modified comment(s), and      */
45 /*                                            added public key validation,*/
46 /*                                            resulting in version 6.1    */
47 /*  01-31-2022     Timothy Stapko           Modified comment(s), and      */
48 /*                                            improved performance,       */
49 /*                                            resulting in version 6.1.10 */
50 /*  04-25-2022     Yuxin Zhou               Modified comment(s),          */
51 /*                                            added x25519 curve,         */
52 /*                                            resulting in version 6.1.11 */
53 /*  07-29-2022     Yuxin Zhou               Modified comment(s),          */
54 /*                                            added x448 curve,           */
55 /*                                            resulting in version 6.1.12 */
56 /*                                                                        */
57 /**************************************************************************/
58 
59 #ifndef NX_CRYPTO_EC_H
60 #define NX_CRYPTO_EC_H
61 
62 /* Determine if a C++ compiler is being used.  If so, ensure that standard
63    C is used to process the API information.  */
64 #ifdef __cplusplus
65 
66 /* Yes, C++ compiler is present.  Use standard C.  */
67 extern   "C" {
68 
69 #endif
70 
71 #include "nx_crypto.h"
72 #include "nx_crypto_huge_number.h"
73 
74 #define NX_CRYPTO_EC_POINT_AFFINE     0
75 #define NX_CRYPTO_EC_POINT_PROJECTIVE 1
76 
77 #define NX_CRYPTO_EC_FP               0
78 #define NX_CRYPTO_EC_F2M              1
79 
80 /* Define Elliptic Curve point. */
81 typedef struct
82 {
83     UINT                  nx_crypto_ec_point_type;
84     NX_CRYPTO_HUGE_NUMBER nx_crypto_ec_point_x;
85     NX_CRYPTO_HUGE_NUMBER nx_crypto_ec_point_y;
86     NX_CRYPTO_HUGE_NUMBER nx_crypto_ec_point_z;
87 } NX_CRYPTO_EC_POINT;
88 
89 typedef struct
90 {
91     USHORT *nx_crypto_ec_polynomial_data;
92     UINT    nx_crypto_ec_polynomial_size;
93 } NX_CRYPTO_EC_POLYNOMIAL;
94 
95 /* Define fixed points */
96 typedef struct
97 {
98 
99     /* Window width */
100     UINT nx_crypto_ec_fixed_points_window_width;
101 
102     /* Bits of curve (m). */
103     UINT nx_crypto_ec_fixed_points_bits;
104 
105     /* d = (m + w - 1) / w */
106     UINT nx_crypto_ec_fixed_points_d;
107 
108     /* e = (d + 1) / 2 */
109     UINT nx_crypto_ec_fixed_points_e;
110 
111     /* [a(w-1),...a(0)]G */
112     /* 0G and 1G are not stored. */
113     /* The count of fixed points are 2 ^ w - 2. */
114     NX_CRYPTO_EC_POINT *nx_crypto_ec_fixed_points_array;
115 
116     /* 2^e[a(w-1),...a(0)]G */
117     /* 0G is not stored. */
118     /* The count of fixed points are 2 ^ w - 1. */
119     NX_CRYPTO_EC_POINT *nx_crypto_ec_fixed_points_array_2e;
120 } NX_CRYPTO_EC_FIXED_POINTS;
121 
122 /* Define Elliptic Curve. */
123 typedef struct NX_CRYPTO_EC_STRUCT
124 {
125     CHAR *nx_crypto_ec_name;
126     UINT  nx_crypto_ec_id;
127     UINT  nx_crypto_ec_window_width;
128     UINT  nx_crypto_ec_bits;
129     union
130     {
131         NX_CRYPTO_HUGE_NUMBER   fp;
132         NX_CRYPTO_EC_POLYNOMIAL f2m;
133     }                          nx_crypto_ec_field;
134     NX_CRYPTO_HUGE_NUMBER      nx_crypto_ec_a;
135     NX_CRYPTO_HUGE_NUMBER      nx_crypto_ec_b;
136     NX_CRYPTO_EC_POINT         nx_crypto_ec_g;
137     NX_CRYPTO_HUGE_NUMBER      nx_crypto_ec_n;
138     NX_CRYPTO_HUGE_NUMBER      nx_crypto_ec_h;
139     NX_CRYPTO_EC_FIXED_POINTS *nx_crypto_ec_fixed_points;
140     VOID (*nx_crypto_ec_add)(struct NX_CRYPTO_EC_STRUCT *curve,
141                              NX_CRYPTO_EC_POINT *left,
142                              NX_CRYPTO_EC_POINT *right,
143                              HN_UBASE *scratch);
144     VOID (*nx_crypto_ec_subtract)(struct NX_CRYPTO_EC_STRUCT *curve,
145                                   NX_CRYPTO_EC_POINT *left,
146                                   NX_CRYPTO_EC_POINT *right,
147                                   HN_UBASE *scratch);
148     VOID (*nx_crypto_ec_multiple)(struct NX_CRYPTO_EC_STRUCT *curve,
149                                   NX_CRYPTO_EC_POINT *g,
150                                   NX_CRYPTO_HUGE_NUMBER *d,
151                                   NX_CRYPTO_EC_POINT *r,
152                                   HN_UBASE *scratch);
153     VOID (*nx_crypto_ec_reduce)(struct NX_CRYPTO_EC_STRUCT *curve,
154                                 NX_CRYPTO_HUGE_NUMBER *value,
155                                 HN_UBASE *scratch);
156 } NX_CRYPTO_EC;
157 
158 #define NX_CRYPTO_EC_POINT_INITIALIZE(p, type, buff, size)                              \
159     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&((p) -> nx_crypto_ec_point_x), buff, size);       \
160     NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&((p) -> nx_crypto_ec_point_y), buff, size);       \
161     if ((type) == NX_CRYPTO_EC_POINT_PROJECTIVE) {                                      \
162         NX_CRYPTO_HUGE_NUMBER_INITIALIZE(&((p) -> nx_crypto_ec_point_z), buff, size); } \
163     (p) -> nx_crypto_ec_point_type = (type);
164 
165 #define NX_CRYPTO_EC_POINT_SETUP(p, x, x_size, y, y_size, z, z_size)         \
166     _nx_crypto_huge_number_setup(&((p) -> nx_crypto_ec_point_x), x, x_size); \
167     _nx_crypto_huge_number_setup(&((p) -> nx_crypto_ec_point_y), y, y_size); \
168     if ((p) -> nx_crypto_ec_point_type == NX_CRYPTO_EC_POINT_PROJECTIVE) {   \
169         _nx_crypto_huge_number_setup(&((p) -> nx_crypto_ec_point_z), z, z_size); }
170 
171 #define NX_CRYPTO_EC_POINT_EXTRACT(p, x, x_size, x_out_size, y, y_size, y_out_size, z, z_size, z_out_size) \
172     _nx_crypto_huge_number_extract(&((p) -> nx_crypto_ec_point_x), x, x_size, x_out_size);                 \
173     _nx_crypto_huge_number_extract(&((p) -> nx_crypto_ec_point_y), y, y_size, y_out_size);                 \
174     if ((p) -> nx_crypto_ec_point_type == NX_CRYPTO_EC_POINT_PROJECTIVE) {                                 \
175         _nx_crypto_huge_number_extract(&((p) -> nx_crypto_ec_point_z), z, z_size, z_out_size); }
176 
177 #define NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE(curve, value, digit, result, scratch) \
178     _nx_crypto_huge_number_multiply_digit(value, digit, result);                 \
179     curve -> nx_crypto_ec_reduce(curve, result, scratch);
180 
181 #define NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, left, right, result, scratch) \
182     _nx_crypto_huge_number_multiply(left, right, result);                 \
183     curve -> nx_crypto_ec_reduce(curve, result, scratch);
184 
185 #define NX_CRYPTO_EC_SQUARE_REDUCE(curve, value, result, scratch) \
186     _nx_crypto_huge_number_square(value, result);                 \
187     curve -> nx_crypto_ec_reduce(curve, result, scratch);
188 
189 #define NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, value, shift, scratch) \
190     _nx_crypto_huge_number_shift_left(value, shift);                 \
191     curve -> nx_crypto_ec_reduce(curve, value, scratch);
192 
193 #if (NX_CRYPTO_HUGE_NUMBER_BITS == 32)
194 
195 #define NX_CRYPTO_EC_ASSIGN_REV(a, b) (a) = (b); NX_CRYPTO_CHANGE_ULONG_ENDIAN(a)
196 #define NX_CRYPTO_EC_CHANGE_ENDIAN(a, b, c) NX_CRYPTO_EC_ASSIGN_REV(b, c); (a) = (b)
197 
198 #define NX_CRYPTO_EC_SECP192R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5)         \
199     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, c0);    \
200     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, c1);    \
201     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, c2);    \
202     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, c3);    \
203     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, c4);    \
204     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, c5);    \
205     (s) -> nx_crypto_huge_number_size = 6;                                      \
206     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
207 
208 #define NX_CRYPTO_EC_SECP224R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5, c6)     \
209     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, c0);    \
210     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, c1);    \
211     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, c2);    \
212     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, c3);    \
213     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, c4);    \
214     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, c5);    \
215     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, c6);    \
216     (s) -> nx_crypto_huge_number_size = 7;                                      \
217     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
218 
219 #define NX_CRYPTO_EC_SECP256R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5, c6, c7) \
220     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[7], b, c0);    \
221     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, c1);    \
222     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, c2);    \
223     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, c3);    \
224     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, c4);    \
225     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, c5);    \
226     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, c6);    \
227     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, c7);    \
228     (s) -> nx_crypto_huge_number_size = 8;                                      \
229     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
230 
231 #define NX_CRYPTO_EC_SECP256R1_DATA_SETUP_LS1(s, b1, b2, c0, c1, c2, c3, c4, c5, c6, c7) \
232     NX_CRYPTO_EC_ASSIGN_REV(b1, c0);                                                     \
233     (s) -> nx_crypto_huge_number_data[8] = (b1) >> 31;                                   \
234     (s) -> nx_crypto_huge_number_size = 8 + ((b1) >> 31);                                \
235     NX_CRYPTO_EC_ASSIGN_REV(b2, c1);                                                     \
236     (s) -> nx_crypto_huge_number_data[7] = ((b1) << 1) | ((b2) >> 31);                   \
237     NX_CRYPTO_EC_ASSIGN_REV(b1, c2);                                                     \
238     (s) -> nx_crypto_huge_number_data[6] = ((b2) << 1) | ((b1) >> 31);                   \
239     NX_CRYPTO_EC_ASSIGN_REV(b2, c3);                                                     \
240     (s) -> nx_crypto_huge_number_data[5] = ((b1) << 1) | ((b2) >> 31);                   \
241     NX_CRYPTO_EC_ASSIGN_REV(b1, c4);                                                     \
242     (s) -> nx_crypto_huge_number_data[4] = ((b2) << 1) | ((b1) >> 31);                   \
243     NX_CRYPTO_EC_ASSIGN_REV(b2, c5);                                                     \
244     (s) -> nx_crypto_huge_number_data[3] = ((b1) << 1) | ((b2) >> 31);                   \
245     NX_CRYPTO_EC_ASSIGN_REV(b1, c6);                                                     \
246     (s) -> nx_crypto_huge_number_data[2] = ((b2) << 1) | ((b1) >> 31);                   \
247     NX_CRYPTO_EC_ASSIGN_REV(b2, c7);                                                     \
248     (s) -> nx_crypto_huge_number_data[1] = ((b1) << 1) | ((b2) >> 31);                   \
249     (s) -> nx_crypto_huge_number_data[0] = (b2) << 1;                                    \
250     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
251 
252 #define NX_CRYPTO_EC_SECP384R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
253     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[11], b, c0);                     \
254     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[10], b, c1);                     \
255     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[9], b, c2);                      \
256     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[8], b, c3);                      \
257     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[7], b, c4);                      \
258     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, c5);                      \
259     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, c6);                      \
260     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, c7);                      \
261     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, c8);                      \
262     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, c9);                      \
263     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, c10);                     \
264     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, c11);                     \
265     (s) -> nx_crypto_huge_number_size = 12;                                                       \
266     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
267 
268 #define NX_CRYPTO_EC_SECP384R1_DATA_SETUP_LS1(s, b1, b2, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
269     NX_CRYPTO_EC_ASSIGN_REV(b1, c0);                                                                       \
270     (s) -> nx_crypto_huge_number_data[12] = (b1) >> 31;                                                    \
271     (s) -> nx_crypto_huge_number_size = 12 + ((b1) >> 31);                                                 \
272     NX_CRYPTO_EC_ASSIGN_REV(b2, c1);                                                                       \
273     (s) -> nx_crypto_huge_number_data[11] = ((b1) << 1) | ((b2) >> 31);                                    \
274     NX_CRYPTO_EC_ASSIGN_REV(b1, c2);                                                                       \
275     (s) -> nx_crypto_huge_number_data[10] = ((b2) << 1) | ((b1) >> 31);                                    \
276     NX_CRYPTO_EC_ASSIGN_REV(b2, c3);                                                                       \
277     (s) -> nx_crypto_huge_number_data[9] = ((b1) << 1) | ((b2) >> 31);                                     \
278     NX_CRYPTO_EC_ASSIGN_REV(b1, c4);                                                                       \
279     (s) -> nx_crypto_huge_number_data[8] = ((b2) << 1) | ((b1) >> 31);                                     \
280     NX_CRYPTO_EC_ASSIGN_REV(b2, c5);                                                                       \
281     (s) -> nx_crypto_huge_number_data[7] = ((b1) << 1) | ((b2) >> 31);                                     \
282     NX_CRYPTO_EC_ASSIGN_REV(b1, c6);                                                                       \
283     (s) -> nx_crypto_huge_number_data[6] = ((b2) << 1) | ((b1) >> 31);                                     \
284     NX_CRYPTO_EC_ASSIGN_REV(b2, c7);                                                                       \
285     (s) -> nx_crypto_huge_number_data[5] = ((b1) << 1) | ((b2) >> 31);                                     \
286     NX_CRYPTO_EC_ASSIGN_REV(b1, c8);                                                                       \
287     (s) -> nx_crypto_huge_number_data[4] = ((b2) << 1) | ((b1) >> 31);                                     \
288     NX_CRYPTO_EC_ASSIGN_REV(b2, c9);                                                                       \
289     (s) -> nx_crypto_huge_number_data[3] = ((b1) << 1) | ((b2) >> 31);                                     \
290     NX_CRYPTO_EC_ASSIGN_REV(b1, c10);                                                                      \
291     (s) -> nx_crypto_huge_number_data[2] = ((b2) << 1) | ((b1) >> 31);                                     \
292     NX_CRYPTO_EC_ASSIGN_REV(b2, c11);                                                                      \
293     (s) -> nx_crypto_huge_number_data[1] = ((b1) << 1) | ((b2) >> 31);                                     \
294     (s) -> nx_crypto_huge_number_data[0] = (b2) << 1;                                                      \
295     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
296 
297 #else
298 
299 #define NX_CRYPTO_EC_ASSIGN_REV(a,b) (a) = (b); NX_CRYPTO_CHANGE_USHORT_ENDIAN(a)
300 #define NX_CRYPTO_EC_CHANGE_ENDIAN(a, b, c) NX_CRYPTO_EC_ASSIGN_REV(b, c); (a) = (b)
301 
302 #define NX_CRYPTO_EC_SECP192R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5)                         \
303     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[11], b, (HN_UBASE)(c0));       \
304     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[10], b, (HN_UBASE)(c0 >> 16)); \
305     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[9], b, (HN_UBASE)(c1));        \
306     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[8], b, (HN_UBASE)(c1 >> 16));  \
307     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[7], b, (HN_UBASE)(c2));        \
308     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, (HN_UBASE)(c2 >> 16));  \
309     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, (HN_UBASE)(c3));        \
310     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, (HN_UBASE)(c3 >> 16));  \
311     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, (HN_UBASE)(c4));        \
312     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, (HN_UBASE)(c4 >> 16));  \
313     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, (HN_UBASE)(c5));        \
314     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, (HN_UBASE)(c5 >> 16));  \
315     (s) -> nx_crypto_huge_number_size = 12;                                                     \
316     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
317 
318 #define NX_CRYPTO_EC_SECP224R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5, c6)                     \
319     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[13], b, (HN_UBASE)(c0));       \
320     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[12], b, (HN_UBASE)(c0 >> 16)); \
321     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[11], b, (HN_UBASE)(c1));       \
322     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[10], b, (HN_UBASE)(c1 >> 16)); \
323     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[9], b, (HN_UBASE)(c2));        \
324     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[8], b, (HN_UBASE)(c2 >> 16));  \
325     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[7], b, (HN_UBASE)(c3));        \
326     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, (HN_UBASE)(c3 >> 16));  \
327     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, (HN_UBASE)(c4));        \
328     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, (HN_UBASE)(c4 >> 16));  \
329     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, (HN_UBASE)(c5));        \
330     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, (HN_UBASE)(c5 >> 16));  \
331     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, (HN_UBASE)(c6));        \
332     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, (HN_UBASE)(c6 >> 16));  \
333     (s) -> nx_crypto_huge_number_size = 14;                                                     \
334     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
335 
336 #define NX_CRYPTO_EC_SECP256R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5, c6, c7)                 \
337     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[15], b, (HN_UBASE)(c0));       \
338     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[14], b, (HN_UBASE)(c0 >> 16)); \
339     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[13], b, (HN_UBASE)(c1));       \
340     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[12], b, (HN_UBASE)(c1 >> 16)); \
341     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[11], b, (HN_UBASE)(c2));       \
342     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[10], b, (HN_UBASE)(c2 >> 16)); \
343     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[9], b, (HN_UBASE)(c3));        \
344     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[8], b, (HN_UBASE)(c3 >> 16));  \
345     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[7], b, (HN_UBASE)(c4));        \
346     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, (HN_UBASE)(c4 >> 16));  \
347     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, (HN_UBASE)(c5));        \
348     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, (HN_UBASE)(c5 >> 16));  \
349     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, (HN_UBASE)(c6));        \
350     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, (HN_UBASE)(c6 >> 16));  \
351     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, (HN_UBASE)(c7));        \
352     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, (HN_UBASE)(c7 >> 16));  \
353     (s) -> nx_crypto_huge_number_size = 16;                                                     \
354     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
355 
356 #define NX_CRYPTO_EC_SECP256R1_DATA_SETUP_LS1(s, b1, b2, c0, c1, c2, c3, c4, c5, c6, c7) \
357     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c0));                                         \
358     (s) -> nx_crypto_huge_number_data[16] = (HN_UBASE)((b1) >> 15);                      \
359     (s) -> nx_crypto_huge_number_size = (UINT)(16 + (HN_UBASE)((b1) >> 15));             \
360     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c0 >> 16));                                   \
361     (s) -> nx_crypto_huge_number_data[15] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));      \
362     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c1));                                         \
363     (s) -> nx_crypto_huge_number_data[14] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));      \
364     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c1 >> 16));                                   \
365     (s) -> nx_crypto_huge_number_data[13] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));      \
366     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c2));                                         \
367     (s) -> nx_crypto_huge_number_data[12] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));      \
368     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c2 >> 16));                                   \
369     (s) -> nx_crypto_huge_number_data[11] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));      \
370     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c3));                                         \
371     (s) -> nx_crypto_huge_number_data[10] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));      \
372     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c3 >> 16));                                   \
373     (s) -> nx_crypto_huge_number_data[9] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));       \
374     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c4));                                         \
375     (s) -> nx_crypto_huge_number_data[8] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));       \
376     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c4 >> 16));                                   \
377     (s) -> nx_crypto_huge_number_data[7] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));       \
378     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c5));                                         \
379     (s) -> nx_crypto_huge_number_data[6] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));       \
380     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c5 >> 16));                                   \
381     (s) -> nx_crypto_huge_number_data[5] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));       \
382     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c6));                                         \
383     (s) -> nx_crypto_huge_number_data[4] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));       \
384     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c6 >> 16));                                   \
385     (s) -> nx_crypto_huge_number_data[3] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));       \
386     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c7));                                         \
387     (s) -> nx_crypto_huge_number_data[2] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));       \
388     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c7 >> 16));                                   \
389     (s) -> nx_crypto_huge_number_data[1] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));       \
390     (s) -> nx_crypto_huge_number_data[0] = (HN_UBASE)((b2) << 1);                        \
391     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
392 
393 #define NX_CRYPTO_EC_SECP384R1_DATA_SETUP(s, b, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
394     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[23], b, (HN_UBASE)(c0));         \
395     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[22], b, (HN_UBASE)(c0 >> 16));   \
396     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[21], b, (HN_UBASE)(c1));         \
397     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[20], b, (HN_UBASE)(c1 >> 16));   \
398     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[19], b, (HN_UBASE)(c2));         \
399     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[18], b, (HN_UBASE)(c2 >> 16));   \
400     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[17], b, (HN_UBASE)(c3));         \
401     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[16], b, (HN_UBASE)(c3 >> 16));   \
402     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[15], b, (HN_UBASE)(c4));         \
403     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[14], b, (HN_UBASE)(c4 >> 16));   \
404     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[13], b, (HN_UBASE)(c5));         \
405     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[12], b, (HN_UBASE)(c5 >> 16));   \
406     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[11], b, (HN_UBASE)(c6));         \
407     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[10], b, (HN_UBASE)(c6 >> 16));   \
408     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[9], b, (HN_UBASE)(c7));          \
409     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[8], b, (HN_UBASE)(c7 >> 16));    \
410     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[7], b, (HN_UBASE)(c8));          \
411     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[6], b, (HN_UBASE)(c8 >> 16));    \
412     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[5], b, (HN_UBASE)(c9));          \
413     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[4], b, (HN_UBASE)(c9 >> 16));    \
414     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[3], b, (HN_UBASE)(c10));         \
415     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[2], b, (HN_UBASE)(c10 >> 16));   \
416     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[1], b, (HN_UBASE)(c11));         \
417     NX_CRYPTO_EC_CHANGE_ENDIAN((s) -> nx_crypto_huge_number_data[0], b, (HN_UBASE)(c11 >> 16));   \
418     (s) -> nx_crypto_huge_number_size = 24;                                                       \
419     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
420 
421 #define NX_CRYPTO_EC_SECP384R1_DATA_SETUP_LS1(s, b1, b2, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) \
422     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c0));                                                           \
423     (s) -> nx_crypto_huge_number_data[24] = (HN_UBASE)((b1) >> 15);                                        \
424     (s) -> nx_crypto_huge_number_size = (UINT)(24 + (HN_UBASE)((b1) >> 15));                               \
425     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c0 >> 16));                                                     \
426     (s) -> nx_crypto_huge_number_data[23] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
427     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c1));                                                           \
428     (s) -> nx_crypto_huge_number_data[22] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
429     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c1 >> 16));                                                     \
430     (s) -> nx_crypto_huge_number_data[21] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
431     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c2));                                                           \
432     (s) -> nx_crypto_huge_number_data[20] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
433     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c2 >> 16));                                                     \
434     (s) -> nx_crypto_huge_number_data[19] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
435     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c3));                                                           \
436     (s) -> nx_crypto_huge_number_data[18] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
437     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c3 >> 16));                                                     \
438     (s) -> nx_crypto_huge_number_data[17] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
439     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c4));                                                           \
440     (s) -> nx_crypto_huge_number_data[16] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
441     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c4 >> 16));                                                     \
442     (s) -> nx_crypto_huge_number_data[15] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
443     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c5));                                                           \
444     (s) -> nx_crypto_huge_number_data[14] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
445     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c5 >> 16));                                                     \
446     (s) -> nx_crypto_huge_number_data[13] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
447     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c6));                                                           \
448     (s) -> nx_crypto_huge_number_data[12] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
449     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c6 >> 16));                                                     \
450     (s) -> nx_crypto_huge_number_data[11] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                        \
451     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c7));                                                           \
452     (s) -> nx_crypto_huge_number_data[10] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                        \
453     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c7 >> 16));                                                     \
454     (s) -> nx_crypto_huge_number_data[9] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                         \
455     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c8));                                                           \
456     (s) -> nx_crypto_huge_number_data[8] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                         \
457     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c8 >> 16));                                                     \
458     (s) -> nx_crypto_huge_number_data[7] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                         \
459     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c9));                                                           \
460     (s) -> nx_crypto_huge_number_data[6] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                         \
461     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c9 >> 16));                                                     \
462     (s) -> nx_crypto_huge_number_data[5] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                         \
463     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c10));                                                          \
464     (s) -> nx_crypto_huge_number_data[4] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                         \
465     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c10 >> 16));                                                    \
466     (s) -> nx_crypto_huge_number_data[3] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                         \
467     NX_CRYPTO_EC_ASSIGN_REV(b1, (HN_UBASE)(c11));                                                          \
468     (s) -> nx_crypto_huge_number_data[2] = (HN_UBASE)(((b2) << 1) | ((b1) >> 15));                         \
469     NX_CRYPTO_EC_ASSIGN_REV(b2, (HN_UBASE)(c11 >> 16));                                                    \
470     (s) -> nx_crypto_huge_number_data[1] = (HN_UBASE)(((b1) << 1) | ((b2) >> 15));                         \
471     (s) -> nx_crypto_huge_number_data[0] = (HN_UBASE)((b2) << 1);                                          \
472     (s) -> nx_crypto_huge_number_is_negative = NX_CRYPTO_FALSE;
473 
474 #endif
475 
476 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp192r1;
477 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp224r1;
478 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp256r1;
479 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp384r1;
480 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp521r1;
481 
482 #define NX_CRYPTO_EC_GET_SECP192R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp192r1
483 #define NX_CRYPTO_EC_GET_SECP224R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp224r1
484 #define NX_CRYPTO_EC_GET_SECP256R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp256r1
485 #define NX_CRYPTO_EC_GET_SECP384R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp384r1
486 #define NX_CRYPTO_EC_GET_SECP521R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp521r1
487 
488 UINT _nx_crypto_ec_point_is_infinite(NX_CRYPTO_EC_POINT *point);
489 VOID _nx_crypto_ec_point_set_infinite(NX_CRYPTO_EC_POINT *point);
490 UINT _nx_crypto_ec_point_setup(NX_CRYPTO_EC_POINT *point, UCHAR *byte_stream, UINT byte_stream_size);
491 VOID _nx_crypto_ec_point_extract_uncompressed(NX_CRYPTO_EC *curve, NX_CRYPTO_EC_POINT *point, UCHAR *byte_stream,
492                                               UINT byte_stream_size, UINT *huge_number_size);
493 
494 VOID _nx_crypto_ec_point_fp_affine_to_projective(NX_CRYPTO_EC_POINT *point);
495 VOID _nx_crypto_ec_point_fp_projective_to_affine(NX_CRYPTO_EC *curve,
496                                                  NX_CRYPTO_EC_POINT *point,
497                                                  HN_UBASE *scratch);
498 
499 VOID _nx_crypto_ec_secp192r1_reduce(NX_CRYPTO_EC *curve,
500                                     NX_CRYPTO_HUGE_NUMBER *value,
501                                     HN_UBASE *scratch);
502 VOID _nx_crypto_ec_secp224r1_reduce(NX_CRYPTO_EC *curve,
503                                     NX_CRYPTO_HUGE_NUMBER *value,
504                                     HN_UBASE *scratch);
505 VOID _nx_crypto_ec_secp256r1_reduce(NX_CRYPTO_EC *curve,
506                                     NX_CRYPTO_HUGE_NUMBER *value,
507                                     HN_UBASE *scratch);
508 VOID _nx_crypto_ec_secp384r1_reduce(NX_CRYPTO_EC *curve,
509                                     NX_CRYPTO_HUGE_NUMBER *value,
510                                     HN_UBASE *scratch);
511 VOID _nx_crypto_ec_secp521r1_reduce(NX_CRYPTO_EC *curve,
512                                     NX_CRYPTO_HUGE_NUMBER *value,
513                                     HN_UBASE *scratch);
514 VOID _nx_crypto_ec_fp_reduce(NX_CRYPTO_EC *curve,
515                              NX_CRYPTO_HUGE_NUMBER *value,
516                              HN_UBASE *scratch);
517 VOID _nx_crypto_ec_fp_projective_add(NX_CRYPTO_EC *curve,
518                                      NX_CRYPTO_EC_POINT *projective_point,
519                                      NX_CRYPTO_EC_POINT *affine_point,
520                                      HN_UBASE *scratch);
521 VOID _nx_crypto_ec_fp_projective_double(NX_CRYPTO_EC *curve,
522                                         NX_CRYPTO_EC_POINT *projective_point,
523                                         HN_UBASE *scratch);
524 VOID _nx_crypto_ec_fp_affine_add(NX_CRYPTO_EC *curve,
525                                  NX_CRYPTO_EC_POINT *left,
526                                  NX_CRYPTO_EC_POINT *right,
527                                  HN_UBASE *scratch);
528 VOID _nx_crypto_ec_fp_affine_subtract(NX_CRYPTO_EC *curve,
529                                       NX_CRYPTO_EC_POINT *left,
530                                       NX_CRYPTO_EC_POINT *right,
531                                       HN_UBASE *scratch);
532 VOID _nx_crypto_ec_fp_projective_multiple(NX_CRYPTO_EC *curve,
533                                           NX_CRYPTO_EC_POINT *g,
534                                           NX_CRYPTO_HUGE_NUMBER *d,
535                                           NX_CRYPTO_EC_POINT *r,
536                                           HN_UBASE *scratch);
537 VOID _nx_crypto_ec_fp_fixed_multiple(NX_CRYPTO_EC *curve,
538                                      NX_CRYPTO_HUGE_NUMBER *d,
539                                      NX_CRYPTO_EC_POINT *r,
540                                      HN_UBASE *scratch);
541 
542 VOID _nx_crypto_ec_naf_compute(NX_CRYPTO_HUGE_NUMBER *d, HN_UBASE *naf_data, UINT *naf_size);
543 VOID _nx_crypto_ec_add_digit_reduce(NX_CRYPTO_EC *curve,
544                                     NX_CRYPTO_HUGE_NUMBER *value,
545                                     HN_UBASE digit,
546                                     HN_UBASE *scratch);
547 VOID _nx_crypto_ec_subtract_digit_reduce(NX_CRYPTO_EC *curve,
548                                          NX_CRYPTO_HUGE_NUMBER *value,
549                                          HN_UBASE digit,
550                                          HN_UBASE *scratch);
551 VOID _nx_crypto_ec_add_reduce(NX_CRYPTO_EC *curve,
552                               NX_CRYPTO_HUGE_NUMBER *left,
553                               NX_CRYPTO_HUGE_NUMBER *right,
554                               HN_UBASE *scratch);
555 VOID _nx_crypto_ec_subtract_reduce(NX_CRYPTO_EC *curve,
556                                    NX_CRYPTO_HUGE_NUMBER *left,
557                                    NX_CRYPTO_HUGE_NUMBER *right,
558                                    HN_UBASE *scratch);
559 VOID _nx_crypto_ec_precomputation(NX_CRYPTO_EC *curve,
560                                   UINT window_width,
561                                   UINT bits,
562                                   HN_UBASE **scratch_pptr);
563 VOID _nx_crypto_ec_fixed_output(NX_CRYPTO_EC *curve,
564                                 INT (*output)(const CHAR *format, ...),
565                                 const CHAR *tab,
566                                 const CHAR *line_ending);
567 UINT _nx_crypto_ec_get_named_curve(NX_CRYPTO_EC **curve, UINT curve_id);
568 UINT _nx_crypto_ec_key_pair_generation_extra(NX_CRYPTO_EC *curve,
569                                              NX_CRYPTO_EC_POINT *g,
570                                              NX_CRYPTO_HUGE_NUMBER *private_key,
571                                              NX_CRYPTO_EC_POINT *public_key,
572                                              HN_UBASE *scratch);
573 NX_CRYPTO_KEEP UINT _nx_crypto_ec_key_pair_stream_generate(NX_CRYPTO_EC *curve,
574                                                            UCHAR *output,
575                                                            ULONG output_length_in_byte,
576                                                            ULONG *actual_output_length,
577                                                            HN_UBASE *scratch);
578 #ifndef NX_CRYPTO_ECC_DISABLE_KEY_VALIDATION
579 UINT _nx_crypto_ec_validate_public_key(NX_CRYPTO_EC_POINT *public_key,
580                                        NX_CRYPTO_EC *chosen_curve,
581                                        UINT partial,
582                                        HN_UBASE *scratch);
583 #endif /* NX_CRYPTO_ECC_DISABLE_KEY_VALIDATION */
584 
585 UINT _nx_crypto_method_ec_secp192r1_operation(UINT op,
586                                               VOID *handle,
587                                               struct NX_CRYPTO_METHOD_STRUCT *method,
588                                               UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
589                                               UCHAR *input, ULONG input_length_in_byte,
590                                               UCHAR *iv_ptr,
591                                               UCHAR *output, ULONG output_length_in_byte,
592                                               VOID *crypto_metadata, ULONG crypto_metadata_size,
593                                               VOID *packet_ptr,
594                                               VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
595 UINT _nx_crypto_method_ec_secp224r1_operation(UINT op,
596                                               VOID *handle,
597                                               struct NX_CRYPTO_METHOD_STRUCT *method,
598                                               UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
599                                               UCHAR *input, ULONG input_length_in_byte,
600                                               UCHAR *iv_ptr,
601                                               UCHAR *output, ULONG output_length_in_byte,
602                                               VOID *crypto_metadata, ULONG crypto_metadata_size,
603                                               VOID *packet_ptr,
604                                               VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
605 UINT _nx_crypto_method_ec_secp256r1_operation(UINT op,
606                                               VOID *handle,
607                                               struct NX_CRYPTO_METHOD_STRUCT *method,
608                                               UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
609                                               UCHAR *input, ULONG input_length_in_byte,
610                                               UCHAR *iv_ptr,
611                                               UCHAR *output, ULONG output_length_in_byte,
612                                               VOID *crypto_metadata, ULONG crypto_metadata_size,
613                                               VOID *packet_ptr,
614                                               VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
615 UINT _nx_crypto_method_ec_secp384r1_operation(UINT op,
616                                               VOID *handle,
617                                               struct NX_CRYPTO_METHOD_STRUCT *method,
618                                               UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
619                                               UCHAR *input, ULONG input_length_in_byte,
620                                               UCHAR *iv_ptr,
621                                               UCHAR *output, ULONG output_length_in_byte,
622                                               VOID *crypto_metadata, ULONG crypto_metadata_size,
623                                               VOID *packet_ptr,
624                                               VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
625 UINT _nx_crypto_method_ec_secp521r1_operation(UINT op,
626                                               VOID *handle,
627                                               struct NX_CRYPTO_METHOD_STRUCT *method,
628                                               UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
629                                               UCHAR *input, ULONG input_length_in_byte,
630                                               UCHAR *iv_ptr,
631                                               UCHAR *output, ULONG output_length_in_byte,
632                                               VOID *crypto_metadata, ULONG crypto_metadata_size,
633                                               VOID *packet_ptr,
634                                               VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
635 
636 #ifdef NX_CRYPTO_ENABLE_CURVE25519_448
637 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_x25519;
638 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_x448;
639 
640 VOID _nx_crypto_ec_cswap(UINT swap, NX_CRYPTO_HUGE_NUMBER *h1, NX_CRYPTO_HUGE_NUMBER *h2);
641 VOID _nx_crypto_ec_x25519_448_multiple(NX_CRYPTO_EC *curve,
642                                        NX_CRYPTO_EC_POINT *u,
643                                        NX_CRYPTO_HUGE_NUMBER *k,
644                                        NX_CRYPTO_EC_POINT *r,
645                                        HN_UBASE *scratch);
646 UINT _nx_crypto_method_ec_x25519_operation(UINT op,
647                                            VOID *handle,
648                                            struct NX_CRYPTO_METHOD_STRUCT *method,
649                                            UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
650                                            UCHAR *input, ULONG input_length_in_byte,
651                                            UCHAR *iv_ptr,
652                                            UCHAR *output, ULONG output_length_in_byte,
653                                            VOID *crypto_metadata, ULONG crypto_metadata_size,
654                                            VOID *packet_ptr,
655                                            VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
656 UINT _nx_crypto_method_ec_x448_operation(UINT op,
657                                          VOID *handle,
658                                          struct NX_CRYPTO_METHOD_STRUCT *method,
659                                          UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
660                                          UCHAR *input, ULONG input_length_in_byte,
661                                          UCHAR *iv_ptr,
662                                          UCHAR *output, ULONG output_length_in_byte,
663                                          VOID *crypto_metadata, ULONG crypto_metadata_size,
664                                          VOID *packet_ptr,
665                                          VOID (*nx_crypto_hw_process_callback)(VOID *, UINT));
666 UINT _nx_crypto_ec_key_pair_generation_x25519_448(NX_CRYPTO_EC *curve,
667                                                   NX_CRYPTO_EC_POINT *g,
668                                                   NX_CRYPTO_HUGE_NUMBER *private_key,
669                                                   NX_CRYPTO_EC_POINT *public_key,
670                                                   HN_UBASE *scratch);
671 UINT _nx_crypto_ec_extract_fixed_size_le(NX_CRYPTO_HUGE_NUMBER *number,
672                                          UCHAR *byte_stream, UINT byte_stream_size);
673 #endif /* NX_CRYPTO_ENABLE_CURVE25519_448 */
674 
675 #ifdef __cplusplus
676 }
677 #endif
678 
679 #endif /* NX_CRYPTO_EC_H */
680 
681