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