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