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