• 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 CRYPT_BN_H
17 #define CRYPT_BN_H
18 
19 #include "hitls_build.h"
20 #ifdef HITLS_CRYPTO_BN
21 
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #if defined(HITLS_SIXTY_FOUR_BITS)
31 #define BN_UINT uint64_t
32 #define BN_MASK (0xffffffffffffffffL)
33 #define BN_DEC_VAL (10000000000000000000ULL)
34 #define BN_DEC_LEN 19
35 #define BN_UNIT_BITS 64
36 #elif defined(HITLS_THIRTY_TWO_BITS)
37 #define BN_UINT uint32_t
38 #define BN_MASK (0xffffffffL)
39 #define BN_DEC_VAL (1000000000L)
40 #define BN_DEC_LEN 9
41 #define BN_UNIT_BITS 32
42 #else
43 #error BN_UINT MUST be defined first.
44 #endif
45 
46 #define BN_MAX_BITS         (1u << 29) /* @note: BN_BigNum bits limitation 2^29 bits */
47 #define BN_BITS_TO_BYTES(n) (((n) + 7) >> 3) /* @note: Calcute bytes form bits, bytes = (bits + 7) >> 3 */
48 #define BN_BYTES_TO_BITS(n) ((n) << 3) /* bits = bytes * 8 = bytes << 3 */
49 #define BN_UINT_BITS ((uint32_t)sizeof(BN_UINT) << 3)
50 #define BITS_TO_BN_UNIT(bits) (((bits) + BN_UINT_BITS - 1) / BN_UINT_BITS)
51 /* Flag of BigNum. If a new number is added, the value increases by 0x01 0x02 0x04... */
52 typedef enum {
53     CRYPT_BN_FLAG_OPTIMIZER = 0x01,      /**< Flag of BigNum, indicating the BigNum obtained from the optimizer */
54     CRYPT_BN_FLAG_STATIC = 0x02,      /**< Flag of BigNum, indicating the BN memory management belongs to the user. */
55     CRYPT_BN_FLAG_CONSTTIME = 0x04,      /**< Flag of BigNum, indicating the constant time execution. */
56 } CRYPT_BN_FLAG;
57 
58 typedef struct BigNum {
59     bool sign; /* *< bignum sign: negtive(true) or not(false) */
60     uint32_t size; /* *< bignum size (count of BN_UINT) */
61     uint32_t room; /* *< bignum max size (count of BN_UINT) */
62     uint32_t flag; /* *< bignum flag */
63     BN_UINT *data; /* *< bignum data chunk(most significant limb at the largest) */
64 } BN_BigNum;
65 
66 typedef struct BnMont BN_Mont;
67 
68 typedef struct BnOptimizer BN_Optimizer;
69 
70 typedef struct BnCbCtx BN_CbCtx;
71 
72 typedef int32_t (*BN_CallBack)(BN_CbCtx *, int32_t, int32_t);
73 
74 /* If a is 0, all Fs are returned. If a is not 0, 0 is returned. */
BN_IsZeroUintConsttime(BN_UINT a)75 static inline BN_UINT BN_IsZeroUintConsttime(BN_UINT a)
76 {
77     BN_UINT t = ~a & (a - 1); // The most significant bit of t is 1 only when a == 0.
78     // Shifting 3 bits to the left is equivalent to multiplying 8, convert the number of bytes into the number of bits.
79     return (BN_UINT)0 - (t >> (((uint32_t)sizeof(BN_UINT) << 3) - 1));
80 }
81 
82 #ifdef HITLS_CRYPTO_EAL_BN
83 /* Check whether the BN entered externally is valid. */
84 bool BnVaild(const BN_BigNum *a);
85 #endif
86 
87 /**
88  * @ingroup bn
89  * @brief   BigNum creation
90  *
91  * @param   bits [IN] Number of bits
92  *
93  * @retval not-NULL Success
94  * @retval NULL fail
95  */
96 BN_BigNum *BN_Create(uint32_t bits);
97 
98 /**
99  * @ingroup bn
100  * @brief   BigNum Destruction
101  *
102  * @param   a [IN] BigNum
103  *
104  * @retval none
105  */
106 void BN_Destroy(BN_BigNum *a);
107 
108 /**
109  * @ingroup bn
110  * @brief   BN initialization
111  * @attention This interface is used to create the BN structure between modules. The BN does not manage the memory of
112               the external BN structure and internal data space. the interface only the fixed attributes such as data,
113               room, and flag. The size attribute is defined by the caller.
114  *
115  * @param   bn [IN/OUT] BN, which is created by users and is not managed by the BN.
116  * @param   data [IN] BN data, the memory is allocated by the user and is not managed by the BN.
117  * @param   number [IN] number of BN that need to be initialized.
118  *
119  * @retval void
120  */
121 void BN_Init(BN_BigNum *bn, BN_UINT *data, uint32_t room, int32_t number);
122 
123 #ifdef HITLS_CRYPTO_BN_CB
124 
125 /**
126  * @ingroup bn
127  * @brief   BigNum callback creation
128  *
129  * @param   none
130  *
131  * @retval not-NULL Success
132  * @retval NULL fail
133  */
134 BN_CbCtx *BN_CbCtxCreate(void);
135 
136 /**
137  * @ingroup bn
138  * @brief   BigNum callback configuration
139  *
140  * @param   gencb [out] Callback
141  * @param   callBack [in] Callback API
142  * @param   arg [in] Callback parameters
143  *
144  * @retval none
145  */
146 void BN_CbCtxSet(BN_CbCtx *gencb, BN_CallBack callBack, void *arg);
147 
148 /**
149  * @ingroup bn
150  * @brief   Invoke the callback.
151  *
152  * @param   callBack [out] Callback
153  * @param   process [in] Parameter
154  * @param   target [in] Parameter
155 
156  * @retval CRYPT_SUCCESS    succeeded
157  * @retval other            determined by the callback function
158  */
159 int32_t BN_CbCtxCall(BN_CbCtx *callBack, int32_t process, int32_t target);
160 
161 /**
162  * @ingroup bn
163  * @brief Obtain the arg parameter in the callback.
164  *
165  * @param callBack [in] Callback
166  * @retval void* NULL or callback parameter.
167  */
168 void *BN_CbCtxGetArg(BN_CbCtx *callBack);
169 
170 /**
171  * @ingroup bn
172  * @brief   Callback release
173  *
174  * @param   cb [in] Callback
175  *
176  * @retval none
177  */
178 void BN_CbCtxDestroy(BN_CbCtx *cb);
179 #endif
180 
181 /**
182  * @ingroup bn
183  * @brief Set the symbol.
184  *
185  * @param a    [IN] BigNum
186  * @param sign [IN] symbol. The value true indicates a negative number and the value false indicates a positive number.
187  *
188  * @retval CRYPT_SUCCESS
189  * @retval CRYPT_NULL_INPUT         Invalid null pointer
190  * @retval CRYPT_BN_NO_NEGATOR_ZERO 0 cannot be set to a negative sign.
191  */
192 int32_t BN_SetSign(BN_BigNum *a, bool sign);
193 
194 /**
195  * @ingroup bn
196  * @brief Set the flag.
197  *
198  * @param a    [IN] BigNum
199  * @param flag [IN] flag, for example, BN_MARK_CONSTTIME indicates that the constant interface is used.
200  *
201  * @retval CRYPT_SUCCESS
202  * @retval CRYPT_NULL_INPUT         Invalid null pointer
203  * @retval CRYPT_BN_FLAG_INVALID    Invalid BigNum flag.
204  */
205 int32_t BN_SetFlag(BN_BigNum *a, uint32_t flag);
206 
207 /**
208  * @ingroup bn
209  * @brief BigNum copy
210  *
211  * @param r [OUT] BigNum
212  * @param a [IN] BigNum
213  *
214  * @retval CRYPT_SUCCESS            succeeded.
215  * @retval CRYPT_NULL_INPUT         Invalid null pointer
216  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
217  */
218 int32_t BN_Copy(BN_BigNum *r, const BN_BigNum *a);
219 
220 /**
221  * @ingroup bn
222  * @brief Generate a BigNum with the same content.
223  *
224  * @param a [IN] BigNum
225  *
226  * @retval Not NULL  Success
227  * @retval NULL      failure
228  */
229 BN_BigNum *BN_Dup(const BN_BigNum *a);
230 
231 /**
232  * @ingroup bn
233  * @brief Check whether the value of a BigNum is 0.
234  *
235  * @attention The input parameter cannot be null.
236  * @param a [IN] BigNum
237  *
238  * @retval true. The value of a BigNum is 0.
239  * @retval false. The value of a BigNum is not 0.
240  * @retval other: indicates that the input parameter is abnormal.
241  *
242  */
243 bool BN_IsZero(const BN_BigNum *a);
244 
245 /**
246  * @ingroup bn
247  * @brief Check whether the value of a BigNum is 1.
248  *
249  * @attention The input parameter cannot be null.
250  * @param a [IN] BigNum
251  *
252  * @retval true. The value of a BigNum is 1.
253  * @retval false. The value of a BigNum is not 1.
254  * @retval other: indicates that the input parameter is abnormal.
255  *
256  */
257 bool BN_IsOne(const BN_BigNum *a);
258 
259 /**
260  * @ingroup bn
261  * @brief Check whether a BigNum is a negative number.
262  *
263  * @attention The input parameter cannot be null.
264  * @param a [IN] BigNum
265  *
266  * @retval true. The value of a BigNum is a negative number.
267  * @retval false. The value of a BigNum is not a negative number.
268  *
269  */
270 bool BN_IsNegative(const BN_BigNum *a);
271 
272 /**
273  * @ingroup bn
274  * @brief Check whether the value of a BigNum is an odd number.
275  *
276  * @attention The input parameter cannot be null.
277  * @param a [IN] BigNum
278  *
279  * @retval true. The value of a BigNum is an odd number.
280  * @retval false. The value of a BigNum is not an odd number.
281  * @retval other: indicates that the input parameter is abnormal.
282  *
283  */
284 bool BN_IsOdd(const BN_BigNum *a);
285 
286 /**
287  * @ingroup bn
288  * @brief Check whether the flag of a BigNum meets the expected flag.
289  *
290  * @param a    [IN] BigNum
291  * @param flag [IN] Flag. For example, BN_MARK_CONSTTIME indicates that the constant interface is used.
292  *
293  * @retval true, invalid null pointer
294  * @retval false, 0 cannot be set to a negative number.
295  * @retval other: indicates that the input parameter is abnormal.
296  */
297 bool BN_IsFlag(const BN_BigNum *a, uint32_t flag);
298 
299 /**
300  * @ingroup bn
301  * @brief Set the value of a BigNum to 0.
302  *
303  * @param a [IN] BigNum
304  *
305  * @retval CRYPT_SUCCESS
306  * @retval CRYPT_NULL_INPUT Invalid null pointer
307  * @retval other: indicates that the input parameter is abnormal.
308  */
309 int32_t BN_Zeroize(BN_BigNum *a);
310 
311 /**
312  * @ingroup bn
313  * @brief Compare whether the value of BigNum a is the target limb w.
314  *
315  * @attention The input parameter cannot be null.
316  * @param a [IN] BigNum
317  * @param w [IN] Limb
318  *
319  * @retval true: equal
320  * @retval false, not equal
321  * @retval other: indicates that the input parameter is abnormal.
322  */
323 bool BN_IsLimb(const BN_BigNum *a, const BN_UINT w);
324 
325 /**
326  * @ingroup bn
327  * @brief Set a limb to the BigNum.
328  *
329  * @param a [IN] BigNum
330  * @param w [IN] Limb
331  *
332  * @retval CRYPT_SUCCESS
333  * @retval CRYPT_NULL_INPUT     Invalid null pointer
334  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
335  */
336 int32_t BN_SetLimb(BN_BigNum *r, BN_UINT w);
337 
338 /**
339  * @ingroup bn
340  * @brief Obtain the limb from the BigNum.
341  *
342  * @param a [IN] BigNum
343  *
344  * @retval 0        Get 0
345  * @retval BN_MASK  Obtain the mask.
346  * @retval others   The limb is obtained successfully.
347  */
348 BN_UINT BN_GetLimb(const BN_BigNum *a);
349 
350 /**
351  * @ingroup bn
352  * @brief Obtain the value of the bit corresponding to a BigNum. The value is 1 or 0.
353  *
354  * @attention The input parameter of a BigNum cannot be null.
355  * @param a [IN] BigNum
356  * @param n [IN] Number of bits
357  *
358  * @retval true. The corresponding bit is 1.
359  * @retval false. The corresponding bit is 0.
360  *
361  */
362 bool BN_GetBit(const BN_BigNum *a, uint32_t n);
363 
364 /**
365  * @ingroup bn
366  * @brief Set the bit corresponding to the BigNum to 1.
367  *
368  * @param a [IN] BigNum
369  * @param n [IN] Number of bits
370  *
371  * @retval CRYPT_SUCCESS
372  * @retval CRYPT_NULL_INPUT             Invalid null pointer
373  * @retval CRYPT_BN_SPACE_NOT_ENOUGH    The space is insufficient.
374  */
375 int32_t BN_SetBit(BN_BigNum *a, uint32_t n);
376 
377 /**
378  * @ingroup bn
379  * @brief Clear the bit corresponding to the BigNum to 0.
380  *
381  * @param a [IN] BigNum
382  * @param n [IN] Number of bits
383  *
384  * @retval CRYPT_SUCCESS
385  * @retval CRYPT_NULL_INPUT             Invalid null pointer
386  * @retval CRYPT_BN_SPACE_NOT_ENOUGH    The space is insufficient.
387  */
388 int32_t BN_ClrBit(BN_BigNum *a, uint32_t n);
389 
390 /**
391  * @ingroup bn
392  * @brief Truncate a BigNum from the corresponding bit.
393  *
394  * @param a [IN] BigNum
395  * @param n [IN] Number of bits
396  *
397  * @retval CRYPT_SUCCESS
398  * @retval CRYPT_NULL_INPUT             Invalid null pointer
399  * @retval CRYPT_BN_SPACE_NOT_ENOUGH    The space is insufficient.
400  */
401 int32_t BN_MaskBit(BN_BigNum *a, uint32_t n);
402 
403 /**
404  * @ingroup bn
405  * @brief Obtain the valid bit length of a BigNum.
406  *
407  * @attention The input parameter of a BigNum cannot be null.
408  * @param a [IN] BigNum
409  *
410  * @retval uint32_t, valid bit length
411  */
412 uint32_t BN_Bits(const BN_BigNum *a);
413 
414 /**
415  * @ingroup bn
416  * @brief Obtain the valid byte length of a BigNum.
417  *
418  * @attention The large input parameter cannot be a null pointer.
419  * @param a [IN] BigNum
420  *
421  * @retval uint32_t, valid byte length of a BigNum
422  */
423 uint32_t BN_Bytes(const BN_BigNum *a);
424 
425 /**
426  * @ingroup bn
427  * @brief BigNum Calculate the greatest common divisor
428  * @par Description: gcd(a, b) (a, b!=0)
429  *
430  * @param r     [OUT] greatest common divisor
431  * @param a     [IN] BigNum
432  * @param b     [IN] BigNum
433  * @param opt   [IN] Optimizer
434  *
435  * @retval CRYPT_SUCCESS
436  * @retval CRYPT_NULL_INPUT             Invalid null pointer
437  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
438  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
439  * @retval CRYPT_BN_ERR_GCD_NO_ZERO     The greatest common divisor cannot be 0.
440  */
441 int32_t BN_Gcd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt);
442 
443 /**
444  * @ingroup bn
445  * @brief BigNum modulo inverse
446  *
447  * @param r   [OUT] Result
448  * @param x   [IN] BigNum
449  * @param m   [IN] mod
450  * @param opt [IN] Optimizer
451  *
452  * @retval CRYPT_SUCCESS
453  * @retval CRYPT_NULL_INPUT             Invalid null pointer
454  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
455  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
456  * @retval CRYPT_BN_ERR_NO_INVERSE      Cannot calculate the module inverse.
457  */
458 int32_t BN_ModInv(BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *m, BN_Optimizer *opt);
459 /**
460  * @ingroup bn
461  * @brief BigNum comparison
462  *
463  * @attention The input parameter of a BigNum cannot be null.
464  * @param a [IN] BigNum
465  * @param b [IN] BigNum
466  *
467  * @retval  0,a == b
468  * @retval  1,a > b
469  * @retval  -1,a < b
470  */
471 int32_t BN_Cmp(const BN_BigNum *a, const BN_BigNum *b);
472 
473 /**
474  * @ingroup bn
475  * @brief BigNum Addition
476  *
477  * @param r [OUT] and
478  * @param a [IN] Addendum
479  * @param b [IN] Addendum
480  *
481  * @retval CRYPT_SUCCESS
482  * @retval CRYPT_NULL_INPUT         Invalid null pointer
483  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
484  */
485 int32_t BN_Add(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b);
486 
487 /**
488  * @ingroup bn
489  * @brief BigNum plus limb
490  *
491  * @param r [OUT] and
492  * @param a [IN] Addendum
493  * @param w [IN] Addendum
494  *
495  * @retval CRYPT_SUCCESS
496  * @retval CRYPT_NULL_INPUT         Invalid null pointer
497  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
498  */
499 int32_t BN_AddLimb(BN_BigNum *r, const BN_BigNum *a, BN_UINT w);
500 
501 /**
502  * @ingroup bn
503  * @brief subtraction of large numbers
504  *
505  * @param r [OUT] difference
506  * @param a [IN] minuend
507  * @param b [IN] subtrahend
508  *
509  * @retval CRYPT_SUCCESS
510  * @retval CRYPT_NULL_INPUT     Invalid null pointer
511  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
512  */
513 int32_t BN_Sub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b);
514 
515 /**
516  * @ingroup bn
517  * @brief BigNum minus limb
518  *
519  * @param   r [OUT] difference
520  * @param   a [IN] minuend
521  * @param   w [IN] subtrahend
522  *
523  * @retval CRYPT_SUCCESS
524  * @retval CRYPT_NULL_INPUT         Invalid null pointer
525  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
526  */
527 int32_t BN_SubLimb(BN_BigNum *r, const BN_BigNum *a, BN_UINT w);
528 
529 /**
530  * @ingroup bn
531  * @brief BigNum Multiplication
532  *
533  * @param r   [OUT] product
534  * @param a   [IN] multiplier
535  * @param b   [IN] multiplier
536  * @param opt [IN] Optimizer
537  *
538  * @retval CRYPT_SUCCESS
539  * @retval CRYPT_NULL_INPUT             Invalid null pointer
540  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
541  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
542  */
543 int32_t BN_Mul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt);
544 
545 /**
546  * @ingroup bn
547  * @brief Multiplication of BigNum by Limb
548  *
549  * @param   r [OUT] product
550  * @param   a [IN] multiplicand
551  * @param   w [IN] multiplier (limb)
552  *
553  * @retval CRYPT_SUCCESS
554  * @retval CRYPT_NULL_INPUT             Invalid null pointer
555  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
556  */
557 int32_t BN_MulLimb(BN_BigNum *r, const BN_BigNum *a, const BN_UINT w);
558 
559 /**
560  * @ingroup bn
561  * @brief BigNum square. r must not be a.
562  *
563  * @param r   [OUT] product
564  * @param a   [IN] multiplier
565  * @param opt [IN] Optimizer
566  *
567  * @retval CRYPT_SUCCESS
568  * @retval CRYPT_NULL_INPUT             Invalid null pointer
569  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
570  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
571  */
572 int32_t BN_Sqr(BN_BigNum *r, const BN_BigNum *a, BN_Optimizer *opt);
573 
574 /**
575  * @ingroup bn
576  * @brief BigNum Division
577  *
578  * @param q   [OUT] quotient
579  * @param r   [OUT] remainder
580  * @param x   [IN] dividend
581  * @param y   [IN] divisor
582  * @param opt [IN] optimizer
583  *
584  * @retval CRYPT_SUCCESS
585  * @retval CRYPT_NULL_INPUT             Invalid null pointer
586  * @retval CRYPT_INVALID_ARG            The addresses of q, r are identical, or both of them are null.
587  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
588  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
589  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    divisor cannot be 0.
590  */
591 int32_t BN_Div(BN_BigNum *q, BN_BigNum *r, const BN_BigNum *x, const BN_BigNum *y, BN_Optimizer *opt);
592 
593 /**
594  * @ingroup bn
595  * @brief BigNum divided by limb
596  *
597  * @param q [OUT] quotient
598  * @param r [OUT] remainder
599  * @param x [IN] dividend
600  * @param y [IN] Divisor (limb)
601  *
602  * @retval CRYPT_SUCCESS
603  * @retval CRYPT_NULL_INPUT             Invalid null pointer
604  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
605  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    divisor cannot be 0.
606  */
607 int32_t BN_DivLimb(BN_BigNum *q, BN_UINT *r, const BN_BigNum *x, const BN_UINT y);
608 
609 /**
610  * @ingroup bn
611  * @brief BigNum Modular addition
612  * @par Description: r = (a + b) mod (mod)
613  *
614  * @param r   [OUT] Modulus result
615  * @param a   [IN] BigNum
616  * @param b   [IN] BigNum
617  * @param mod [IN] mod
618  * @param opt [IN] Optimizer
619  *
620  * @retval CRYPT_SUCCESS
621  * @retval CRYPT_NULL_INPUT             Invalid null pointer
622  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
623  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
624  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    module cannot be 0.
625  */
626 int32_t BN_ModAdd(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
627     const BN_BigNum *mod, BN_Optimizer *opt);
628 /**
629  * @ingroup bn
630  * @brief BigNum Modular subtraction
631  * @par Description: r = (a - b) mod (mod)
632  *
633  * @param r   [OUT] Modulo result
634  * @param a   [IN] minuend
635  * @param b   [IN] subtrahend
636  * @param mod [IN] mod
637  * @param opt [IN] Optimizer
638  *
639  * @retval CRYPT_SUCCESS
640  * @retval CRYPT_NULL_INPUT             Invalid null pointer
641  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
642  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
643  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    module cannot be 0.
644  */
645 int32_t BN_ModSub(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
646     const BN_BigNum *mod, BN_Optimizer *opt);
647 
648 /**
649  * @ingroup bn
650  * @brief BigNum Modular multiplication
651  * @par Description: r = (a * b) mod (mod)
652  *
653  * @param r   [OUT] Modulus result
654  * @param a   [IN] BigNum
655  * @param b   [IN] BigNum
656  * @param mod [IN] mod
657  * @param opt [IN] Optimizer
658  *
659  * @retval CRYPT_SUCCESS
660  * @retval CRYPT_NULL_INPUT             Invalid null pointer
661  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
662  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
663  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    module cannot be 0.
664  */
665 int32_t BN_ModMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
666     const BN_BigNum *mod, BN_Optimizer *opt);
667 
668 /**
669  * @ingroup bn
670  * @brief BigNum Modular squared
671  * @par Description: r = (a ^ 2) mod (mod)
672  *
673  * @param r   [OUT] Modulus result
674  * @param a   [IN] BigNum
675  * @param mod [IN] mod
676  * @param opt [IN] Optimizer
677  *
678  * @retval CRYPT_SUCCESS
679  * @retval CRYPT_NULL_INPUT             Invalid null pointer
680  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
681  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
682  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    module cannot be 0.
683  */
684 int32_t BN_ModSqr(
685     BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt);
686 
687 /**
688  * @ingroup bn
689  * @brief BigNum Modular power
690  * @par Description: r = (a ^ e) mod (mod)
691  *
692  * @param r   [OUT] Modulus result
693  * @param a   [IN] BigNum
694  * @param mod [IN] mod
695  * @param opt [IN] Optimizer
696  *
697  * @retval CRYPT_SUCCESS
698  * @retval CRYPT_NULL_INPUT               Invalid null pointer
699  * @retval CRYPT_MEM_ALLOC_FAIL           Memory allocation failure
700  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL    Failed to apply for space from the optimizer.
701  * @retval CRYPT_BN_ERR_DIVISOR_ZERO      module cannot be 0.
702  * @retval CRYPT_BN_ERR_EXP_NO_NEGATIVE   exponent cannot be a negative number
703  */
704 int32_t BN_ModExp(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e,
705     const BN_BigNum *m, BN_Optimizer *opt);
706 
707 /**
708  * @ingroup bn
709  * @brief BigNum modulo
710  * @par Description: r = a mod m
711  *
712  * @param r   [OUT] Modulus result
713  * @param a   [IN] BigNum
714  * @param m   [IN] mod
715  * @param opt [IN] Optimizer
716  *
717  * @retval CRYPT_SUCCESS
718  * @retval CRYPT_NULL_INPUT             Invalid null pointer
719  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
720  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL  Failed to apply for space from the optimizer.
721  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    module cannot be 0.
722  */
723 int32_t BN_Mod(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt);
724 
725 /**
726  * @ingroup bn
727  * @brief BigNum modulo limb
728  * @par Description: r = a mod m
729  *
730  * @param r [OUT] Modulus result
731  * @param a [IN] BigNum
732  * @param m [IN] Modulus (limb)
733  *
734  * @retval CRYPT_SUCCESS
735  * @retval CRYPT_NULL_INPUT             Invalid null pointer
736  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
737  * @retval CRYPT_BN_ERR_DIVISOR_ZERO    module cannot be 0.
738  */
739 int32_t BN_ModLimb(BN_UINT *r, const BN_BigNum *a, const BN_UINT m);
740 
741 #ifdef HITLS_CRYPTO_BN_PRIME
742 /**
743  * @ingroup bn
744  * @brief generate BN prime
745  *
746  * @param r    [OUT] Generate a prime number.
747  * @param e    [OUT] A helper prime to reduce the number of Miller-Rabin primes check.
748  * @param bits [IN] Length of the generated prime number
749  * @param half [IN] Whether to generate a prime number greater than the maximum value of this prime number by 1/2:
750  *                  Yes: True, No: false
751  * @param opt  [IN] Optimizer
752  * @param cb   [IN] BigNum callback
753  * @retval CRYPT_SUCCESS                    The prime number is successfully generated.
754  * @retval CRYPT_NULL_INPUT                 Invalid null pointer.
755  * @retval CRYPT_MEM_ALLOC_FAIL             Memory allocation failure
756  * @retval CRYPT_BN_OPTIMIZER_STACK_FULL    The optimizer stack is full.
757  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL      Failed to apply for space from the optimizer.
758  * @retval CRYPT_BN_NOR_GEN_PRIME           Failed to generate prime numbers.
759  * @retval CRYPT_NO_REGIST_RAND             No random number is registered.
760  * @retval CRYPT_BN_RAND_GEN_FAIL           Failed to generate a random number.
761  */
762 int32_t BN_GenPrime(BN_BigNum *r, BN_BigNum *e, uint32_t bits, bool half, BN_Optimizer *opt, BN_CbCtx *cb);
763 
764 /**
765  * @ingroup bn
766  * @brief check prime number
767  *
768  * @param bn  [IN] Prime number to be checked
769  * @param checkTimes  [IN] the user can set the check times of miller-rabin testing.
770  *                         if checkTimes == 0, it will use the default detection times of miller-rabin.
771  * @param opt [IN] Optimizer
772  *
773  * @retval CRYPT_SUCCESS                    The check result is a prime number.
774  * @retval CRYPT_BN_NOR_CHECK_PRIME         The check result is a non-prime number.
775  * @retval CRYPT_NULL_INPUT                 Invalid null pointer
776  * @retval CRYPT_BN_OPTIMIZER_STACK_FULL    The optimizer stack is full.
777  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL      Failed to apply for space from the optimizer.
778  * @retval CRYPT_NO_REGIST_RAND             No random number is registered.
779  * @retval CRYPT_BN_RAND_GEN_FAIL           Failed to generate a random number.
780  */
781 int32_t BN_PrimeCheck(const BN_BigNum *bn, uint32_t checkTimes, BN_Optimizer *opt, BN_CbCtx *cb);
782 #endif // HITLS_CRYPTO_BN_PRIME
783 
784 #ifdef HITLS_CRYPTO_BN_RAND
785 #define BN_RAND_TOP_NOBIT      0 /* Not set bits */
786 #define BN_RAND_TOP_ONEBIT     1 /* Set the most significant bit to 1. */
787 #define BN_RAND_TOP_TWOBIT     2 /* Set the highest two bits to 1 */
788 
789 #define BN_RAND_BOTTOM_NOBIT   0 /* Not set bits */
790 #define BN_RAND_BOTTOM_ONEBIT  1 /* Set the least significant bit to 1. */
791 #define BN_RAND_BOTTOM_TWOBIT  2 /* Set the least significant two bits to 1. */
792 
793 /**
794  * @ingroup bn
795  * @brief generate random BigNum
796  *
797  * @param r      [OUT] Generate a random number.
798  * @param bits   [IN] Length of the generated prime number
799  * @param top    [IN] Generating the flag indicating whether to set the most significant bit of a random number
800  * @param bottom [IN] Generate the flag indicating whether to set the least significant bit of the random number.
801  *
802  * @retval CRYPT_SUCCESS                        A random number is generated successfully.
803  * @retval CRYPT_NULL_INPUT                     Invalid null pointer
804  * @retval CRYPT_MEM_ALLOC_FAIL                 Memory allocation failure
805  * @retval CRYPT_BN_ERR_RAND_TOP_BOTTOM         The top or bottom is invalid during random number generation.
806  * @retval CRYPT_NO_REGIST_RAND                 No random number is registered.
807  * @retval CRYPT_BN_RAND_GEN_FAIL               Failed to generate a random number.
808  * @retval CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH    The bit is too small during random number generation.
809  */
810 int32_t BN_Rand(BN_BigNum *r, uint32_t bits, uint32_t top, uint32_t bottom);
811 
812 /**
813  * @ingroup bn
814  * @brief generate random BigNum
815  *
816  * @param libCtx [IN] provider libCtx
817  * @param r      [OUT] Generate a random number.
818  * @param bits   [IN] Length of the generated prime number
819  * @param top    [IN] Generating the flag indicating whether to set the most significant bit of a random number
820  * @param bottom [IN] Generate the flag indicating whether to set the least significant bit of the random number.
821  *
822  * @retval CRYPT_SUCCESS                        A random number is generated successfully.
823  * @retval CRYPT_NULL_INPUT                     Invalid null pointer
824  * @retval CRYPT_MEM_ALLOC_FAIL                 Memory allocation failure
825  * @retval CRYPT_BN_ERR_RAND_TOP_BOTTOM         The top or bottom is invalid during random number generation.
826  * @retval CRYPT_BN_RAND_GEN_FAIL               Failed to generate a random number.
827  * @retval CRYPT_BN_ERR_RAND_BITS_NOT_ENOUGH    The bit is too small during random number generation.
828  */
829 int32_t BN_RandEx(void *libCtx, BN_BigNum *r, uint32_t bits, uint32_t top, uint32_t bottom);
830 
831 /**
832  * @ingroup bn
833  * @brief generate random BigNum
834  *
835  * @param r [OUT] Generate a random number.
836  * @param p [IN] Compare data so that the generated r < p
837  *
838  * @retval CRYPT_SUCCESS            A random number is successfully generated.
839  * @retval CRYPT_NULL_INPUT         Invalid null pointer
840  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
841  * @retval CRYPT_NO_REGIST_RAND     No random number is registered.
842  * @retval CRYPT_BN_RAND_GEN_FAIL   Failed to generate a random number.
843  * @retval CRYPT_BN_ERR_RAND_ZERO   Generate a random number smaller than 0.
844  * @retval CRYPT_BN_ERR_RAND_NEGATE Generate a negative random number.
845  */
846 int32_t BN_RandRange(BN_BigNum *r, const BN_BigNum *p);
847 
848 /**
849  * @ingroup bn
850  * @brief generate random BigNum
851  *
852  * @param libCtx [IN] provider libCtx
853  * @param r [OUT] Generate a random number.
854  * @param p [IN] Compare data so that the generated r < p
855  *
856  * @retval CRYPT_SUCCESS            A random number is successfully generated.
857  * @retval CRYPT_NULL_INPUT         Invalid null pointer
858  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
859  * @retval CRYPT_BN_RAND_GEN_FAIL   Failed to generate a random number.
860  * @retval CRYPT_BN_ERR_RAND_ZERO   Generate a random number smaller than 0.
861  * @retval CRYPT_BN_ERR_RAND_NEGATE Generate a negative random number.
862  */
863 int32_t BN_RandRangeEx(void *libCtx, BN_BigNum *r, const BN_BigNum *p);
864 #endif
865 /**
866  * @ingroup bn
867  * @brief Binary to BigNum
868  *
869  * @param r      [OUT] BigNum
870  * @param bin    [IN] Data stream to be converted
871  * @param binLen [IN] Data stream length
872  *
873  * @retval CRYPT_SUCCESS
874  * @retval CRYPT_NULL_INPUT     Invalid null pointer
875  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
876  */
877 int32_t BN_Bin2Bn(BN_BigNum *r, const uint8_t *bin, uint32_t binLen);
878 
879 /**
880  * @ingroup bn
881  * @brief Convert BigNum to a big-endian binary
882  *
883  * @param a      [IN] BigNum
884  * @param bin    [IN/OUT] Data stream to be converted -- The input pointer cannot be null.
885  * @param binLen [IN/OUT] Data stream length -- When input, binLen is also the length of the bin buffer.
886  *
887  * @retval CRYPT_SUCCESS
888  * @retval CRYPT_NULL_INPUT     Invalid null pointer
889  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
890  * @retval CRYPT_SECUREC_FAIL   An error occurred during the copy.
891  */
892 int32_t BN_Bn2Bin(const BN_BigNum *a, uint8_t *bin, uint32_t *binLen);
893 
894 /**
895  * @ingroup bn
896  * @brief fix size of BigNum
897  *
898  * @param a      [IN] BigNum
899  *
900  * @retval void
901  */
902 void BN_FixSize(BN_BigNum *a);
903 
904 /**
905  * @ingroup bn
906  * @brief
907  *
908  * @param a      [IN/OUT] BigNum
909  * @param words  [IN] the bn room that the caller wanted.
910  *
911  * @retval CRYPT_SUCCESS
912  * @retval others, see crypt_errno.h
913  */
914 int32_t BN_Extend(BN_BigNum *a, uint32_t words);
915 
916 /**
917  * @ingroup bn
918  * @brief Convert BigNum to binary to obtain big-endian data with the length of binLen.
919  *        The most significant bits are filled with 0.
920  *
921  * @param a      [IN] BigNum
922  * @param bin    [OUT] Data stream to be converted -- The input pointer cannot be null.
923  * @param binLen [IN] Data stream length -- When input, binLen is also the length of the bin buffer.
924  *
925  * @retval CRYPT_SUCCESS
926  * @retval CRYPT_NULL_INPUT             Invalid null pointer
927  * @retval CRYPT_BN_BUFF_LEN_NOT_ENOUGH The space is insufficient.
928  */
929 int32_t BN_Bn2BinFixZero(const BN_BigNum *a, uint8_t *bin, uint32_t binLen);
930 
931 #ifdef HITLS_CRYPTO_BN_STR_CONV
932 /**
933  * @ingroup bn
934  * @brief Hexadecimal to a BigNum
935  *
936  * @param r [OUT] BigNum
937  * @param r [IN] Data stream to be converted
938  *
939  * @retval CRYPT_SUCCESS
940  * @retval CRYPT_NULL_INPUT                 Invalid null pointer
941  * @retval CRYPT_MEM_ALLOC_FAIL             Memory allocation failure
942  * @retval CRYPT_BN_CONVERT_INPUT_INVALID   Invalid string
943  */
944 int32_t BN_Hex2Bn(BN_BigNum **r, const char *str);
945 
946 /**
947  * @ingroup bn
948  * @brief Convert BigNum to hexadecimal number
949  *
950  * @param a    [IN] BigNum
951  * @param char [OUT] Converts a hexadecimal string.
952  *
953  * @retval CRYPT_SUCCESS
954  * @retval CRYPT_NULL_INPUT     Invalid null pointer
955  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
956  */
957 char *BN_Bn2Hex(const BN_BigNum *a);
958 
959 /**
960  * @ingroup bn
961  * @brief Decimal to BigNum
962  *
963  * @param r   [OUT] BigNum
964  * @param str [IN] A decimal string to be converted
965  *
966  * @retval CRYPT_SUCCESS
967  * @retval CRYPT_NULL_INPUT                 Invalid null pointer
968  * @retval CRYPT_MEM_ALLOC_FAIL             Memory allocation failure
969  * @retval CRYPT_BN_CONVERT_INPUT_INVALID   Invalid string
970  */
971 int32_t BN_Dec2Bn(BN_BigNum **r, const char *str);
972 
973 /**
974  * @ingroup bn
975  * @brief Convert BigNum to decimal number
976  *
977  * @param r   [IN] BigNum
978  *
979  * @retval A decimal string after conversion or push error.
980  */
981 char *BN_Bn2Dec(const BN_BigNum *a);
982 #endif
983 
984 #if defined(HITLS_CRYPTO_CURVE_SM2_ASM) ||                                             \
985     ((defined(HITLS_CRYPTO_CURVE_NISTP521) || defined(HITLS_CRYPTO_CURVE_NISTP384_ASM)) && \
986         defined(HITLS_CRYPTO_NIST_USE_ACCEL))
987 /**
988  * @ingroup bn
989  * @brief Converting a 64-bit unsigned number array to a BigNum
990  *
991  * @param r     [OUT] BigNum
992  * @param array [IN] Array to be converted
993  * @param len   [IN] Number of elements in the array
994  *
995  * @retval CRYPT_SUCCESS
996  * @retval CRYPT_NULL_INPUT     Invalid null pointer
997  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
998  */
999 int32_t BN_U64Array2Bn(BN_BigNum *r, const uint64_t *array, uint32_t len);
1000 
1001 /**
1002  * @ingroup bn
1003  * @brief BigNum to 64-bit unsigned number array
1004  *
1005  * @param a     [IN] BigNum
1006  * @param array [IN/OUT] Array for storing results -- The input pointer cannot be null.
1007  * @param len   [IN/OUT] Length of the written array -- Number of writable elements when input
1008  *
1009  * @retval CRYPT_SUCCESS
1010  * @retval CRYPT_NULL_INPUT     Invalid null pointer
1011  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
1012  * @retval CRYPT_SECUREC_FAIL   A copy error occurs.
1013  */
1014 int32_t BN_Bn2U64Array(const BN_BigNum *a, uint64_t *array, uint32_t *len);
1015 #endif
1016 
1017 /**
1018  * @ingroup bn
1019  * @brief BigNum optimizer creation
1020  *
1021  * @param None
1022  *
1023  * @retval Not NULL Success
1024  * @retval NULL failure
1025  */
1026 BN_Optimizer *BN_OptimizerCreate(void);
1027 
1028 /**
1029  * @ingroup bn
1030  * @brief Destroy the BigNum optimizer.
1031  *
1032  * @param opt [IN] BigNum optimizer
1033  *
1034  * @retval none
1035  */
1036 void BN_OptimizerDestroy(BN_Optimizer *opt);
1037 
1038 /**
1039  * @ingroup bn
1040  * @brief set library context
1041  *
1042  * @param libCtx [IN] Library context
1043  * @param opt [OUT] BigNum optimizer
1044  *
1045  * @retval none
1046  */
1047 void BN_OptimizerSetLibCtx(void *libCtx, BN_Optimizer *opt);
1048 
1049 /**
1050  * @ingroup bn
1051  * @brief get library context
1052  *
1053  * @param opt [In] BigNum optimizer
1054  *
1055  * @retval library context
1056  */
1057 void *BN_OptimizerGetLibCtx(BN_Optimizer *opt);
1058 
1059 /**
1060  * @ingroup bn
1061  * @brief BigNum Montgomery context creation and setting
1062  *
1063  * @param m [IN] Modulus m, which must be positive and odd
1064  *
1065  * @retval Not NULL Success
1066  * @retval NULL failure
1067  */
1068 BN_Mont *BN_MontCreate(const BN_BigNum *m);
1069 
1070 /**
1071  * @ingroup bn
1072  * @brief BigNum Montgomery modular exponentiation.
1073  *        Whether to use the constant API depends on the property of the BigNum.
1074  *
1075  * @param r    [OUT] Modular exponentiation result
1076  * @param a    [IN] base
1077  * @param e    [IN] Index
1078  * @param mont [IN] Montgomery context
1079  * @param opt  [IN] Optimizer
1080  *
1081  * @retval CRYPT_SUCCESS                    calculated successfully.
1082  * @retval CRYPT_NULL_INPUT                 Invalid null pointer
1083  * @retval CRYPT_MEM_ALLOC_FAIL             Memory allocation failure
1084  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL      Failed to apply for space from the optimizer.
1085  * @retval CRYPT_BN_MONT_BASE_TOO_MAX       Montgomery modulus exponentiation base is too large
1086  * @retval CRYPT_BN_OPTIMIZER_STACK_FULL    The optimizer stack is full.
1087  * @retval CRYPT_BN_ERR_EXP_NO_NEGATE       exponent cannot be a negative number
1088  */
1089 int32_t BN_MontExp(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e, BN_Mont *mont,
1090     BN_Optimizer *opt);
1091 
1092 /**
1093  * @ingroup bn
1094  * @brief Constant time BigNum Montgomery modular exponentiation
1095  *
1096  * @param r    [OUT] Modular exponentiation result
1097  * @param a    [IN] base
1098  * @param e    [IN] exponent
1099  * @param mont [IN] Montgomery context
1100  * @param opt  [IN] Optimizer
1101  *
1102  * @retval CRYPT_SUCCESS                    calculated successfully.
1103  * @retval CRYPT_NULL_INPUT                 Invalid null pointer
1104  * @retval CRYPT_MEM_ALLOC_FAIL             Memory allocation failure
1105  * @retval CRYPT_BN_OPTIMIZER_GET_FAIL      Failed to apply for space from the optimizer.
1106  * @retval CRYPT_BN_MONT_BASE_TOO_MAX       Montgomery Modular exponentiation base is too large
1107  * @retval CRYPT_BN_OPTIMIZER_STACK_FULL    The optimizer stack is full.
1108  * @retval CRYPT_BN_ERR_EXP_NO_NEGATE       exponent cannot be a negative number
1109  */
1110 int32_t BN_MontExpConsttime(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *e,
1111     BN_Mont *mont, BN_Optimizer *opt);
1112 
1113 /**
1114  * @ingroup mont
1115  * @brief BigNum Montgomery Context Destruction
1116  *
1117  * @param mont [IN] BigNum Montgomery context
1118  *
1119  * @retval none
1120  */
1121 void BN_MontDestroy(BN_Mont *mont);
1122 
1123 /**
1124  * @ingroup bn
1125  * @brief shift a BigNum to the right
1126  *
1127  * @param r [OUT] Shift result
1128  * @param a [IN] Source data
1129  * @param n [IN] Shift bit num
1130  *
1131  * @retval CRYPT_SUCCESS            succeeded.
1132  * @retval CRYPT_NULL_INPUT         Invalid null pointer
1133  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
1134  * @retval CRYPT_SECUREC_FAIL       The security function returns an error.
1135  */
1136 int32_t BN_Rshift(BN_BigNum *r, const BN_BigNum *a, uint32_t n);
1137 
1138 /**
1139  * @ingroup bn
1140  * @brief shift a BigNum to the left
1141  *
1142  * @param r [OUT] Shift result
1143  * @param a [IN] Source data
1144  * @param n [IN] Shift bit num
1145  *
1146  * @retval CRYPT_SUCCESS            succeeded.
1147  * @retval CRYPT_NULL_INPUT         Invalid null pointer
1148  * @retval CRYPT_MEM_ALLOC_FAIL     Memory allocation failure
1149  */
1150 int32_t BN_Lshift(BN_BigNum *r, const BN_BigNum *a, uint32_t n);
1151 
1152 #ifdef HITLS_CRYPTO_DSA
1153 int32_t BN_MontExpMul(BN_BigNum *r, const BN_BigNum *a1, const BN_BigNum *e1,
1154     const BN_BigNum *a2, const BN_BigNum *e2, BN_Mont *mont, BN_Optimizer *opt);
1155 #endif
1156 
1157 #ifdef HITLS_CRYPTO_ECC
1158 /**
1159  * @ingroup bn
1160  * @brief Mould opening root
1161  * @par Description: r^2 = a mod p; p-1=q*2^s.
1162  *      In the current implementation s=1 will take a special branch, and the calculation speed is faster.
1163  *      The fast calculation branch with s=2 is not implemented currently.
1164  *      Currently, the s corresponding to the mod p of the EC nist224, 256, 384, and 521 is 96, 1, 1, and 1 respectively
1165  *      The branch with s=2 is not used.
1166  *      The root number is provided for the EC.
1167  * @param r   [OUT] Modular root result
1168  * @param a   [IN] Source data, 0 <= a <= p-1
1169  * @param p   [IN] module, odd prime number
1170  * @param opt [IN] Optimizer
1171  *
1172  * @retval CRYPT_SUCCESS                calculated successfully.
1173  * @retval CRYPT_NULL_INPUT             Invalid null pointer
1174  * @retval CRYPT_BN_ERR_SQRT_PARA       The input parameter is incorrect.
1175  * @retval CRYPT_BN_ERR_LEGENDE_DATA:
1176  * Failed to find the specific number of the Legendre sign (z|p) of z to p equal to -1 when calculating the square root.
1177  * @retval CRYPT_BN_ERR_NO_SQUARE_ROOT  The square root cannot be found.
1178  */
1179 int32_t BN_ModSqrt(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *p, BN_Optimizer *opt);
1180 #endif
1181 
1182 #if defined(HITLS_CRYPTO_CURVE_SM2_ASM) || (defined(HITLS_CRYPTO_CURVE_NISTP256_ASM) && \
1183     defined(HITLS_CRYPTO_NIST_USE_ACCEL))
1184 /**
1185  * @ingroup bn
1186  * @brief BigNum to BN_UINT array
1187  *
1188  * @param src  [IN] BigNum
1189  * @param dst  [OUT] BN_UINT array for receiving the conversion result
1190  * @param size [IN] Length of the dst buffer
1191  *
1192  * @retval CRYPT_SUCCESS
1193  * @retval CRYPT_NULL_INPUT     Invalid null pointer
1194  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
1195  * @retval CRYPT_SECUREC_FAIL   The security function returns an error.
1196  */
1197 int32_t BN_BN2Array(const BN_BigNum *src, BN_UINT *dst, uint32_t size);
1198 
1199 /**
1200  * @ingroup bn
1201  * @brief BN_UINT array to BigNum
1202  *
1203  * @param dst [OUT] BigNum
1204  * @param src [IN] BN_UINT array to be converted
1205  * @param size [IN] Length of the src buffer
1206  *
1207  * @retval CRYPT_SUCCESS
1208  * @retval CRYPT_NULL_INPUT     Invalid null pointer.
1209  * @retval CRYPT_MEM_ALLOC_FAIL Memory allocation failure
1210  */
1211 int32_t BN_Array2BN(BN_BigNum *dst, const BN_UINT *src, const uint32_t size);
1212 #endif
1213 
1214 #ifdef HITLS_CRYPTO_ECC
1215 /**
1216  * @ingroup bn
1217  * @brief Copy with the mask. When the mask is set to (0), r = a; when the mask is set to (-1), r = b.
1218  *
1219  * @attention Data r, a, and b must have the same room.
1220  *
1221  * @param r    [OUT] Output result
1222  * @param a    [IN] Source data
1223  * @param b    [IN] Source data
1224  * @param mask [IN] Mask data
1225  *
1226  * @retval CRYPT_SUCCESS    succeeded.
1227  * @retval For details about other errors, see crypt_errno.h.
1228  */
1229 int32_t BN_CopyWithMask(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_UINT mask);
1230 
1231 /**
1232  * @ingroup bn
1233  * @brief Calculate r = (a - b) % mod
1234  *
1235  * @attention This API is invoked in the area where ECC point computing is intensive and is performance-sensitive.
1236  * The user must ensure that a < mod, b < mod
1237  * In addition, a->room and b->room are not less than mod->size.
1238  * All data are non-negative
1239  * The mod information cannot be 0.
1240  * Otherwise, the interface may not be functional.
1241  *
1242  * @param r   [OUT] Output result
1243  * @param a   [IN] Source data
1244  * @param b   [IN] Source data
1245  * @param mod [IN] Modular data
1246  * @param opt [IN] Optimizer
1247  *
1248  * @retval CRYPT_SUCCESS    succeeded.
1249  * @retval For details about other errors, see crypt_errno.h.
1250  */
1251 int32_t BN_ModSubQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
1252     const BN_BigNum *mod, const BN_Optimizer *opt);
1253 
1254 /**
1255  * @ingroup bn
1256  * @brief Calculate r = (a + b) % mod
1257  *
1258  * @attention This API is invoked in the area where ECC point computing is intensive and is performance-sensitive.
1259  * The user must ensure that a < mod, b < mod
1260  * In addition, a->room and b->room are not less than mod->size.
1261  * All data are non-negative
1262  * The mod information cannot be 0.
1263  * Otherwise, the interface may not be functional.
1264  *
1265  * @param r   [OUT] Output result
1266  * @param a   [IN] Source data
1267  * @param b   [IN] Source data
1268  * @param mod [IN] Modular data
1269  * @param opt [IN] Optimizer
1270  *
1271  * @retval CRYPT_SUCCESS    succeeded.
1272  * @retval For details about other errors, see crypt_errno.h.
1273  */
1274 int32_t BN_ModAddQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
1275     const BN_BigNum *mod, const BN_Optimizer *opt);
1276 
1277 /**
1278  * @ingroup bn
1279  * @brief Calculate r = (a * b) % mod
1280  *
1281  * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive.
1282  * The user must ensure that a < mod, b < mod
1283  * In addition, a->room and b->room are not less than mod->size.
1284  * All data are non-negative
1285  * The mod information can only be the parameter p of the curve of nistP224, nistP256, nistP384, and nistP521.
1286  * Otherwise, the interface may not be functional.
1287  *
1288  * @param r   [OUT] Output result
1289  * @param a   [IN] Source data
1290  * @param b   [IN] Source data
1291  * @param mod [IN] Modular data
1292  * @param opt [IN] Optimizer
1293  *
1294  * @retval CRYPT_SUCCESS    succeeded.
1295  * @retval For other errors, see crypt_errno.h.
1296  */
1297 int32_t BN_ModNistEccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
1298     void *mod, BN_Optimizer *opt);
1299 
1300 /**
1301  * @ingroup bn
1302  * @brief Calculate r = (a ^ 2) % mod
1303  *
1304  * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive.
1305  * The user must guarantee a < mod
1306  * In addition, a->room are not less than mod->size.
1307  * All data are non-negative
1308  * The mod information can only be the parameter p of the curve of nistP224, nistP256, nistP384, and nistP521.
1309  * Otherwise, the interface may not be functional.
1310  *
1311  * @param r   [OUT] Output result
1312  * @param a   [IN] Source data
1313  * @param mod [IN] Modular data
1314  * @param opt [IN] Optimizer
1315  *
1316  * @retval CRYPT_SUCCESS    succeeded.
1317  * @retval For details about other errors, see crypt_errno.h.
1318  */
1319 int32_t BN_ModNistEccSqr(BN_BigNum *r, const BN_BigNum *a, void *mod, BN_Optimizer *opt);
1320 #endif
1321 
1322 #ifdef HITLS_CRYPTO_CURVE_SM2
1323 /**
1324  * @ingroup ecc
1325  * @brief   sm2 curve: calculate r = (a*b)% mod
1326  *
1327  * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive.
1328  * The user must guarantee a < mod、b < mod
1329  * In addition, a->room and b->room are not less than mod->size.
1330  * All data are non-negative
1331  * The mod information can only be the parameter p of the curve of sm2.
1332  * Otherwise, the interface may not be functional.
1333  *
1334  * @param r   [OUT] Output result
1335  * @param a   [IN] Source data
1336  * @param b   [IN] Source data
1337  * @param mod [IN] Modular data
1338  * @param opt [IN] Optimizer
1339  *
1340  * @retval CRYPT_SUCCESS    succeeded.
1341  * @retval For details about other errors, see crypt_errno.h.
1342  */
1343 int32_t BN_ModSm2EccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, void *data, BN_Optimizer *opt);
1344 
1345 /**
1346  * @ingroup ecc
1347  * @brief   sm2 curve: calculate r = (a ^ 2) % mod
1348  *
1349  * @attention This API is invoked in the area where ECC point computing is intensive and is performance sensitive.
1350  * The user must guarantee a < mod
1351  * In addition, a->room are not less than mod->size.
1352  * All data are non-negative
1353  * The mod information can only be the parameter p of the curve of sm2.
1354  * Otherwise, the interface may not be functional.
1355  *
1356  * @param r   [OUT] Output result
1357  * @param a   [IN] Source data
1358  * @param mod [IN] Modular data
1359  * @param opt [IN] Optimizer
1360  *
1361  * @retval CRYPT_SUCCESS    succeeded.
1362  * @retval For details about other errors, see crypt_errno.h.
1363  */
1364 int32_t BN_ModSm2EccSqr(BN_BigNum *r, const BN_BigNum *a, void *data, BN_Optimizer *opt);
1365 #endif
1366 
1367 #ifdef HITLS_CRYPTO_BN_PRIME_RFC3526
1368 /**
1369  * @ingroup bn
1370  * @brief Return the corresponding length of modulo exponent of the BigNum.
1371  *
1372  * @param r   [OUT] Output result
1373  * @param len [IN] Length
1374  *
1375  * @retval Not NULL     Success
1376  * @retval NULL         failure
1377  */
1378 BN_BigNum *BN_GetRfc3526Prime(BN_BigNum *r, uint32_t len);
1379 #endif
1380 
1381 /**
1382  * @ingroup bn
1383  * @brief Return the number of security bits provided by a specific algorithm and specific key size.
1384  *
1385  * @param [OUT] Output the result.
1386  * @param pubLen [IN] Size of the public key
1387  * @param prvLen [IN] Size of the private key.
1388  *
1389  * @retval Number of security bits
1390  */
1391 int32_t BN_SecBits(int32_t pubLen, int32_t prvLen);
1392 
1393 #if defined(HITLS_CRYPTO_RSA)
1394 
1395 /**
1396  * @ingroup bn
1397  * @brief   Montgomery modulus calculation process, need a < m, b < m, All is positive numbers, The large number
1398      optimizer must be enabled before this function is used.
1399  *
1400  * @param   r [OUT] Output results
1401  * @param   a [IN] Input data
1402  * @param   b [IN] Input data
1403  * @param   mont [IN] Montgomery context
1404  * @param   opt [IN] Large number optimizer
1405  *
1406  * @retval  CRYPT_SUCCESS
1407  * @retval  For details about other errors, see crypt_errno.h.
1408  */
1409 int32_t MontMulCore(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Mont *mont, BN_Optimizer *opt);
1410 
1411 #endif // HITLS_CRYPTO_RSA
1412 
1413 #if defined(HITLS_CRYPTO_BN_PRIME)
1414 /**
1415  * @ingroup bn
1416  * @brief   Montgomery modulus calculation process, need a < m, unlimited symbols.
1417  *
1418  * @param   r [OUT] Output results
1419  * @param   a [IN] Input data
1420  * @param   mont [IN] Montgomery context
1421  * @param   opt [IN] Large number optimizer
1422  *
1423  * @retval  CRYPT_SUCCESS
1424  * @retval  For details about other errors, see crypt_errno.h.
1425  */
1426 int32_t MontSqrCore(BN_BigNum *r, const BN_BigNum *a, BN_Mont *mont, BN_Optimizer *opt);
1427 
1428 #endif // HITLS_CRYPTO_BN_PRIME
1429 
1430 /**
1431  * @ingroup bn
1432  * @brief   Enabling the big data optimizer
1433  *
1434  * @param   opt [IN] Large number optimizer
1435  *
1436  * @retval  CRYPT_SUCCESS
1437  * @retval  For details about other errors, see crypt_errno.h.
1438  */
1439 int32_t OptimizerStart(BN_Optimizer *opt);
1440 
1441 /**
1442  * @ingroup bn
1443  * @brief   Disabling the Large Number Optimizer
1444  *
1445  * @param   opt [IN] Large number optimizer
1446  *
1447  * @retval  CRYPT_SUCCESS
1448  * @retval  For details about other errors, see crypt_errno.h.
1449  */
1450 void OptimizerEnd(BN_Optimizer *opt);
1451 
1452 /**
1453  * @ingroup bn
1454  * @brief   Get Bn from the large number optimizer.
1455  *
1456  * @param   opt [IN] Large number optimizer
1457  * @param   room [IN] Length of the big number.
1458  *
1459  * @retval  BN_BigNum if success
1460  * @retval  NULL if failed
1461  */
1462 BN_BigNum *OptimizerGetBn(BN_Optimizer *opt, uint32_t room);
1463 
1464 #ifdef HITLS_CRYPTO_PAILLIER
1465 /**
1466  * @ingroup bn
1467  * @brief BigNum Calculate the least common multiple
1468  * @par Description: lcm(a, b) (a, b!=0)
1469  *
1470  * @param r     [OUT] least common multiple
1471  * @param a     [IN] BigNum
1472  * @param b     [IN] BigNum
1473  * @param opt   [IN] Optimizer
1474  *
1475  * @retval CRYPT_SUCCESS
1476  * @retval CRYPT_NULL_INPUT             Invalid null pointer
1477  * @retval CRYPT_MEM_ALLOC_FAIL         Memory allocation failure
1478  */
1479 int32_t BN_Lcm(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, BN_Optimizer *opt);
1480 #endif
1481 
1482 /**
1483  * @ingroup bn
1484  * @brief   Enabling the big data optimizer
1485  *
1486  * @param   opt [IN] Large number optimizer
1487  *
1488  * @retval  CRYPT_SUCCESS
1489  * @retval  For details about other errors, see crypt_errno.h.
1490  */
1491 int32_t OptimizerStart(BN_Optimizer *opt);
1492 
1493 /**
1494  * @ingroup bn
1495  * @brief   Disabling the Large Number Optimizer
1496  *
1497  * @param   opt [IN] Large number optimizer
1498  *
1499  * @retval  CRYPT_SUCCESS
1500  * @retval  For details about other errors, see crypt_errno.h.
1501  */
1502 void OptimizerEnd(BN_Optimizer *opt);
1503 
1504 /**
1505  * @ingroup bn
1506  * @brief   Get Bn from the large number optimizer.
1507  *
1508  * @param   opt [IN] Large number optimizer
1509  * @param   room [IN] Length of the big number.
1510  *
1511  * @retval  BN_BigNum if success
1512  * @retval  NULL if failed
1513  */
1514 BN_BigNum *OptimizerGetBn(BN_Optimizer *opt, uint32_t room);
1515 
1516 #ifdef HITLS_CRYPTO_CURVE_MONT
1517 
1518 /**
1519  * a, b is mont form.
1520  * r = a * b
1521  */
1522 int32_t BN_EcPrimeMontMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, void *data, BN_Optimizer *opt);
1523 
1524 /**
1525  * a is mont form.
1526  * r = a ^ 2
1527  */
1528 int32_t BN_EcPrimeMontSqr(BN_BigNum *r, const BN_BigNum *a, void *mont, BN_Optimizer *opt);
1529 
1530 /**
1531  * r = Reduce(r * RR)
1532  */
1533 int32_t BnMontEnc(BN_BigNum *r, BN_Mont *mont, BN_Optimizer *opt, bool consttime);
1534 
1535 /**
1536  * r = Reduce(r)
1537  */
1538 void BnMontDec(BN_BigNum *r, BN_Mont *mont);
1539 
1540 /**
1541  * This interface is a constant time.
1542  * if mask = BN_MASK. swap a and b.
1543  * if mask = 0, a and b remain as they are.
1544  */
1545 int32_t BN_SwapWithMask(BN_BigNum *a, BN_BigNum *b, BN_UINT mask);
1546 
1547 #endif // HITLS_CRYPTO_CURVE_MONT
1548 
1549 #ifdef __cplusplus
1550 }
1551 #endif
1552 
1553 #endif /* HITLS_CRYPTO_BN */
1554 
1555 #endif
1556