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_CURVE_SM2) && defined(HITLS_SIXTY_FOUR_BITS)
18
19 #include <stdint.h>
20 #include "securec.h"
21 #include "crypt_ecc.h"
22 #include "ecc_local.h"
23 #include "crypt_utils.h"
24 #include "crypt_errno.h"
25 #include "bsl_sal.h"
26 #include "bsl_err_internal.h"
27 #include "asm_ecp_sm2.h"
28
29 #define SM2_MASK2 0xff
30 #define WINDOW_SIZE 4
31 #define PRECOMPUTED_TABLE_SIZE (1 << WINDOW_SIZE)
32 #define WINDOW_HALF_TABLE_SIZE 8
33 #define SM2_NUMTOOFFSET(num) (((num) < 0) ? (WINDOW_HALF_TABLE_SIZE - 1 - (((num) - 1) >> 1)) : (((num) - 1) >> 1))
34
35 static const BN_UINT g_sm2p[SM2_LIMBS] = {
36 0xffffffffffffffff, 0xffffffff00000000,
37 0xffffffffffffffff, 0xfffffffeffffffff
38 };
39
40 static const BN_UINT g_sm2ord[SM2_LIMBS] = {
41 0x53bbf40939d54123, 0x7203df6b21c6052b,
42 0xffffffffffffffff, 0xfffffffeffffffff
43 };
44
45 static const BN_UINT g_one[SM2_LIMBS] = {1, 0, 0, 0};
46
47 #define FDIV(uout, uin, xout, xin, div, mod) \
48 do { \
49 ECP_Sm2Div##div(uout, uin); \
50 ECP_Sm2Div##div##Mod##mod(xout, xin); \
51 } while (0)
52
53 #define FSUB(uout, uin, xout, xin, mod) \
54 do { \
55 ECP_Sm2BnSub(uout, uout, uin); \
56 ECP_Sm2SubMod##mod(xout, xout, xin); \
57 } while (0)
58
59 #define FSUB_DIV(u, v, x1, x2, div, mod) \
60 do { \
61 if (IsGreater(u, v) == 1) { \
62 FSUB(u, v, x1, x2, mod); \
63 FDIV(u, u, x1, x1, div, mod); \
64 } else { \
65 FSUB(v, u, x2, x1, mod); \
66 FDIV(v, v, x2, x2, div, mod); \
67 } \
68 } while (0)
69
IsZero(BN_UINT a)70 static uint32_t IsZero(BN_UINT a)
71 {
72 BN_UINT t = a;
73 t |= (0 - t);
74 t = ~t;
75 t >>= (BN_UNIT_BITS - 1);
76 return (uint32_t)t;
77 }
78
IsZeros(const BN_UINT * a)79 static uint32_t IsZeros(const BN_UINT *a)
80 {
81 BN_UINT res = a[0] ^ 0;
82 for (uint32_t i = 1; i < SM2_LIMBS; i++) {
83 res |= a[i] ^ 0;
84 }
85 return IsZero(res);
86 }
87
IsEqual(const BN_UINT * a,const BN_UINT * b)88 static uint32_t IsEqual(const BN_UINT *a, const BN_UINT *b)
89 {
90 BN_UINT res = a[0] ^ b[0];
91 for (uint32_t i = 1; i < SM2_LIMBS; i++) {
92 res |= a[i] ^ b[i];
93 }
94 return IsZero(res);
95 }
96
97 #define IS_ONE(a) IsEqual(a, g_one)
98
IsGreater(const BN_UINT * a,const BN_UINT * b)99 static int32_t IsGreater(const BN_UINT *a, const BN_UINT *b)
100 {
101 for (int32_t i = (int32_t)(SM2_LIMBS - 1); i >= 0; --i) {
102 if (a[i] > b[i]) {
103 return 1;
104 }
105 if (a[i] < b[i]) {
106 return -1;
107 }
108 }
109
110 return 0;
111 }
112
113 /*
114 * Radix-4 Binary algorithm for modular inversion in Fp
115 * ref. <Ultra High-Speed SM2 ASIC Implementation>
116 */
117
118 /* Modular inv: out = in^(-1) mod p */
ECP_Sm2ModInverse(BN_UINT * out,const BN_UINT * in)119 static void ECP_Sm2ModInverse(BN_UINT *out, const BN_UINT *in)
120 {
121 BN_UINT u[SM2_LIMBS] ALIGN32;
122 BN_UINT v[SM2_LIMBS] ALIGN32;
123 BN_UINT x1[SM2_LIMBS] ALIGN32 = {1, 0, 0, 0};
124 BN_UINT x2[SM2_LIMBS] ALIGN32 = {0};
125 BN_UINT c;
126 BN_UINT d;
127 if (IsZeros(in) != 0) {
128 return;
129 }
130 (void)memcpy_s(u, SM2_BYTES_NUM, in, SM2_BYTES_NUM);
131 (void)memcpy_s(v, SM2_BYTES_NUM, g_sm2p, SM2_BYTES_NUM);
132 while (((!IS_ONE(u)) != 0) && ((!IS_ONE(v)) != 0)) {
133 c = u[0] & 0x3; // Use 0x03 to obtain the last two bits.
134 d = v[0] & 0x3;
135 if (c == 0) {
136 FDIV(u, u, x1, x1, 4, P);
137 } else if (d == 0) {
138 FDIV(v, v, x2, x2, 4, P);
139 } else if (c == d) {
140 FSUB_DIV(u, v, x1, x2, 4, P);
141 } else if (c == 2) { // if c == 2
142 FDIV(u, u, x1, x1, 2, P);
143 FSUB_DIV(u, v, x1, x2, 2, P);
144 } else if (d == 2) { // if d == 2
145 FDIV(v, v, x2, x2, 2, P);
146 FSUB_DIV(u, v, x1, x2, 2, P);
147 } else {
148 FSUB_DIV(u, v, x1, x2, 2, P);
149 }
150 }
151 if (IS_ONE(u) != 0) {
152 (void)memcpy_s(out, SM2_BYTES_NUM, x1, SM2_BYTES_NUM);
153 } else {
154 (void)memcpy_s(out, SM2_BYTES_NUM, x2, SM2_BYTES_NUM);
155 }
156 }
157
158 /* Modular inv: out = in^(-1) mod n, where n = ord(p) */
ECP_Sm2InvModOrd(BN_UINT * out,const BN_UINT * in)159 static void ECP_Sm2InvModOrd(BN_UINT *out, const BN_UINT *in)
160 {
161 BN_UINT u[SM2_LIMBS] ALIGN32;
162 BN_UINT v[SM2_LIMBS] ALIGN32;
163 BN_UINT x1[SM2_LIMBS] ALIGN32 = {1, 0, 0, 0};
164 BN_UINT x2[SM2_LIMBS] ALIGN32 = {0};
165 BN_UINT c;
166 BN_UINT d;
167 if (IsZeros(in) != 0) {
168 return;
169 }
170 (void)memcpy_s(u, SM2_BYTES_NUM, in, SM2_BYTES_NUM);
171 (void)memcpy_s(v, SM2_BYTES_NUM, g_sm2ord, SM2_BYTES_NUM);
172 while (((!IS_ONE(u)) != 0) && ((!IS_ONE(v)) != 0)) {
173 c = u[0] & 0x3; // Use 0x03 to obtain the last two bits.
174 d = v[0] & 0x3;
175 if (c == 0) {
176 FDIV(u, u, x1, x1, 4, Ord);
177 } else if (d == 0) {
178 FDIV(v, v, x2, x2, 4, Ord);
179 } else if (c == d) {
180 FSUB_DIV(u, v, x1, x2, 4, Ord);
181 } else if (c == 2) { // if c == 2
182 FDIV(u, u, x1, x1, 2, Ord);
183 FSUB_DIV(u, v, x1, x2, 2, Ord);
184 } else if (d == 2) { // if d == 2
185 FDIV(v, v, x2, x2, 2, Ord);
186 FSUB_DIV(u, v, x1, x2, 2, Ord);
187 } else {
188 FSUB_DIV(u, v, x1, x2, 2, Ord);
189 }
190 }
191 if (IS_ONE(u) != 0) {
192 (void)memcpy_s(out, SM2_BYTES_NUM, x1, SM2_BYTES_NUM);
193 } else {
194 (void)memcpy_s(out, SM2_BYTES_NUM, x2, SM2_BYTES_NUM);
195 }
196 }
197
ECP_Sm2Point2Array(SM2_point * r,const ECC_Point * p)198 static int32_t ECP_Sm2Point2Array(SM2_point *r, const ECC_Point *p)
199 {
200 int32_t ret;
201 uint32_t len = SM2_LIMBS;
202 GOTO_ERR_IF_EX(BN_Bn2U64Array(p->x, (BN_UINT *)&r->x, &len), ret);
203 GOTO_ERR_IF_EX(BN_Bn2U64Array(p->y, (BN_UINT *)&r->y, &len), ret);
204 GOTO_ERR_IF_EX(BN_Bn2U64Array(p->z, (BN_UINT *)&r->z, &len), ret);
205 ERR:
206 return ret;
207 }
208
ECP_Sm2Array2Point(ECC_Point * r,const SM2_point * a)209 static int32_t ECP_Sm2Array2Point(ECC_Point *r, const SM2_point *a)
210 {
211 int32_t ret;
212 GOTO_ERR_IF_EX(BN_U64Array2Bn(r->x, (const BN_UINT *)a->x, SM2_LIMBS), ret);
213 GOTO_ERR_IF_EX(BN_U64Array2Bn(r->y, (const BN_UINT *)a->y, SM2_LIMBS), ret);
214 GOTO_ERR_IF_EX(BN_U64Array2Bn(r->z, (const BN_UINT *)a->z, SM2_LIMBS), ret);
215 ERR:
216 return ret;
217 }
218
ECP_Sm2GetAffine(SM2_AffinePoint * r,const SM2_point * a)219 int32_t ECP_Sm2GetAffine(SM2_AffinePoint *r, const SM2_point *a)
220 {
221 BN_UINT zInv3[SM2_LIMBS] ALIGN32 = {0};
222 BN_UINT zInv2[SM2_LIMBS] ALIGN32 = {0};
223 if (IsZeros(a->z) != 0) {
224 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY);
225 return CRYPT_ECC_POINT_AT_INFINITY;
226 }
227 if (IsEqual(a->z, g_one) != 0) {
228 (void)memcpy_s(r->x, sizeof(r->x), a->x, sizeof(r->x));
229 (void)memcpy_s(r->y, sizeof(r->y), a->y, sizeof(r->x));
230 return CRYPT_SUCCESS;
231 }
232
233 ECP_Sm2ModInverse(zInv3, a->z);
234 ECP_Sm2Sqr(zInv2, zInv3);
235 ECP_Sm2Mul(r->x, a->x, zInv2);
236 ECP_Sm2Mul(zInv3, zInv3, zInv2);
237 ECP_Sm2Mul(r->y, a->y, zInv3);
238
239 return CRYPT_SUCCESS;
240 }
241
ECP_Sm2Point2Affine(const ECC_Para * para,ECC_Point * r,const ECC_Point * a)242 int32_t ECP_Sm2Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a)
243 {
244 if (r == NULL || a == NULL || para == NULL) {
245 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
246 return CRYPT_NULL_INPUT;
247 }
248 if (para->id != CRYPT_ECC_SM2 || r->id != CRYPT_ECC_SM2 || a->id != CRYPT_ECC_SM2) {
249 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
250 return CRYPT_ECC_POINT_ERR_CURVE_ID;
251 }
252
253 SM2_point temp = {0};
254 SM2_AffinePoint rTemp = {0};
255 int32_t ret;
256 GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&temp, a), ret);
257 GOTO_ERR_IF_EX(ECP_Sm2GetAffine(&rTemp, &temp), ret);
258 GOTO_ERR_IF_EX(BN_Array2BN(r->x, rTemp.x, SM2_LIMBS), ret);
259 GOTO_ERR_IF_EX(BN_Array2BN(r->y, rTemp.y, SM2_LIMBS), ret);
260 GOTO_ERR_IF_EX(BN_SetLimb(r->z, 1), ret);
261
262 ERR:
263 return ret;
264 }
265
ECP_Sm2PointDouble(const ECC_Para * para,ECC_Point * r,const ECC_Point * a)266 int32_t ECP_Sm2PointDouble(const ECC_Para *para, ECC_Point *r, const ECC_Point *a)
267 {
268 return ECP_NistPointDouble(para, r, a);
269 }
270
ECP_Sm2PointAddAffine(const ECC_Para * para,ECC_Point * r,const ECC_Point * a,const ECC_Point * b)271 int32_t ECP_Sm2PointAddAffine(const ECC_Para *para, ECC_Point *r, const ECC_Point *a, const ECC_Point *b)
272 {
273 return ECP_NistPointAddAffine(para, r, a, b);
274 }
275
ECP_Sm2ScalarMulG(SM2_point * r,const BN_UINT * k)276 static void ECP_Sm2ScalarMulG(SM2_point *r, const BN_UINT *k)
277 {
278 const BN_UINT *precomputed = ECP_Sm2Precomputed();
279 uint32_t index;
280 for (int32_t i = SM2_BYTES_NUM - 1; i >= 0; --i) {
281 index = (k[i / sizeof(BN_UINT)] >> (SM2_BITSOFBYTES * (i % sizeof(BN_UINT)))) & SM2_MASK2;
282 #ifndef HITLS_SM2_PRECOMPUTE_512K_TBL
283 ECP_Sm2PointDoubleMont(r, r);
284 ECP_Sm2PointDoubleMont(r, r);
285 ECP_Sm2PointDoubleMont(r, r);
286 ECP_Sm2PointDoubleMont(r, r);
287 ECP_Sm2PointDoubleMont(r, r);
288 ECP_Sm2PointDoubleMont(r, r);
289 ECP_Sm2PointDoubleMont(r, r);
290 ECP_Sm2PointDoubleMont(r, r);
291 #endif
292 if (index != 0) {
293 #ifdef HITLS_SM2_PRECOMPUTE_512K_TBL
294 index = index + i * SM2_BITS;
295 #endif
296 index = index * SM2_BITSOFBYTES;
297 ECP_Sm2PointAddAffineMont(r, r, (const SM2_AffinePoint *)&precomputed[index]);
298 }
299 }
300 }
301
ECP_Sm2WnafMul(SM2_point * r,const BN_BigNum * k,SM2_point p)302 static int32_t ECP_Sm2WnafMul(SM2_point *r, const BN_BigNum *k, SM2_point p)
303 {
304 ReCodeData *recodeK = ECC_ReCodeK(k, WINDOW_SIZE);
305 if (recodeK == NULL) {
306 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
307 return CRYPT_MEM_ALLOC_FAIL;
308 }
309 SM2_point doublePoint;
310 SM2_point precomputed[PRECOMPUTED_TABLE_SIZE] ALIGN64;
311 ECP_Sm2ToMont(precomputed[0].x, p.x);
312 ECP_Sm2ToMont(precomputed[0].y, p.y);
313 ECP_Sm2ToMont(precomputed[0].z, p.z);
314 ECP_Sm2PointDoubleMont(&doublePoint, &precomputed[0]);
315
316 (void)memcpy_s(precomputed[WINDOW_HALF_TABLE_SIZE].x, SM2_BYTES_NUM, precomputed[0].x, SM2_BYTES_NUM);
317 ECP_Sm2Neg(precomputed[WINDOW_HALF_TABLE_SIZE].y, precomputed[0].y);
318 (void)memcpy_s(precomputed[WINDOW_HALF_TABLE_SIZE].z, SM2_BYTES_NUM, precomputed[0].z, SM2_BYTES_NUM);
319
320 for (uint32_t i = 1; i < WINDOW_HALF_TABLE_SIZE; i++) {
321 ECP_Sm2PointAddMont(&precomputed[i], &precomputed[i - 1], &doublePoint); // 1, 3, 5, 7, 9, 11, 13, 15
322 (void)memcpy_s(precomputed[i + WINDOW_HALF_TABLE_SIZE].x, SM2_BYTES_NUM, precomputed[i].x, SM2_BYTES_NUM);
323 ECP_Sm2Neg(precomputed[i + WINDOW_HALF_TABLE_SIZE].y, precomputed[i].y);
324 (void)memcpy_s(precomputed[i + WINDOW_HALF_TABLE_SIZE].z, SM2_BYTES_NUM, precomputed[i].z, SM2_BYTES_NUM);
325 }
326 int8_t index = SM2_NUMTOOFFSET(recodeK->num[0]);
327 (void)memcpy_s(r, sizeof(SM2_point), &precomputed[index], sizeof(SM2_point));
328 uint32_t w = recodeK->wide[0];
329 while (w != 0) {
330 ECP_Sm2PointDoubleMont(r, r);
331 w--;
332 }
333 for (uint32_t i = 1; i < recodeK->size; i++) {
334 index = SM2_NUMTOOFFSET(recodeK->num[i]);
335 ECP_Sm2PointAddMont(r, r, &precomputed[index]);
336 w = recodeK->wide[i];
337 while (w != 0) {
338 ECP_Sm2PointDoubleMont(r, r);
339 w--;
340 }
341 }
342 ECC_ReCodeFree(recodeK);
343 return CRYPT_SUCCESS;
344 }
345
ECP_Sm2PointMul(ECC_Para * para,ECC_Point * r,const BN_BigNum * scalar,const ECC_Point * pt)346 int32_t ECP_Sm2PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *scalar, const ECC_Point *pt)
347 {
348 if (para == NULL || r == NULL || scalar == NULL) {
349 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
350 return CRYPT_NULL_INPUT;
351 }
352 if (para->id != CRYPT_ECC_SM2 || r->id != CRYPT_ECC_SM2 || (pt != NULL && (pt->id != CRYPT_ECC_SM2))) {
353 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
354 return CRYPT_ECC_POINT_ERR_CURVE_ID;
355 }
356 if (pt != NULL && BN_IsZero(pt->z)) {
357 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY);
358 return CRYPT_ECC_POINT_AT_INFINITY;
359 }
360 if (BN_IsZero(scalar)) {
361 return BN_Zeroize(r->z);
362 }
363 int32_t ret;
364 BN_UINT k[SM2_LIMBS] = {0};
365 uint32_t klen = SM2_LIMBS;
366 SM2_point re = {0};
367 SM2_point sm2Pt = {0};
368 GOTO_ERR_IF_EX(BN_Bn2U64Array(scalar, k, &klen), ret);
369 if (pt == NULL) {
370 // calculate k*G
371 ECP_Sm2ScalarMulG(&re, k);
372 } else {
373 // point 2 affine
374 GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&sm2Pt, pt), ret);
375 GOTO_ERR_IF_EX(ECP_Sm2WnafMul(&re, scalar, sm2Pt), ret);
376 }
377 ECP_Sm2FromMont(re.x, re.x);
378 ECP_Sm2FromMont(re.y, re.y);
379 ECP_Sm2FromMont(re.z, re.z);
380 // SM2_point 2 ECC_Point
381 GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &re), ret);
382 ERR:
383 return ret;
384 }
385
ECP_Sm2PointMulFast(ECC_Para * para,ECC_Point * r,const BN_BigNum * k,const ECC_Point * pt)386 int32_t ECP_Sm2PointMulFast(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt)
387 {
388 return ECP_Sm2PointMul(para, r, k, pt);
389 }
390
ECP_Sm2OrderInv(const ECC_Para * para,BN_BigNum * r,const BN_BigNum * a)391 int32_t ECP_Sm2OrderInv(const ECC_Para *para, BN_BigNum *r, const BN_BigNum *a)
392 {
393 if (para == NULL || r == NULL || a == NULL) {
394 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
395 return CRYPT_NULL_INPUT;
396 }
397 if (BN_IsZero(a)) {
398 BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_DIVISOR_ZERO);
399 return CRYPT_BN_ERR_DIVISOR_ZERO;
400 }
401 int32_t ret = BN_Extend(r, SM2_LIMBS);
402 if (ret != CRYPT_SUCCESS) {
403 BSL_ERR_PUSH_ERROR(ret);
404 return ret;
405 }
406 ECP_Sm2InvModOrd(r->data, a->data);
407 r->size = SM2_LIMBS;
408 BN_FixSize(r);
409 if (BN_IsZero(r)) {
410 BSL_ERR_PUSH_ERROR(CRYPT_BN_ERR_NO_INVERSE);
411 return CRYPT_BN_ERR_NO_INVERSE;
412 }
413 return CRYPT_SUCCESS;
414 }
415
ECP_Sm2PointMulAddCheck(ECC_Para * para,ECC_Point * r,const BN_BigNum * k1,const BN_BigNum * k2,const ECC_Point * pt)416 static int32_t ECP_Sm2PointMulAddCheck(
417 ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt)
418 {
419 bool flag = (para == NULL || r == NULL || k1 == NULL || k2 == NULL || pt == NULL);
420 uint32_t bits1;
421 uint32_t bits2;
422 if (flag) {
423 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
424 return CRYPT_NULL_INPUT;
425 }
426 if (para->id != CRYPT_ECC_SM2 || r->id != CRYPT_ECC_SM2 || pt->id != CRYPT_ECC_SM2) {
427 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
428 return CRYPT_ECC_POINT_ERR_CURVE_ID;
429 }
430 // Special processing of the infinite point.
431 if (BN_IsZero(pt->z)) {
432 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY);
433 return CRYPT_ECC_POINT_AT_INFINITY;
434 }
435 bits1 = BN_Bits(k1);
436 bits2 = BN_Bits(k2);
437 if (bits1 > SM2_BITS || bits2 > SM2_BITS) {
438 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_MUL_ERR_K_LEN);
439 return CRYPT_ECC_POINT_MUL_ERR_K_LEN;
440 }
441
442 return CRYPT_SUCCESS;
443 }
444
445 // r = k1 * G + k2 * pt
ECP_Sm2PointMulAdd(ECC_Para * para,ECC_Point * r,const BN_BigNum * k1,const BN_BigNum * k2,const ECC_Point * pt)446 int32_t ECP_Sm2PointMulAdd(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt)
447 {
448 int32_t ret = ECP_Sm2PointMulAddCheck(para, r, k1, k2, pt);
449 if (ret != CRYPT_SUCCESS) {
450 return ret;
451 }
452 BN_UINT k1Uint[SM2_LIMBS] = {0};
453 uint32_t k1Len = SM2_LIMBS;
454 SM2_point k1G = {0};
455 SM2_point k2Pt = {0};
456 SM2_point sm2Pt = {0};
457 GOTO_ERR_IF_EX(BN_Bn2U64Array(k1, k1Uint, &k1Len), ret);
458 GOTO_ERR_IF_EX(ECP_Sm2Point2Array(&sm2Pt, pt), ret);
459
460 // k1 * G
461 ECP_Sm2ScalarMulG(&k1G, k1Uint);
462 // k2 * pt
463 GOTO_ERR_IF_EX(ECP_Sm2WnafMul(&k2Pt, k2, sm2Pt), ret);
464 ECP_Sm2PointAddMont(&k2Pt, &k1G, &k2Pt);
465
466 ECP_Sm2FromMont(k2Pt.x, k2Pt.x);
467 ECP_Sm2FromMont(k2Pt.y, k2Pt.y);
468 ECP_Sm2FromMont(k2Pt.z, k2Pt.z);
469 GOTO_ERR_IF_EX(ECP_Sm2Array2Point(r, &k2Pt), ret);
470 ERR:
471 return ret;
472 }
473
474 #endif
475