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