1 /*******************************************************************************
2 * \file cy_cryptolite_nist_p.c
3 * \version 2.30
4 *
5 * \brief
6 * This file provides Elliptic Curve (EC) Scalar Multiplication using (X,Y)-only,
7 * Co-Z arithmetic in the Crypto driver.
8 *
9 ********************************************************************************
10 * Copyright 2022 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25
26 #include "cy_device.h"
27
28 #if defined (CY_IP_MXCRYPTOLITE)
29
30 #if defined(__cplusplus)
31 extern "C" {
32 #endif
33
34 #include "cy_cryptolite_vu.h"
35 #include "cy_cryptolite_nist_p.h"
36
37 #if (CRYPTOLITE_VU_PRESENT == 1)
38 #if defined(CY_CRYPTOLITE_CFG_ECP_C)
39
40 /*******************************************************************************
41 * Elliptic Curve (EC) Scalar Multiplication using (X,Y)-only, Co-Z arithmetic
42 *
43 * Theoretic and algorithmic references:
44 * Algorithms and Co-Z arithmetic theory: 'Fast and Regular Algorithms for Scalar
45 * Multiplication over Elliptic Curves', Matthieu Rivain NIST P-curves
46 * (parameters and curve-specific modular reduction):
47 * 'RECOMMENDED ELLIPTIC CURVES FOR FEDERAL GOVERNMENT USE', NIST, 1999
48 *
49 * Useful resources:
50 * Large number calculator and converter:
51 * - http://www.mobilefish.com/services/big_number/big_number.php
52 * - https://www.mobilefish.com/services/big_number_equation/big_number_equation.php
53 *
54 * - ECC curves and test vectors: http://point-at-infinity.org/ecc/nisttv
55 *
56 * Valid values for scalar multiplier, 2 < d < (order-1)
57 *
58 *******************************************************************************/
59 #include "cy_cryptolite_vu.h"
60
61 /***************************************************************
62 * Global Variables
63 ***************************************************************/
64 // static cy_en_cryptolite_ecc_curve_id_t cryptolite_eccMode;
65 //static cy_en_cryptolite_ecc_red_mul_algs_t cryptolite_mul_red_alg_select = CY_CRYPTOLITE_NIST_P_BARRETT_RED_ALG;
66 /* Barrett reduction z = x % mod */
67 void Cryptolite_EC_Bar_MulRed ( CRYPTOLITE_Type *base,
68 cy_stc_cryptolite_context_ecdsa_t *cfContext,
69 uint8_t* p_z, // bit_size
70 uint8_t* p_x, // bit_size
71 uint32_t bit_size );
72
73
74 /* Barrett reduction z = x % mod */
Cryptolite_EC_Bar_MulRed(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * p_z,uint8_t * p_x,uint32_t bit_size)75 void Cryptolite_EC_Bar_MulRed ( CRYPTOLITE_Type *base,
76 cy_stc_cryptolite_context_ecdsa_t *cfContext,
77 uint8_t* p_z, // bit_size
78 uint8_t* p_x, // bit_size
79 uint32_t bit_size )
80 {
81 uint32_t sign;
82 CY_ALIGN(4) uint8_t p_t_double[VU_BITS_TO_BYTES(2U*BIT_SIZE)]; // 2*bit_size
83 CY_ALIGN(4) uint8_t t2_plus2[VU_BITS_TO_BYTES(BIT_SIZE+2U+1U)]; // bit_size + 3
84
85 uint8_t *p_temp_plus2;//temp_plus2;
86 uint8_t *p_t1_plus2 = p_t_double;//t1_plus2;
87 uint8_t *p_t2_plus2 = t2_plus2;
88 uint8_t *my_P = cfContext->my_P;
89 uint8_t *my_BARRETT_U = cfContext->my_BARRETT_U;
90 uint8_t *p_t1 = p_t2_plus2;
91
92 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0];
93 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1];
94
95 (void)Cy_Cryptolite_Vu_lsr_hw (base, vu_struct0, p_z, VU_BITS_TO_WORDS(bit_size), p_x, VU_BITS_TO_WORDS(2U*bit_size), bit_size);
96
97 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct1, p_t_double, VU_BITS_TO_WORDS(2U*bit_size), p_z, VU_BITS_TO_WORDS(bit_size), my_BARRETT_U, VU_BITS_TO_WORDS(bit_size+1U));
98 (void)Cy_Cryptolite_Vu_lsr_hw (base, vu_struct0, p_t1, VU_BITS_TO_WORDS(bit_size), p_t_double, VU_BITS_TO_WORDS(2U*bit_size), bit_size);
99 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct1, p_t_double, VU_BITS_TO_WORDS(2U*bit_size), p_t1, VU_BITS_TO_WORDS(bit_size), my_P, VU_BITS_TO_WORDS(bit_size));
100
101 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct0, p_t2_plus2, VU_BITS_TO_WORDS(bit_size+2U+1U), p_x, VU_BITS_TO_WORDS(bit_size+2U+1U), p_t_double, VU_BITS_TO_WORDS(bit_size+2U+1U));
102 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct1, p_t1_plus2, VU_BITS_TO_WORDS(bit_size+2U+1U), p_t2_plus2, VU_BITS_TO_WORDS(bit_size+2U), my_P, VU_BITS_TO_WORDS(bit_size));
103 Cy_Cryptolite_Vu_wait_hw(base);
104 sign = Cy_Cryptolite_Vu_get_bit(p_t1_plus2, bit_size+2U);
105
106 if ((bool)sign)
107 {
108 p_temp_plus2 = p_t2_plus2;
109 p_t2_plus2 = p_t1_plus2;
110 p_t1_plus2 = p_temp_plus2;
111 }
112 (void)Cy_Cryptolite_Vu_cond_sub_hw (base, vu_struct1, p_z, VU_BITS_TO_WORDS(bit_size), p_t1_plus2, VU_BITS_TO_WORDS(bit_size+3U), my_P, VU_BITS_TO_WORDS(bit_size));
113 }
114
115 /*------------------------------------------------------
116 // Multiplication reduction algorithm select
117 //------------------------------------------------------
118 */
119 void Cryptolite_EC_MulRed( CRYPTOLITE_Type *base,
120 cy_stc_cryptolite_context_ecdsa_t *cfContext,
121 uint8_t *z,
122 uint8_t *x,
123 int size);
Cryptolite_EC_MulRed(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * z,uint8_t * x,int size)124 void Cryptolite_EC_MulRed( CRYPTOLITE_Type *base,
125 cy_stc_cryptolite_context_ecdsa_t *cfContext,
126 uint8_t *z,
127 uint8_t *x,
128 int size)
129 {
130
131 Cryptolite_EC_Bar_MulRed(base, cfContext, z, x, (uint32_t)size);
132 }
133
134 /*
135 @brief Modular multiplication in GF(p).
136 z = a * b % mod
137
138 Leaf function.
139
140 @param[in] z Register index for product value.
141 @param[in] a Register index for multiplicand value.
142 @param[in] b Register index for multiplier value.
143 @param[in] barrett_u Register index for Barrett reduction value.
144 @param[in] mod Register index for modulo value.
145 @param[in] size Bit size.
146 */
Cryptolite_EC_MulMod(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * z,uint8_t * a,uint8_t * b,int size)147 void Cryptolite_EC_MulMod ( CRYPTOLITE_Type *base,
148 cy_stc_cryptolite_context_ecdsa_t *cfContext,
149 uint8_t * z,
150 uint8_t * a,
151 uint8_t * b,
152 int size )
153 {
154
155 CY_ALIGN(4) uint8_t ab_double[VU_BITS_TO_BYTES(2U * BIT_SIZE)]; // the variable size is ignored
156 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0];
157
158 (void)Cy_Cryptolite_Vu_mul_hw (base, vu_struct0, ab_double, VU_BITS_TO_WORDS(2U*(uint32_t)size), a, VU_BITS_TO_WORDS((uint32_t)size), b, VU_BITS_TO_WORDS((uint32_t)size));
159 /* Modular Reduction: Barrett reduction or curve-specific or shift-multiply */
160 Cryptolite_EC_MulRed (base, cfContext, z, ab_double, (int)size);
161 }
162
163 /*
164 @brief Modular squaring in GF(p).
165 z = a * a % mod
166
167 @param[in] z Register index for product value.
168 @param[in] a Register index for multiplicand and multiplier value.
169 @param[in] barrett_u Register index for Barrett reduction value.
170 @param[in] mod Register index for modulo value.
171 @param[in] size Bit size.
172 */
Cryptolite_EC_SquareMod(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * z,uint8_t * a,int size)173 void Cryptolite_EC_SquareMod( CRYPTOLITE_Type *base,
174 cy_stc_cryptolite_context_ecdsa_t *cfContext,
175 uint8_t * z,
176 uint8_t * a,
177 int size )
178 {
179 Cryptolite_EC_MulMod (base, cfContext, z, a, a, size);
180 }
181
182 /*
183 @brief Modular division in GF(p).
184 z = a / b % mod
185
186 This algorithm works when "dividend" and "divisor" are relatively prime,
187 Reference: "From Euclid's GCD to Montgomery Multiplication to the Great Divide", S.C. Schantz
188 @param[in] z Register index for quotient value.
189 @param[in] a Register index for dividend value.
190 @param[in] b Register index for divisor value.
191 @param[in] mod Register index for modulo value.
192 @param[in] size Bit size.
193 */
Cryptolite_EC_DivMod(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * z,uint8_t * a,uint8_t * b,int size)194 void Cryptolite_EC_DivMod( CRYPTOLITE_Type *base,
195 cy_stc_cryptolite_context_ecdsa_t *cfContext,
196 uint8_t * z,
197 uint8_t * a,
198 uint8_t * b,
199 int size )
200 {
201 //uint16_t status;
202 bool zero;
203 bool sign;
204 bool a_even;
205 bool b_even;
206 uint16_t wordsize = VU_BITS_TO_WORDS((uint16_t)size);
207 uint16_t wordsize1 = VU_BITS_TO_WORDS((uint16_t)size+1U);
208
209 CY_ALIGN(4) uint8_t my_a[VU_BITS_TO_BYTES(BIT_SIZE)];
210 CY_ALIGN(4) uint8_t my_b[VU_BITS_TO_BYTES(BIT_SIZE)];
211 CY_ALIGN(4) uint8_t my_v[VU_BITS_TO_BYTES(BIT_SIZE)];
212 CY_ALIGN(4) uint8_t temp[VU_BITS_TO_BYTES(BIT_SIZE+1U)];
213
214 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0];
215 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1];
216 uint8_t *my_P = cfContext->my_P;
217
218 (void)Cy_Cryptolite_Vu_mov_hw (base,vu_struct0, my_a, wordsize, b, wordsize);
219 (void)Cy_Cryptolite_Vu_mov_hw (base,vu_struct1, my_b, wordsize, my_P, wordsize);
220 (void)Cy_Cryptolite_Vu_mov_hw (base,vu_struct0, z, wordsize, a, wordsize);
221
222 Cy_Cryptolite_Vu_wait_hw(base);
223 Cy_Cryptolite_Vu_clr(my_v, wordsize);
224
225 while ((bool)1)
226 {
227 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct0, temp, wordsize1, my_a, wordsize, my_b, wordsize);
228 Cy_Cryptolite_Vu_wait_hw(base);
229
230 sign = (bool)Cy_Cryptolite_Vu_get_bit(temp, (uint32_t)size);
231 zero = Cy_Cryptolite_Vu_test_zero (base, vu_struct1, temp, (uint16_t)size);
232
233 a_even = Cy_Cryptolite_Vu_test_even (my_a);
234 b_even = Cy_Cryptolite_Vu_test_even (my_b);
235
236
237
238 if (zero)
239 {
240 break;
241 }
242
243 if (a_even)
244 {
245 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct1, my_a, wordsize, my_a, wordsize);
246 Cryptolite_EC_HalfMod (base, cfContext, z, z);
247
248 }
249 else if (b_even)
250 {
251 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct0, my_b, wordsize, my_b, wordsize);
252 Cryptolite_EC_HalfMod (base, cfContext, my_v, my_v);
253
254 }
255 else if (!sign)
256 { // (a >= b)
257 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct1, my_a, wordsize, my_a, wordsize, my_b, wordsize);
258 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct0, my_a, wordsize, my_a, wordsize);
259 Cryptolite_EC_SubMod(base, cfContext, z, z, my_v);
260 Cryptolite_EC_HalfMod (base, cfContext, z, z);
261
262 }
263 else
264 {
265 (void)Cy_Cryptolite_Vu_sub_hw (base, vu_struct1, my_b, wordsize, my_b, wordsize, my_a, wordsize);
266 (void)Cy_Cryptolite_Vu_lsr1_hw (base, vu_struct0, my_b, wordsize, my_b, wordsize);
267 Cryptolite_EC_SubMod (base, cfContext, my_v, my_v, z);
268 Cryptolite_EC_HalfMod (base, cfContext, my_v, my_v);
269
270 }
271
272 }
273 }
274
275 /*
276 @brief (X,Y)-only co-Z addition with update: Calculate P+Q and P' (co-Z with P+Q)
277 Algorithm 5, "Fast and regular algorithms for scalar multiplication over elliptic curves"
278
279 @param[in, out] x1/x3 : input X-coordinate of P (Jacobian, projective coordinate) and output X-coordinate of P+Q
280 @param[in, out] y1/y3 : input Y-coordinate of P (Jacobian, projective coordinate) and output Y-coordinate of P+Q
281 @param[in, out] x2/x1' : input X-coordinate of Q (Jacobian, projective coordinate) and output X-coordinate of P'
282 @param[in, out] y2/y1' : input Y-coordinate of Q (Jacobian, projective coordinate) and output Y-coordinate of P'
283 where P = (x1, y1, z), Q = (x2, y2, z), P+Q = (x3,y3,z3) and P' = (x1',y1',z3), for some z3 on the elliptic curve
284
285 @param[in] barrett_u : Register index for Barrett reduction value.
286 @param[in] mod : Register index for modulo value.
287 @param[in] size : Bit size.
288 */
289 void Cryptolite_EC_XYCZ_ADD( CRYPTOLITE_Type *base,
290 cy_stc_cryptolite_context_ecdsa_t *cfContext,
291 int carry,
292 uint8_t * x1,
293 uint8_t * y1,
294 uint8_t * x2,
295 uint8_t * y2,
296 int size );
Cryptolite_EC_XYCZ_ADD(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,int carry,uint8_t * x1,uint8_t * y1,uint8_t * x2,uint8_t * y2,int size)297 void Cryptolite_EC_XYCZ_ADD( CRYPTOLITE_Type *base,
298 cy_stc_cryptolite_context_ecdsa_t *cfContext,
299 int carry,
300 uint8_t * x1,
301 uint8_t * y1,
302 uint8_t * x2,
303 uint8_t * y2,
304 int size )
305 {
306 CY_ALIGN(4) uint8_t t1[VU_BITS_TO_BYTES(BIT_SIZE)];
307 CY_ALIGN(4) uint8_t t2[VU_BITS_TO_BYTES(BIT_SIZE)];
308 uint8_t *temp;
309
310 Cy_Cryptolite_Vu_wait_hw(base);
311 // Swap if carry set, b = 1 : (R0, R1) <- ADDC(R1, R0)
312 if ((bool)carry)
313 {
314 temp = x1;
315 x1 = x2;
316 x2 = temp;
317
318 temp = y1;
319 y1 = y2;
320 y2 = temp;
321 }
322
323 Cryptolite_EC_SubMod( base, cfContext, t1, x1, x2);
324 Cryptolite_EC_SquareMod(base, cfContext, t1, t1, size);
325 Cryptolite_EC_MulMod(base, cfContext, t2, x1, t1, size);
326 Cryptolite_EC_MulMod(base, cfContext, x2, x2, t1, size);
327 Cryptolite_EC_SubMod(base, cfContext, t1, y1, y2);
328 Cryptolite_EC_SubMod(base, cfContext, x1, t2, x2);
329 Cryptolite_EC_MulMod(base, cfContext, y2, y2, x1, size);
330 Cryptolite_EC_AddMod(base, cfContext, x1, x2, t2);
331 Cryptolite_EC_SquareMod(base, cfContext, t2, t1, size);
332 Cryptolite_EC_SubMod(base, cfContext, x1, t2, x1);
333 Cryptolite_EC_SubMod(base, cfContext, t2, x2, x1);
334 Cryptolite_EC_MulMod(base, cfContext, t1, t1, t2, size);
335 Cryptolite_EC_SubMod(base, cfContext, y1, t1, y2);
336 }
337
338 /*
339 @brief (X,Y)-only co-Z conjugate addition with update: Calculate P+Q and P-Q, which are co-Z
340 Algorithm 6, "Fast and regular algorithms for scalar multiplication over elliptic curves"
341
342 @param[in] carry : input carry flag, value = element of {0,1}
343 @param[in, out] x1,x3 : input X-coordinate of R0, my_r0_x (Jacobian, projective coordinate) and output X-coordinate of P+Q
344 @param[in, out] y1,y3 : input Y-coordinate of R0, my_r0_y (Jacobian, projective coordinate) and output Y-coordinate of P+Q
345 @param[in, out] x2,x3' : input X-coordinate of R1, my_r1_x (Jacobian, projective coordinate) and output X-coordinate of P-Q
346 @param[in, out] y2,y3' : input Y-coordinate of R1, my_r1_y (Jacobian, projective coordinate) and output Y-coordinate of P-Q
347 where P = (x1, y1, z), Q = (x2, y2, z), P+Q = (x3,y3,z3) and P-Q = (x3',y3',z3), for some z3 on the elliptic curve
348
349 @param[in] barrett_u : Register index for Barrett reduction value.
350 @param[in] mod : Register index for modulo value.
351 @param[in] size : Bit size.
352 */
353 void Cryptolite_EC_XYCZ_ADDC( CRYPTOLITE_Type *base,
354 cy_stc_cryptolite_context_ecdsa_t *cfContext,
355 int carry,
356 uint8_t *x1,
357 uint8_t *y1,
358 uint8_t *x2,
359 uint8_t *y2,
360 int size );
Cryptolite_EC_XYCZ_ADDC(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,int carry,uint8_t * x1,uint8_t * y1,uint8_t * x2,uint8_t * y2,int size)361 void Cryptolite_EC_XYCZ_ADDC( CRYPTOLITE_Type *base,
362 cy_stc_cryptolite_context_ecdsa_t *cfContext,
363 int carry,
364 uint8_t *x1,
365 uint8_t *y1,
366 uint8_t *x2,
367 uint8_t *y2,
368 int size )
369 {
370 CY_ALIGN(4) uint8_t t1[VU_BITS_TO_BYTES(BIT_SIZE)];
371 CY_ALIGN(4) uint8_t t2[VU_BITS_TO_BYTES(BIT_SIZE)];
372 CY_ALIGN(4) uint8_t t3[VU_BITS_TO_BYTES(BIT_SIZE)];
373 CY_ALIGN(4) uint8_t t4[VU_BITS_TO_BYTES(BIT_SIZE)];
374 CY_ALIGN(4) uint8_t t5[VU_BITS_TO_BYTES(BIT_SIZE)];
375 uint8_t *temp;
376
377 Cy_Cryptolite_Vu_wait_hw(base);
378 // Swap if carry set, b = 1 : (R0, R1) <- ADDC(R1, R0)
379 if ((bool)carry)
380 {
381 temp = x1;
382 x1 = x2;
383 x2 = temp;
384
385 temp = y1;
386 y1 = y2;
387 y2 = temp;
388 }
389
390
391
392
393
394 Cryptolite_EC_SubMod( base, cfContext, t1, x2, x1);
395 Cryptolite_EC_SquareMod( base, cfContext, t1, t1, size);
396 Cryptolite_EC_MulMod( base, cfContext, t2, x2, t1, size);
397 Cryptolite_EC_MulMod( base, cfContext, t3, x1, t1, size);
398 Cryptolite_EC_SubMod( base, cfContext, t1, y2, y1);
399 Cryptolite_EC_AddMod( base, cfContext, t5, y1, y2);
400 Cryptolite_EC_SubMod( base, cfContext, x2, t2, t3);
401 Cryptolite_EC_MulMod( base, cfContext, y1, y1, x2, size);
402 Cryptolite_EC_AddMod( base, cfContext, t2, t3, t2);
403 Cryptolite_EC_SquareMod( base, cfContext, x2, t1, size);
404
405
406
407 Cryptolite_EC_SubMod( base, cfContext, x2, x2, t2);
408 Cryptolite_EC_SquareMod( base, cfContext, t4, t5, size);
409 Cryptolite_EC_SubMod( base, cfContext, x1, t3, x2);
410 Cryptolite_EC_MulMod( base, cfContext, x1, t1, x1, size);
411 Cryptolite_EC_SubMod( base, cfContext, y2, x1, y1);
412 Cryptolite_EC_SubMod( base, cfContext, x1, t4, t2);
413 Cryptolite_EC_SubMod( base, cfContext, t1, x1, t3);
414 Cryptolite_EC_MulMod( base, cfContext, t3, t5, t1, size);
415 Cryptolite_EC_SubMod( base, cfContext, y1, t3, y1);
416
417 Cy_Cryptolite_Vu_wait_hw(base);
418 temp = y1;
419 y1 = y2;
420 y2 = temp;
421 }
422
423 /* @brief Elliptic curve point multiplication, in GF(p), using (X,Y)-only, co-Z arithmetic.
424 @param[in] s_x Register index for affine X coordinate of base point.
425 @param[in] s_y Register index for affine Y coordinate of base point.
426 @param[in] d Register index for multiplication/exponentiation value.
427 @param[in] barrett_u Register index for Barrett reduction value.
428 @param[in] mod Register index for modulo value.
429 @param[in] size Bit size.
430 */
431 void Cryptolite_EC_JacobianEcScalarMul_coZ( CRYPTOLITE_Type *base,
432 cy_stc_cryptolite_context_ecdsa_t *cfContext,
433 uint8_t * px,
434 uint8_t * py,
435 uint8_t * pd,
436 int size, // bit size
437 uint8_t * porder);
Cryptolite_EC_JacobianEcScalarMul_coZ(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * px,uint8_t * py,uint8_t * pd,int size,uint8_t * porder)438 void Cryptolite_EC_JacobianEcScalarMul_coZ( CRYPTOLITE_Type *base,
439 cy_stc_cryptolite_context_ecdsa_t *cfContext,
440 uint8_t * px,
441 uint8_t * py,
442 uint8_t * pd,
443 int size, // bit size
444 uint8_t * porder)
445 {
446 int i;
447 uint8_t carry;
448 uint8_t carry_sizeplus1;
449 uint8_t carry_size;
450 uint8_t carry_sizeminus1;
451 bool carry_combination;
452 CY_ALIGN(4) uint8_t dc[VU_BITS_TO_BYTES(BIT_SIZE+2)];
453 CY_ALIGN(4) uint8_t lambda[VU_BITS_TO_BYTES(BIT_SIZE)];
454 CY_ALIGN(4) uint8_t my_r1_x[VU_BITS_TO_BYTES(BIT_SIZE)];
455 CY_ALIGN(4) uint8_t my_r1_y[VU_BITS_TO_BYTES(BIT_SIZE)];
456 CY_ALIGN(4) uint8_t my_p_x[VU_BITS_TO_BYTES(BIT_SIZE)];
457 CY_ALIGN(4) uint8_t my_p_y[VU_BITS_TO_BYTES(BIT_SIZE)];
458 CY_ALIGN(4) uint8_t t1[VU_BITS_TO_BYTES(BIT_SIZE)];
459 CY_ALIGN(4) uint8_t t2[VU_BITS_TO_BYTES(BIT_SIZE)];
460 CY_ALIGN(4) uint8_t t3[VU_BITS_TO_BYTES(BIT_SIZE)];
461
462 uint8_t *p_my_r1_x = my_r1_x;
463 uint8_t *p_my_r1_y = my_r1_y;
464 uint8_t *p_t1 = t1;
465 uint8_t *p_t2 = t2;
466
467 uint8_t *p_t3 = t3;
468 uint8_t *t4 = porder;
469 uint8_t *p_t4 = t4;
470
471 uint8_t *temp;
472 int even_size;
473 uint32_t bitsize = cfContext->bitsize;
474 cy_stc_cryptolite_descr_t *vu_struct0 = &cfContext->vu_desptr[0];
475 cy_stc_cryptolite_descr_t *vu_struct1 = &cfContext->vu_desptr[1];
476
477
478 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, my_p_x, VU_BITS_TO_WORDS(bitsize), px, VU_BITS_TO_WORDS(bitsize));
479 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct1, my_p_y, VU_BITS_TO_WORDS(bitsize), py, VU_BITS_TO_WORDS(bitsize));
480 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, dc, VU_BITS_TO_WORDS(bitsize+2U), pd, VU_BITS_TO_WORDS(bitsize));
481
482 Cy_Cryptolite_Vu_wait_hw(base);
483
484 if (Cy_Cryptolite_Vu_test_even(dc) == false)
485 {
486 (void)Cy_Cryptolite_Vu_add_hw (base, vu_struct0, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize + 2U), porder, VU_BITS_TO_WORDS(bitsize));
487 }
488
489 (void)Cy_Cryptolite_Vu_add_hw (base, vu_struct1, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize + 2U), porder, VU_BITS_TO_WORDS(bitsize));
490
491
492
493
494 /*------------------------------------------------
495 * Montgomery ladder with (X,Y)-only co-Z addition
496 *------------------------------------------------
497 * Initialization function
498 * Calculate 2P, corresponding to leading 1 in dc
499 * Ensures constant timing looping over all bits in dc, which can vary in the number of bits over the range [size, size_2]
500 *Crypto_EC_CoZ_Init (dc, my_p_x, my_p_y, px, py, p_my_r1_x, my_r1_y, size);
501 */
502
503 /*--------------------------------
504 * IDBL: 2P and P*
505 *---------------------------------
506 */
507
508
509 Cryptolite_EC_SquareMod (base, cfContext, p_my_r1_y, my_p_y, size);
510 Cryptolite_EC_AddMod (base, cfContext, p_my_r1_y, p_my_r1_y, p_my_r1_y);
511 Cryptolite_EC_SquareMod (base, cfContext, py, p_my_r1_y, size);
512 Cryptolite_EC_AddMod (base, cfContext, py, py, py);
513 Cryptolite_EC_AddMod (base, cfContext, px, p_my_r1_y, p_my_r1_y);
514 Cryptolite_EC_MulMod (base, cfContext, px, px, my_p_x, size);
515 Cryptolite_EC_SquareMod (base, cfContext, p_my_r1_x, my_p_x, size);
516 Cryptolite_EC_AddMod (base, cfContext, p_my_r1_y, p_my_r1_x, p_my_r1_x);
517 Cryptolite_EC_AddMod (base, cfContext, p_my_r1_x, p_my_r1_y, p_my_r1_x);
518 Cy_Cryptolite_Vu_wait_hw(base);
519 Cy_Cryptolite_Vu_clr (p_t1, VU_BITS_TO_WORDS(bitsize));
520 Cy_Cryptolite_Vu_set_bit (p_t1, 0);
521 Cy_Cryptolite_Vu_set_bit (p_t1, 1);
522
523
524
525 Cryptolite_EC_SubMod (base, cfContext, p_my_r1_y, p_my_r1_x, p_t1);
526 Cryptolite_EC_SquareMod (base, cfContext, p_my_r1_x, p_my_r1_y, size);
527 Cryptolite_EC_SubMod (base, cfContext, p_my_r1_x, p_my_r1_x, px);
528 Cryptolite_EC_SubMod (base, cfContext, p_my_r1_x, p_my_r1_x, px);
529 Cryptolite_EC_SubMod (base, cfContext, p_t1, px, p_my_r1_x);
530 Cryptolite_EC_MulMod (base, cfContext, p_my_r1_y, p_my_r1_y, p_t1, size);
531 Cryptolite_EC_SubMod (base, cfContext, p_my_r1_y, p_my_r1_y, py);
532 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, p_t1, VU_BITS_TO_WORDS(bitsize), p_my_r1_x, VU_BITS_TO_WORDS(bitsize));
533 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct1, p_t2, VU_BITS_TO_WORDS(bitsize), p_my_r1_y, VU_BITS_TO_WORDS(bitsize));
534 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, p_t3, VU_BITS_TO_WORDS(bitsize), px, VU_BITS_TO_WORDS(bitsize));
535 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct1, p_t4, VU_BITS_TO_WORDS(bitsize), py, VU_BITS_TO_WORDS(bitsize));
536
537
538
539 /*--------------------------------
540 * b_{s+1}
541 *--------------------------------
542 */
543 carry_sizeplus1 = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1;
544 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct0, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
545
546
547 /*--------------------------------
548 * b_{s}
549 *--------------------------------
550 */
551
552 if (!(bool)carry_sizeplus1)
553 {
554 temp = px;
555 px = p_t1;
556 p_t1 = temp;
557
558 temp = py;
559 py = p_t2;
560 p_t2 = temp;
561
562 temp = p_my_r1_x;
563 p_my_r1_x = p_t3;
564 p_t3 = temp;
565
566 temp = p_my_r1_y;
567 p_my_r1_y = p_t4;
568 p_t4 = temp;
569 }
570
571 Cy_Cryptolite_Vu_wait_hw(base);
572 carry_size = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1;
573 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct1, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
574
575
576
577 Cryptolite_EC_XYCZ_ADDC(base, cfContext, (int)carry_size, px, py, p_my_r1_x, p_my_r1_y, size);
578
579
580
581 Cryptolite_EC_XYCZ_ADD(base, cfContext, (int)carry_size, px, py, p_my_r1_x, p_my_r1_y, size);
582
583
584
585 carry_combination = ((!(bool)carry_sizeplus1) && (bool)carry_size);
586
587 if (carry_combination)
588 {
589 temp = px;
590 px = p_t1;
591 p_t1 = temp;
592
593 temp = py;
594 py = p_t2;
595 p_t2 = temp;
596
597 temp = p_my_r1_x;
598 p_my_r1_x = p_t3;
599 p_t3 = temp;
600
601 temp = p_my_r1_y;
602 p_my_r1_y = p_t4;
603 p_t4 = temp;
604 }
605
606 carry_sizeminus1 = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1U;
607 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct0, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
608 Cryptolite_EC_XYCZ_ADDC(base, cfContext, (int)carry_sizeminus1, px, py, p_my_r1_x, p_my_r1_y, size);
609 Cryptolite_EC_XYCZ_ADD(base, cfContext, (int)carry_sizeminus1, px, py, p_my_r1_x, p_my_r1_y, size);
610
611 carry_combination = !(bool)carry_sizeplus1 && !(bool)carry_size && (bool)carry_sizeminus1;
612
613 if (carry_combination)
614 {
615 temp = px;
616 px = p_t1;
617 p_t1 = temp;
618
619 temp = py;
620 py = p_t2;
621 p_t2 = temp;
622
623 temp = p_my_r1_x;
624 p_my_r1_x = p_t3;
625 p_t3 = temp;
626
627 temp = p_my_r1_y;
628 p_my_r1_y = p_t4;
629 p_t4 = temp;
630 }
631
632 even_size = (bool)(size % 2) ? (size -1) : size;
633 for (i = 0; i < (even_size-2); i+=2)
634 {
635 carry = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1;
636 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct1, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
637 Cryptolite_EC_XYCZ_ADDC (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
638 Cryptolite_EC_XYCZ_ADD (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
639
640 carry = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1;
641 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct0, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
642 Cryptolite_EC_XYCZ_ADDC (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
643 Cryptolite_EC_XYCZ_ADD (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
644 }
645
646 if (!(bool)even_size)
647 {
648 carry = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1;
649 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct1, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
650 Cryptolite_EC_XYCZ_ADDC (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
651 Cryptolite_EC_XYCZ_ADD (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
652 }
653
654 carry = (dc[VU_BITS_TO_BYTES(bitsize+2U)-4U] & (0x2U)) >> 1;
655 (void)Cy_Cryptolite_Vu_lsl1_hw (base, vu_struct0, dc, VU_BITS_TO_WORDS(bitsize+2U), dc, VU_BITS_TO_WORDS(bitsize+2U));
656
657 Cryptolite_EC_XYCZ_ADDC (base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
658 Cryptolite_EC_SubMod (base, cfContext, p_t1, p_my_r1_x, px);
659 Cryptolite_EC_MulMod (base, cfContext, p_t1, p_t1, my_p_x, size);
660
661 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct0, p_t2, VU_BITS_TO_WORDS(bitsize), px, VU_BITS_TO_WORDS(bitsize));
662 (void)Cy_Cryptolite_Vu_mov_hw (base, vu_struct1, p_t3, VU_BITS_TO_WORDS(bitsize), py, VU_BITS_TO_WORDS(bitsize));
663
664 /* Swap values if carry bit is set to 1 */
665 if ((bool)carry)
666 {
667 p_t2 = p_my_r1_x;
668 p_t3 = p_my_r1_y;
669 }
670
671 Cryptolite_EC_MulMod( base, cfContext, p_t3, p_t1, p_t3, size);
672 Cy_Cryptolite_Vu_wait_hw(base);
673
674 Cy_Cryptolite_Vu_clr(p_t1, VU_BITS_TO_WORDS(bitsize));
675 Cy_Cryptolite_Vu_set_bit(p_t1, 0);
676
677 Cryptolite_EC_DivMod(base, cfContext, p_t3, p_t1, p_t3, (int)size);
678 Cryptolite_EC_MulMod(base, cfContext, p_t1, my_p_y, p_t3, size);
679 Cryptolite_EC_MulMod(base, cfContext, lambda, p_t2, p_t1, size);
680 Cryptolite_EC_XYCZ_ADD(base, cfContext, (int)carry, px, py, p_my_r1_x, p_my_r1_y, size);
681
682 Cryptolite_EC_SquareMod(base, cfContext, my_p_x, lambda, size);
683 Cryptolite_EC_MulMod(base, cfContext, lambda, my_p_x, lambda, size);
684 Cryptolite_EC_MulMod(base, cfContext, px, px, my_p_x, size);
685 Cryptolite_EC_MulMod(base, cfContext, py, py, lambda, size);
686 }
687
688 /**
689 * @brief Elliptic curve point multiplication in GF(p)
690 * @param[in] p_x Register index for affine X coordinate of base point.
691 * @param[in] p_y Register index for affine Y coordinate of base point.
692 * @param[in] p_d Register index for multiplication value.
693 * @param[in] p_order Register index for order value.
694 * @param[in] bitsize Bit size of the used curve.
695 */
Cryptolite_EC_NistP_PointMul(CRYPTOLITE_Type * base,cy_stc_cryptolite_context_ecdsa_t * cfContext,uint8_t * p_x,uint8_t * p_y,uint8_t * p_d,uint8_t * p_order,int bitsize)696 void Cryptolite_EC_NistP_PointMul(CRYPTOLITE_Type *base,
697 cy_stc_cryptolite_context_ecdsa_t *cfContext,
698 uint8_t *p_x, uint8_t *p_y,
699 uint8_t *p_d, uint8_t *p_order,
700 int bitsize)
701 {
702 Cryptolite_EC_JacobianEcScalarMul_coZ(base, cfContext, p_x, p_y, p_d, bitsize, p_order);
703 Cy_Cryptolite_Vu_wait_hw(base);
704 }
705
706
707 #endif /* #if defined(CY_CRYPTOLITE_CFG_ECP_C) */
708 #endif /* #if (CPUSS_CRYPTOLITE_VU == 1) */
709
710 #if defined(__cplusplus)
711 }
712 #endif
713
714 #endif /* CY_IP_MXCRYPTOLITE */
715
716
717