1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "hvb_sm2_bn.h"
16 #include <hvb_sysdeps.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 #define SM2_DATA_MUL_DWORD_SIZE (SM2_DATA_DWORD_SIZE * 2)
21 #define SM2_DATA_BIT_SIZE 256
22 #define SM2_BIT_PER_BYTE 8
23 #define SM2_SWORD_BIT_MASK ((1UL << SM2_SWORD_BIT_SIZE) - 1)
24 #define SM2_BIT_PER_LONG 64
25 #define SLIDING_WINDOW_SIZE 5
26 #define SLIDING_WINDOW_PRE_TABLE_SIZE (1 << (SLIDING_WINDOW_SIZE - 1))
27 #define get_low_64bits(a) ((a) & 0xFFFFFFFFFFFFFFFF)
28 #define get_high_64bits(a) ((__uint128_t)(a) >> 64)
29 #define get_low_32bits(a) ((a) & 0xFFFFFFFF)
30 #define get_high_32bits(a) ((uint64_t)(a) >> 32)
31
32 struct sm2_point_scalar_encode_info {
33 /* encode res per window */
34 int8_t code_num[SM2_DATA_BIT_SIZE / SLIDING_WINDOW_SIZE + 1];
35 /* bit num that cur window distance from last window */
36 uint16_t shift_bit[SM2_DATA_BIT_SIZE / SLIDING_WINDOW_SIZE + 1];
37 /* window num */
38 uint32_t window_num;
39 /* the first bit exclued the first code_num */
40 uint32_t start_bit;
41 };
42
43
44 /* 2 ^ 256 - p */
45 const uint64_t g_negative_p[] = {0x1, 0xffffffff, 0x0, 0x100000000};
46 /* 2 ^ 256 - n */
47 const uint64_t g_negative_n[] = {0xAC440BF6C62ABEDD, 0x8DFC2094DE39FAD4, 0x0, 0x100000000};
48 const uint64_t g_p[] = { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFFFF };
49 const uint64_t g_n[] = { 0x53BBF40939D54123, 0x7203DF6B21C6052B, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFFFF };
50 const uint64_t g_a_bigendian[] = { 0xFFFFFFFFFEFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0xFCFFFFFFFFFFFFFF };
51 const uint64_t g_b_bigendian[] = { 0x345E9F9D9EFAE928, 0xA70965CF4B9E5A4D, 0x928FAB15F58997F3, 0x930E944D41BDBCDD };
52 const uint64_t g_gx_bigendian[] = { 0x1981191F2CAEC432, 0x94C9396A4604995F, 0xE10B66F2BF0BE38F, 0xC7744C3389455A71 };
53 const uint64_t g_gy_bigendian[] = { 0x9C77F6F4A23637BC, 0x5321696BE3CEBD59, 0x40472AC67C87A9D0, 0xA0F03921E532DF02 };
54 const struct sm2_point_jcb g_pointg = {
55 .x = { 0x715A4589334C74C7, 0x8FE30BBFF2660BE1, 0x5F9904466A39C994, 0x32C4AE2C1F198119 },
56 .y = { 0x02DF32E52139F0A0, 0xD0A9877CC62A4740, 0x59BDCEE36B692153, 0xBC3736A2F4F6779C },
57 .z = { 1, 0, 0, 0 }
58 };
59
60 /*
61 * r = a + b + c, the param 'carry' means carry of sum
62 * note that c and r can't be the same
63 */
add_with_carry(uint64_t a,uint64_t b,uint64_t c,uint64_t * r,uint64_t * carry)64 static void add_with_carry(uint64_t a, uint64_t b, uint64_t c, uint64_t *r, uint64_t *carry)
65 {
66 uint64_t tmp_res = a + c;
67 *carry = tmp_res >= a ? 0 : 1;
68 tmp_res += b;
69 *carry += tmp_res >= b ? 0 : 1;
70 *r = tmp_res;
71 }
72
73 /*
74 * r = a - b - c, the param 'borrow' means borrow of sub
75 * note that c and r can't be the same
76 */
sub_with_borrow(uint64_t a,uint64_t b,uint64_t c,uint64_t * r,uint64_t * borrow)77 static void sub_with_borrow(uint64_t a, uint64_t b, uint64_t c, uint64_t *r, uint64_t *borrow)
78 {
79 uint64_t tmp_borrow = a >= b ? 0 : 1;
80 *r = a - b;
81 tmp_borrow += *r >= c ? 0 : 1;
82 *r -= c;
83 *borrow = tmp_borrow;
84 }
85
86 /* a = a >> 1 */
87 #define shift_right_one_bit(a) \
88 do { \
89 ((a)[0] = ((a)[0] >> 1) + ((a)[1] << 63)); \
90 ((a)[1] = ((a)[1] >> 1) + ((a)[2] << 63)); \
91 ((a)[2] = ((a)[2] >> 1) + ((a)[3] << 63)); \
92 ((a)[3] = (a)[3] >> 1); \
93 } while (0)
94
95 /* a = (a + p) >> 1 */
96 #define add_p_shift_right_one_bit(a) \
97 do { \
98 uint64_t carry = 0; \
99 for (uint32_t i = 0; i < SM2_DATA_DWORD_SIZE; i++) { \
100 add_with_carry((a)[i], (g_p[i]), (carry), &((a)[i]), &(carry)); \
101 } \
102 ((a)[0] = ((a)[0] >> 1) + ((a)[1] << 63)); \
103 ((a)[1] = ((a)[1] >> 1) + ((a)[2] << 63)); \
104 ((a)[2] = ((a)[2] >> 1) + ((a)[3] << 63)); \
105 ((a)[3] = ((a)[3] >> 1) + (carry << 63)); \
106 } while (0)
107
invert_copy_byte(uint8_t * dst,uint8_t * src,uint32_t len)108 void invert_copy_byte(uint8_t *dst, uint8_t *src, uint32_t len)
109 {
110 for (uint32_t i = 0; i < len; i++)
111 dst[i] = src[len - i - 1];
112 }
113
114 /* get sm2 curve param a */
sm2_bn_get_param_a(void)115 uint8_t *sm2_bn_get_param_a(void)
116 {
117 return (uint8_t *)g_a_bigendian;
118 }
119
120 /* get sm2 curve param b */
sm2_bn_get_param_b(void)121 uint8_t *sm2_bn_get_param_b(void)
122 {
123 return (uint8_t *)g_b_bigendian;
124 }
125
126 /* get sm2 curve param Gx */
sm2_bn_get_param_gx(void)127 uint8_t *sm2_bn_get_param_gx(void)
128 {
129 return (uint8_t *)g_gx_bigendian;
130 }
131
132 /* get sm2 curve param Gy */
sm2_bn_get_param_gy(void)133 uint8_t *sm2_bn_get_param_gy(void)
134 {
135 return (uint8_t *)g_gy_bigendian;
136 }
137
138 /*
139 * r = (a + b) mod p, p is SM2 elliptic curve param
140 * note that this function only ensure r is 256bits, can't ensure r < p
141 */
sm2_bn_add_mod_p(uint64_t a[],uint64_t b[],uint64_t r[])142 static void sm2_bn_add_mod_p(uint64_t a[], uint64_t b[], uint64_t r[])
143 {
144 uint64_t carry = 0;
145 uint32_t i = 0;
146
147 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
148 add_with_carry(a[i], b[i], carry, &r[i], &carry);
149 }
150
151 while (carry == 1) {
152 carry = 0;
153 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
154 add_with_carry(r[i], g_negative_p[i], carry, &r[i], &carry);
155 }
156 }
157 }
158
159 /*
160 * r = (a + b) mod n, n is SM2 elliptic curve param
161 */
sm2_bn_add_mod_n(uint64_t a[],uint64_t b[],uint64_t r[])162 int sm2_bn_add_mod_n(uint64_t a[], uint64_t b[], uint64_t r[])
163 {
164 uint64_t carry = 0;
165 uint32_t i = 0;
166 uint64_t r_tmp[SM2_DATA_DWORD_SIZE] = { 0 };
167 int ret = -1;
168
169 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
170 add_with_carry(a[i], b[i], carry, &r[i], &carry);
171 }
172
173 while (carry == 1) {
174 carry = 0;
175 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++)
176 add_with_carry(r[i], g_negative_n[i], carry, &r[i], &carry);
177 }
178
179 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++)
180 sub_with_borrow(r[i], g_n[i], carry, &r_tmp[i], &carry);
181
182 if (carry == 0) {
183 ret = hvb_memcpy_s(r, SM2_KEY_LEN, r_tmp, sizeof(r_tmp));
184 if (hvb_check(ret != 0))
185 return SM2_BN_MEMORY_ERR;
186 }
187
188 return SM2_BN_OK;
189 }
190
191 /*
192 * r = (a - b) mod p, p is SM2 elliptic curve param
193 * note that this function only ensure r is 256bits, can't ensure r < p
194 */
sm2_bn_sub_mod_p(uint64_t a[],uint64_t b[],uint64_t r[])195 static void sm2_bn_sub_mod_p(uint64_t a[], uint64_t b[], uint64_t r[])
196 {
197 uint64_t borrow = 0;
198 uint32_t i = 0;
199
200 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
201 sub_with_borrow(a[i], b[i], borrow, &r[i], &borrow);
202 }
203
204 while (borrow == 1) {
205 borrow = 0;
206 for (i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
207 sub_with_borrow(r[i], g_negative_p[i], borrow, &r[i], &borrow);
208 }
209 }
210 }
211
212 /* r = a mod p */
sm2_bn_mod_p(uint64_t a[],uint64_t r[])213 static void sm2_bn_mod_p(uint64_t a[], uint64_t r[])
214 {
215 uint64_t sum_add_to_a0 = 0;
216 uint64_t sum_add_to_a1 = 0;
217 uint64_t sum_add_to_a2 = 0;
218 uint64_t sum_add_to_a3 = 0;
219 uint64_t carry = 0;
220
221 /*
222 * 1. RDC with 64 bit
223 * sum_add_to_a2 = a7 + a7 + a6
224 */
225 add_with_carry(a[7], a[6], 0, &sum_add_to_a2, &carry);
226 sum_add_to_a3 += carry;
227 add_with_carry(sum_add_to_a2, a[7], 0, &sum_add_to_a2, &carry);
228 sum_add_to_a3 += carry;
229
230 /* sum_add_to_a0 = sum_add_to_a2 + a4 + a5 */
231 add_with_carry(sum_add_to_a2, a[4], 0, &sum_add_to_a0, &carry);
232 sum_add_to_a1 = sum_add_to_a3 + carry;
233 add_with_carry(sum_add_to_a0, a[5], 0, &sum_add_to_a0, &carry);
234 sum_add_to_a1 += carry;
235
236 /* add sum_add_to_ai to a[i] */
237 add_with_carry(a[0], sum_add_to_a0, 0, &a[0], &carry);
238 add_with_carry(a[1], sum_add_to_a1, carry, &a[1], &carry);
239 add_with_carry(a[2], sum_add_to_a2, carry, &a[2], &carry);
240 /* sum_add_to_a3 = a[7] */
241 add_with_carry(a[3], a[7], carry, &a[3], &carry);
242 add_with_carry(a[3], sum_add_to_a3, 0, &a[3], &sum_add_to_a0);
243 /* carry to next unit */
244 carry += sum_add_to_a0;
245
246 /* 1. RDC with 32 bit, sum_add_to_ai means a[i + 4]'low 32 bits */
247 sum_add_to_a0 = get_low_32bits(a[4]); /* a8 */
248 sum_add_to_a1 = get_low_32bits(a[5]); /* a10 */
249 sum_add_to_a2 = get_low_32bits(a[6]); /* a12 */
250 sum_add_to_a3 = get_low_32bits(a[7]); /* a14 */
251 a[4] = get_high_32bits(a[4]); /* a9 */
252 a[5] = get_high_32bits(a[5]); /* a11 */
253 a[6] = get_high_32bits(a[6]); /* a13 */
254 a[7] = get_high_32bits(a[7]); /* a15 */
255
256 uint64_t sum_tmp1 = sum_add_to_a2 + sum_add_to_a3; /* a12_14 */
257 uint64_t sum_tmp2 = sum_add_to_a1 + sum_add_to_a3; /* a10_14 */
258 uint64_t sum_tmp3 = a[6] + a[7]; /* a13_15 */
259 uint64_t sum_tmp4 = sum_add_to_a0 + a[4]; /* a8_9 */
260
261 a[7] += a[5]; /* a11_15 */
262 sum_add_to_a2 = sum_tmp3 + sum_tmp1; /* a12_13_14_15 */
263 sum_add_to_a1 += sum_add_to_a2; /* a10_12_13_14_15 */
264 sum_add_to_a1 += sum_add_to_a2; /* a10_2*12_2*13_2*14_2*15 */
265 sum_add_to_a1 += sum_tmp4; /* a8_9_10_2*12_2*13_2*14_2*15 */
266 sum_add_to_a1 += a[5]; /* a8_9_10_11_2*12_2*13_2*14_2*15 */
267
268 sum_add_to_a2 += a[6]; /* a12_2*13_14_15 */
269 sum_add_to_a2 += a[5]; /* a11_12_2*13_14_15 */
270 sum_add_to_a2 += sum_add_to_a0; /* a8_11_12_2*13_14_15 */
271
272 sum_tmp4 += sum_add_to_a3; /* a8_9_14 */
273 sum_tmp4 += a[6]; /* a8_9_13_14 */
274
275 a[4] += sum_tmp3; /* a9_13_15 */
276
277 a[5] += a[4]; /* a9_11_13_15 */
278 a[5] += sum_tmp3; /* a9_11_2*13_2*15 */
279
280 sum_tmp1 += sum_tmp2; /* a10_12_2*14 */
281
282 /* from low to high are a[5], sum_tmp1, sum_tmp4, sum_add_to_a2, a[4], sum_tmp2, a[7], sum_add_to_a1 */
283 sum_add_to_a0 = sum_tmp1 << 32;
284 sum_tmp1 = (sum_tmp1 >> 32) + (sum_add_to_a2 << 32);
285 sum_add_to_a2 = (sum_add_to_a2 >> 32) + (sum_tmp2 << 32);
286 sum_tmp2 = (sum_tmp2 >> 32) + (sum_add_to_a1 << 32);
287 sum_add_to_a1 = sum_add_to_a1 >> 32;
288
289 /* 64bit add */
290 uint64_t carry_tmp = 0;
291
292 add_with_carry(a[5], sum_add_to_a0, 0, &a[5], &carry_tmp); /* the first 64bit num */
293 add_with_carry(sum_tmp1, 0, carry_tmp, &sum_tmp1, &carry_tmp);
294 add_with_carry(a[4], sum_add_to_a2, carry_tmp, &a[4], &carry_tmp);
295 add_with_carry(a[7], sum_tmp2, carry_tmp, &a[7], &carry_tmp);
296 add_with_carry(carry, sum_add_to_a1, carry_tmp, &carry, &carry_tmp);
297
298 add_with_carry(a[0], a[5], 0, &r[0], &carry_tmp);
299 add_with_carry(a[1], sum_tmp1, carry_tmp, &r[1], &carry_tmp);
300 add_with_carry(a[2], a[4], carry_tmp, &r[2], &carry_tmp);
301 add_with_carry(a[3], a[7], carry_tmp, &r[3], &carry_tmp);
302 add_with_carry(carry, 0, carry_tmp, &carry, &carry_tmp);
303
304 sub_with_borrow(r[1], sum_tmp4, 0, &r[1], &carry_tmp); /* carry_tmp means borrow */
305 sub_with_borrow(r[2], 0, carry_tmp, &r[2], &carry_tmp);
306 sub_with_borrow(r[3], 0, carry_tmp, &r[3], &carry_tmp);
307 sub_with_borrow(carry, 0, carry_tmp, &carry, &carry_tmp);
308
309 /* there may be carry, so still need to RDC */
310 /* sub carry times p */
311 sum_tmp1 = carry;
312 sum_tmp2 = sum_tmp1 << 32;
313 sum_tmp1 = sum_tmp2 - sum_tmp1;
314 add_with_carry(r[0], carry, 0, &r[0], &carry_tmp);
315 add_with_carry(r[1], sum_tmp1, carry_tmp, &r[1], &carry_tmp);
316 add_with_carry(r[2], 0, carry_tmp, &r[2], &carry_tmp);
317 add_with_carry(r[3], sum_tmp2, carry_tmp, &r[3], &carry_tmp);
318
319 if (carry_tmp == 1) {
320 add_with_carry(r[0], g_negative_p[0], 0, &r[0], &carry_tmp);
321 add_with_carry(r[1], g_negative_p[1], carry_tmp, &r[1], &carry_tmp);
322 add_with_carry(r[2], g_negative_p[2], carry_tmp, &r[2], &carry_tmp);
323 add_with_carry(r[3], g_negative_p[3], carry_tmp, &r[3], &carry_tmp);
324 }
325 }
326
sm2_bn_word_mul(uint64_t a,uint64_t b,uint64_t * res_low,uint64_t * res_high)327 static void sm2_bn_word_mul(uint64_t a, uint64_t b, uint64_t *res_low, uint64_t *res_high)
328 {
329 uint64_t a_h, a_l;
330 uint64_t b_h, b_l;
331 uint64_t res_h, res_l;
332 uint64_t c, t;
333
334 a_h = a >> SM2_SWORD_BIT_SIZE;
335 a_l = a & SM2_SWORD_BIT_MASK;
336 b_h = b >> SM2_SWORD_BIT_SIZE;
337 b_l = b & SM2_SWORD_BIT_MASK;
338
339 res_h = a_h * b_h;
340 res_l = a_l * b_l;
341
342 c = a_h * b_l;
343 res_h += c >> SM2_SWORD_BIT_SIZE;
344 t = res_l;
345 res_l += c << SM2_SWORD_BIT_SIZE;
346 res_h += t > res_l;
347
348 c = a_l * b_h;
349 res_h += c >> SM2_SWORD_BIT_SIZE;
350 t = res_l;
351 res_l += c << SM2_SWORD_BIT_SIZE;
352 res_h += t > res_l;
353 *res_high = res_h;
354 *res_low = res_l;
355 }
356
357 /* r = a * b mod p */
sm2_bn_mul_mod_p(uint64_t a[],uint64_t b[],uint64_t r[])358 static void sm2_bn_mul_mod_p(uint64_t a[], uint64_t b[], uint64_t r[])
359 {
360 uint64_t bn_mul_res[SM2_DATA_MUL_DWORD_SIZE] = { 0 };
361 uint64_t bn_mul_res_low = 0;
362 uint64_t bn_mul_res_high = 0;
363 uint64_t mul_carry = 0;
364 uint64_t add_carry = 0;
365 uint64_t carry_to_next_unit = 0;
366
367 /* 1. cal a0 * b0 */
368 sm2_bn_word_mul(a[0], b[0], &bn_mul_res_low, &bn_mul_res_high);
369 bn_mul_res[0] = bn_mul_res_low;
370 mul_carry = bn_mul_res_high;
371
372 /* 2. cal a0 * b1, a1 * b0 */
373 sm2_bn_word_mul(a[0], b[1], &bn_mul_res_low, &bn_mul_res_high);
374 bn_mul_res[1] = bn_mul_res_low;
375 add_with_carry(bn_mul_res[1], mul_carry, 0, &bn_mul_res[1], &add_carry);
376 mul_carry = bn_mul_res_high + add_carry;
377
378 sm2_bn_word_mul(a[1], b[0], &bn_mul_res_low, &bn_mul_res_high);
379 add_with_carry(bn_mul_res[1], bn_mul_res_low, 0, &bn_mul_res[1], &add_carry);
380 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &carry_to_next_unit);
381
382 /* 3. cal a0 * b2, a1 * b1, a2 * b0 */
383 sm2_bn_word_mul(a[0], b[2], &bn_mul_res_low, &bn_mul_res_high);
384 bn_mul_res[2] = bn_mul_res_low;
385 add_with_carry(bn_mul_res[2], mul_carry, 0, &bn_mul_res[2], &add_carry);
386 add_with_carry(bn_mul_res_high, carry_to_next_unit, add_carry, &mul_carry, &add_carry);
387 carry_to_next_unit = add_carry;
388
389 sm2_bn_word_mul(a[1], b[1], &bn_mul_res_low, &bn_mul_res_high);
390 add_with_carry(bn_mul_res[2], bn_mul_res_low, 0, &bn_mul_res[2], &add_carry);
391 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
392 carry_to_next_unit += add_carry;
393
394 sm2_bn_word_mul(a[2], b[0], &bn_mul_res_low, &bn_mul_res_high);
395 add_with_carry(bn_mul_res[2], bn_mul_res_low, 0, &bn_mul_res[2], &add_carry);
396 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
397 carry_to_next_unit += add_carry;
398
399 /* 4. cal a0 * b3, a1 * b2, a2 * b1, a3 * b0 */
400 sm2_bn_word_mul(a[0], b[3], &bn_mul_res_low, &bn_mul_res_high);
401 bn_mul_res[3] = bn_mul_res_low;
402 add_with_carry(bn_mul_res[3], mul_carry, 0, &bn_mul_res[3], &add_carry);
403 add_with_carry(bn_mul_res_high, carry_to_next_unit, add_carry, &mul_carry, &add_carry);
404 carry_to_next_unit = add_carry;
405
406 sm2_bn_word_mul(a[1], b[2], &bn_mul_res_low, &bn_mul_res_high);
407 add_with_carry(bn_mul_res[3], bn_mul_res_low, 0, &bn_mul_res[3], &add_carry);
408 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
409 carry_to_next_unit += add_carry;
410
411 sm2_bn_word_mul(a[2], b[1], &bn_mul_res_low, &bn_mul_res_high);
412 add_with_carry(bn_mul_res[3], bn_mul_res_low, 0, &bn_mul_res[3], &add_carry);
413 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
414 carry_to_next_unit += add_carry;
415
416 sm2_bn_word_mul(a[3], b[0], &bn_mul_res_low, &bn_mul_res_high);
417 add_with_carry(bn_mul_res[3], bn_mul_res_low, 0, &bn_mul_res[3], &add_carry);
418 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
419 carry_to_next_unit += add_carry;
420
421 /* 5. cal a1 * b3, a2 * b2, a3 * b1 */
422 sm2_bn_word_mul(a[1], b[3], &bn_mul_res_low, &bn_mul_res_high);
423 bn_mul_res[4] = bn_mul_res_low;
424 add_with_carry(bn_mul_res[4], mul_carry, 0, &bn_mul_res[4], &add_carry);
425 add_with_carry(bn_mul_res_high, carry_to_next_unit, add_carry, &mul_carry, &add_carry);
426 carry_to_next_unit = add_carry;
427
428 sm2_bn_word_mul(a[2], b[2], &bn_mul_res_low, &bn_mul_res_high);
429 add_with_carry(bn_mul_res[4], bn_mul_res_low, 0, &bn_mul_res[4], &add_carry);
430 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
431 carry_to_next_unit += add_carry;
432
433 sm2_bn_word_mul(a[3], b[1], &bn_mul_res_low, &bn_mul_res_high);
434 add_with_carry(bn_mul_res[4], bn_mul_res_low, 0, &bn_mul_res[4], &add_carry);
435 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
436 carry_to_next_unit += add_carry;
437
438 /* 6. cal a2 * b3, a3 * b2 */
439 sm2_bn_word_mul(a[2], b[3], &bn_mul_res_low, &bn_mul_res_high);
440 bn_mul_res[5] = bn_mul_res_low;
441 add_with_carry(bn_mul_res[5], mul_carry, 0, &bn_mul_res[5], &add_carry);
442 add_with_carry(bn_mul_res_high, carry_to_next_unit, add_carry, &mul_carry, &add_carry);
443 carry_to_next_unit = add_carry;
444
445 sm2_bn_word_mul(a[3], b[2], &bn_mul_res_low, &bn_mul_res_high);
446 add_with_carry(bn_mul_res[5], bn_mul_res_low, 0, &bn_mul_res[5], &add_carry);
447 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
448 carry_to_next_unit += add_carry;
449
450 /* 7. cal a3 * a3 */
451 sm2_bn_word_mul(a[3], b[3], &bn_mul_res_low, &bn_mul_res_high);
452 bn_mul_res[6] = bn_mul_res_low;
453 add_with_carry(bn_mul_res[6], mul_carry, 0, &bn_mul_res[6], &add_carry);
454 add_with_carry(bn_mul_res_high, carry_to_next_unit, add_carry, &bn_mul_res[7], &add_carry);
455
456 sm2_bn_mod_p(bn_mul_res, r);
457 }
458
459 /* r = a * a mod p */
sm2_bn_square_mod_p(uint64_t a[],uint64_t r[])460 static void sm2_bn_square_mod_p(uint64_t a[], uint64_t r[])
461 {
462 uint64_t bn_square_res[SM2_DATA_MUL_DWORD_SIZE] = { 0 };
463 uint64_t bn_mul_res_low = 0;
464 uint64_t bn_mul_res_high = 0;
465 uint64_t mul_carry = 0;
466 uint64_t add_carry = 0;
467 uint64_t carry_to_next_unit = 0;
468
469 /* cal a0 * a1 */
470 sm2_bn_word_mul(a[0], a[1], &bn_mul_res_low, &bn_mul_res_high);
471 bn_square_res[1] = bn_mul_res_low;
472 mul_carry = bn_mul_res_high;
473
474 /* cal a0 * a2 */
475 sm2_bn_word_mul(a[0], a[2], &bn_mul_res_low, &bn_mul_res_high);
476 bn_square_res[2] = bn_mul_res_low;
477 add_with_carry(bn_square_res[2], mul_carry, 0, &bn_square_res[2], &add_carry);
478 add_with_carry(bn_mul_res_high, 0, add_carry, &mul_carry, &add_carry);
479
480 /* cal a0 *a3, a1 * a2 */
481 sm2_bn_word_mul(a[0], a[3], &bn_mul_res_low, &bn_mul_res_high);
482 bn_square_res[3] = bn_mul_res_low;
483 add_with_carry(bn_square_res[3], mul_carry, 0, &bn_square_res[3], &add_carry);
484 add_with_carry(bn_mul_res_high, 0, add_carry, &mul_carry, &add_carry);
485
486 sm2_bn_word_mul(a[1], a[2], &bn_mul_res_low, &bn_mul_res_high);
487 add_with_carry(bn_square_res[3], bn_mul_res_low, 0, &bn_square_res[3], &add_carry);
488 add_with_carry(mul_carry, bn_mul_res_high, add_carry, &mul_carry, &add_carry);
489 carry_to_next_unit += add_carry;
490
491 /* cal a1 * a3 */
492 sm2_bn_word_mul(a[1], a[3], &bn_mul_res_low, &bn_mul_res_high);
493 bn_square_res[4] = bn_mul_res_low;
494 add_with_carry(bn_square_res[4], mul_carry, 0, &bn_square_res[4], &add_carry);
495 add_with_carry(bn_mul_res_high, carry_to_next_unit, add_carry, &mul_carry, &add_carry);
496
497 /* cal a2 * a3 */
498 sm2_bn_word_mul(a[2], a[3], &bn_mul_res_low, &bn_mul_res_high);
499 bn_square_res[5] = bn_mul_res_low;
500 add_with_carry(bn_square_res[5], mul_carry, 0, &bn_square_res[5], &add_carry);
501 add_with_carry(bn_mul_res_high, 0, add_carry, &bn_square_res[6], &bn_square_res[7]);
502
503 /* cal 2 * bn_square_res */
504 add_with_carry(bn_square_res[1], bn_square_res[1], 0, &bn_square_res[1], &add_carry);
505 add_with_carry(bn_square_res[2], bn_square_res[2], add_carry, &bn_square_res[2], &add_carry);
506 add_with_carry(bn_square_res[3], bn_square_res[3], add_carry, &bn_square_res[3], &add_carry);
507 add_with_carry(bn_square_res[4], bn_square_res[4], add_carry, &bn_square_res[4], &add_carry);
508 add_with_carry(bn_square_res[5], bn_square_res[5], add_carry, &bn_square_res[5], &add_carry);
509 add_with_carry(bn_square_res[6], bn_square_res[6], add_carry, &bn_square_res[6], &add_carry);
510 add_with_carry(bn_square_res[7], bn_square_res[7], add_carry, &bn_square_res[7], &add_carry);
511
512 /* cal ai ^ 2 */
513 sm2_bn_word_mul(a[0], a[0], &bn_mul_res_low, &bn_mul_res_high);
514 bn_square_res[0] = bn_mul_res_low;
515 mul_carry = bn_mul_res_high;
516
517 sm2_bn_word_mul(a[1], a[1], &bn_mul_res_low, &bn_mul_res_high);
518 r[0] = bn_mul_res_low;
519 r[1] = bn_mul_res_high;
520
521 sm2_bn_word_mul(a[2], a[2], &bn_mul_res_low, &bn_mul_res_high);
522 add_with_carry(bn_square_res[1], mul_carry, 0, &bn_square_res[1], &add_carry);
523 add_with_carry(bn_square_res[2], r[0], add_carry, &bn_square_res[2], &add_carry);
524 add_with_carry(bn_square_res[3], r[1], add_carry, &bn_square_res[3], &add_carry);
525 add_with_carry(bn_square_res[4], bn_mul_res_low, add_carry, &bn_square_res[4], &add_carry);
526 add_with_carry(bn_square_res[5], bn_mul_res_high, add_carry, &bn_square_res[5], &add_carry);
527 add_with_carry(bn_square_res[6], 0, add_carry, &bn_square_res[6], &add_carry);
528 add_with_carry(bn_square_res[7], 0, add_carry, &bn_square_res[7], &add_carry);
529
530 sm2_bn_word_mul(a[3], a[3], &bn_mul_res_low, &bn_mul_res_high);
531 add_with_carry(bn_square_res[6], bn_mul_res_low, 0, &bn_square_res[6], &add_carry);
532 add_with_carry(bn_square_res[7], bn_mul_res_high, add_carry, &bn_square_res[7], &add_carry);
533
534 sm2_bn_mod_p(bn_square_res, r);
535 }
536
537 /* check a is valid or not */
sm2_bn_is_valid(uint64_t a[])538 int sm2_bn_is_valid(uint64_t a[])
539 {
540 for (uint32_t i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
541 if (a[i] != 0)
542 return SM2_BN_OK;
543 }
544
545 return SM2_BN_INVALID;
546 }
547
548 /*
549 * cmp a and b
550 * a = b, return 0; a > b, return 1; a < b, return -1
551 */
sm2_bn_cmp(uint64_t a[],uint64_t b[])552 int sm2_bn_cmp(uint64_t a[], uint64_t b[])
553 {
554 uint64_t borrow = 0;
555 uint64_t r[SM2_DATA_DWORD_SIZE] = { 0 };
556
557 for (uint32_t i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
558 sub_with_borrow(a[i], b[i], borrow, &r[i], &borrow);
559 }
560
561 if (borrow == 1)
562 return -1;
563
564 if (sm2_bn_is_valid(r) == SM2_BN_INVALID)
565 return 0;
566
567 return 1;
568 }
569
570 /* check a in [1, n - 1] */
sm2_bn_check_indomain_n(uint64_t a[])571 int sm2_bn_check_indomain_n(uint64_t a[])
572 {
573 int ret;
574
575 ret = sm2_bn_is_valid(a);
576 if (hvb_check(ret != SM2_BN_OK))
577 return SM2_BN_INVALID;
578
579 if (sm2_bn_cmp((uint64_t *)g_n, a) <= 0)
580 return SM2_BN_NOT_INDOMAIN;
581
582 return ret;
583 }
584
sm2_bn_is_not_one(uint64_t a[])585 static inline int sm2_bn_is_not_one(uint64_t a[])
586 {
587 return (a[0] != 1 || a[1] != 0 || a[2] != 0 || a[3] != 0);
588 }
589
590 /*
591 * a >= b, return 1
592 * a < b, return 0
593 */
sm2_bn_a_is_no_samll_b(uint64_t a[],uint64_t b[])594 static int sm2_bn_a_is_no_samll_b(uint64_t a[], uint64_t b[])
595 {
596 for (int i = 3; i >= 0; i--) {
597 if (a[i] == b[i])
598 continue;
599 else
600 return a[i] > b[i] ? 1 : 0;
601 }
602
603 return 1;
604 }
605
sm2_bn_mod_inv_p(uint64_t a[],uint64_t r[])606 static int sm2_bn_mod_inv_p(uint64_t a[], uint64_t r[])
607 {
608 uint64_t u[SM2_DATA_DWORD_SIZE] = { 0 };
609 uint64_t x1[SM2_DATA_DWORD_SIZE] = { 1, 0, 0, 0 };
610 uint64_t x2[SM2_DATA_DWORD_SIZE] = { 0, 0, 0, 0 };
611 uint64_t v[SM2_DATA_DWORD_SIZE] = { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF00000000,
612 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFEFFFFFFFF };
613 /* (p + 1) / 2 */
614 uint64_t p_add_1_div_2[SM2_DATA_DWORD_SIZE] = {0x8000000000000000, 0xFFFFFFFF80000000,
615 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFF7FFFFFFF };
616 int ret = -1;
617
618 ret = hvb_memcpy_s(u, sizeof(u), a, SM2_KEY_LEN);
619 if (hvb_check(ret != 0))
620 return SM2_BN_MEMORY_ERR;
621
622 while (sm2_bn_is_not_one(u) && sm2_bn_is_not_one(v)) {
623 while (!(u[0] & 1)) {
624 shift_right_one_bit(u);
625 if (x1[0] & 1) {
626 shift_right_one_bit(x1);
627 sm2_bn_add_mod_p(x1, p_add_1_div_2, x1);
628 } else {
629 shift_right_one_bit(x1);
630 }
631 }
632
633 while (!(v[0] & 1)) {
634 shift_right_one_bit(v);
635 if (x2[0] & 1) {
636 shift_right_one_bit(x2);
637 sm2_bn_add_mod_p(x2, p_add_1_div_2, x2);
638 } else {
639 shift_right_one_bit(x2);
640 }
641 }
642
643 if (sm2_bn_a_is_no_samll_b(u, v)) {
644 sm2_bn_sub_mod_p(u, v, u);
645 sm2_bn_sub_mod_p(x1, x2, x1);
646 } else {
647 sm2_bn_sub_mod_p(v, u, v);
648 sm2_bn_sub_mod_p(x2, x1, x2);
649 }
650 }
651
652 if (sm2_bn_is_not_one(u))
653 ret = hvb_memcpy_s(r, SM2_KEY_LEN, x2, SM2_KEY_LEN);
654 else
655 ret = hvb_memcpy_s(r, SM2_KEY_LEN, x1, SM2_KEY_LEN);
656
657 if (hvb_check(ret != 0))
658 return SM2_BN_MEMORY_ERR;
659
660 return SM2_BN_OK;
661 }
662
663 /* if a is infinity point, return 1, else return 0. */
sm2_is_infinity_point(struct sm2_point_jcb * a)664 static int sm2_is_infinity_point(struct sm2_point_jcb *a)
665 {
666 for (uint32_t i = 0; i < SM2_DATA_DWORD_SIZE; i++) {
667 if (a->z[i] != 0)
668 return 0;
669 }
670 return 1;
671 }
672
673 /* set point's z to zero */
sm2_set_point_infinity_point(struct sm2_point_jcb * a)674 static void sm2_set_point_infinity_point(struct sm2_point_jcb *a)
675 {
676 for (uint32_t i = 0; i < SM2_DATA_DWORD_SIZE; i++)
677 a->z[i] = 0;
678 }
679
680 /* r = 2 * a */
sm2_point_double(struct sm2_point_jcb * a,struct sm2_point_jcb * r)681 static void sm2_point_double(struct sm2_point_jcb *a, struct sm2_point_jcb *r)
682 {
683 uint64_t t1[SM2_DATA_DWORD_SIZE] = { 0 };
684 uint64_t t2[SM2_DATA_DWORD_SIZE] = { 0 };
685
686 if (sm2_is_infinity_point(a)) {
687 sm2_set_point_infinity_point(r);
688 return;
689 }
690
691 /* t1 = z ^ 2 */
692 sm2_bn_square_mod_p(a->z, t1);
693
694 /* t2 = x - t1 */
695 sm2_bn_sub_mod_p(a->x, t1, t2);
696
697 /* t1 = x + t1 */
698 sm2_bn_add_mod_p(a->x, t1, t1);
699
700 /* t2 = t1 * t2 */
701 sm2_bn_mul_mod_p(t1, t2, t2);
702
703 /* t1 = t2 + t2 */
704 sm2_bn_add_mod_p(t2, t2, t1);
705
706 /* t1 = t1 + t2 */
707 sm2_bn_add_mod_p(t1, t2, t1);
708
709 /* r.y = a.y + a.y */
710 sm2_bn_add_mod_p(a->y, a->y, r->y);
711
712 /* r.z = r.y * a.z */
713 sm2_bn_mul_mod_p(r->y, a->z, r->z);
714
715 /* r.y = r.y ^ 2 */
716 sm2_bn_square_mod_p(r->y, r->y);
717
718 /* t2 = r.y * a.x */
719 sm2_bn_mul_mod_p(r->y, a->x, t2);
720
721 /* r.y = r.y ^ 2 */
722 sm2_bn_square_mod_p(r->y, r->y);
723
724 /* r.y = r.y / 2 */
725 if (r->y[0] % 2 == 0)
726 shift_right_one_bit(r->y);
727 else
728 add_p_shift_right_one_bit(r->y);
729
730 /* r.x = t1 ^ 2 */
731 sm2_bn_square_mod_p(t1, r->x);
732
733 /* r.x -= t2 */
734 sm2_bn_sub_mod_p(r->x, t2, r->x);
735
736 /* r.x -= t2 */
737 sm2_bn_sub_mod_p(r->x, t2, r->x);
738
739 /* t2 -= r.x */
740 sm2_bn_sub_mod_p(t2, r->x, t2);
741
742 /* t1 = t1 * t2 */
743 sm2_bn_mul_mod_p(t1, t2, t1);
744
745 /* r.y = t1 - r.y */
746 sm2_bn_sub_mod_p(t1, r->y, r->y);
747
748 return;
749 }
750
751 /* r = a + b */
sm2_point_add(struct sm2_point_jcb * a,struct sm2_point_jcb * b,struct sm2_point_jcb * r)752 static int sm2_point_add(struct sm2_point_jcb *a, struct sm2_point_jcb *b, struct sm2_point_jcb *r)
753 {
754 uint64_t t1[SM2_DATA_DWORD_SIZE] = { 0 };
755 uint64_t t2[SM2_DATA_DWORD_SIZE] = { 0 };
756 uint64_t t3[SM2_DATA_DWORD_SIZE] = { 0 };
757 int ret = -1;
758
759 if (sm2_is_infinity_point(a)) {
760 ret = hvb_memcpy_s(r->x, SM2_KEY_LEN, b->x, SM2_KEY_LEN);
761 if (hvb_check(ret != 0))
762 return SM2_BN_MEMORY_ERR;
763
764 ret = hvb_memcpy_s(r->y, SM2_KEY_LEN, b->y, SM2_KEY_LEN);
765 if (hvb_check(ret != 0))
766 return SM2_BN_MEMORY_ERR;
767
768 ret = hvb_memcpy_s(r->z, SM2_KEY_LEN, b->z, SM2_KEY_LEN);
769 if (hvb_check(ret != 0))
770 return SM2_BN_MEMORY_ERR;
771
772 return SM2_BN_OK;
773 }
774
775 if (sm2_is_infinity_point(b)) {
776 ret = hvb_memcpy_s(r->x, SM2_KEY_LEN, a->x, SM2_KEY_LEN);
777 if (hvb_check(ret != 0))
778 return SM2_BN_MEMORY_ERR;
779
780 ret = hvb_memcpy_s(r->y, SM2_KEY_LEN, a->y, SM2_KEY_LEN);
781 if (hvb_check(ret != 0))
782 return SM2_BN_MEMORY_ERR;
783
784 ret = hvb_memcpy_s(r->z, SM2_KEY_LEN, a->z, SM2_KEY_LEN);
785 if (hvb_check(ret != 0))
786 return SM2_BN_MEMORY_ERR;
787
788 return SM2_BN_OK;
789 }
790
791 /* 1) t1 = a.z ^ 2 */
792 sm2_bn_square_mod_p(a->z, t1);
793
794 /* 2) t2 = t1 * a.z */
795 sm2_bn_mul_mod_p(t1, a->z, t2);
796
797 /* 3) t1 = t1 * b.x check */
798 sm2_bn_mul_mod_p(t1, b->x, t1);
799
800 /* 4) t2 = t2 * b.y */
801 sm2_bn_mul_mod_p(t2, b->y, t2);
802
803 /* 6) r.y = a.y * b.z */
804 sm2_bn_mul_mod_p(a->y, b->z, r->y);
805
806 /* 7) r.z = a.z * b.z */
807 sm2_bn_mul_mod_p(a->z, b->z, r->z);
808
809 /* 8) t3 = b.z ^ 2 */
810 sm2_bn_square_mod_p(b->z, t3);
811
812 /* 9) r.y = r.y * t3 */
813 sm2_bn_mul_mod_p(r->y, t3, r->y);
814
815 /* 10) r.x = a.x * t3 */
816 sm2_bn_mul_mod_p(a->x, t3, r->x);
817
818 /* 11) t1 -= r.x */
819 sm2_bn_sub_mod_p(t1, r->x, t1);
820
821 /* 12) r.z *= t1 *z1 */
822 sm2_bn_mul_mod_p(r->z, t1, r->z);
823
824 /* 13) t2 -= r.y */
825 sm2_bn_sub_mod_p(t2, r->y, t2);
826
827 /* 14) t3 = t1 ^ 2 */
828 sm2_bn_square_mod_p(t1, t3);
829
830 /* 15) t1 *= t3 */
831 sm2_bn_mul_mod_p(t1, t3, t1);
832
833 /* 16) t3 *= r.x */
834 sm2_bn_mul_mod_p(t3, r->x, t3);
835
836 /* 17) r.x = t2 ^ 2 */
837 sm2_bn_square_mod_p(t2, r->x);
838
839 /* 18) r.x -= t3 */
840 sm2_bn_sub_mod_p(r->x, t3, r->x);
841
842 /* 19) r.x -= t3 */
843 sm2_bn_sub_mod_p(r->x, t3, r->x);
844
845 /* 20) r.x -= t1 */
846 sm2_bn_sub_mod_p(r->x, t1, r->x);
847
848 /* 21) t3 -= r.x */
849 sm2_bn_sub_mod_p(t3, r->x, t3);
850
851 /* 22) t3 *= t2 */
852 sm2_bn_mul_mod_p(t3, t2, t3);
853
854 /* 23) t1 *= r.y */
855 sm2_bn_mul_mod_p(t1, r->y, t1);
856
857 /* 24) r.y = t3 - t1 */
858 sm2_bn_sub_mod_p(t3, t1, r->y);
859
860 return SM2_BN_OK;
861 }
862
863 /* convert jcb point to aff point */
sm2_point_jcb2aff(const struct sm2_point_jcb * a,struct sm2_point_aff * r)864 static int sm2_point_jcb2aff(const struct sm2_point_jcb *a, struct sm2_point_aff *r)
865 {
866 uint64_t t1[SM2_DATA_DWORD_SIZE] = { 0 };
867 uint64_t t2[SM2_DATA_DWORD_SIZE] = { 0 };
868 int ret = -1;
869
870 /* t1 = a.z ^ -1 */
871 ret = sm2_bn_mod_inv_p((uint64_t *)a->z, t1);
872 if (hvb_check(ret != SM2_BN_OK))
873 return ret;
874
875 /* t2 = t1 ^ 2 */
876 sm2_bn_square_mod_p(t1, t2);
877
878 /* r.x = a.x * t2 */
879 sm2_bn_mul_mod_p((uint64_t *)a->x, t2, r->x);
880
881 /* r.y = a.y * t1 * t2 */
882 sm2_bn_mul_mod_p((uint64_t *)a->y, t1, r->y);
883 sm2_bn_mul_mod_p(r->y, t2, r->y);
884
885 return ret;
886 }
887
888 /* convert aff point to jcb point */
sm2_point_aff2jcb(const struct sm2_point_aff * a,struct sm2_point_jcb * r)889 static int sm2_point_aff2jcb(const struct sm2_point_aff *a, struct sm2_point_jcb *r)
890 {
891 int ret = -1;
892 ret = hvb_memcpy_s(r->x, SM2_KEY_LEN, a->x, SM2_KEY_LEN);
893 if (hvb_check(ret != 0))
894 return SM2_BN_MEMORY_ERR;
895
896 ret = hvb_memcpy_s(r->y, SM2_KEY_LEN, a->y, SM2_KEY_LEN);
897 if (hvb_check(ret != 0))
898 return SM2_BN_MEMORY_ERR;
899
900 ret = hvb_memset_s(r->z, SM2_KEY_LEN, 0, SM2_KEY_LEN);
901 if (hvb_check(ret != 0))
902 return SM2_BN_MEMORY_ERR;
903
904 r->z[0] = 1;
905 return SM2_BN_OK;
906 }
907
908 /* r = -a, jcb point neg same as aff point neg, just neg y */
sm2_point_neg(const struct sm2_point_jcb * a,struct sm2_point_jcb * r)909 static int sm2_point_neg(const struct sm2_point_jcb *a, struct sm2_point_jcb *r)
910 {
911 int ret = -1;
912
913 ret = hvb_memcpy_s(r->x, SM2_KEY_LEN, a->x, SM2_KEY_LEN);
914 if (hvb_check(ret != 0))
915 return SM2_BN_MEMORY_ERR;
916
917 ret = hvb_memcpy_s(r->z, SM2_KEY_LEN, a->z, SM2_KEY_LEN);
918 if (hvb_check(ret != 0))
919 return SM2_BN_MEMORY_ERR;
920
921 sm2_bn_sub_mod_p((uint64_t *)g_p, (uint64_t *)a->y, r->y);
922 return SM2_BN_OK;
923 }
924
925 /* cal p, 3p, 5p ,..., (2^(SLIDING_WINDOW_SIZE-2)-1)p, -p, -3p, -5p ,..., -(2^(SLIDING_WINDOW_SIZE-2)-1)p */
sm2_point_pre_cal_table(const struct sm2_point_jcb * p,struct sm2_point_jcb table[])926 static int sm2_point_pre_cal_table(const struct sm2_point_jcb *p, struct sm2_point_jcb table[])
927 {
928 struct sm2_point_jcb double_p = { 0 };
929 uint32_t i;
930 int ret = -1;
931
932 ret = hvb_memcpy_s(table[0].x, SM2_KEY_LEN, p->x, SM2_KEY_LEN);
933 if (hvb_check(ret != 0))
934 return SM2_BN_MEMORY_ERR;
935
936 ret = hvb_memcpy_s(table[0].y, SM2_KEY_LEN, p->y, SM2_KEY_LEN);
937 if (hvb_check(ret != 0))
938 return SM2_BN_MEMORY_ERR;
939
940 ret = hvb_memcpy_s(table[0].z, SM2_KEY_LEN, p->z, SM2_KEY_LEN);
941 if (hvb_check(ret != 0))
942 return SM2_BN_MEMORY_ERR;
943
944 sm2_point_double(&table[0], &double_p);
945 for (i = 1; i < (SLIDING_WINDOW_PRE_TABLE_SIZE / 2); i++) {
946 ret = sm2_point_add(&table[i - 1], &double_p, &table[i]);
947 if (hvb_check(ret != SM2_BN_OK))
948 return ret;
949 }
950 for (i = (SLIDING_WINDOW_PRE_TABLE_SIZE / 2); i < SLIDING_WINDOW_PRE_TABLE_SIZE; i++) {
951 ret = sm2_point_neg(&table[i - (SLIDING_WINDOW_PRE_TABLE_SIZE / 2)], &table[i]);
952 if (hvb_check(ret != SM2_BN_OK))
953 return ret;
954 }
955
956 return SM2_BN_OK;
957 }
958
sm2_bn_get_valid_bits(const uint64_t a[])959 static uint32_t sm2_bn_get_valid_bits(const uint64_t a[])
960 {
961 uint32_t zero_bits = 0;
962 uint64_t mask;
963
964 for (int i = SM2_DATA_DWORD_SIZE - 1; i >= 0; i--) {
965 if (a[i] == 0) {
966 zero_bits += sizeof(uint64_t) * SM2_BIT_PER_BYTE;
967 continue;
968 }
969 mask = (uint64_t)1 << (sizeof(uint64_t) * SM2_BIT_PER_BYTE - 1);
970 while ((a[i] & mask) == 0) {
971 zero_bits++;
972 mask = mask >> 1;
973 }
974 break;
975 }
976
977 return SM2_DATA_BIT_SIZE - zero_bits;
978 }
979
sm2_bn_get_bit_value(const uint64_t a[],uint32_t index)980 static uint8_t sm2_bn_get_bit_value(const uint64_t a[], uint32_t index)
981 {
982 uint32_t dword_index = index / (sizeof(uint64_t) * SM2_BIT_PER_BYTE);
983 uint32_t bit_index = index % (sizeof(uint64_t) * SM2_BIT_PER_BYTE);
984
985 return ((uint8_t)(a[dword_index] >> bit_index)) & 0x1;
986 }
987
988 /* pretable arrangement rule is 1 3 5 7 ... 15 -1 -3 ... -15 */
sm2_get_index_in_pretable(int8_t code_num)989 static int8_t sm2_get_index_in_pretable(int8_t code_num)
990 {
991 int8_t index = (code_num - 1) / 2;
992 return code_num < 0 ? (SLIDING_WINDOW_PRE_TABLE_SIZE / 2 - 1 - index) : index;
993 }
994
sm2_calculate_window_value(uint32_t cur_bits,uint32_t window_size,const uint64_t k[])995 static uint32_t sm2_calculate_window_value(uint32_t cur_bits, uint32_t window_size, const uint64_t k[])
996 {
997 uint32_t dword_index = cur_bits / (sizeof(uint64_t) * SM2_BIT_PER_BYTE);
998 uint32_t bit_index = cur_bits % (sizeof(uint64_t) * SM2_BIT_PER_BYTE);
999 uint64_t tmp = (1 << window_size) - 1;
1000 uint32_t code_num_low = (k[dword_index] >> bit_index) & tmp;
1001 if (bit_index + window_size <= SM2_BIT_PER_LONG || dword_index == SM2_DATA_DWORD_SIZE - 1)
1002 return code_num_low;
1003 uint32_t lower_bits = SM2_BIT_PER_LONG - bit_index;
1004 uint32_t code_num_high = (k[dword_index + 1] << lower_bits) & tmp;
1005 return code_num_high + code_num_low;
1006 }
1007
sm2_point_scalar_encode(const uint64_t k[],struct sm2_point_scalar_encode_info * encode_info)1008 static void sm2_point_scalar_encode(const uint64_t k[], struct sm2_point_scalar_encode_info *encode_info)
1009 {
1010 uint8_t max_num = (1 << SLIDING_WINDOW_SIZE);
1011 uint32_t valid_bits = sm2_bn_get_valid_bits(k);
1012 uint32_t window_offset = -1;
1013 uint32_t cur_bits = 0;
1014 uint8_t is_carry = 0;
1015 uint32_t last_shift_bits = 0;
1016 while (cur_bits < valid_bits) {
1017 int8_t encode_num = 0;
1018 window_offset++;
1019 while (cur_bits < valid_bits && sm2_bn_get_bit_value(k, cur_bits) == is_carry) {
1020 cur_bits++;
1021 last_shift_bits++;
1022 }
1023
1024 if (cur_bits < valid_bits)
1025 encode_num = sm2_calculate_window_value(cur_bits, SLIDING_WINDOW_SIZE, k);
1026
1027 cur_bits += SLIDING_WINDOW_SIZE;
1028 encode_num += is_carry;
1029 is_carry = (encode_num >= (max_num >> 1));
1030 encode_num = is_carry ? (-(max_num - encode_num)) : encode_num;
1031 encode_info->code_num[window_offset] = encode_num;
1032 encode_info->shift_bit[window_offset] = last_shift_bits;
1033 if (window_offset > 0)
1034 encode_info->shift_bit[window_offset] += encode_info->shift_bit[window_offset - 1];
1035 last_shift_bits = (valid_bits > cur_bits) ? SLIDING_WINDOW_SIZE : valid_bits + SLIDING_WINDOW_SIZE - cur_bits;
1036 }
1037
1038 if (is_carry) {
1039 window_offset++;
1040 encode_info->code_num[window_offset] = 1;
1041 encode_info->shift_bit[window_offset] = last_shift_bits + encode_info->shift_bit[window_offset - 1];
1042 }
1043 encode_info->start_bit = is_carry ? valid_bits : (valid_bits - last_shift_bits);
1044 encode_info->window_num = window_offset + 1;
1045 }
1046
sm2_point_mul_add(const uint64_t k1[],const uint64_t k2[],struct sm2_point_aff * p,struct sm2_point_aff * r)1047 int sm2_point_mul_add(const uint64_t k1[], const uint64_t k2[], struct sm2_point_aff *p,
1048 struct sm2_point_aff *r)
1049 {
1050 struct sm2_point_jcb p_jcb = { 0 };
1051 struct sm2_point_jcb r_jcb = { 0 };
1052 struct sm2_point_jcb precompute_g_table[SLIDING_WINDOW_PRE_TABLE_SIZE] = { 0 };
1053 struct sm2_point_jcb precompute_p_table[SLIDING_WINDOW_PRE_TABLE_SIZE] = { 0 };
1054 struct sm2_point_scalar_encode_info k1_encode_info = { 0 };
1055 struct sm2_point_scalar_encode_info k2_encode_info = { 0 };
1056 int8_t index = 0;
1057 int ret = -1;
1058
1059 ret = sm2_point_aff2jcb(p, &p_jcb);
1060 if (hvb_check(ret != SM2_BN_OK))
1061 return ret;
1062
1063 ret = sm2_point_pre_cal_table(&p_jcb, precompute_p_table);
1064 if (hvb_check(ret != SM2_BN_OK))
1065 return ret;
1066
1067 ret = sm2_point_pre_cal_table(&g_pointg, precompute_g_table);
1068 if (hvb_check(ret != SM2_BN_OK))
1069 return ret;
1070
1071 sm2_point_scalar_encode(k1, &k1_encode_info);
1072 sm2_point_scalar_encode(k2, &k2_encode_info);
1073
1074 int start_bit = (k1_encode_info.start_bit > k2_encode_info.start_bit) ?
1075 k1_encode_info.start_bit : k2_encode_info.start_bit;
1076
1077 int32_t k1_window_index = k1_encode_info.window_num - 1;
1078 int32_t k2_window_index = k2_encode_info.window_num - 1;
1079
1080 while (start_bit > 0) {
1081 if (k1_window_index >= 0 && start_bit == k1_encode_info.shift_bit[k1_window_index]) {
1082 index = sm2_get_index_in_pretable(k1_encode_info.code_num[k1_window_index]);
1083 ret = sm2_point_add(&r_jcb, &precompute_g_table[index], &r_jcb);
1084 if (hvb_check(ret != SM2_BN_OK))
1085 return ret;
1086 k1_window_index--;
1087 }
1088 if (k2_window_index >= 0 && start_bit == k2_encode_info.shift_bit[k2_window_index]) {
1089 index = sm2_get_index_in_pretable(k2_encode_info.code_num[k2_window_index]);
1090 ret = sm2_point_add(&r_jcb, &precompute_p_table[index], &r_jcb);
1091 if (hvb_check(ret != SM2_BN_OK))
1092 return ret;
1093 k2_window_index--;
1094 }
1095 sm2_point_double(&r_jcb, &r_jcb);
1096 start_bit--;
1097 }
1098
1099 if (k1_window_index >= 0 && start_bit == k1_encode_info.shift_bit[k1_window_index]) {
1100 index = sm2_get_index_in_pretable(k1_encode_info.code_num[k1_window_index]);
1101 ret = sm2_point_add(&r_jcb, &precompute_g_table[index], &r_jcb);
1102 if (hvb_check(ret != SM2_BN_OK))
1103 return ret;
1104 }
1105 if (k2_window_index >= 0 && start_bit == k2_encode_info.shift_bit[k2_window_index]) {
1106 index = sm2_get_index_in_pretable(k2_encode_info.code_num[k2_window_index]);
1107 ret = sm2_point_add(&r_jcb, &precompute_p_table[index], &r_jcb);
1108 if (hvb_check(ret != SM2_BN_OK))
1109 return ret;
1110 }
1111
1112 ret = sm2_bn_is_valid(r_jcb.z);
1113 if (hvb_check(ret != SM2_BN_OK))
1114 return SM2_BN_INVALID;
1115
1116 ret = sm2_point_jcb2aff((const struct sm2_point_jcb *)&r_jcb, r);
1117 if (hvb_check(ret != SM2_BN_OK))
1118 return ret;
1119
1120 return ret;
1121 }
1122