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_NISTP256_ASM) && defined(HITLS_CRYPTO_NIST_ECC_ACCELERATE)
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include "securec.h"
23 #include "crypt_errno.h"
24 #include "crypt_bn.h"
25 #include "ecp_nistp256.h"
26 #include "crypt_ecc.h"
27 #include "ecc_local.h"
28 #include "bsl_err_internal.h"
29 #include "asm_ecp_nistp256.h"
30
31 #if defined(HITLS_SIXTY_FOUR_BITS)
32 // 1 is on the field with Montgomery, 1 * RR * R' mod P = R mod P = R - P
33 static const Coord g_oneMont = {{
34 0x0000000000000001,
35 0xffffffff00000000,
36 0xffffffffffffffff,
37 0x00000000fffffffe
38 }};
39 static const Coord g_rrModP = {{
40 0x0000000000000003,
41 0xfffffffbffffffff,
42 0xfffffffffffffffe,
43 0x00000004fffffffd
44 }};
45 #elif defined(HITLS_THIRTY_TWO_BITS)
46 // 1 is on the field with Montgomery, 1 * RR * R' mod P = R mod P = R - P
47 static const Coord g_oneMont = {{
48 0x00000001,
49 0x00000000,
50 0x00000000,
51 0xffffffff,
52 0xffffffff,
53 0xffffffff,
54 0xfffffffe,
55 0x00000000
56 }};
57 static const Coord g_rrModP = {{
58 0x00000003,
59 0x00000000,
60 0xffffffff,
61 0xfffffffb,
62 0xfffffffe,
63 0xffffffff,
64 0xfffffffd,
65 0x00000004
66 }};
67 #else
68 #error BN_UINT MUST be 4 or 8
69 #endif
70
71 // If the value is 0, all Fs are returned. If the value is not 0, 0 is returned.
IsZero(const Coord * a)72 static BN_UINT IsZero(const Coord *a)
73 {
74 BN_UINT ret = a->value[0];
75 for (uint32_t i = 1; i < P256_SIZE; i++) {
76 ret |= a->value[i];
77 }
78 return BN_IsZeroUintConsttime(ret);
79 }
80
81 // r = cond == 0 ? r : a, the input parameter cond can only be 0 or 1.
82 // If cond is 0, the value remains unchanged. If cond is 1, copy a.
CopyConditional(Coord * r,const Coord * a,BN_UINT cond)83 static void CopyConditional(Coord *r, const Coord *a, BN_UINT cond)
84 {
85 BN_UINT mask1 = ~cond & (cond - 1);
86 BN_UINT mask2 = ~mask1;
87
88 for (uint32_t i = 0; i < P256_SIZE; i++) {
89 r->value[i] = (r->value[i] & mask1) ^ (a->value[i] & mask2);
90 }
91 }
92
93 // Jacobian affine -> Jacobian projection, (X,Y)->(X,Y,Z)
Affine2Jproj(P256_Point * r,const P256_AffinePoint * a,BN_UINT mask)94 static void Affine2Jproj(P256_Point *r, const P256_AffinePoint *a, BN_UINT mask)
95 {
96 for (uint32_t i = 0; i < P256_SIZE; i++) {
97 r->x.value[i] = a->x.value[i] & mask;
98 r->y.value[i] = a->y.value[i] & mask;
99 r->z.value[i] = g_oneMont.value[i] & mask;
100 }
101 }
102
103 // r = a^-1 mod p = a^(p-2) mod p
104 // p-2 = 0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffd
ECP256_ModInverse(Coord * r,const Coord * a)105 static void ECP256_ModInverse(Coord *r, const Coord *a)
106 {
107 // a^(0x3), a^(0xc) = a^(0b1100), a^(0xf), a^(0xf0), a^(0xff)
108 // a^(0xff00), a^(0xffff), a^(0xffff0000), a^(0xffffffff)
109 Coord a3, ac, af, af0, a2f, a2f20, a4f, a4f40, a8f, ans;
110 uint32_t i;
111 // 0x3 = 0b11 = 0b10 + 0b01
112 ECP256_Sqr(&a3, a); // a^2
113 ECP256_Mul(&a3, &a3, a); // a^3 = a^2 * a
114 // 0xf = 0b1111 = 0b1100 + 0b11, 0b11->0b1100 requires *4, and the exponent*4(2^2) requires twice square operations
115 ECP256_Sqr(&af, &a3); // a^6 = (a^3)^2
116 ECP256_Sqr(&ac, &af); // a^12 = (a^3)^2 = a^(0xc)
117 ECP256_Mul(&af, &ac, &a3); // a^f = a^15 = a^12 * a^3
118 // 0xff = 0b11111111 = 0b11110000 + 0b1111, 0b1111->0b11110000 requires *16,
119 // the exponent*16(2^4) requires 4 times square operations
120 ECP256_Sqr(&a2f, &af); // a^(0b11110) = (a^f)^2
121 ECP256_Sqr(&a2f, &a2f); // a^(0b111100) = (a^(0b11110))^2
122 ECP256_Sqr(&a2f, &a2f); // a^(0b1111000) = (a^(0b111100))^2
123 ECP256_Sqr(&af0, &a2f); // a^(0xf0) = a^(0b11110000) = (a^(0b1111000))^2
124 ECP256_Mul(&a2f, &af0, &af); // a^(0xff) = a^(0xf0) * a^(0xf)
125 // a^(0xffff)
126 ECP256_Sqr(&a2f20, &a2f);
127 for (i = 1; i < 8; i++) { // need to left shift by 8 bits
128 ECP256_Sqr(&a2f20, &a2f20);
129 }
130 // When the loop ends, &a2f20 = a^(0xff00)
131 ECP256_Mul(&a4f, &a2f20, &a2f); // a^(0xffff) = a^(0xff00) * a^(0xff)
132 // a^(0xffffffff)
133 ECP256_Sqr(&a4f40, &a4f);
134 for (i = 1; i < 16; i++) { // need to left shift by 16 bits
135 ECP256_Sqr(&a4f40, &a4f40);
136 }
137 // When the loop ends, &a4f40 = a^(0xffff0000)
138 ECP256_Mul(&a8f, &a4f40, &a4f); // a^(0xffffffff) = a^(0xffff0000) * a^(0xffff)
139 // a^(0xffffffff 00000001)
140 ECP256_Sqr(&ans, &a8f);
141 for (i = 1; i < 32; i++) { // need to left shift by 32 bits
142 ECP256_Sqr(&ans, &ans);
143 }
144 ECP256_Mul(&ans, &ans, a); // a^(0xffffffff 00000001) = a^(0xffffffff 00000000) * a
145 // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff)
146 for (i = 0; i < 32 * 4; i++) { // need to left shift by 32 * 4 bits
147 ECP256_Sqr(&ans, &ans);
148 }
149 ECP256_Mul(&ans, &ans, &a8f);
150 // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff)
151 for (i = 0; i < 32; i++) { // need to left shift by 32 bits
152 ECP256_Sqr(&ans, &ans);
153 }
154 ECP256_Mul(&ans, &ans, &a8f);
155 // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffd)
156 for (i = 0; i < 32; i++) { // need to left shift by 32 bits
157 ECP256_Sqr(&ans, &ans);
158 }
159 // a^(0xffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff 00000000)
160 ECP256_Mul(&ans, &ans, &a4f40); // a^(0xffff0000)
161 ECP256_Mul(&ans, &ans, &a2f20); // a^(0xff00)
162 ECP256_Mul(&ans, &ans, &af0); // a^(0xf0)
163 ECP256_Mul(&ans, &ans, &ac); // a^(0xc)
164 ECP256_Mul(r, &ans, a); // a^(0x1)
165 }
166
ECP256_GetAffine(ECC_Point * r,const P256_Point * pt)167 static int32_t ECP256_GetAffine(ECC_Point *r, const P256_Point *pt)
168 {
169 Coord zInv3;
170 Coord zInv2;
171 Coord res_x;
172 Coord res_y;
173 int32_t ret;
174 if (IsZero(&(pt->z)) != 0) {
175 ret = CRYPT_ECC_POINT_AT_INFINITY;
176 BSL_ERR_PUSH_ERROR(ret);
177 return ret;
178 }
179 ECP256_ModInverse(&zInv3, &(pt->z)); // zInv
180 ECP256_Sqr(&zInv2, &zInv3); // zInv^2
181 ECP256_Mul(&zInv3, &zInv2, &zInv3); // zInv^3
182 ECP256_Mul(&res_x, &(pt->x), &zInv2); // xMont = x / (z^2)
183 ECP256_Mul(&res_y, &(pt->y), &zInv3); // yMont = y / (z^3)
184 ECP256_FromMont(&res_x, &res_x);
185 ECP256_FromMont(&res_y, &res_y);
186 ret = BN_Array2BN(r->x, res_x.value, P256_SIZE);
187 if (ret != CRYPT_SUCCESS) {
188 BSL_ERR_PUSH_ERROR(ret);
189 return ret;
190 }
191 ret = BN_Array2BN(r->y, res_y.value, P256_SIZE);
192 if (ret != CRYPT_SUCCESS) {
193 BSL_ERR_PUSH_ERROR(ret);
194 return ret;
195 }
196 ret = BN_SetLimb(r->z, 1);
197 if (ret != CRYPT_SUCCESS) {
198 BSL_ERR_PUSH_ERROR(ret);
199 }
200 return ret;
201 }
202
ECP256_P256Point2EccPoint(ECC_Point * r,const P256_Point * pt)203 static void ECP256_P256Point2EccPoint(ECC_Point *r, const P256_Point *pt)
204 {
205 Coord xTemp;
206 Coord yTemp;
207 Coord zTemp;
208 ECP256_FromMont(&xTemp, &(pt->x));
209 ECP256_FromMont(&yTemp, &(pt->y));
210 ECP256_FromMont(&zTemp, &(pt->z));
211 (void)BN_Array2BN(r->x, xTemp.value, P256_SIZE);
212 (void)BN_Array2BN(r->y, yTemp.value, P256_SIZE);
213 (void)BN_Array2BN(r->z, zTemp.value, P256_SIZE);
214 }
215
ECP256_EccPoint2P256Point(P256_Point * r,const ECC_Point * pt)216 static void ECP256_EccPoint2P256Point(P256_Point *r, const ECC_Point *pt)
217 {
218 (void)BN_BN2Array(pt->x, r->x.value, P256_SIZE);
219 (void)BN_BN2Array(pt->y, r->y.value, P256_SIZE);
220 (void)BN_BN2Array(pt->z, r->z.value, P256_SIZE);
221 ECP256_Mul(&(r->x), &(r->x), &g_rrModP);
222 ECP256_Mul(&(r->y), &(r->y), &g_rrModP);
223 ECP256_Mul(&(r->z), &(r->z), &g_rrModP);
224 }
225
ECP256_Point2Affine(const ECC_Para * para,ECC_Point * r,const ECC_Point * pt)226 int32_t ECP256_Point2Affine(const ECC_Para *para, ECC_Point *r, const ECC_Point *pt)
227 {
228 if (r == NULL || pt == NULL || para == NULL) {
229 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
230 return CRYPT_NULL_INPUT;
231 }
232
233 if (para->id != CRYPT_ECC_NISTP256 || r->id != CRYPT_ECC_NISTP256 || pt->id != CRYPT_ECC_NISTP256) {
234 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
235 return CRYPT_ECC_POINT_ERR_CURVE_ID;
236 }
237 P256_Point temp;
238 ECP256_EccPoint2P256Point(&temp, pt);
239 return ECP256_GetAffine(r, &temp);
240 }
241
242 // The value of 'in' contains a maximum of six bits. The input parameter must be & 0b111111 in advance.
Recodew5(uint32_t in)243 static uint32_t Recodew5(uint32_t in)
244 {
245 // Shift rightwards by 5 bits to get the most significant bit, check whether the most significant bit is 1.
246 uint32_t sign = (in >> 5) - 1;
247 uint32_t data = (1 << 6) - 1 - in; // (6 Ones)0b111111 - in
248 data = (data & ~sign) | (in & sign);
249 data = (data >> 1) + (data & 1);
250
251 return (data << 1) + (~sign & 1);
252 }
253
254 // The value of 'in' contains a maximum of six bits. The input parameter must be & 0b11111111 in advance.
Recodew7(uint32_t in)255 static uint32_t Recodew7(uint32_t in)
256 {
257 // Shift rightwards by 7 bits to get the most significant bit, check whether the most significant bit is 1.
258 uint32_t sign = (in >> 7) - 1;
259 uint32_t data = (1 << 8) - 1 - in; // (8 Ones)0b11111111 - in
260 data = (data & ~sign) | (in & sign);
261 data = (data >> 1) + (data & 1);
262
263 return (data << 1) + (~sign & 1);
264 }
265
ECP256_PreCompWindow(P256_Point table[16],P256_Point * pt)266 static void ECP256_PreCompWindow(P256_Point table[16], P256_Point *pt)
267 {
268 P256_Point temp[4];
269 ECP256_Scatterw5(table, pt, 1);
270 ECP256_PointDouble(&temp[0], pt); // 2G
271 ECP256_Scatterw5(table, &temp[0], 2); // Discretely save temp[0] to the 2nd position of the table.
272 ECP256_PointAdd(&temp[1], &temp[0], pt); // temp[0] = 3G = 2G + G
273 ECP256_Scatterw5(table, &temp[1], 3); // Discretely saves temp[1] to the 3rd position of the table.
274 ECP256_PointDouble(&temp[2], &temp[0]); // temp[2] = 4G = 2G * 2
275 ECP256_Scatterw5(table, &temp[2], 4); // Discretely save temp[2] to the 4th position in the table.
276 ECP256_PointAdd(&temp[3], &temp[2], pt); // temp[3] = 5G = 4G + G = = temp[2] + pt
277 ECP256_Scatterw5(table, &temp[3], 5); // Discretely save temp[3] to the 5th position in the table.
278 ECP256_PointDouble(&temp[0], &temp[1]); // temp[0] = 6G = 3G * 2
279 ECP256_Scatterw5(table, &temp[0], 6); // Discretely save temp[0] to the 6th position in the table.
280 ECP256_PointAdd(&temp[1], &temp[0], pt); // temp[1] = 7G = 6G + G
281 ECP256_Scatterw5(table, &temp[1], 7); // Discretely save temp[1] to the 7th position in the table.
282 ECP256_PointDouble(&temp[2], &temp[2]); // temp[2] = 8G = 4G * 2
283 ECP256_Scatterw5(table, &temp[2], 8); // Discretely save temp[2] to the 8th position in the table.
284 ECP256_PointDouble(&temp[3], &temp[3]); // temp[3] = 10G = 5G * 2
285 ECP256_Scatterw5(table, &temp[3], 10); // Discretely save temp[3] to the 10th position in the table.
286 ECP256_PointAdd(&temp[3], &temp[3], pt); // temp[3] = 11G = 10G + G
287 ECP256_Scatterw5(table, &temp[3], 11); // Discretely save temp[3] to the 11th position in the table.
288 ECP256_PointDouble(&temp[0], &temp[0]); // temp[0] = 12G = 6G * 2
289 ECP256_Scatterw5(table, &temp[0], 12); // Discretely save temp[0] to the 12th position in the table.
290 ECP256_PointAdd(&temp[3], &temp[2], pt); // temp[3] = 9G = 8G + G = temp[2] + pt
291 ECP256_Scatterw5(table, &temp[3], 9); // Discretely save temp[3] to the 9th position in the table.
292 ECP256_PointAdd(&temp[3], &temp[0], pt); // temp[3] = 13G = 12G + G
293 ECP256_Scatterw5(table, &temp[3], 13); // Discretely save temp[3] to the 13th position of the table.
294 ECP256_PointDouble(&temp[1], &temp[1]); // temp[1] = 14G = 7G * 2
295 ECP256_Scatterw5(table, &temp[1], 14); // Discretely saves temp[1] to the 14th position of the table.
296 ECP256_PointAdd(&temp[0], &temp[1], pt); // temp[0] = 15G = 14G + G = temp[1] + pt
297 ECP256_Scatterw5(table, &temp[0], 15); // Discretely save temp[0] to the 15th position of the table.
298 ECP256_PointDouble(&temp[1], &temp[2]); // temp[1] = 16G = 8G * 2 = temp[2] * 2
299 ECP256_Scatterw5(table, &temp[1], 16); // Discretely saves temp[1] to the 16th position of the table.
300 }
301
CRYPT_ECP256_PointDouble5Times(P256_Point * r)302 static void CRYPT_ECP256_PointDouble5Times(P256_Point *r)
303 {
304 ECP256_PointDouble(r, r);
305 ECP256_PointDouble(r, r);
306 ECP256_PointDouble(r, r);
307 ECP256_PointDouble(r, r);
308 ECP256_PointDouble(r, r);
309 }
310
311 // r = k*point
312 // Ensure that m is not empty and is in the range (0, n-1)
ECP256_WindowMul(P256_Point * r,const BN_BigNum * k,const ECC_Point * point)313 static void ECP256_WindowMul(P256_Point *r, const BN_BigNum *k, const ECC_Point *point)
314 {
315 uint8_t kOctets[33]; // m big endian byte stream. Apply for 33 bytes and reserve one byte for the following offset.
316 uint32_t mLen = BN_Bytes(k);
317 // Offset during byte stream conversion. Ensure that the valid data of the mOctet is in the upper bits.
318 uint32_t offset = sizeof(kOctets) - mLen;
319 P256_Point table[16]; // The pre-computation window is 2 ^ (5 - 1) = 16 points
320 P256_Point temp; // Apply for temporary space of two points.
321 Coord tempY;
322 (void)BN_Bn2Bin(k, kOctets + offset, &mLen);
323 for (uint32_t i = 0; i < offset; i++) {
324 kOctets[i] = 0;
325 }
326
327 ECP256_EccPoint2P256Point(&temp, point);
328
329 ECP256_PreCompWindow(table, &temp);
330
331 // The first byte is the first two bits of kOctets[1].
332 // The subscript starts from 0. Therefore, it is bit 0 + 8 and bit 1 + 8 = 9.
333 uint32_t scans = 9;
334 uint32_t index; // position of the byte to be scanned.
335 // Number of bits to be shifted rightwards by the current byte.
336 // Each byte needs to be moved backward by a maximum of 7 bits.
337 uint32_t shift = 7 - (scans % 8);
338 uint32_t w = 5; // Window size = 5
339 // the recode mask, the window size is 5, thus the value is 6 bits, mask = 0b111111 = 0x3f
340 uint32_t mask = (1u << (w + 1)) - 1;
341 uint32_t wCode = kOctets[1];
342 wCode = (wCode >> shift) & mask;
343 wCode = Recodew5(wCode);
344 ECP256_Gatherw5(&temp, table, wCode >> 1);
345 (void)memcpy_s(r, sizeof(P256_Point), &temp, sizeof(P256_Point));
346
347 // 5 bits is obtained each time. The total number of bits is 256 + 8 (1 byte reserved) = 264 bits.
348 // Therefore, the last time can be scanned to 264-5 = 259 bits.
349 while (scans < 259) {
350 // Double the point for 5 times
351 CRYPT_ECP256_PointDouble5Times(r);
352
353 scans += w; // Number of bits in the next scan.
354 index = scans / 8; // Location of the byte to be scanned. (1 byte = 8 bits)
355 // Number of bits to be shifted rightwards by the current byte.
356 // Each byte needs to be moved backward by a maximum of 7 bits. (1 byte = 8 bits)
357 shift = 7 - (scans % 8);
358 // Shift the upper byte by 8 bits to left, concatenate the current byte, and then shift to get the current wCode
359 wCode = kOctets[index] | (kOctets[index - 1] << 8);
360 wCode = (wCode >> shift) & mask;
361 wCode = Recodew5(wCode);
362 ECP256_Gatherw5(&temp, table, wCode >> 1);
363 ECP256_Neg(&tempY, &(temp.y));
364 // If the least significant bit of the code is 1, plus -(wCode >> 1) times point.
365 CopyConditional(&(temp.y), &tempY, wCode & 1);
366 ECP256_PointAdd(r, r, &temp);
367 }
368
369 // Special processing of the last block
370 CRYPT_ECP256_PointDouble5Times(r);
371
372 wCode = kOctets[32]; // Obtain the last byte, that is, kOctets[32].
373 wCode = (wCode << 1) & mask;
374 wCode = Recodew5(wCode);
375 ECP256_Gatherw5(&temp, table, wCode >> 1);
376 ECP256_Neg(&tempY, &(temp.y));
377 // If the least significant bit of the code is 1, plus -(wCode >> 1) times point.
378 CopyConditional(&(temp.y), &tempY, wCode & 1);
379 ECP256_PointAdd(r, r, &temp);
380 }
381
ComputeK1G(P256_Point * k1G,const BN_BigNum * k1)382 static void ComputeK1G(P256_Point *k1G, const BN_BigNum *k1)
383 {
384 uint8_t kOctets[33]; // applies for 33 bytes and reserves one byte for the following offset. 256 bits are 32 bytes.
385 Coord tempY;
386 P256_AffinePoint k1GAffine;
387 const ECP256_TableRow *preCompTable = NULL; // precompute window size is 2 ^(7 - 1) = 64
388 preCompTable = ECP256_GetPreCompTable();
389
390 uint32_t kLen = BN_Bytes(k1);
391 // Offset during byte stream conversion. Ensure that the valid data of the mOctet is in the upper bits.
392 uint32_t offset = sizeof(kOctets) - kLen;
393 (void)BN_Bn2Bin(k1, kOctets + offset, &kLen);
394 for (uint32_t i = 0; i < offset; i++) {
395 kOctets[i] = 0;
396 }
397
398 uint32_t w = 7; // Window size = 7
399 // the recode mask, the window size is 7, thus 8 bits are used (one extra bit is the sign bit).
400 // mask = 0b11111111 = 0xff
401 uint32_t mask = (1u << (w + 1)) - 1;
402 uint32_t wCode = (kOctets[32] << 1) & mask; // Last byte kOctets[32] is the least significant 7 bits.
403 wCode = Recodew7(wCode);
404 ECP256_Gatherw7(&k1GAffine, preCompTable[0], wCode >> 1);
405 ECP256_Neg(&tempY, &(k1GAffine.y));
406 // If the least significant bit of the code is 1, plus -(wCode >> 1) times point.
407 CopyConditional(&(k1GAffine.y), &tempY, wCode & 1);
408 // If the x and y coordinates of k1GAffine are both 0, then the infinity is all Fs; otherwise, the infinity is 0.
409 BN_UINT infinity = IsZero(&(k1GAffine.x)) & IsZero(&(k1GAffine.y));
410 Affine2Jproj(k1G, &k1GAffine, ~infinity);
411
412 uint32_t scans = 0;
413 uint32_t index, shift;
414 // pre-computation table is table[37][64]. The table is queried every 7 bits (valid bits) of 256 bits. 256/7 = 36.57
415 for (uint32_t i = 1; i < 37; i++) {
416 scans += w;
417 index = 32 - ((scans - 1) / 8); // The subscript of the last byte is 32, and 8 means 8 bits(1byte)
418 shift = (scans - 1) % 8; // 8 means 8 bits(1byte)
419 wCode = kOctets[index] | (kOctets[index - 1] << 8); // 8 means 8 bits(1byte)
420 wCode = (wCode >> shift) & mask;
421 wCode = Recodew7(wCode);
422 ECP256_Gatherw7(&k1GAffine, preCompTable[i], wCode >> 1);
423 ECP256_Neg(&tempY, &(k1GAffine.y));
424 // If the least significant bit of the code is 1, plus -(wCode >> 1) times point.
425 CopyConditional(&(k1GAffine.y), &tempY, wCode & 1);
426 ECP256_AddAffine(k1G, k1G, &k1GAffine);
427 }
428 }
429
ECP256_PointMulCheck(ECC_Para * para,ECC_Point * r,const BN_BigNum * k,const ECC_Point * pt)430 static int32_t ECP256_PointMulCheck(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt)
431 {
432 bool flag = (para == NULL || r == NULL || k == NULL);
433 uint32_t bits;
434 if (flag) {
435 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
436 return CRYPT_NULL_INPUT;
437 }
438 if (para->id != CRYPT_ECC_NISTP256 || r->id != CRYPT_ECC_NISTP256) {
439 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
440 return CRYPT_ECC_POINT_ERR_CURVE_ID;
441 }
442 if (pt != NULL) {
443 if (pt->id != CRYPT_ECC_NISTP256) {
444 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
445 return CRYPT_ECC_POINT_ERR_CURVE_ID;
446 }
447 // Special processing for the infinite point.
448 if (BN_IsZero(pt->z)) {
449 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY);
450 return CRYPT_ECC_POINT_AT_INFINITY;
451 }
452 }
453 bits = BN_Bits(k);
454 if (bits > 256) { // 256 is the number of bits in the curve mode
455 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_MUL_ERR_K_LEN);
456 return CRYPT_ECC_POINT_MUL_ERR_K_LEN;
457 }
458
459 return CRYPT_SUCCESS;
460 }
461
462 // if pt == NULL, r = k * G, otherwise r = k * pt
ECP256_PointMul(ECC_Para * para,ECC_Point * r,const BN_BigNum * k,const ECC_Point * pt)463 int32_t ECP256_PointMul(ECC_Para *para, ECC_Point *r, const BN_BigNum *k, const ECC_Point *pt)
464 {
465 P256_Point rTemp;
466 int32_t ret = ECP256_PointMulCheck(para, r, k, pt);
467 if (ret != CRYPT_SUCCESS) {
468 return ret;
469 }
470
471 if (pt == NULL) {
472 ComputeK1G(&rTemp, k);
473 } else {
474 ECP256_WindowMul(&rTemp, k, pt);
475 }
476
477 ECP256_P256Point2EccPoint(r, &rTemp);
478
479 return ret;
480 }
481
ECP256_PointMulAddCheck(ECC_Para * para,ECC_Point * r,const BN_BigNum * k1,const BN_BigNum * k2,const ECC_Point * pt)482 static int32_t ECP256_PointMulAddCheck(
483 ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2, const ECC_Point *pt)
484 {
485 bool flag = (para == NULL || r == NULL || k1 == NULL || k2 == NULL || pt == NULL);
486 uint32_t bits1, bits2;
487 if (flag) {
488 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
489 return CRYPT_NULL_INPUT;
490 }
491 if (para->id != CRYPT_ECC_NISTP256 || r->id != CRYPT_ECC_NISTP256 || pt->id != CRYPT_ECC_NISTP256) {
492 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_ERR_CURVE_ID);
493 return CRYPT_ECC_POINT_ERR_CURVE_ID;
494 }
495 // Special processing of the infinite point.
496 if (BN_IsZero(pt->z)) {
497 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_AT_INFINITY);
498 return CRYPT_ECC_POINT_AT_INFINITY;
499 }
500 bits1 = BN_Bits(k1);
501 bits2 = BN_Bits(k2);
502 if (bits1 > 256 || bits2 > 256) { // 256 is the number of bits in the curve mode
503 BSL_ERR_PUSH_ERROR(CRYPT_ECC_POINT_MUL_ERR_K_LEN);
504 return CRYPT_ECC_POINT_MUL_ERR_K_LEN;
505 }
506
507 return CRYPT_SUCCESS;
508 }
509
510 // r = k1 * G + k2 * pt
ECP256_PointMulAdd(ECC_Para * para,ECC_Point * r,const BN_BigNum * k1,const BN_BigNum * k2,const ECC_Point * pt)511 int32_t ECP256_PointMulAdd(ECC_Para *para, ECC_Point *r, const BN_BigNum *k1, const BN_BigNum *k2,
512 const ECC_Point *pt)
513 {
514 int32_t ret = ECP256_PointMulAddCheck(para, r, k1, k2, pt);
515 if (ret != CRYPT_SUCCESS) {
516 return ret;
517 }
518
519 P256_Point k2Pt;
520 P256_Point k1G;
521
522 ECP256_WindowMul(&k2Pt, k2, pt);
523
524 ComputeK1G(&k1G, k1);
525
526 ECP256_PointAdd(&k1G, &k1G, &k2Pt);
527 ECP256_P256Point2EccPoint(r, &k1G);
528 return ret;
529 }
530 #endif /* defined(HITLS_CRYPTO_CURVE_NISTP256) && defined(HITLS_CRYPTO_NIST_USE_ACCEL) */
531