• 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 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_BN) && defined(HITLS_CRYPTO_ECC)
18 
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "bsl_err_internal.h"
22 #include "crypt_errno.h"
23 #include "bn_bincal.h"
24 
25 // Refresh the valid length of the BigNum r. The maximum length is modSize.
UpdateSize(BN_BigNum * r,uint32_t modSize)26 static void UpdateSize(BN_BigNum *r, uint32_t modSize)
27 {
28     uint32_t size = modSize;
29     while (size > 0) {
30         if (r->data[size - 1] != 0) {
31             break;
32         }
33         size--;
34     }
35     if (r->size > modSize) {
36         // Clear the high bits.
37         uint32_t i = 0;
38         for (i = modSize; i < r->size; i++) {
39             r->data[i] = 0;
40         }
41     }
42     r->size = size;
43     r->sign = false;
44 }
45 
46 #define P521SIZE SIZE_OF_BNUINT(521)
47 #define SIZE_OF_BNUINT(bits) (((bits) + BN_UINT_BITS - 1) / BN_UINT_BITS) // 1byte = 8bit
48 
49 
50 #if defined(HITLS_SIXTY_FOUR_BITS)
51 #define P224SIZE SIZE_OF_BNUINT(224)
52 #define P256SIZE SIZE_OF_BNUINT(256)
53 #define P384SIZE SIZE_OF_BNUINT(384)
54 
55 BN_UINT g_modDataP224[][P224SIZE] = {
56     {   // 1p
57         0x0000000000000001UL, 0xffffffff00000000UL,
58         0xffffffffffffffffUL, 0x00000000ffffffffUL
59     },
60     {   // 2p
61         0x0000000000000002UL, 0xfffffffe00000000UL,
62         0xffffffffffffffffUL, 0x00000001ffffffffUL
63     }
64 };
65 
66 BN_UINT g_modDataP256[][P256SIZE] = {
67     {   // p
68         0xffffffffffffffffUL, 0x00000000ffffffffUL,
69         0x0000000000000000UL, 0xffffffff00000001UL
70     },
71     {   // 2p
72         0xfffffffffffffffeUL, 0x00000001ffffffffUL,
73         0x0000000000000000UL, 0xfffffffe00000002UL
74     },
75     {   // 3p
76         0xfffffffffffffffdUL, 0x00000002ffffffffUL,
77         0x0000000000000000UL, 0xfffffffd00000003UL
78     },
79     {   // 4p
80         0xfffffffffffffffcUL, 0x00000003ffffffffUL,
81         0x0000000000000000UL, 0xfffffffc00000004UL
82     },
83     {   // 5p
84         0xfffffffffffffffbUL, 0x00000004ffffffffUL,
85         0x0000000000000000UL, 0xfffffffb00000005UL
86     },
87 };
88 #ifdef HITLS_CRYPTO_CURVE_SM2
89 const BN_UINT MODDATASM2P256[][P256SIZE] = {
90     {   // p
91         0xffffffffffffffffUL, 0xffffffff00000000UL,
92         0xffffffffffffffffUL, 0xfffffffeffffffffUL
93     },
94     {   // 2p
95         0xfffffffffffffffeUL, 0xfffffffe00000001UL,
96         0xffffffffffffffffUL, 0xfffffffdffffffffUL
97     },
98     {   // 3p
99         0xfffffffffffffffdUL, 0xfffffffd00000002UL,
100         0xffffffffffffffffUL, 0xfffffffcffffffffUL
101     },
102     {   // 4p
103         0xfffffffffffffffcUL, 0xfffffffc00000003UL,
104         0xffffffffffffffffUL, 0xfffffffbffffffffUL
105     },
106     {   // 5p
107         0xfffffffffffffffbUL, 0xfffffffb00000004UL,
108         0xffffffffffffffffUL, 0xfffffffaffffffffUL
109     },
110     {   // 6p
111         0xfffffffffffffffaUL, 0xfffffffa00000005UL,
112         0xffffffffffffffffUL, 0xfffffff9ffffffffUL
113     },
114     {   // 7p
115         0xfffffffffffffff9UL, 0xfffffff900000006UL,
116         0xffffffffffffffffUL, 0xfffffff8ffffffffUL
117     },
118     {   // 8p
119         0xfffffffffffffff8UL, 0xfffffff800000007UL,
120         0xffffffffffffffffUL, 0xfffffff7ffffffffUL
121     },
122     {   // 9p
123         0xfffffffffffffff7UL, 0xfffffff700000008UL,
124         0xffffffffffffffffUL, 0xfffffff6ffffffffUL
125     },
126     {   // 10p
127         0xfffffffffffffff6UL, 0xfffffff600000009UL,
128         0xffffffffffffffffUL, 0xfffffff5ffffffffUL
129     },
130     {   // 11p
131         0xfffffffffffffff5UL, 0xfffffff50000000aUL,
132         0xffffffffffffffffUL, 0xfffffff4ffffffffUL
133     },
134     {   // 12p
135         0xfffffffffffffff4UL, 0xfffffff40000000bUL,
136         0xffffffffffffffffUL, 0xfffffff3ffffffffUL
137     },
138     {   // 13p
139         0xfffffffffffffff3UL, 0xfffffff30000000cUL,
140         0xffffffffffffffffUL, 0xfffffff2ffffffffUL
141     },
142 };
143 #endif
144 
145 const BN_UINT MOD_DATA_P384[][P384SIZE] = {
146     {
147         0x00000000ffffffffUL, 0xffffffff00000000UL, 0xfffffffffffffffeUL,
148         0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
149     },
150     {
151         0x00000001fffffffeUL, 0xfffffffe00000000UL, 0xfffffffffffffffdUL,
152         0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
153     },
154     {
155         0x00000002fffffffdUL, 0xfffffffd00000000UL, 0xfffffffffffffffcUL,
156         0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
157     },
158     {
159         0x00000003fffffffcUL, 0xfffffffc00000000UL, 0xfffffffffffffffbUL,
160         0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
161     },
162     {
163         0x00000004fffffffbUL, 0xfffffffb00000000UL, 0xfffffffffffffffaUL,
164         0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
165     },
166 };
167 
168 const BN_UINT MOD_DATA_P521[P521SIZE] = {
169     0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL,
170     0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL,
171     0xffffffffffffffffUL, 0xffffffffffffffffUL, 0x00000000000001ffUL
172 };
173 
NistP384Add(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)174 static BN_UINT NistP384Add(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
175 {
176     (void)n;
177     BN_UINT carry = 0;
178     ADD_ABC(carry, r[0], a[0], b[0], carry); /* offset 0 */
179     ADD_ABC(carry, r[1], a[1], b[1], carry); /* offset 1 */
180     ADD_ABC(carry, r[2], a[2], b[2], carry); /* offset 2 */
181     ADD_ABC(carry, r[3], a[3], b[3], carry); /* offset 3 */
182     ADD_ABC(carry, r[4], a[4], b[4], carry); /* offset 4 */
183     ADD_ABC(carry, r[5], a[5], b[5], carry); /* offset 5 */
184     return carry;
185 }
186 
NistP384Sub(BN_UINT * r,const BN_UINT * a,const BN_UINT * b,uint32_t n)187 static BN_UINT NistP384Sub(BN_UINT *r, const BN_UINT *a, const BN_UINT *b, uint32_t n)
188 {
189     (void)n;
190     BN_UINT borrow = 0;
191     SUB_ABC(borrow, r[0], a[0], b[0], borrow); /* offset 0 */
192     SUB_ABC(borrow, r[1], a[1], b[1], borrow); /* offset 1 */
193     SUB_ABC(borrow, r[2], a[2], b[2], borrow); /* offset 2 */
194     SUB_ABC(borrow, r[3], a[3], b[3], borrow); /* offset 3 */
195     SUB_ABC(borrow, r[4], a[4], b[4], borrow); /* offset 4 */
196     SUB_ABC(borrow, r[5], a[5], b[5], borrow); /* offset 5 */
197     return borrow;
198 }
199 
200 /**
201  * Reduction item: 2^128 + 2^96  - 2^32+ 2^0
202  *
203  * Reduction list   11  10   9   8   7   6   5   4   3   2   1   0
204  *        a12	    00, 00, 00, 00, 00, 00, 00, 01, 01, 00, -1, 01,
205  *        a13	    00, 00, 00, 00, 00, 00, 01, 01, 00, -1, 01, 00,
206  *        a14	    00, 00, 00, 00, 00, 01, 01, 00, -1, 01, 00, 00,
207  *        a15	    00, 00, 00, 00, 01, 01, 00, -1, 01, 00, 00, 00,
208  *        a16	    00, 00, 00, 01, 01, 00, -1, 01, 00, 00, 00, 00,
209  *        a17	    00, 00, 01, 01, 00, -1, 01, 00, 00, 00, 00, 00,
210  *        a18	    00, 01, 01, 00, -1, 01, 00, 00, 00, 00, 00, 00,
211  *        a19	    01, 01, 00, -1, 01, 00, 00, 00, 00, 00, 00, 00,
212  *        a20	    01, 00, -1, 01, 00, 00, 00, 01, 01, 00, -1, 01,
213  *        a21	    00, -1, 01, 00, 00, 00, 01, 02, 01, -1, 00, 01,
214  *        a22	    -1, 01, 00, 00, 00, 01, 02, 01, -1, 00, 01, 00,
215  *        a23	    01, 00, 00, 00, 01, 02, 01, -2, -1, 01, 01, -1
216  *
217  * Reduction chain
218  * Coefficient   11  10   9   8   7   6   5   4   3   2   1   0
219  *           1	 a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12
220  *           1	 a20 a19 a18 a17 a16 a15 a14 a13 a12 a23 a22 a21
221  *           1	 a19 a18 a17 a16 a15 a14 a13 a12 a20	 a23 a20
222  *           1				 a23 a22 a21 a20 a21
223  *           1						 a23 a22
224  *           2					 a23 a22 a21
225  *          -1   a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a23
226  *          -1							 a23 a22 a21 a20
227  *          -1							 a23 a23
228  */
ReduceNistP384(BN_UINT * r,const BN_UINT * a)229 int8_t ReduceNistP384(BN_UINT *r, const BN_UINT *a)
230 {
231     BN_UINT list[P384SIZE];
232     BN_UINT t[P384SIZE];
233     // 0
234     list[5] = a[11];                                        // offset 5 a23|a22 == ah[11]|al[11]
235     list[4] = a[10];                                        // offset 4 a21|a20 == ah[10]|al[10]
236     list[3] = a[9];                                         // offset 3 a19|a18 == ah[9]|al[9]
237     list[2] = a[8];                                         // offset 2 a17|a16 == ah[8]|al[8]
238     list[1] = a[7];                                         // offset 1 a15|a14 == ah[7]|al[7]
239     list[0] = a[6];                                         // offset 0 a13|a12 == ah[6]|al[6]
240     // 1
241     t[5] = BN_UINT_LO_TO_HI(a[10]) | BN_UINT_HI(a[9]);      // offset 5 a20|a19 == al[10]|ah[9]
242     t[4] = BN_UINT_LO_TO_HI(a[9]) | BN_UINT_HI(a[8]);       // offset 4 a18|a17 == al[9]|ah[8]
243     t[3] = BN_UINT_LO_TO_HI(a[8]) | BN_UINT_HI(a[7]);       // offset 3 a16|a15 == al[8]|ah[7]
244     t[2] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]);       // offset 2 a14|a13 == al[7]|ah[6]
245     t[1] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[11]);      // offset 1 a12|a23 == al[6]|ah[11]
246     t[0] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]);     // offset 0 a22|a21 == al[11]|ah[10]
247     int8_t carry = (int8_t)NistP384Add(t, list, t, P384SIZE);
248     // 2
249     list[5] = a[9];                                         // offset 5 a19|a18 == ah[9]|al[9]
250     list[4] = a[8];                                         // offset 4 a17|a16 == ah[8]|al[8]
251     list[3] = a[7];                                         // offset 3 a15|a14 == ah[7]|al[7]
252     list[2] = a[6];                                         // offset 2 a13|a12 == ah[6]|al[6]
253     list[1] = BN_UINT_LO_TO_HI(a[10]);                      // offset 1 a20|0  == al[10]| 0
254     list[0] = BN_UINT_HI_TO_HI(a[11]) | BN_UINT_LO(a[10]);  // offset 0 a23|a20 == ah[11]|al[10]
255     carry += (int8_t)NistP384Add(t, list, t, P384SIZE);
256     // 3
257     list[5] = 0;                                            // offset 5 0
258     list[4] = 0;                                            // offset 4 0
259     list[3] = a[11];                                        // offset 3 a23|a22 == ah[11]|al[11]
260     list[2] = a[10];                                        // offset 2 a21|a20 == ah[10]|al[10]
261     list[1] = BN_UINT_HI_TO_HI(a[10]);                      // offset 1 a21|0 == ah[10]|0
262     list[0] = 0;                                            // offset 0 0
263     carry += (int8_t)NistP384Add(t, list, t, P384SIZE);
264     // 4
265     list[5] = 0;                                            // offset 5 0
266     list[4] = 0;                                            // offset 4 0
267     list[3] = 0;                                            // offset 3 0
268     list[2] = a[11];                                        // offset 2 a23|a22 == ah[11]|al[11]
269     list[1] = 0;                                            // offset 1 0
270     list[0] = 0;                                            // offset 0 0
271     carry += (int8_t)NistP384Add(t, list, t, P384SIZE);
272     // 5
273     list[5] = 0;                                            // offset 5 0
274     list[4] = 0;                                            // offset 4 0
275     list[3] = BN_UINT_HI(a[11]);                            // offset 3 0|a23 == 0|ah[11]
276     list[2] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]);  // offset 2 a22|a21 == al[11]|ah[10]
277     list[1] = 0;                                            // offset 1 0
278     list[0] = 0;                                            // offset 0 0
279     // double 5
280     // list[3] is left-shifted by 1 bit and the most significant bit of list[2] is added.
281     list[3] = (list[2] >> (BN_UINT_BITS - 1)) | (list[3] << 1);
282     list[2] = list[2] << 1;  // list[2] left-shifted by 1bit
283     carry += (int8_t)NistP384Add(t, list, t, P384SIZE);
284     // 6
285     list[5] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]);  // offset 5 a22|a21 == al[11]|ah[10]
286     list[4] = BN_UINT_LO_TO_HI(a[10]) | BN_UINT_HI(a[9]);   // offset 4 a20|a19 == al[10]|ah[9]
287     list[3] = BN_UINT_LO_TO_HI(a[9]) | BN_UINT_HI(a[8]);    // offset 3 a18|a17 == al[9]|ah[8]
288     list[2] = BN_UINT_LO_TO_HI(a[8]) | BN_UINT_HI(a[7]);    // offset 2 a16|a15 == al[8]|ah[7]
289     list[1] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]);    // offset 1 a14|a13 == al[7]|ah[6]
290     list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[11]);   // offset 0 a12|a23 == al[6]|ah[11]
291     carry -= (int8_t)NistP384Sub(t, t, list, P384SIZE);
292     // 7
293     list[5] = 0;                                            // offset 5 0
294     list[4] = 0;                                            // offset 4 0
295     list[3] = 0;                                            // offset 3 0
296     list[2] = BN_UINT_HI(a[11]);                            // offset 2 0|a23 == 0|ah[11]
297     list[1] = BN_UINT_LO_TO_HI(a[11]) | BN_UINT_HI(a[10]);  // offset 1 a22|a21 == al[11]|ah[10]
298     list[0] = BN_UINT_LO_TO_HI(a[10]);                      // offset 0 a20|0 == al[10]|0
299     carry -= (int8_t)NistP384Sub(t, t, list, P384SIZE);
300     // 8
301     list[5] = 0;                                            // offset 5 0
302     list[4] = 0;                                            // offset 4 0
303     list[3] = 0;                                            // offset 3 0
304     list[2] = BN_UINT_HI(a[11]);                            // offset 2 0|a23 == 0|ah[11]
305     list[1] = BN_UINT_HI_TO_HI(a[11]);                      // offset 1 a23|0 == ah[11]|0
306     list[0] = 0;                                            // offset 0
307     carry -= (int8_t)NistP384Sub(t, t, list, P384SIZE);
308     carry += (int8_t)NistP384Add(r, t, a, P384SIZE);
309 
310     return carry;
311 }
312 
313 // The size of a is 2*P384SIZE, and the size of r is P384SIZE
ModNistP384(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)314 int32_t ModNistP384(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
315 {
316     (void)opt;
317     (void)m;
318     const BN_UINT *mod = MOD_DATA_P384[0];
319     int8_t carry = ReduceNistP384(r->data, a->data);
320     if (carry > 0) {
321         carry = (int8_t)1 - (int8_t)BinSub(r->data, r->data, MOD_DATA_P384[carry - 1], P384SIZE);
322     } else if (carry < 0) {
323         // For details could ref p256.
324         carry = (int8_t)1 - (int8_t)BinAdd(r->data, r->data, MOD_DATA_P384[-carry - 1], P384SIZE);
325         carry = -carry;
326     }
327     if (carry < 0) {
328         BinAdd(r->data, r->data, mod, P384SIZE);
329     } else if (carry > 0 || BinCmp(r->data, P384SIZE, mod, P384SIZE) >= 0) {
330         BinSub(r->data, r->data, mod, P384SIZE);
331     }
332     UpdateSize(r, P384SIZE);
333     return 0;
334 }
335 
336 // Reduction item: 2^0
ReduceNistP521(BN_UINT * r,const BN_UINT * a)337 int8_t ReduceNistP521(BN_UINT *r, const BN_UINT *a)
338 {
339     #define P521LEFTBITS  (521 % (sizeof(BN_UINT) * 8))
340     #define P521RIGHTBITS ((sizeof(BN_UINT) * 8) - P521LEFTBITS)
341     BN_UINT t[P521SIZE];
342     uint32_t base = P521SIZE - 1;
343     uint32_t i;
344     for (i = 0; i < P521SIZE - 1; i++) {
345         t[i] = (a[i + base] >> P521LEFTBITS) | (a[i + base + 1] << P521RIGHTBITS);
346         r[i] = a[i];
347     }
348     r[i] = a[i] & (((BN_UINT)1 << (P521LEFTBITS)) - 1);
349     t[i] = (a[i + base] >> P521LEFTBITS);
350     BinAdd(r, t, r, P521SIZE);
351     return 0;
352 }
353 
354 // The size of a is 2*P521SIZE-1, and the size of r is P521SIZE
ModNistP521(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)355 int32_t ModNistP521(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
356 {
357     (void)opt;
358     (void)m;
359     const BN_UINT *mod = MOD_DATA_P521;
360     ReduceNistP521(r->data, a->data);
361 
362     if (BinCmp(r->data, P521SIZE, mod, P521SIZE) >= 0) {
363         BinSub(r->data, r->data, mod, P521SIZE);
364     }
365     UpdateSize(r, P521SIZE);
366 
367     return 0;
368 }
369 
P256SUB(BN_UINT * rr,const BN_UINT * aa,const BN_UINT * bb)370 static inline int8_t P256SUB(BN_UINT *rr, const BN_UINT *aa, const BN_UINT *bb)
371 {
372     BN_UINT borrow;
373     SUB_AB(borrow, rr[0], aa[0], bb[0]);
374     SUB_ABC(borrow, rr[1], aa[1], bb[1], borrow); /* offset 1 */
375     SUB_ABC(borrow, rr[2], aa[2], bb[2], borrow); /* offset 2 */
376     SUB_ABC(borrow, rr[3], aa[3], bb[3], borrow); /* offset 3 */
377     return (int8_t)borrow;
378 }
379 
P256ADD(BN_UINT * rr,const BN_UINT * aa,const BN_UINT * bb)380 static inline int8_t P256ADD(BN_UINT *rr, const BN_UINT *aa, const BN_UINT *bb)
381 {
382     BN_UINT carry;
383     ADD_AB(carry, rr[0], aa[0], bb[0]); /* offset 0 */
384     ADD_ABC(carry, rr[1], aa[1], bb[1], carry); /* offset 1 */
385     ADD_ABC(carry, rr[2], aa[2], bb[2], carry); /* offset 2 */
386     ADD_ABC(carry, rr[3], aa[3], bb[3], carry); /* offset 3 */
387     return (int8_t)carry;
388 }
389 
390 /**
391  *  NIST_P256 curve reduction calculation for parameter P
392  *  Reduction item: 2^224 - 2^192 - 2^96 + 2^0
393  *  ref. https://csrc.nist.gov/csrc/media/events/workshop-on-elliptic-curve-cryptography-standards/documents/papers/session6-adalier-mehmet.pdf
394  *
395  *  Reduction list:
396  *   	 7   6   5   4   3   2   1   0
397  *  a8	01, -1, 00, 00, -1, 00, 00, 01,
398  *  a9	00, -1, 00, -1, -1, 00, 01, 01,
399  *  a10	-1, 00, -1, -1, 00, 01, 01, 00,
400  *  a11	-1, 00, -1, 00, 02, 01, 00, -1,
401  *  a12	-1, 00, 00, 02, 02, 00, -1, -1,
402  *  a13	-1, 01, 02, 02, 01, -1, -1, -1,
403  *  a14	00, 03, 02, 01, 00, -1, -1, -1,
404  *  a15	03, 02, 01, 00, -1, -1, -1, 00
405  *
406  *  Reduction chain
407  *  Compared with the reduce flow of the paper, we have made proper transformation,
408  *  which can reduce the splicing of upper 32 bits and lower 32 bits.
409  *  Coefficient  7   6   5   4   3   2  1   0
410  *           2	a15	a14	a13	a12	a12	 0	0	0
411  *           2		a15	a14	a13	a11
412  *           1	a15	a14	a15	a14	a13	a11	a9	a8
413  *           1	a8	a13				a10	a10	a9
414  *          -1	a13	a9	a11	a10	a15	a14	a15	a14
415  *          -1	a12	a8	a10	a9	a8	a13	a14	a13
416  *          -1	a11				a9	a15	a13	a12
417  *          -1	a10						a12	a11
418  */
ReduceNistP256(BN_UINT * r,const BN_UINT * a)419 static int8_t ReduceNistP256(BN_UINT *r, const BN_UINT *a)
420 {
421     BN_UINT list[P256SIZE];
422     BN_UINT t[P256SIZE];
423     // Reduction chain 0
424     list[3] = a[7];                                         // offset 3 a15|a14 == ah[7]|al[7]
425     list[2] = a[6];                                         // offset 2 a13|a12 == ah[6]|al[6]
426     list[1] = BN_UINT_LO_TO_HI(a[6]);                       // offset 1 a12|0 == al[6]|0
427     list[0] = 0;                                            // offset 0 0
428     // Reduction chain 1
429     t[3] = BN_UINT_HI(a[7]);                                // offset 3 0|a15 == 0|ah[7]
430     t[2] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]);       // offset 2 a14|a13 == al[7]|ah[6]
431     t[1] = BN_UINT_HI_TO_HI(a[5]);                          // offset 1 a11|0 == ah[5]|0
432     t[0] = 0;                                               // offset 0 0
433     int8_t carry = P256ADD(t, t, list);
434     // carry multiplied by 2 and padded with the most significant bit of t[3]
435     carry = (carry * 2) + (int8_t)(t[3] >> (BN_UINT_BITS - 1));
436     t[3] = (t[3] << 1) | (t[2] >> (BN_UINT_BITS - 1)); // t[3] is shifted left by 1 bit and the MSB of t[2] is added.
437     t[2] = (t[2] << 1) | (t[1] >> (BN_UINT_BITS - 1)); // t[2] is shifted left by 1 bit and the MSB of t[1] is added.
438     t[1] = (t[1] << 1) | (t[0] >> (BN_UINT_BITS - 1)); // t[1] is shifted left by 1 bit and the MSB of t[0] is added.
439     t[0] <<= 1;
440     // 2
441     list[3] = a[7];                                         // offset 3 a15|a14 == ah[7]|al[7]
442     list[2] = a[7];                                         // offset 2 a15|a14 == ah[7]|al[7]
443     list[1] = BN_UINT_HI_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 1 a13|a11 == ah[6]|ah[5]
444     list[0] = a[4];                                         // offset 0 a9|a8 == ah[4]|al[4]
445     carry += (int8_t)P256ADD(t, t, list);
446     // 3
447     list[3] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[6]);    // offset 3 a8|a13 == al[4]|ah[6]
448     list[2] = 0;                                            // offset 2 0
449     list[1] = BN_UINT_LO(a[5]);                             // offset 1 0|a10 == 0|al[5]
450     list[0] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]);    // offset 0 a10|a9 == al[5]|ah[4]
451     carry += (int8_t)P256ADD(t, t, list);
452     // 4
453     list[3] = BN_UINT_HI_TO_HI(a[6]) | BN_UINT_HI(a[4]);    // offset 3 a13|a9 == ah[6]|ah[4]
454     list[2] = a[5];                                         // offset 2 a11|a10 == ah[5]|al[5]
455     list[1] = a[7];                                         // offset 1 a15|a14 == ah[7]|al[7]
456     list[0] = a[7];                                         // offset 0 a15|a14 == ah[7]|al[7]
457     carry -= (int8_t)P256SUB(t, t, list);
458     // 5
459     list[3] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_LO(a[4]);    // offset 3 a12|a8 == al[6]|al[4]
460     list[2] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]);    // offset 2 a10|a9 == al[5]|ah[4]
461     list[1] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[6]);    // offset 1 a8|a13 == al[4]|ah[6]
462     list[0] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]);    // offset 0 a14|a13 == al[7]|ah[6]
463     carry -= (int8_t)P256SUB(t, t, list);
464     // 6
465     list[3] = BN_UINT_HI_TO_HI(a[5]);                       // offset 3 a11|0 == ah[5]|0
466     list[2] = 0;                                            // offset 2 0
467     list[1] = BN_UINT_HI_TO_HI(a[4]) | BN_UINT_HI(a[7]);    // offset 1 a9|a15 == ah[4]|ah[7]
468     list[0] = a[6];                                         // offset 0 a13|a12 == ah[6]|al[6]
469     carry -= (int8_t)P256SUB(t, t, list);
470     // 7
471     list[3] = BN_UINT_LO_TO_HI(a[5]);                       // offset 3 a10|0 == al[5]|0
472     list[2] = 0;                                            // offset 2 0
473     list[1] = 0;                                            // offset 1 0
474     list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 0 a12|a11 == al[6]|ah[5]
475     carry -= (int8_t)P256SUB(t, t, list);
476     carry += (int8_t)P256ADD(r, t, a);
477     return carry;
478 }
479 
480 // For the NIST_P256 curve, perform modulo operation on parameter P.
481 // The size of a is 2*P256SIZE, and the size of r is P256SIZE
ModNistP256(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)482 int32_t ModNistP256(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
483 {
484     (void)opt;
485     (void)m;
486     const BN_UINT *mod = g_modDataP256[0];
487     int8_t carry = ReduceNistP256(r->data, a->data);
488     if (carry > 0) {
489         carry = (int8_t)1 - (int8_t)P256SUB(r->data, r->data, g_modDataP256[carry - 1]);
490     } else if (carry < 0) {
491         /*
492          * Here, we take carry < 0 as an example.
493          * If carry = -3, it indicates that ReduceNistP256 needs to be borrowed three times. In this case,
494          * we need to add 3 * p. It is worth noting that we have estimated 3 * p in g_modDataP256,
495          * but the carry of 3 * p is not save, which is expressed by the following formula:
496          *           g_modDataP256[2] = 3 * p mod 2^256, we denoted as 2 + (3 * p)_remain.
497          * Actually, we need to calculate the following formula:
498          *           -3 + r_data + 2 + (3 * p)_remain = -1 + r_data + (3 * p)_remain
499          * Obviously, -1 is a mathematical borrowing, only r_data + (3 * p)_remain is calculated in actual P256ADD.
500          * Therefore, we still need to consider the carry case of P256ADD.
501          *   1. r_data + (3 * p)_remain has a carry. -1 has been eliminated. We only need to consider
502          *       whether r_data + (3 * p)_remain belongs to [0, p).
503          *   2. r_data + (3*p)_remain does not carry. It indicates that –1 is not eliminated. We need to add another P
504          *       to eliminate –1. Considering the value of 3 * p in g_modDataP256, r_data + (3 * p)_remain + P must
505          *       generate a carry, and the final result value < P.
506         */
507         carry = (int8_t)1 - (int8_t)P256ADD(r->data, r->data, g_modDataP256[-carry - 1]);
508         carry = -carry;
509     }
510     if (carry < 0) {
511         P256ADD(r->data, r->data, mod);
512     } else if (carry > 0 || BinCmp(r->data, P256SIZE, mod, P256SIZE) >= 0) {
513         P256SUB(r->data, r->data, mod);
514     }
515     UpdateSize(r, P256SIZE);
516     return 0;
517 }
518 
519 /**
520  *  NIST_P224 curve reduction calculation for parameter P
521  *  Reduction item: 2^96 - 2^0
522  *
523  *  Reduction list:
524  *      6   5   4   3   2  1   0
525  *  a7	00, 00, 00, 01, 00, 00, -1
526  *  a8	00, 00, 01, 00, 00, -1, 00
527  *  a9	00, 01, 00, 00, -1, 00, 00
528  *  a10	01, 00, 00, -1, 00, 00, 00
529  *  a11	00, 00, -1, 01, 00, 00, -1
530  *  a12	00, -1, 01, 00, 00, -1, 00
531  *  a13	-1, 01, 00, 00, -1, 00, 00
532  *
533  *  Reduction chain
534  *  Coefficient  6  5	 4	 3	 2	1	0
535  *          1	a10	a9	a8	a7
536  *          1		a13	a12	a11
537  *         -1	a13	a12	a11	a10	a9	a8	a7
538  *         -1					a13	a12	a11
539  */
ReduceNistP224(BN_UINT * r,const BN_UINT * a)540 static int8_t ReduceNistP224(BN_UINT *r, const BN_UINT *a)
541 {
542     BN_UINT list[P224SIZE];
543     BN_UINT t[P224SIZE];
544     // 1
545     list[3] = BN_UINT_LO(a[5]);                             // offset 3 0|a10 == 0|al[5]
546     list[2] = a[4];                                         // offset 2 a9|a8 == ah[4]|al[4]
547     list[1] = BN_UINT_HI_TO_HI(a[3]);                       // offset 1 a7|0 == ah[3]|0
548     list[0] = 0;                                            // offset 0 0
549     // 2
550     t[3] = 0;                                               // offset 3 0
551     t[2] = a[6];                                            // offset 2 a13|a12 == ah[6]|al[6]
552     t[1] = BN_UINT_HI_TO_HI(a[5]);                          // offset 1 a11|0 == ah[5]|0
553     t[0] = 0;                                               // offset 0 0
554     P256ADD(t, t, list);
555     // 3
556     list[3] = BN_UINT_HI(a[6]);                             // offset 3 0|a13 == 0|ah[6]
557     list[2] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 2 a12|a11 == al[6]|ah[5]
558     list[1] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]);    // offset 1 a10|a9 == al[5]|ah[4]
559     list[0] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[3]);    // offset 0 a8|a7 == al[4]|ah[3]
560     P256SUB(t, t, list);
561     // 4
562     list[3] = 0;                                            // offset 3 0
563     list[2] = 0;                                            // offset 2 0
564     list[1] = BN_UINT_HI(a[6]);                             // offset 1 0|a13 == 0|ah[6]
565     list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 0 a12|a11 == al[6]|ah[5]
566     P256SUB(t, t, list);
567 
568     r[3] = BN_UINT_LO(a[3]);                                // Take lower 32 bits of a[3]
569     r[2] = a[2];                                            // Take a[2]
570     r[1] = a[1];
571     r[0] = a[0];
572     P256ADD(r, r, t);
573 
574     return 0;
575 }
576 
577 // NIST_P224 curve reduction calculation for parameter P. The size of a is 2*P224SIZE-1, and the size of r is P224SIZE
ModNistP224(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)578 int32_t ModNistP224(
579     BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
580 {
581     (void)opt;
582     (void)m;
583     const BN_UINT *mod = g_modDataP224[0];
584     ReduceNistP224(r->data, a->data);
585     // Obtain the high-order data of r[3] as carry information
586     int8_t carry = (int8_t)((uint8_t)(BN_UINT_HI(r->data[3]) & 0xFF));
587     if (carry > 0) {
588         (void)P256SUB(r->data, r->data, g_modDataP224[carry - 1]);
589     } else if (carry < 0) {
590         (void)P256ADD(r->data, r->data, g_modDataP224[-carry - 1]);
591     }
592     // Obtain the high-order data of r[3] as carry information
593     carry = (int8_t)((uint8_t)(BN_UINT_HI(r->data[3]) & 0xFF));
594     if (carry < 0) {
595         P256ADD(r->data, r->data, mod);
596     } else if (carry > 0 || BinCmp(r->data, P256SIZE, mod, P256SIZE) >= 0) {
597         P256SUB(r->data, r->data, mod);
598     }
599     UpdateSize(r, P224SIZE);
600     return 0;
601 }
602 
603 /**
604  * Reduction item: 2^224 + 2^96 - 2^64  + 2^0
605  *   	  7    6    5    4    3    2    1    0
606  *  a8   01,  00,  00,  00,  01,  -1,  00,  01,
607  *  a9	 01,  00,  00,  01,  00,  -1,  01,  01,
608  *  a10	 01,  00,  01,  00,  00,  00,  01,  01,
609  *  a11	 01,  01,  00,  00,  01,  00,  01,  01,
610  *  a12	 02,  00,  00,  01,  01,  00,  01,  01,
611  *  a13	 02,  00,  01,  01,  02,  -1,  01,  02,
612  *  a14	 02,  01,  01,  02,  01,  -1,  02,  02,
613  *  a15	 03,  01,  02,  01,  01,  00,  02,  02,
614 
615 
616  *  Reduction chain
617  *  The last two reduction chain can be combined into the third to last chain for calculation.
618  *  Coefficient  7    6    5    4     3    2    1    0
619  *         2    a15  a14  a15  a14   a13   0   a15   a14
620  *         2    a14   0    0    0    0     0   a14   a13
621  *         2    a13   0   a13  a12   a11   0   a12   a11
622  *         2    a12  a11  a10   a9    0    0   a9    a8
623  *         1    a15   0    0    a15  a14   0   a13   a12
624  *         1    a11   0    0    0     a8   0    0    a15
625  *         1    a10   0    0    0    a15   0   a11   a10
626  *         1    a9                             a10   a9
627  *         1    a8   a15  a14  a13   a12             a15
628  *        -1         a14  a13  a12   a11  a13  a12   a11
629  *        -1         a11  a10   a9    0   a14  a9    a8
630  *        -1                              a8
631  *        -1                              a9
632  */
633 #ifdef HITLS_CRYPTO_CURVE_SM2
ReduceSm2P256(BN_UINT * r,const BN_UINT * a)634 static int8_t ReduceSm2P256(BN_UINT *r, const BN_UINT *a)
635 {
636     BN_UINT list[P256SIZE];
637     BN_UINT t[P256SIZE];
638 
639     // Reduction chain 0, Coefficient 2
640     list[3] = a[7];                                         // offset 3 a15|a14 == ah[7]|al[7]
641     list[2] = a[7];                                         // offset 2 a15|a14 == ah[7]|al[7]
642     list[1] = BN_UINT_HI_TO_HI(a[6]);                       // offset 1 a13|0 == ah[6]|0
643     list[0] = a[7];                                         // offset 0 a15|a14 == ah[7]|al[7]
644 
645     // Reduction chain 1, Coefficient 2
646     t[3] = BN_UINT_LO_TO_HI(a[7]);                          // offset 3 a14|0 == al[7]|0
647     t[2] = 0;                                               // offset 2 0
648     t[1] = 0;                                               // offset 1 0
649     t[0] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]);       // offset 0 a14|a13 = al[7]|ah[6]
650     int8_t carry = P256ADD(t, t, list);
651 
652     // Reduction chain 2, Coefficient 2
653     list[3] = BN_UINT_HI_TO_HI(a[6]);                       // offset 3 a13|0 == ah[6]|0
654     list[2] = a[6];                                         // offset 2 a13|a12 == ah[6]|al[6]
655     list[1] = BN_UINT_HI_TO_HI(a[5]);                       // offset 1 a11|0 == ah[5]|0
656     list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 0 a12|a11 == al[6]|ah[5]
657     carry += (int8_t)P256ADD(t, t, list);
658 
659     // Reduction chain 3, Coefficient 2
660     list[3] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 3 a12|a11 == al[6]|ah[5]
661     list[2] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]);    // offset 2 a10|a9 == al[5]|ah[4]
662     list[1] = 0;                                            // offset 1 0
663     list[0] = a[4];                                         // offset 0 a9|a8 == ah[4]|al[4]
664     carry += (int8_t)P256ADD(t, t, list);
665 
666     // carry multiplied by 2 and padded with the most significant bit of t[3]
667     carry = (carry * 2) + (int8_t)(t[3] >> (BN_UINT_BITS - 1));
668     t[3] = (t[3] << 1) | (t[2] >> (BN_UINT_BITS - 1)); // t[3] is shifted left by 1 bit and the MSB of t[2] is added.
669     t[2] = (t[2] << 1) | (t[1] >> (BN_UINT_BITS - 1)); // t[2] is shifted left by 1 bit and the MSB of t[1] is added.
670     t[1] = (t[1] << 1) | (t[0] >> (BN_UINT_BITS - 1)); // t[1] is shifted left by 1 bit and the MSB of t[0] is added.
671     t[0] <<= 1;
672 
673     // Reduction chain 4, Coefficient 1
674     list[3] = BN_UINT_HI_TO_HI(a[7]);                      // offset 3 a15|0 == ah[7]|0
675     list[2] = BN_UINT_HI(a[7]);                            // offset 2  0|a15 == 0|ah[7]
676     list[1] = BN_UINT_LO_TO_HI(a[7]);                      // offset 1 a14|0 == al[7]|0
677     list[0] = a[6];                                        // offset 0 a13|a12 == ah[6]|al[6]
678     carry += (int8_t)P256ADD(t, t, list);
679 
680     // Reduction chain 5, Coefficient 1
681     list[3] = BN_UINT_HI_TO_HI(a[5]);                      // offset 3 a11|0 == ah[5]|0
682     list[2] = 0;                                           // offset 2 0
683     list[1] = BN_UINT_LO_TO_HI(a[4]);                      // offset 1 a8|0 == al[4]|0
684     list[0] = BN_UINT_HI(a[7]);                            // offset 0 0|a15 == 0|ah[7]
685     carry += (int8_t)P256ADD(t, t, list);
686 
687     // Reduction chain 6, Coefficient 1
688     list[3] = BN_UINT_LO_TO_HI(a[5]);                      // offset 3 a10|0 == al[5]|0
689     list[2] = 0;                                           // offset 2 0
690     list[1] = BN_UINT_HI_TO_HI(a[7]);                      // offset 1 a15|0 == ah[7]|0
691     list[0] = a[5];                                        // offset 0 a11|a10 == ah[5]|al[5]
692     carry += (int8_t)P256ADD(t, t, list);
693 
694     // Reduction chain 7, Coefficient 1
695     list[3] = BN_UINT_HI_TO_HI(a[4]);                     // offset 3 a9|0 == ah[4]|0
696     list[2] = 0;                                          // offset 2 0
697     list[1] = 0;                                          // offset 1 0
698     list[0] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]);  // offset 0 a10|a9 == al[5]|ah[4]
699     carry += (int8_t)P256ADD(t, t, list);
700 
701     // Reduction chain 8, Coefficient 1
702     list[3] = BN_UINT_LO_TO_HI(a[4]) | BN_UINT_HI(a[7]);  // offset 3 a8|a15 == al[4]|ah[7]
703     list[2] = BN_UINT_LO_TO_HI(a[7]) | BN_UINT_HI(a[6]);  // offset 2 a14|a13 = al[7]|ah[6]
704     list[1] = BN_UINT_LO_TO_HI(a[6]);                     // offset 1 a12|0 == al[6]|0
705     list[0] = BN_UINT_HI(a[7]);                           // offset 0  0|a15 == 0|ah[7]
706     carry += (int8_t)P256ADD(t, t, list);
707 
708     // Reduction chain 9, Coefficient -1
709     list[3] = BN_UINT_LO(a[7]);                             // offset 3 0|a14 == 0|al[7]
710     list[2] = a[6];                                         // offset 2 a13|a12 == ah[6]|al[6]
711     list[1] = BN_UINT_HI_TO_HI(a[5]) | BN_UINT_HI(a[6]);    // offset 1 a11|a13 == ah[5]|ah[6]
712     list[0] = BN_UINT_LO_TO_HI(a[6]) | BN_UINT_HI(a[5]);    // offset 0 a12|a11 == al[6]|ah[5]
713     carry -= (int8_t)P256SUB(t, t, list);
714 
715     // Reduction chain 10, Coefficient -1
716     list[3] = BN_UINT_HI(a[5]);                                       // offset 3 0|a11 == 0|ah[5]
717     list[2] = BN_UINT_LO_TO_HI(a[5]) | BN_UINT_HI(a[4]);              // offset 2 a10|a9 == al[5]|ah[4]
718     // offset 1 0|a14 == 0|al[7]. Add the values of the last two chains.
719     list[1] = BN_UINT_LO(a[7]) + BN_UINT_HI(a[4]) + BN_UINT_LO(a[4]);
720     list[0] = a[4];                                                   // offset 0 a9|a8 == ah[4]|al[4]
721     carry -= (int8_t)P256SUB(t, t, list);
722 
723     carry += (int8_t)P256ADD(r, t, a);
724     return carry;
725 }
726 
727 // SM2_P256 curve modulo parameter P. The size of a is 2*P256SIZE, and the size of r is P256SIZE
ModSm2P256(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)728 int32_t ModSm2P256(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
729 {
730     (void)opt;
731     (void)m;
732     const BN_UINT *mod = MODDATASM2P256[0];
733     int8_t carry = ReduceSm2P256(r->data, a->data);
734     if (carry < 0) {
735         carry = (int8_t)1 - (int8_t)P256ADD(r->data, r->data, MODDATASM2P256[-carry - 1]);
736         carry = -carry;
737     } else if (carry > 0) {
738         // For details could ref p256.
739         carry = (int8_t)1 - (int8_t)P256SUB(r->data, r->data, MODDATASM2P256[carry - 1]);
740     }
741     if (carry < 0) {
742         P256ADD(r->data, r->data, mod);
743     } else if (carry > 0 || BinCmp(r->data, P256SIZE, mod, P256SIZE) >= 0) {
744         P256SUB(r->data, r->data, mod);
745     }
746     UpdateSize(r, P256SIZE);
747     return 0;
748 }
749 #endif
750 
751 #elif defined(HITLS_THIRTY_TWO_BITS)
752 
ModNistP224(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)753 int32_t ModNistP224(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
754 {
755     return BN_Mod(r, a, m, opt);
756 }
757 
ModNistP256(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)758 int32_t ModNistP256(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
759 {
760     return BN_Mod(r, a, m, opt);
761 }
762 
763 #ifdef HITLS_CRYPTO_CURVE_SM2
ModSm2P256(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)764 int32_t ModSm2P256(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
765 {
766     return BN_Mod(r, a, m, opt);
767 }
768 #endif
769 
ModNistP384(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)770 int32_t ModNistP384(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
771 {
772     return BN_Mod(r, a, m, opt);
773 }
774 
ModNistP521(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * m,BN_Optimizer * opt)775 int32_t ModNistP521(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *m, BN_Optimizer *opt)
776 {
777     return BN_Mod(r, a, m, opt);
778 }
779 
780 #endif
781 
782 #if defined(HITLS_CRYPTO_BN_COMBA) && defined(HITLS_SIXTY_FOUR_BITS)
MulNistP256P224(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize,const BN_UINT * b,uint32_t bSize)783 static uint32_t MulNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize,
784     const BN_UINT *b, uint32_t bSize)
785 {
786     (void)rSize;
787     (void)aSize;
788     (void)bSize;
789 
790     MulComba4(r, a, b);
791     uint32_t size = P224SIZE << 1; // in 64-bit environment, P224SIZE = P256SIZE
792     while (size > 0) {
793         if (r[size - 1] != 0) {
794             break;
795         }
796         --size;
797     }
798     return size;
799 }
800 
SqrNistP256P224(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize)801 static uint32_t SqrNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize)
802 {
803     (void)rSize;
804     (void)aSize;
805 
806     SqrComba4(r, a);
807     uint32_t size = P224SIZE << 1; // in 64-bit environment, P224SIZE = P256SIZE
808     while (size > 0) {
809         if (r[size - 1] != 0) {
810             break;
811         }
812         --size;
813     }
814     return size;
815 }
816 
MulNistP384(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize,const BN_UINT * b,uint32_t bSize)817 static uint32_t MulNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize,
818     const BN_UINT *b, uint32_t bSize)
819 {
820     (void)rSize;
821     (void)aSize;
822     (void)bSize;
823 
824     MulComba6(r, a, b);
825     uint32_t size = P384SIZE << 1;
826     while (size > 0) {
827         if (r[size - 1] != 0) {
828             break;
829         }
830         size--;
831     }
832     return size;
833 }
834 
SqrNistP384(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize)835 static uint32_t SqrNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize)
836 {
837     (void)rSize;
838     (void)aSize;
839 
840     SqrComba6(r, a);
841     uint32_t size = P384SIZE << 1;
842     while (size > 0) {
843         if (r[size - 1] != 0) {
844             break;
845         }
846         size--;
847     }
848     return size;
849 }
850 #else
MulNistP256P224(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize,const BN_UINT * b,uint32_t bSize)851 static uint32_t MulNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize,
852     const BN_UINT *b, uint32_t bSize)
853 {
854     return BinMul(r, rSize, a, aSize, b, bSize);
855 }
856 
SqrNistP256P224(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize)857 static uint32_t SqrNistP256P224(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize)
858 {
859     return BinSqr(r, rSize, a, aSize);
860 }
861 
MulNistP384(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize,const BN_UINT * b,uint32_t bSize)862 static uint32_t MulNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize,
863     const BN_UINT *b, uint32_t bSize)
864 {
865     return BinMul(r, rSize, a, aSize, b, bSize);
866 }
867 
SqrNistP384(BN_UINT * r,uint32_t rSize,const BN_UINT * a,uint32_t aSize)868 static uint32_t SqrNistP384(BN_UINT *r, uint32_t rSize, const BN_UINT *a, uint32_t aSize)
869 {
870     return BinSqr(r, rSize, a, aSize);
871 }
872 
873 #endif
874 
ModCalParaCheck(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * b,const BN_BigNum * mod)875 static inline int32_t ModCalParaCheck(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, const BN_BigNum *mod)
876 {
877     if (r == NULL || a == NULL || b == NULL || mod == NULL) {
878         return CRYPT_NULL_INPUT;
879     }
880     // 保证不越界访问
881     if ((mod->size > a->room) || (mod->size > b->room)) {
882         return CRYPT_BN_SPACE_NOT_ENOUGH;
883     }
884     return BnExtend(r, mod->size);
885 }
886 
887 // The user must ensure that a < m, and a->room & b->room are not less than mod->size.
888 // All the data must be not negative number, otherwise the API may be not functional.
BN_ModAddQuick(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * b,const BN_BigNum * mod,const BN_Optimizer * opt)889 int32_t BN_ModAddQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
890     const BN_BigNum *mod, const BN_Optimizer *opt)
891 {
892     int32_t ret = ModCalParaCheck(r, a, b, mod);
893     if (ret != CRYPT_SUCCESS) {
894         BSL_ERR_PUSH_ERROR(ret);
895         return ret;
896     }
897     (void)opt;
898     BN_UINT carry = BinAdd(r->data, a->data, b->data, mod->size);
899     if (carry > 0 || BinCmp(r->data, mod->size, mod->data, mod->size) >= 0) {
900         BinSub(r->data, r->data, mod->data, mod->size);
901     }
902     UpdateSize(r, mod->size);
903     return CRYPT_SUCCESS;
904 }
905 
906 // The user must ensure that a < m, and a->room & b->room are not less than mod->size.
907 // All the data must be not negative number, otherwise the API may be not functional.
BN_ModSubQuick(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * b,const BN_BigNum * mod,const BN_Optimizer * opt)908 int32_t BN_ModSubQuick(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b,
909     const BN_BigNum *mod, const BN_Optimizer *opt)
910 {
911     int32_t ret = ModCalParaCheck(r, a, b, mod);
912     if (ret != CRYPT_SUCCESS) {
913         BSL_ERR_PUSH_ERROR(ret);
914         return ret;
915     }
916     (void)opt;
917     int32_t res = BinCmp(a->data, a->size, b->data, b->size);
918     if (res < 0) {
919         /* Apply for the temporary space of the BN object. */
920         BinSub(r->data, a->data, b->data, mod->size);
921         BinAdd(r->data, r->data, mod->data, mod->size);
922     } else {
923         BinSub(r->data, a->data, b->data, mod->size);
924     }
925     UpdateSize(r, mod->size);
926     return CRYPT_SUCCESS;
927 }
928 
ModEccMulParaCheck(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * b,const BN_BigNum * mod,BN_Optimizer * opt)929 static inline int32_t ModEccMulParaCheck(BN_BigNum *r, const BN_BigNum *a,
930     const BN_BigNum *b, const BN_BigNum *mod, BN_Optimizer *opt)
931 {
932     if (r == NULL || a == NULL || b == NULL || mod == NULL || opt == NULL) {
933         return CRYPT_NULL_INPUT;
934     }
935     // Ensure that no out-of-bounds access occurs.
936     if ((mod->size > b->room) || (mod->size > a->room)) {
937         return CRYPT_BN_SPACE_NOT_ENOUGH;
938     }
939     return BnExtend(r, mod->size);
940 }
941 // The user must ensure that a < m, and a->room & b->room are not less than mod->size.
942 // All the data must be not negative number, otherwise the API may be not functional.
BN_ModNistEccMul(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * b,void * data,BN_Optimizer * opt)943 int32_t BN_ModNistEccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, void *data, BN_Optimizer *opt)
944 {
945     BN_BigNum *mod = (BN_BigNum *)data;
946     int32_t ret = ModEccMulParaCheck(r, a, b, mod, opt);
947     if (ret != CRYPT_SUCCESS) {
948         BSL_ERR_PUSH_ERROR(ret);
949         return ret;
950     }
951     if (b->size == 0 || a->size == 0) {
952         return BN_Zeroize(r);
953     }
954     BN_UINT tData[P521SIZE << 1] = { 0 };
955     BN_BigNum rMul = {
956         .data = tData,
957         .size = 0,
958         .sign = false,
959         .room = P521SIZE << 1
960     };
961     uint32_t size = mod->size << 1;
962     uint32_t bits = BN_Bits(mod);
963     if (bits == 224) { // 224bit
964         rMul.size = MulNistP256P224(rMul.data, size, a->data, mod->size, b->data, mod->size);
965         ModNistP224(r, &rMul, mod, opt);
966     } else if (bits == 256) { // 256bit
967         rMul.size = MulNistP256P224(rMul.data, size, a->data, mod->size, b->data, mod->size);
968         ModNistP256(r, &rMul, mod, opt);
969     } else if (bits == 384) { // 384bit
970         rMul.size = MulNistP384(rMul.data, size, a->data, mod->size, b->data, mod->size);
971         ModNistP384(r, &rMul, mod, opt);
972     } else if (bits == 521) { // 521bit
973         rMul.size = BinMul(rMul.data, size, a->data, mod->size, b->data, mod->size);
974         ModNistP521(r, &rMul, mod, opt);
975     } else {
976         BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_QUICK_MODDATA);
977         return CRYPT_BN_ERR_QUICK_MODDATA;
978     }
979     return CRYPT_SUCCESS;
980 }
981 
ModEccSqrParaCheck(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * mod,BN_Optimizer * opt)982 static int32_t ModEccSqrParaCheck(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *mod, BN_Optimizer *opt)
983 {
984     if (r == NULL || a == NULL || mod == NULL || opt == NULL) {
985         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
986         return CRYPT_NULL_INPUT;
987     }
988     // Ensure that no out-of-bounds access occurs.
989     if (mod->size > a->room) {
990         BSL_ERR_PUSH_ERROR(CRYPT_BN_SPACE_NOT_ENOUGH);
991         return CRYPT_BN_SPACE_NOT_ENOUGH;
992     }
993     return BnExtend(r, mod->size);
994 }
995 
996 // The user must ensure that a < m, and a->room & b->room are not less than mod->size.
997 // All the data must be not negative number, otherwise the API may be not functional.
BN_ModNistEccSqr(BN_BigNum * r,const BN_BigNum * a,void * data,BN_Optimizer * opt)998 int32_t BN_ModNistEccSqr(BN_BigNum *r, const BN_BigNum *a, void *data, BN_Optimizer *opt)
999 {
1000     BN_BigNum *mod = (BN_BigNum *)data;
1001     int32_t ret = ModEccSqrParaCheck(r, a, mod, opt);
1002     if (ret != CRYPT_SUCCESS) {
1003         return ret;
1004     }
1005     if (a->size == 0) {
1006         return BN_Zeroize(r);
1007     }
1008     BN_UINT tData[P521SIZE << 1] = { 0 };
1009     BN_BigNum rSqr = {
1010         .data = tData,
1011         .size = 0,
1012         .sign = false,
1013         .room = P521SIZE << 1
1014     };
1015     uint32_t size = mod->size << 1;
1016     uint32_t bits = BN_Bits(mod);
1017     if (bits == 224) { // 224bit
1018         rSqr.size = SqrNistP256P224(rSqr.data, size, a->data, mod->size);
1019         ModNistP224(r, &rSqr, mod, opt);
1020     } else if (bits == 256) { // 256bit
1021         rSqr.size = SqrNistP256P224(rSqr.data, size, a->data, mod->size);
1022         ModNistP256(r, &rSqr, mod, opt);
1023     } else if (bits == 384) { // 384bit
1024         rSqr.size = SqrNistP384(rSqr.data, size, a->data, mod->size);
1025         ModNistP384(r, &rSqr, mod, opt);
1026     } else if (bits == 521) { // 521bit
1027         rSqr.size = BinSqr(rSqr.data, size, a->data, mod->size);
1028         ModNistP521(r, &rSqr, mod, opt);
1029     } else {
1030         BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_QUICK_MODDATA);
1031         return CRYPT_BN_ERR_QUICK_MODDATA;
1032     }
1033     return CRYPT_SUCCESS;
1034 }
1035 
1036 #ifdef HITLS_CRYPTO_CURVE_SM2
1037 
1038 #define SM2SIZE SIZE_OF_BNUINT(256)
1039 
1040 // The user must ensure that a < m, and a->room & b->room are not less than mod->size.
1041 // All the data must be not negative number, otherwise the API may be not functional.
BN_ModSm2EccMul(BN_BigNum * r,const BN_BigNum * a,const BN_BigNum * b,void * data,BN_Optimizer * opt)1042 int32_t BN_ModSm2EccMul(BN_BigNum *r, const BN_BigNum *a, const BN_BigNum *b, void *data, BN_Optimizer *opt)
1043 {
1044     BN_BigNum *mod = (BN_BigNum *)data;
1045     int32_t ret = ModEccMulParaCheck(r, a, b, mod, opt);
1046     if (ret != CRYPT_SUCCESS) {
1047         BSL_ERR_PUSH_ERROR(ret);
1048         return ret;
1049     }
1050     if (a->size == 0 || b->size == 0) {
1051         return BN_Zeroize(r);
1052     }
1053     BN_UINT tData[SM2SIZE << 1] = { 0 };
1054     BN_BigNum rMul = {
1055         .data = tData,
1056         .size = 0,
1057         .sign = false,
1058         .room = SM2SIZE << 1
1059     };
1060     uint32_t size = mod->size << 1;
1061     rMul.size = MulNistP256P224(rMul.data, size, a->data, mod->size, b->data, mod->size);
1062     ModSm2P256(r, &rMul, mod, opt);
1063 
1064     return CRYPT_SUCCESS;
1065 }
1066 
1067 // The user must ensure that a < m, and a->room & b->room are not less than mod->size.
1068 // All the data must be not negative number, otherwise the API may be not functional.
BN_ModSm2EccSqr(BN_BigNum * r,const BN_BigNum * a,void * data,BN_Optimizer * opt)1069 int32_t BN_ModSm2EccSqr(BN_BigNum *r, const BN_BigNum *a, void *data, BN_Optimizer *opt)
1070 {
1071     BN_BigNum *mod = (BN_BigNum *)data;
1072     int32_t ret = ModEccSqrParaCheck(r, a, mod, opt);
1073     if (ret != CRYPT_SUCCESS) {
1074         return ret;
1075     }
1076     if (a->size == 0) {
1077         return BN_Zeroize(r);
1078     }
1079     BN_UINT tData[SM2SIZE << 1] = { 0 };
1080     BN_BigNum rSqr = {
1081         .data = tData,
1082         .size = 0,
1083         .sign = false,
1084         .room = SM2SIZE << 1
1085     };
1086     uint32_t size = mod->size << 1;
1087     rSqr.size = SqrNistP256P224(rSqr.data, size, a->data, mod->size);
1088     ModSm2P256(r, &rSqr, mod, opt);
1089 
1090     return CRYPT_SUCCESS;
1091 }
1092 #endif
1093 #endif