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