• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #ifndef ECC_LOCAL_H
17 #define ECC_LOCAL_H
18 
19 #include "hitls_build.h"
20 #ifdef HITLS_CRYPTO_ECC
21 
22 #include "crypt_ecc.h"
23 #include "crypt_bn.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #define ECC_MAX_BIT_LEN 521
30 
31 #define PRE_COMPUTE_WINDOW 5 // Default Window Size
32 #define PRE_COMPUTE_MAX_TABLELEN (1 << 5) // Maximum specifications of the pre-calculation table
33 
34 /**
35  * Elliptic Curve Implementation Method
36  */
37 typedef struct {
38     // Calculate  r = k1 * G + k2 * pt
39     int32_t (*pointMulAdd)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt);
40     // Calculate r = k * pt. If pt is null, calculate r = k * G. This is the ConstTime processing function.
41     int32_t (*pointMul)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt);
42     // Calculate r = k * pt. If pt is null, calculate r = k * G
43     int32_t (*pointMulFast)(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt);
44     // point addition r = a + b, a all can be the jacobi coordinate, b must be an affine point
45     int32_t (*pointAddAffine)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
46     // point addition r = a + b, a, b all can be the jacobi coordinate.
47     int32_t (*pointAdd)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
48     // point double r = a + a, a can be the jacobi coordinate.
49     int32_t (*pointDouble)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a);
50     // point Multi-double Calculate r = (2^m)*a, a can be the jacobi coordinate.
51     int32_t (*pointMultDouble)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m);
52     // Module inverse
53     int32_t (*modInv)(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt);
54     // Convert points to affine coordinates based on the given module inverse information.
55     int32_t (*point2AffineWithInv)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const BN_BigNum *inv);
56     // Convert the point information to affine coordinates.
57     int32_t (*point2Affine)(const ECC_Para *para, ECC_Point *r, const ECC_Point *a);
58     // Calculate r = (a*b) % mod
59     int32_t (*bnModNistEccMul)(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
60         void *mod, BN_Optimizer *opt);
61     // Calculate r = (a^2) % mod
62     int32_t (*bnModNistEccSqr)(BN_BigNum *r, const BN_BigNum *a, void *mod, BN_Optimizer *opt);
63     // Inverse mode order.
64     int32_t (*modOrdInv)(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a);
65     // convert date to Montgomery form
66     int32_t (*bnMontEnc)(BN_BigNum *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime);
67     // convert Montgomery form to common form
68     void (*bnMontDec)(BN_BigNum *r, BN_Mont *mont);
69 } ECC_Method;
70 
71 /**
72  * Elliptic Curve Point Information
73  */
74 struct EccPointInfo {
75     BN_BigNum *x;
76     BN_BigNum *y;
77     BN_BigNum *z;
78     CRYPT_PKEY_ParaId id;
79 };
80 
81 /**
82  * Elliptic curve parameter information
83  */
84 struct EccPara {
85     BN_BigNum *p;
86     BN_BigNum *a;
87     BN_BigNum *b;
88     BN_BigNum *n;
89     BN_BigNum *h;
90     BN_BigNum *x;
91     BN_BigNum *y;
92     // Currently, the 5-bit window is used. Only odd multiple points are calculated.
93     // The total number of pre-calculated data is (2 ^ 5)/2, that is 16 points.
94     ECC_Point *tableG[16];
95     const ECC_Method *method;
96     CRYPT_PKEY_ParaId id;
97 	BN_Mont *montP;
98     void *libCtx;
99 };
100 
101 /**
102  * @ingroup ecc
103  * @brief   Check whether the checkpoint is at infinity.
104  *
105  * @param   para [IN] Curve parameters
106  * @param   pt [IN] Point information
107  *
108  * @retval CRYPT_SUCCESS    succeeded, indicating that the point is not at infinity.
109  * @retval For details about other errors, see crypt_errno.h
110  */
111 int32_t ECP_PointAtInfinity(const ECC_Para *para, const ECC_Point *pt);
112 
113 /**
114  * @ingroup ecc
115  * @brief   Check whether the point is on the curve.
116  * The determined point must be on the Cartesian coordinate, which is used to check the validity of the point input.
117  *
118  * @param   para [IN] Curve parameters
119  * @param   pt [IN] Point information
120  *
121  * @retval CRYPT_SUCCESS    succeeded.
122  * @retval For details about other errors, see crypt_errno.h
123  */
124 int32_t ECP_PointOnCurve(const ECC_Para *para, const ECC_Point *pt);
125 
126 /**
127  * @ingroup ecc
128  * @brief   Add salt to the pt point and add random z information.
129  *
130  * @param   para [IN] Curve parameters
131  * @param   pt [IN/OUT] Point information
132  *
133  * @retval CRYPT_SUCCESS    succeeded.
134  * @retval For details about other errors, see crypt_errno.h
135  */
136 int32_t ECP_PointBlind(const ECC_Para *para, ECC_Point *pt);
137 
138 /**
139  * @ingroup ecc
140  * @brief   Convert the point information pt to the affine coordinate system and synchronize the data to r.
141  *
142  * @param   para [IN] Curve parameters
143  * @param   r [OUT] Output point information
144  * @param   pt [IN] Input point information
145  *
146  * @retval CRYPT_SUCCESS    succeeded.
147  * @retval For details about other errors, see crypt_errno.h
148  */
149 int32_t ECP_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt);
150 
151 /**
152  * @ingroup ecc
153  * @brief   Converts all point information on pt to affine coordinate system,
154  *          which is used for the coordinate system conversion of the pre-computation table.
155  *
156  * @attention pt[0] cannot be an infinite point.
157  *
158  * @param   para [IN] Curve parameters
159  * @param   pt [IN/OUT] Point information
160  * @param   ptNums [IN] Number of pts
161  *
162  * @retval CRYPT_SUCCESS    succeeded.
163  * @retval For details about other errors, see crypt_errno.h
164  */
165 int32_t ECP_Points2Affine(const ECC_Para *para, ECC_Point *pt[], uint32_t ptNums);
166 
167 /**
168  * @ingroup ecc
169  * @brief   Calculated r = -a
170  *
171  * @attention point a must be a point in the Cartesian coordinate system
172  *
173  * @param   para [IN] Curve parameters
174  * @param   r [OUT] Output point information
175  * @param   pt [IN] Input point information
176  *
177  * @retval CRYPT_SUCCESS    succeeded.
178  * @retval For details about other errors, see crypt_errno.h
179  */
180 int32_t ECP_PointInvertAtAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a);
181 
182 /**
183  * @ingroup ecc
184  * @brief   Convert the point information pt to the affine coordinate system and refresh the data to r.
185  *          The inverse information of z is provided by the user.
186  *
187  * @attention The validity of inv is guaranteed by the user.
188  *
189  * @param   para [IN] Curve parameters
190  * @param   r [OUT] Output point information
191  * @param   pt [IN] Input point information
192  * @param   inv [IN] inverse information of z
193  *
194  * @retval CRYPT_SUCCESS    succeeded.
195  * @retval For details about other errors, see crypt_errno.h
196  */
197 int32_t ECP_Point2AffineWithInv(
198     const ECC_Para *para, ECC_Point *r, const ECC_Point *pt, const BN_BigNum *inv);
199 
200 /**
201  * @ingroup ecc
202  * @brief   Calculate r = k1 * G + k2 * pt
203  *
204  * @param   para [IN] Curve parameters
205  * @param   r [OUT] Output point information
206  * @param   k1 [IN] Scalar 1
207  * @param   k2 [IN] Scalar 2
208  * @param   pt [IN] Point data
209  *
210  * @retval CRYPT_SUCCESS    succeeded.
211  * @retval For details about other errors, see crypt_errno.h
212  */
213 int32_t ECP_PointMulAdd(
214     ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt);
215 
216 /**
217  * @ingroup ecc
218  * @brief   Check whether a is consistent with b.
219  *
220  * @param   para [IN] Curve parameter information
221  * @param   a [IN] Input point information
222  * @param   b [IN] Input point information
223  *
224  * @retval CRYPT_SUCCESS                The two points are the same.
225  * @retval CRYPT_ECC_POINT_NOT_EQUAL    The two points are different.
226  * @retval For details about other errors, see crypt_errno.h
227  */
228 int32_t ECP_PointCmp(const ECC_Para *para, const ECC_Point *a, const ECC_Point *b);
229 
230 /**
231  * @ingroup ecc
232  * @brief   Calculate r = k * pt. When pt is NULL, calculate r = k * G
233  *          The pre-computation table under para will be updated.
234  *
235  * @param   para [IN] Curve parameter information
236  * @param   r [OUT] Output point information
237  * @param   k [IN] Scalar
238  * @param   pt [IN] Point data, which can be set to NULL
239  *
240  * @retval CRYPT_SUCCESS    set successfully
241  * @retval For details about other errors, see crypt_errno.h
242  */
243 int32_t ECP_PointMul(ECC_Para *para,  ECC_Point *r,
244     const BN_BigNum *k, const ECC_Point *pt);
245 
246 /**
247  * @ingroup ecc
248  * @brief   Calculate r = k * pt. When pt is NULL, calculate r = k * G
249  *          The pre-computation table under para will be updated.
250  *          Non-consttime calculation
251  *
252  * @param   para [IN] Curve parameter information
253  * @param   r [OUT] Output point information
254  * @param   k [IN] Scalar
255  * @param   pt [IN] Point data, which can be set to NULL
256  *
257  * @retval CRYPT_SUCCESS    set successfully
258  * @retval For details about other errors, see crypt_errno.h
259  */
260 int32_t ECP_PointMulFast(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt);
261 
262 /**
263  * @ingroup ecc
264  * @brief   Obtaining a prime number curve (p + 1)/2
265  *
266  * @param   p [IN] Input module
267  *
268  * @retval non-NULL   succeeded.
269  * @retval NULL       failed
270  */
271 BN_BigNum *ECP_HalfPGet(const BN_BigNum *p);
272 
273 /**
274  * @ingroup ecc
275  * @brief   Search implementation method by curve ID
276  *
277  * @param   id [IN] Curve enumeration
278  *
279  * @retval non-NULL   succeeded.
280  * @retval NULL       failed
281  */
282 const ECC_Method *ECC_FindMethod(CRYPT_PKEY_ParaId id);
283 
284 /**
285  * @ingroup ecc
286  * @brief   nist Calculation of multiplication(double) of points of prime curve: r = a + a
287  *
288  * @param   para [IN] Curve parameters
289  * @param   r [OUT] Output point information
290  * @param   a [IN] Input point information
291  *
292  * @retval CRYPT_SUCCESS    succeeded.
293  * @retval For details about other errors, see crypt_errno.h
294  */
295 int32_t ECP_NistPointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a);
296 
297 /**
298  * @ingroup ecc
299  * @brief   nist Calculation of multi-double of points of prime curve: r = (2^m)*a
300  *
301  * @param   para [IN] Curve parameters
302  * @param   r [OUT] Output point information
303  * @param   a [IN] Input point information
304  * @param   m [IN] Exponential information of point multiplication scalar
305  *
306  * @retval CRYPT_SUCCESS    succeeded.
307  * @retval For details about other errors, see crypt_errno.h
308  */
309 int32_t ECP_NistPointMultDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m);
310 
311 /**
312  * @ingroup ecc
313  * @brief   nist Calculation of multiplication(double) of points of prime curve: r = a + b
314  *
315  * @param   para [IN] Curve parameters
316  * @param   r [OUT] Output point information
317  * @param   a [IN] Input point information, a can be the jacobi coordinate.
318  * @param   b [IN] Input point information, b must be the affine coordinate.
319  *
320  * @retval CRYPT_SUCCESS    succeeded.
321  * @retval For details about other errors, see crypt_errno.h
322  */
323 int32_t ECP_NistPointAddAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
324 
325 /**
326  * @ingroup ecc
327  * @brief   nist Calculation of multiplication(double) of points of prime curve: r = a + b
328  *
329  * @param   para [IN] Curve parameters
330  * @param   r [OUT] Output point information
331  * @param   a [IN] Input point information, a can be the jacobi coordinate.
332  * @param   b [IN] Input point information, b can be the jacobi coordinate.
333  *
334  * @retval CRYPT_SUCCESS    succeeded.
335  * @retval For details about other errors, see crypt_errno.h
336  */
337 int32_t ECP_NistPointAdd(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
338 
339 /**
340  * @ingroup ecc
341  * @brief   Convert the point to the affine coordinate and encode the point information as a data stream.
342  *
343  * @param   para [IN] Curve parameter information
344  * @param   pt [IN/OUT] Point data
345  * @param   data [OUT] data stream
346  * @param   dataLen [IN/OUT] The input is the buff length of data and the output is the valid length of data.
347  * @param   format [IN] Encoding format
348  *
349  * @retval CRYPT_SUCCESS    succeeded.
350  * @retval For details about other errors, see crypt_errno.h
351  */
352 int32_t ECP_EncodePoint(const ECC_Para *para, ECC_Point *pt, uint8_t *data, uint32_t *dataLen,
353     CRYPT_PKEY_PointFormat format);
354 
355 /**
356  * @ingroup ecc
357  * @brief   Encode the data stream into point information.
358  *
359  * @param   para [IN] Curve parameter information
360  * @param   pt [OUT] Point data
361  * @param   data [IN] data stream
362  * @param   dataLen [IN] data stream length
363  *
364  * @retval CRYPT_SUCCESS    succeeded.
365  * @retval For details about other errors, see crypt_errno.h
366  */
367 int32_t ECP_DecodePoint(const ECC_Para *para, ECC_Point *pt, const uint8_t *data, uint32_t dataLen);
368 
369 /**
370  * @brief   Calculate r = 1/a mod para->n
371  *
372  * @param   para [IN] Curve parameter information
373  * @param   r [OUT] Output modulus inverse value
374  * @param   a [IN] BigNum that needs to be inverted.
375  *
376  * @retval CRYPT_SUCCESS    set successfully
377  * @retval For details about other errors, see crypt_errno.h
378  */
379 int32_t ECP_ModOrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a);
380 
381 #ifdef HITLS_CRYPTO_CURVE_MONT
382 
383 /**
384  * The nist curve is based on Montgomery's calculation of double points.
385  * r = a + a
386  */
387 int32_t ECP_NistPointDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a);
388 
389 /**
390  * The nist curve is based on Montgomery's calculation of multi-double points.
391  * r = m * (a + a)
392  */
393 int32_t ECP_NistPointMultDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m);
394 
395 /**
396  * The nist curve is based on Montgomery's calculation of add points.
397  * r = a + b, b must be an affine point.
398  */
399 int32_t ECP_NistPointAddAffineMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
400 
401 /**
402  * The nist curve is based on Montgomery's calculation of add points.
403  * r = a + b
404  */
405 int32_t ECP_NistPointAddMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
406 
407 /**
408  * The nist curve is based on Montgomery's calculation of turn an point to an affine point.
409  * r = a -> affine a
410  */
411 int32_t ECP_Point2AffineMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt);
412 
413 /**
414  * The nist curve is based on Montgomery's calculation of turn an point to an affine point.
415  * r = a -> affine a
416  */
417 int32_t ECP_PrimePointDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a);
418 
419 /**
420  * The prime curve is based on Montgomery's calculation of multi-double points.
421  * r = m * (a + a)
422  */
423 int32_t ECP_PrimePointMultDoubleMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, uint32_t m);
424 
425 /**
426  * The prime curve is based on Montgomery's calculation of add points.
427  * r = a + b, b must be an affine point.
428  */
429 int32_t ECP_PrimePointAddAffineMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
430 
431 /**
432  * The prime curve is based on Montgomery's calculation of add points.
433  * r = a + b
434  */
435 int32_t ECP_PrimePointAddMont(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b);
436 
437 /**
438  * The prime curve is based on Montgomery's calculation of  k * pt.
439  * The implementation is based on the Montgomery ladder.
440  */
441 int32_t ECP_PointMulMont(ECC_Para *para,  ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt);
442 
443 #endif // HITLS_CRYPTO_CURVE_MONT
444 
445 #ifdef __cplusplus
446 }
447 #endif
448 
449 #endif // HITLS_CRYPTO_ECC
450 
451 #endif // ECC_LOCAL_H
452