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