• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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