1 /***************************************************************************//**
2 * \file cy_crypto_core_ecc_nist_p.c
3 * \version 2.120
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
11 * Copyright (c) (2020-2022), Cypress Semiconductor Corporation (an Infineon company) or
12 * an affiliate of Cypress Semiconductor Corporation.
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include "cy_device.h"
29
30 #if defined (CY_IP_MXCRYPTO)
31
32 #include "cy_crypto_core_ecc_nist_p.h"
33
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37
38 #if defined (CY_CRYPTO_CFG_ECP_C)
39
40 #include "cy_crypto_core_vu.h"
41
42 /*******************************************************************************
43 * Elliptic Curve (EC) Scalar Multiplication using (X,Y)-only, Co-Z arithmetic
44 *
45 * Theoretic and algorithmic references:
46 * Algorithms and Co-Z arithmetic theory: 'Fast and Regular Algorithms for Scalar
47 * Multiplication over Elliptic Curves', Matthieu Rivain NIST P-curves
48 * (parameters and curve-specific modular reduction):
49 * 'RECOMMENDED ELLIPTIC CURVES FOR FEDERAL GOVERNMENT USE', NIST, 1999
50 *
51 * Useful resources:
52 * Large number calculator and converter:
53 * - http://www.mobilefish.com/services/big_number/big_number.php
54 * - https://www.mobilefish.com/services/big_number_equation/big_number_equation.php
55 *
56 * - ECC curves and test vectors: http://point-at-infinity.org/ecc/nisttv
57 *
58 * Valid values for scalar multiplier, 2 < d < (order-1)
59 *
60 *******************************************************************************/
61
62
63 /***************************************************************
64 * Global Variables
65 ***************************************************************/
66 static cy_en_crypto_ecc_curve_id_t eccMode;
67
68 static cy_en_crypto_ecc_red_mul_algs_t mul_red_alg_select = CY_CRYPTO_NIST_P_BARRETT_RED_ALG;
69
70 /***************************************************************
71 * Collection of multiplication reduction algorithms
72 * Method 1: (Crypto_EC_CS_MUL_Red_Pxxx): curve specific
73 * reduction as proposed by NIST
74 * Method 2: (Crypto_EC_SM_MUL_Red_Pxxx): curve specific
75 * reduction based on Mersenne prime reduction approach
76 * Method 3: generic Barrett reduction
77 ***************************************************************/
78 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
79 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x);
80 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x);
81 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
82
83 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
84 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x);
85 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x);
86 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
87
88 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
89 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x);
90 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x);
91 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
92
93 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
94 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x);
95 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x);
96 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
97
98 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
99 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x);
100 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x);
101 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
102
103 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
104 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
105 static cy_en_crypto_status_t Cy_Crypto_Core_EC_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size);
106
107
108 /***************************************************************
109 * Curve-specific multiplication reduction algorithms
110 ***************************************************************/
111
112 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
113 /*******************************************************************************
114 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P192
115 ****************************************************************************//**
116 *
117 * Curve-specific multiplication modular reduction for P192.
118 * 0 <= a, b < P192
119 * a5..a0 * b5..b0 % P192 = t11..t0 % P192
120 * P192 = 2^192-2^64-1
121 * t11..t0 % 2^192-2^64-1
122 * t11..t6 * 2^192 + t5..t0 % 2^192-2^64-1
123 * t11..t6 * 2^192-2^64-1 + t11..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
124 * t11..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
125 * t11..t10 * 2^192 + t9..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
126 * t11..t10 * 2^192-2^64-1 + t11..t10 * 2^64 + t11..t10 + t9..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
127 * t11..t10 * 2^64 + t11..t10 + t9..t6 * 2^64 + t11..t6 + t5..t0 % 2^192-2^64-1
128 *
129 * \param base
130 * The pointer to a Crypto instance.
131 *
132 * \param z
133 * Product = a*b [2*192 bits].
134 *
135 * \param x
136 * Result = x mod P = a*b mod P [192 bits].
137 *
138 * \return status code. See \ref cy_en_crypto_status_t.
139 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P192(CRYPTO_Type * base,uint32_t z,uint32_t x)140 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x)
141 {
142 uint32_t sh = 0u;
143 uint32_t t1 = 2u; /* 128 */
144 uint32_t t2 = 3u; /* 192 */
145 uint32_t my_z = 4u;
146 uint32_t my_x = 5u;
147 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
148
149 CY_CRYPTO_VU_PUSH_REG (base);
150
151 CY_CRYPTO_VU_LD_REG (base, my_z, z);
152 CY_CRYPTO_VU_LD_REG (base, my_x, x);
153
154 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, 128u);
155 if(CY_CRYPTO_SUCCESS != tmpResult)
156 {
157 return tmpResult;
158 }
159
160 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, 192u);
161 if(CY_CRYPTO_SUCCESS != tmpResult)
162 {
163 return tmpResult;
164 }
165
166 CY_CRYPTO_VU_SET_REG (base, sh, 192u, 1u);
167 CY_CRYPTO_VU_LSR (base, my_z, my_x, sh); /* t11..t6 */
168
169 CY_CRYPTO_VU_SET_REG (base, sh, 128u, 1u);
170 CY_CRYPTO_VU_LSR (base, t1, my_z, sh); /* t11..t10 */
171 CY_CRYPTO_VU_SET_REG (base, sh, 64u, 1u);
172 CY_CRYPTO_VU_LSL (base, t2, my_z, sh); /* t9..t6 * 2^64 */
173
174
175 CY_CRYPTO_VU_ADD (base, my_z, my_z, my_x); /* t11..t6 + t5..t0 */
176 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
177 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
178
179 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* t9..t6 * 2^64 + t11..t6 + t5..t0 */
180 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
181 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
182
183 CY_CRYPTO_VU_LSL (base, t2, t1, sh); /* t11..t10 * 2^64 */
184 CY_CRYPTO_VU_OR (base, t1, t1, t2); /* t11..t10 * 2^64 + t11..t10 */
185
186 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* t11..t10 * 2^64 + t11..t10 + t9..t6 * 2^64 + t11..t6 + t5..t0 */
187 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
188 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
189
190 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2));
191 CY_CRYPTO_VU_POP_REG (base);
192
193 return CY_CRYPTO_SUCCESS;
194 }
195 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
196
197
198 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
199 /*******************************************************************************
200 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P224
201 ****************************************************************************//**
202 *
203 * Curve-specific multiplication modular reduction for P224.
204 * 0 <= a, b < P224
205 * a6..a0 * b6..b0 % P224 = t13..t0 % P224
206 * P224 = 2^224 - 2^96 - 1
207 * t6..t0 + t10..t7*2^96 + t13..t11*2^96 - t13..t7 - t13..t11 % 2^224 - 2^96 - 1
208 * t13..t11*2^96 + t6..t0 - t13..t7 - t13..t11 + t10..t7*2^96 % 2^224 - 2^96 - 1
209 *
210 * \param base
211 * The pointer to a Crypto instance.
212 *
213 * \param z
214 * Result = x mod P = a*b mod P [224 bits].
215 *
216 * \param x
217 * Product = a*b [2*224 bits].
218 *
219 *
220 * \return status code. See \ref cy_en_crypto_status_t.
221 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P224(CRYPTO_Type * base,uint32_t z,uint32_t x)222 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x)
223 {
224 uint32_t sh = 0u;
225 uint32_t t1 = 1u; /* 224 */
226 uint32_t t2 = 2u; /* 224 */
227 uint32_t t3 = 3u; /* 224 */
228 uint32_t my_z = 4u;
229 uint32_t my_x = 5u;
230 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
231
232 CY_CRYPTO_VU_PUSH_REG (base);
233
234 CY_CRYPTO_VU_LD_REG (base, my_z, z);
235 CY_CRYPTO_VU_LD_REG (base, my_x, x);
236
237 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, CY_CRYPTO_ECC_P224_SIZE); /* 224 */
238 if(CY_CRYPTO_SUCCESS != tmpResult)
239 {
240 return tmpResult;
241 }
242
243 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, CY_CRYPTO_ECC_P224_SIZE); /* 224 */
244 if(CY_CRYPTO_SUCCESS != tmpResult)
245 {
246 return tmpResult;
247 }
248
249 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, CY_CRYPTO_ECC_P224_SIZE); /* 224 */
250 if(CY_CRYPTO_SUCCESS != tmpResult)
251 {
252 return tmpResult;
253 }
254
255 CY_CRYPTO_VU_SET_REG (base, sh, CY_CRYPTO_ECC_P224_SIZE, 1u); /* sh = 224 */
256 CY_CRYPTO_VU_LSR (base, my_z, my_x, sh); /* z = t13..t7 */
257
258 CY_CRYPTO_VU_SET_REG (base, sh, 128u, 1u);
259 CY_CRYPTO_VU_LSR (base, t1, my_z, sh); /* t1 = t13..t11 */
260
261 CY_CRYPTO_VU_SET_REG (base, sh, 96u, 1u);
262 CY_CRYPTO_VU_LSL (base, t2, t1, sh); /* t2 = t13..t11*2^96 */
263
264 CY_CRYPTO_VU_SET_REG (base, sh, 96u, 1u);
265 CY_CRYPTO_VU_LSL (base, t3, my_z, sh); /* t3 = t10..t7*2^96 */
266
267 CY_CRYPTO_VU_ADD (base, t2, t2, my_x); /* t2 = t13..t11*2^96 + t6..t0 */
268 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, t2, VR_P); /* C = (t2 >= VR_P) */
269 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, t2, t2, VR_P); /* t2 = t2 - p, if C==1 (Carry is set) */
270
271 CY_CRYPTO_VU_SUB (base, t2, t2, my_z); /* t2 = (t13..t11*2^96 + t6..t0) - t13..t7 */
272 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, t2, t2, VR_P); /* t2 = t2 + p, if C==0 (Carry is clear) */
273
274 CY_CRYPTO_VU_SUB (base, t2, t2, t1); /* t2 = (t13..t11*2^96 + t6..t0 - t13..t7) - t13..t11 */
275 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, t2, t2, VR_P); /* t2 = t2 + p, if C==0 (Carry is clear) */
276
277 CY_CRYPTO_VU_ADD (base, my_z, t2, t3); /* z = (t13..t11*2^96 + t6..t0 - t13..t7 - t13..t11) + t10..t7*2^96 */
278 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
279 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
280
281 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2) | CY_CRYPTO_VU_REG_BIT(t3));
282
283 CY_CRYPTO_VU_POP_REG (base);
284
285 return CY_CRYPTO_SUCCESS;
286 }
287 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
288
289
290 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
291 /*******************************************************************************
292 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P256
293 ****************************************************************************//**
294 *
295 * Curve-specific multiplication modular reduction for P256.
296 * 0 <= a, b < P256
297 * a7..a0 * b7..b0 % P256 = t15..t0 % P256
298 * P224 = 2^256 - 2^224 + 2^192 + 2^96 - 1
299 * t7..t0 + 2*t15..t11*2^96 + 2*t15..t12*2^96 + (t15..t14*2^192 + t10..t8)
300 * + (t8*2^224 + t13*2^192 + t15..t9) - (t10*2^224 + t8*2^192 + t13..t11)
301 * - (t11*2^224 + t9*2^192 + t15..t12) - (t12*2^224 + t10..t8*2^96 + t15..t13)
302 * - (t13*2^224 + t11..t9*2^96 + t15..t14) % 2^256 - 2^224 + 2^192 + 2^96 - 1
303 *
304 * \param base
305 * The pointer to a Crypto instance.
306 *
307 * \param z
308 * Result = x mod P = a*b mod P [256 bits].
309 *
310 * \param x
311 * Product = a*b [2*256 bits].
312 *
313 * \return status code. See \ref cy_en_crypto_status_t.
314 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P256(CRYPTO_Type * base,uint32_t z,uint32_t x)315 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x)
316 {
317 uint32_t sh = 0u; /* Variable values */
318 uint32_t sh32 = 1u;
319 uint32_t sh96 = 2u;
320 uint32_t sh192 = 3u;
321 uint32_t sh224 = 4u;
322 uint32_t t0 = 5u; /* 256 */
323 uint32_t t1 = 6u; /* 256 */
324 uint32_t t2 = 7u; /* 256 */
325 uint32_t t3 = 8u; /* 32 */
326 uint32_t t4 = 9u; /* 96 */
327 uint32_t my_z = 10u;
328 uint32_t my_x = 11u;
329 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
330
331 CY_CRYPTO_VU_PUSH_REG (base);
332
333 CY_CRYPTO_VU_LD_REG (base, my_z, z);
334 CY_CRYPTO_VU_LD_REG (base, my_x, x);
335
336 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P256_SIZE); /* 256 */
337 if(CY_CRYPTO_SUCCESS != tmpResult)
338 {
339 return tmpResult;
340 }
341
342 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, CY_CRYPTO_ECC_P256_SIZE); /* 256 */
343 if(CY_CRYPTO_SUCCESS != tmpResult)
344 {
345 return tmpResult;
346 }
347
348 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, CY_CRYPTO_ECC_P256_SIZE); /* 256 */
349 if(CY_CRYPTO_SUCCESS != tmpResult)
350 {
351 return tmpResult;
352 }
353
354 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, 32u); /* 32 */
355 if(CY_CRYPTO_SUCCESS != tmpResult)
356 {
357 return tmpResult;
358 }
359
360 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t4, 96u); /* 96 */
361 if(CY_CRYPTO_SUCCESS != tmpResult)
362 {
363 return tmpResult;
364 }
365
366 CY_CRYPTO_VU_SET_REG (base, sh, CY_CRYPTO_ECC_P256_SIZE, 1u); /* sh = 256 */
367 CY_CRYPTO_VU_SET_REG (base, sh32, 32u, 1u); /* sh = 32 */
368 CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u); /* sh = 96 */
369 CY_CRYPTO_VU_SET_REG (base, sh192, 192u, 1u); /* sh = 192 */
370 CY_CRYPTO_VU_SET_REG (base, sh224, 224u, 1u); /* sh = 224 */
371
372 CY_CRYPTO_VU_LSR (base, t0, my_x, sh); /* t0 = t15..t8 */
373 CY_CRYPTO_VU_LSR (base, my_z, t0, sh96); /* z = t15..t11 */
374 CY_CRYPTO_VU_LSR (base, t1, my_z, sh32); /* t1 = t15..t12 */
375 CY_CRYPTO_VU_LSR (base, t3, my_z, sh32); /* t3 = t12 */
376
377 /* 2*S1 -- 2*t15..t11*2^96 */
378 CY_CRYPTO_VU_LSL (base, my_z, my_z, sh96); /* z = t15..t11*2^96 */
379 CY_CRYPTO_VU_ADD (base, my_z, my_z, my_z); /* z = 2*t15..t11*2^96 */
380 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
381 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
382
383 /* D3 (a) -- t12*2^224 */
384 CY_CRYPTO_VU_LSL (base, t2, t3, sh224); /* t2 = t12*2^224 */
385 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t12*2^224 */
386 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
387
388 /* 2*S2 -- 2*t15..t12*2^96 */
389 CY_CRYPTO_VU_LSL (base, t2, t1, sh96); /* t2 = t15..t12*2^96 */
390
391 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t15..t12*2^96 */
392 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
393 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
394
395 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + 2*t15..t12*2^96 */
396 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
397 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
398
399 /* D4 (c) -- t15..t14 */
400 CY_CRYPTO_VU_LSR (base, t2, t0, sh192); /* t2 = t15..t14 */
401 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t15..t14 */
402 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
403
404 /* S3 (a) -- t15..t14*2^192 */
405 CY_CRYPTO_VU_LSL (base, t2, t2, sh192); /* t2 = t15..t14*2^192 */
406 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t15..t14*2^192 */
407 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
408 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
409
410 /* D2 (c) -- t15..t12 */
411 CY_CRYPTO_VU_SUB (base, my_z, my_z, t1); /* z = z - t15..t12 */
412 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
413
414 /* S4 (b) -- t13*2^192 */
415 CY_CRYPTO_VU_LSR (base, t3, t1, sh32); /* t3 = t13 */
416 CY_CRYPTO_VU_LSL (base, t2, t3, sh192); /* t2 = t13*2^192 */
417 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t13*2^192 */
418 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
419 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
420
421 /* D4 (a) -- t13*2^224 */
422 CY_CRYPTO_VU_LSL (base, t2, t2, sh32); /* t2 = t13*2^224 */
423 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t13*2^224 */
424 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
425
426 /* D3 (c) -- t15..t13 */
427 CY_CRYPTO_VU_LSR (base, t1, t1, sh32); /* t1 = t15..t13 */
428 CY_CRYPTO_VU_SUB (base, my_z, my_z, t1); /* z = z - t15..t13 */
429 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
430
431 /* S4 (c) -- t15..t13*2^96 */
432 CY_CRYPTO_VU_LSL (base, t2, t1, sh96); /* t2 = t15..t13*2^96 */
433 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t15..t13*2^96 */
434 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
435 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
436
437 /* D2 (a) -- t11*2^224 */
438 CY_CRYPTO_VU_LSR (base, t3, t0, sh96); /* t3 = t11 */
439 CY_CRYPTO_VU_LSL (base, t2, t3, sh224); /* t2 = t11*2^224 */
440 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t11*2^224 */
441 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
442
443 /* D2 (b) -- t9*2^192 */
444 CY_CRYPTO_VU_LSR (base, t3, t0, sh32); /* t3 = t9 */
445 CY_CRYPTO_VU_LSL (base, t2, t3, sh192); /* t2 = t9*2^192 */
446 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t9*2^192 */
447 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
448
449 /* D1 (c) -- t13..t11 */
450 CY_CRYPTO_VU_LSR (base, t4, t0, sh96); /* t4 = t13..t11 */
451 CY_CRYPTO_VU_SUB (base, my_z, my_z, t4); /* z = z - t13..t11 */
452 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
453
454 /* S4 (d) -- t11..t9 */
455 CY_CRYPTO_VU_LSR (base, t4, t0, sh32); /* t4 = t11..t9 */
456 CY_CRYPTO_VU_ADD (base, my_z, my_z, t4); /* z = z + t11..t9 */
457 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
458 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
459
460 /* D1 (a) -- t10*2^224 */
461 CY_CRYPTO_VU_LSR (base, t3, t4, sh32); /* t3 = t10 */
462 CY_CRYPTO_VU_LSL (base, t2, t3, sh224); /* t2 = t10*2^224 */
463 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t10*2^224 */
464 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
465
466
467 /* D4 (b) -- t11..t9*2^96 */
468 CY_CRYPTO_VU_LSL (base, t2, t4, sh96); /* t2 = t11..t9*2^96 */
469 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t11..t9*2^96 */
470 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
471
472 CY_CRYPTO_VU_SET_REG (base, sh, 0u, 1u); /* sh = 0; */
473
474 /* S3 (b) -- t10..t8 */
475 CY_CRYPTO_VU_LSR (base, t4, t0, sh); /* t4 = t10..t8 */
476 CY_CRYPTO_VU_ADD (base, my_z, my_z, t4); /* z = z + t10..t8 */
477 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
478 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
479
480 /* D3 (b) -- t10..t8*2^96 */
481 CY_CRYPTO_VU_LSL (base, t2, t4, sh96); /* t4 = t10..t8*2^96 */
482 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t10..t8*2^96 */
483 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
484
485 /* S4 (a) -- t8*2^224 */
486 CY_CRYPTO_VU_LSL (base, t2, t0, sh224); /* t2 = t8*2^224 */
487 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t8*2^224 */
488 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
489 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
490
491 /* D1 (b) -- t8*2^192 */
492 CY_CRYPTO_VU_LSR (base, t2, t2, sh32); /* t2 = t8*2^192 */
493 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t8*2^192 */
494 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
495
496 /* T -- t7..t0 */
497 CY_CRYPTO_VU_LSR (base, t2, my_x, sh); /* t2 = t8*2^192 */
498 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t7..t0 */
499 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
500 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
501
502 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0) | CY_CRYPTO_VU_REG_BIT(t1) |
503 CY_CRYPTO_VU_REG_BIT(t2) | CY_CRYPTO_VU_REG_BIT(t3) | CY_CRYPTO_VU_REG_BIT(t4));
504 CY_CRYPTO_VU_POP_REG (base);
505
506 return CY_CRYPTO_SUCCESS;
507 }
508 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
509
510
511 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
512 /*******************************************************************************
513 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P384
514 ****************************************************************************//**
515 *
516 * Curve-specific multiplication modular reduction for P384.
517 * 0 <= a, b < P384
518 * a11..a0 * b11..b0 % P384 = t23..t0 % P384
519 * P384 = 2^384 - 2^128 - 2*96 + 2*32 - 1
520 * t11..t0 + 2*t23..t21*2^128 + t23..t12 + (t20..t12*2^96 + t23..t21)
521 * + (t19..t12*2^128 + t20*2^96 +t23*2^32) + t23..t20*2^128 + (t23..t21*2^96 + t20)
522 * - (t22..t12*2^32 + t23) - t23..t20*2^32 - (t23*2^128 + t23*2^96) % P384
523 *
524 * \param base
525 * The pointer to a Crypto instance.
526 *
527 * \param z
528 * Result = x mod P = a*b mod P [384 bits]
529 *
530 * \param x
531 * Product = a*b [2*384 bits]
532 *
533 * \return status code. See \ref cy_en_crypto_status_t.
534 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P384(CRYPTO_Type * base,uint32_t z,uint32_t x)535 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x)
536 {
537 uint32_t sh32 = 0u;
538 uint32_t sh64 = 1u;
539 uint32_t sh96 = 2u;
540 uint32_t sh128 = 3u;
541 uint32_t sh256 = 4u;
542 uint32_t sh384 = 5u;
543 uint32_t t0 = 6u; /* 384 */
544 uint32_t t1 = 7u; /* 384 */
545 uint32_t t2 = 8u; /* 32 */
546 uint32_t my_z = 9u;
547 uint32_t my_x = 10u;
548 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
549
550 CY_CRYPTO_VU_PUSH_REG (base);
551
552 CY_CRYPTO_VU_LD_REG (base, my_z, z);
553 CY_CRYPTO_VU_LD_REG (base, my_x, x);
554
555 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P384_SIZE); /* 384 */
556 if(CY_CRYPTO_SUCCESS != tmpResult)
557 {
558 return tmpResult;
559 }
560
561 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, CY_CRYPTO_ECC_P384_SIZE); /* 384 */
562 if(CY_CRYPTO_SUCCESS != tmpResult)
563 {
564 return tmpResult;
565 }
566 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, 32u); /* 32 */
567 if(CY_CRYPTO_SUCCESS != tmpResult)
568 {
569 return tmpResult;
570 }
571
572 CY_CRYPTO_VU_SET_REG (base, sh32, 32u, 1u); /* sh32 = 32 */
573 CY_CRYPTO_VU_SET_REG (base, sh64, 64u, 1u); /* sh64 = 64 */
574 CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u); /* sh96 = 96 */
575 CY_CRYPTO_VU_SET_REG (base, sh128, 128u, 1u); /* sh128 = 128 */
576 CY_CRYPTO_VU_SET_REG (base, sh256, 256u, 1u); /* sh256 = 256 */
577 CY_CRYPTO_VU_SET_REG (base, sh384, CY_CRYPTO_ECC_P384_SIZE, 1u); /* sh384 = 384 */
578
579 CY_CRYPTO_VU_LSR (base, t0, my_x, sh384); /* t0 = t23..t12 */
580
581 /* T + S2 -- t11..t0 + t23..t12 */
582 CY_CRYPTO_VU_ADD (base, my_z, t0, my_x); /* z = t23..t12 + t11..t0 */
583 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
584 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
585
586 /* S6 (b) -- t_20 */
587 CY_CRYPTO_VU_LSR (base, t2, t0, sh256); /* t2 = t20 */
588 CY_CRYPTO_VU_ADD (base, my_z, my_z, t2); /* z = z + t20 */
589 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
590 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
591
592 /* S4 (b) -- t20*2^96 */
593 CY_CRYPTO_VU_LSL (base, t1, t2, sh96); /* t1 = t20*2^96 */
594 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t20*2^96 */
595 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
596 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
597
598 /* S5 -- t23..t20*2^128 */
599 CY_CRYPTO_VU_LSR (base, t1, t0, sh256); /* t1 = t23..t20 */
600 CY_CRYPTO_VU_LSL (base, t1, t1, sh128); /* t1 = t23..t20*2^128 */
601 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t23..t20*2^128 */
602 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
603 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
604
605 /* D2 -- t23..t20*2^32 */
606 CY_CRYPTO_VU_LSR (base, t1, t1, sh96); /* t1 = t23..t20*2^32 */
607 CY_CRYPTO_VU_SUB (base, my_z, my_z, t1); /* z = z - t23..t20*2^32 */
608 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
609
610 /* S3 (b) -- t23..t21 */
611 CY_CRYPTO_VU_LSR (base, t1, t1, sh64); /* t1 = t23..t21 */
612 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t23..t21 */
613 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
614 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
615
616 /* D1 (b) -- t23 */
617 CY_CRYPTO_VU_LSR (base, t2, t1, sh64); /* t2 = t23 */
618 CY_CRYPTO_VU_SUB (base, my_z, my_z, t2); /* z = z - t23 */
619 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
620
621 /* S6 (a) -- t23..t21*2^96 */
622 CY_CRYPTO_VU_LSL (base, t1, t1, sh96); /* t1 = t23..t21*2^96 */
623 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t23..t21*2^96 */
624 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
625 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
626
627 /* 2*S1 -- 2*t23..t21*2^128 */
628 CY_CRYPTO_VU_LSL (base, t1, t1, sh32); /* t1 = t23..t21*2^128 */
629 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t23..t21*2^128 */
630 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
631 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
632 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t20..t12*2^128 */
633 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
634 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
635
636 /* S4 (c) -- t23*2^32 */
637 CY_CRYPTO_VU_LSL (base, t1, t2, sh32); /* t1 = t23*2^32 */
638 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t23*2^32 */
639 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
640 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
641
642 /* D3 (b) -- t23*2^96 */
643 CY_CRYPTO_VU_LSL (base, t1, t1, sh64); /* t1 = t23*2^96 */
644 CY_CRYPTO_VU_SUB (base, my_z, my_z, t1); /* z = z - t23*2^96 */
645 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
646
647 /* D3 (a) -- t23*2^128 */
648 CY_CRYPTO_VU_LSL (base, t1, t1, sh32); /* t1 = t23*2^128 */
649 CY_CRYPTO_VU_SUB (base, my_z, my_z, t1); /* z = z - t23*2^128 */
650 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
651
652 /* D1 (a) -- t22..t12*2^32 */
653 CY_CRYPTO_VU_LSL (base, t1, t0, sh32); /* t1 = t22..t12*2^32 */
654 CY_CRYPTO_VU_SUB (base, my_z, my_z, t1); /* z = z - t22..t12*2^32 */
655 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, my_z, my_z, VR_P); /* z = z + p, if C==0 (Carry is clear) */
656
657 /* S3 (a) -- t20..t12*2^96 */
658 CY_CRYPTO_VU_LSL (base, t1, t1, sh64); /* t1 = t20..t12*2^96 */
659 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t20..t12*2^96 */
660 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
661 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
662
663 /* S4 (a) -- t19..t12*2^128 */
664 CY_CRYPTO_VU_LSL (base, t1, t1, sh32); /* t1 = t19..t12*2^128 */
665 CY_CRYPTO_VU_ADD (base, my_z, my_z, t1); /* z = z + t19..t12*2^128 */
666 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (z >= VR_P) */
667 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* z = z - p, if C==1 (Carry is set) */
668
669 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0) | CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2));
670 CY_CRYPTO_VU_POP_REG (base);
671
672 return CY_CRYPTO_SUCCESS;
673 }
674 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
675
676
677 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
678 /*******************************************************************************
679 * Function Name: Cy_Crypto_Core_EC_CS_MUL_Red_P521
680 ****************************************************************************//**
681 *
682 * Curve-specific multiplication modular reduction for P521.
683 * 0 <= a, b < P521
684 * P521 = 2^521 - 1
685 * a*b = T = T1*2^521 + T0
686 * T1 = t1041..t521
687 * T0 = t520..t0
688 * T mod p521 = T0 + T1 mod P521
689 *
690 * \param base
691 * The pointer to a Crypto instance.
692 *
693 * \param z
694 * Result = x mod P = a*b mod P [521 bits]
695 *
696 * \param x
697 * Product = a*b [2*521 bits]
698 *
699 * \return status code. See \ref cy_en_crypto_status_t.
700 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MUL_Red_P521(CRYPTO_Type * base,uint32_t z,uint32_t x)701 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x)
702 {
703 uint32_t sh521 = 0u;
704 uint32_t t0 = 1u;
705 uint32_t my_z = 2u;
706 uint32_t my_x = 3u;
707 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
708
709 CY_CRYPTO_VU_PUSH_REG (base);
710
711 CY_CRYPTO_VU_LD_REG (base, my_z, z);
712 CY_CRYPTO_VU_LD_REG (base, my_x, x);
713
714 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P521_SIZE); /* 521 */
715 if(CY_CRYPTO_SUCCESS != tmpResult)
716 {
717 return tmpResult;
718 }
719 CY_CRYPTO_VU_SET_REG (base, sh521, 521u, 1u); /* sh521 = 521 */
720
721 CY_CRYPTO_VU_LSR (base, my_z, my_x, sh521); /* z = T1 */
722
723 CY_CRYPTO_VU_ADD (base, my_z, my_z, my_x); /* z = T1 + T0 */
724
725 /* T0 + T1 mod p */
726 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (t2 >= VR_P) */
727 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* t2 = t2 - p, if C==1 (Carry is set) */
728
729 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0));
730
731 CY_CRYPTO_VU_POP_REG (base);
732
733 return CY_CRYPTO_SUCCESS;
734 }
735 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
736
737
738 /*******************************************************************************
739 * Function Name: Cy_Crypto_Core_EC_CS_MulRed
740 ****************************************************************************//**
741 *
742 * \param base
743 * The pointer to a Crypto instance.
744 *
745 * \param z
746 * Result.
747 *
748 * \param x
749 * Product.
750 *
751 * \param size
752 * Size.
753 *
754 * \return status code. See \ref cy_en_crypto_status_t.
755 *******************************************************************************/
Cy_Crypto_Core_EC_CS_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)756 static cy_en_crypto_status_t Cy_Crypto_Core_EC_CS_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size)
757 {
758 (void)size; /* Suppress warning */
759 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
760
761 switch (eccMode)
762 {
763 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
764 case CY_CRYPTO_ECC_ECP_SECP192R1:
765 tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P192(base, z, x);
766 break;
767 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
768 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
769 case CY_CRYPTO_ECC_ECP_SECP224R1:
770 tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P224(base, z, x);
771 break;
772 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
773 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
774 case CY_CRYPTO_ECC_ECP_SECP256R1:
775 tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P256(base, z, x);
776 break;
777 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
778 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
779 case CY_CRYPTO_ECC_ECP_SECP384R1:
780 tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P384(base, z, x);
781 break;
782 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
783 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
784 case CY_CRYPTO_ECC_ECP_SECP521R1:
785 tmpResult = Cy_Crypto_Core_EC_CS_MUL_Red_P521(base, z, x);
786 break;
787 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
788 default:
789 /* Unsupported Eliptic Curve ID */
790 break;
791 }
792
793 return tmpResult;
794 }
795
796
797 /**********************************************************************
798 * Shift-multiply, curve-specific multiplication reduction algorithms
799 **********************************************************************/
800
801
802 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
803 /*******************************************************************************
804 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P192
805 ****************************************************************************//**
806 *
807 * Shift-multiply multiplication modular reduction for P192.
808 * a[CURVE_SIZE-1:0] * b[CURVE_SIZE-1:0] mod p[CURVE_SIZE-1:0]
809 *
810 * \param base
811 * The pointer to a Crypto instance.
812 *
813 * \param z
814 * Result = x mod P = a*b mod P [192 bits].
815 *
816 * \param x
817 * Product = a*b [2*192 bits].
818 *
819 *
820 * \return status code. See \ref cy_en_crypto_status_t.
821 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P192(CRYPTO_Type * base,uint32_t z,uint32_t x)822 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P192(CRYPTO_Type *base, uint32_t z, uint32_t x)
823 {
824 /* Setup */
825 uint32_t partial = 0u;
826 uint32_t hi = 1u;
827 uint32_t sh64 = 2u;
828 uint32_t sh192 = 3u;
829 uint32_t my_z = 4u;
830 uint32_t my_x = 5u;
831 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
832
833 CY_CRYPTO_VU_PUSH_REG (base);
834
835 CY_CRYPTO_VU_LD_REG (base, my_z, z);
836 CY_CRYPTO_VU_LD_REG (base, my_x, x);
837
838 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P192_SIZE + 65u);
839 if(CY_CRYPTO_SUCCESS != tmpResult)
840 {
841 return tmpResult;
842 }
843
844 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P192_SIZE + 64u);
845 if(CY_CRYPTO_SUCCESS != tmpResult)
846 {
847 return tmpResult;
848 }
849 CY_CRYPTO_VU_SET_REG (base, sh64, 64u, 1u);
850 CY_CRYPTO_VU_SET_REG (base, sh192, 192u, 1u);
851
852 /* Step 2: 1st round of shift-multiply
853 * (Separate hi and lo (LSR hi>>CURVE_SIZE), multiply hi (LSL hi and add 1) and add shifted hi to lo)
854 * hi * (2^{64} + 1) + lo
855 */
856 CY_CRYPTO_VU_LSR (base, hi, my_x, sh192); /* hi = prod >> CURVE_SIZE = prod[383:192] */
857 CY_CRYPTO_VU_MOV (base, my_z, my_x); /* z == lo = prod[191:0] */
858
859 CY_CRYPTO_VU_ADD (base, partial, hi, my_z); /* partial = (hi*1) + lo */
860
861 CY_CRYPTO_VU_LSL (base, hi, hi, sh64); /* hi = hi << 64 = hi*2^{64} */
862
863 CY_CRYPTO_VU_ADD (base, partial, partial, hi); /* partial = hi*(2^{64}+1) + lo */
864
865 /* Step 3: 2nd round of shift-multiply */
866 CY_CRYPTO_VU_LSR (base, hi, partial, sh192); /* hi = partial >> CURVE_SIZE = partial[383:192] */
867
868 CY_CRYPTO_VU_ADD (base, my_z, hi, partial); /* z = (hi*1) + lo (Note: partial == lo, since it will be cut to CURVE_SIZE since z = CURVE_SIZE) */
869
870 CY_CRYPTO_VU_LSL (base, hi, hi, sh64); /* hi = hi << 64 = hi*2^{64} */
871
872 CY_CRYPTO_VU_ADD (base, my_z, my_z, hi); /* z = hi*(2^{64}+1) + lo */
873
874 /* Step 4: Final reduction (compare to P-192 and reduce if necessary, based on CARRY flag) */
875 CY_CRYPTO_VU_CMP_SUB (base, my_z, VR_P); /* C = (z >= VR_P) */
876 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
877
878 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi));
879 CY_CRYPTO_VU_POP_REG (base);
880
881 return CY_CRYPTO_SUCCESS;
882 }
883 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
884
885
886 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
887 /*******************************************************************************
888 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P224
889 ****************************************************************************//**
890 *
891 * Curve-specific multiplication modular reduction for P224.
892 * 0 <= a, b < P224
893 *
894 * \param base
895 * The pointer to a Crypto instance.
896 *
897 * \param z
898 * Result = x mod P = a*b mod P [224 bits].
899 *
900 * \param x
901 * Product = a*b [2*224 bits].
902 *
903 * \return status code. See \ref cy_en_crypto_status_t.
904 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P224(CRYPTO_Type * base,uint32_t z,uint32_t x)905 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P224(CRYPTO_Type *base, uint32_t z, uint32_t x)
906 {
907
908 /* Setup */
909 uint32_t partial = 0u;
910 uint32_t hi = 1u;
911 uint32_t sh96 = 2u;
912 uint32_t sh224 = 3u;
913 uint32_t my_z = 4u;
914 uint32_t my_x = 5u;
915 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
916
917 CY_CRYPTO_VU_PUSH_REG (base);
918
919 CY_CRYPTO_VU_LD_REG (base, my_z, z);
920 CY_CRYPTO_VU_LD_REG (base, my_x, x);
921
922 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P224_SIZE + 97u);
923 if(CY_CRYPTO_SUCCESS != tmpResult)
924 {
925 return tmpResult;
926 }
927
928 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P224_SIZE + 96u);
929 if(CY_CRYPTO_SUCCESS != tmpResult)
930 {
931 return tmpResult;
932 }
933
934 CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u);
935 CY_CRYPTO_VU_SET_REG (base, sh224, 224u, 1u);
936
937 /* Step 2: 1st round of shift-multiply
938 * (Separate hi and lo (LSR hi>>CURVE_SIZE), multiply hi (LSL hi<<96 and subtract 1) and add shifted hi to lo)
939 * hi * (2^{96} + 1) + lo
940 */
941 CY_CRYPTO_VU_LSR (base, hi, my_x, sh224); /* hi = prod >> CURVE_SIZE = prod[447:224] */
942 CY_CRYPTO_VU_MOV (base, my_z, my_x); /* z == lo = prod[223:0] */
943
944 CY_CRYPTO_VU_SUB (base, partial, my_z, hi); /* partial = lo - (hi*1) */
945
946 CY_CRYPTO_VU_LSL (base, hi, hi, sh96); /* hi = hi << 96 = hi*2^{96} */
947
948 CY_CRYPTO_VU_ADD (base, partial, partial, hi); /* partial = hi*(2^{96}-1) + lo */
949
950 /* Step 3: 2nd round of shift-multiply */
951 CY_CRYPTO_VU_LSR (base, hi, partial, sh224); /* hi = partial>>CURVE_SIZE = partial[447:224] */
952
953 CY_CRYPTO_VU_SUB (base, my_z, partial, hi); /* z = lo - (hi*1) (Note: partial == lo, since it will be cut to CURVE_SIZE since z = CURVE_SIZE) */
954
955 CY_CRYPTO_VU_LSL (base, hi, hi, sh96); /* hi = hi<<96 = hi*2^{96} */
956
957 CY_CRYPTO_VU_ADD (base, my_z, my_z, hi); /* z = hi*(2^{96}-1) + lo */
958
959 /* Step 4: Final reduction (compare to P-224 and reduce if necessary, based on CARRY flag) */
960 CY_CRYPTO_VU_CMP_SUB (base, my_z, VR_P); /* C = (z >= VR_P) */
961 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
962
963 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi));
964 CY_CRYPTO_VU_POP_REG (base);
965
966 return CY_CRYPTO_SUCCESS;
967
968 }
969 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
970
971
972 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
973 /*******************************************************************************
974 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P256
975 ****************************************************************************//**
976 *
977 * Shift-multiply modular reduction algorithm.
978 * a*b mod p
979 * 0 <= a, b < P256
980 *
981 * \param base
982 * The pointer to a Crypto instance.
983 *
984 * \param z
985 * Result.
986 *
987 * \param x
988 * Product.
989 *
990 * \return status code. See \ref cy_en_crypto_status_t.
991 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P256(CRYPTO_Type * base,uint32_t z,uint32_t x)992 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P256(CRYPTO_Type *base, uint32_t z, uint32_t x)
993 {
994 /* Pre-computed coefficient for shift-multiply modular reduction for P256 */
995 const uint8_t P256_ShMul_COEFF[] = {
996 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
997 0x00u, 0x00u, 0x00u, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
998 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
999 0xFEu, 0xFFu, 0xFFu, 0xFFu
1000 };
1001
1002 /* Setup */
1003 uint32_t partial = 0u;
1004 uint32_t hi = 1u;
1005 uint32_t sh256 = 2u;
1006 uint32_t my_z = 3u;
1007 uint32_t my_x = 4u;
1008 uint32_t coeff = 5u;
1009 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1010
1011 CY_CRYPTO_VU_PUSH_REG (base);
1012
1013 CY_CRYPTO_VU_LD_REG (base, my_z, z);
1014 CY_CRYPTO_VU_LD_REG (base, my_x, x);
1015
1016 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, coeff, 224u);
1017 if(CY_CRYPTO_SUCCESS != tmpResult)
1018 {
1019 return tmpResult;
1020 }
1021
1022 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P256_SIZE + 224u);
1023 if(CY_CRYPTO_SUCCESS != tmpResult)
1024 {
1025 return tmpResult;
1026 }
1027
1028 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P256_SIZE);
1029 if(CY_CRYPTO_SUCCESS != tmpResult)
1030 {
1031 return tmpResult;
1032 }
1033
1034 CY_CRYPTO_VU_SET_REG (base, sh256, 256u, 1u);
1035
1036 Cy_Crypto_Core_Vu_SetMemValue (base, coeff, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(P256_ShMul_COEFF), 224u);
1037
1038 /* Step 2: 1st round of shift-multiply:
1039 * - separate hi and lo (LSR hi >> CURVE_SIZE),
1040 * - multiply hi * coeff,
1041 * - add hi * coeff + lo
1042 */
1043 CY_CRYPTO_VU_LSR (base, hi, my_x, sh256); /* hi = prod >> CURVE_SIZE = prod[511:256] */
1044 CY_CRYPTO_VU_MOV (base, my_z, my_x); /* z == lo = prod[255:0] */
1045
1046 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1047 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* partial = hi * coeff + lo */
1048
1049 /* Step 3: 2nd round of shift-multiply */
1050 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1051 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1052
1053 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1054 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1055
1056 /* Step 4: 3rd round of shift-multiply */
1057 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1058 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1059
1060 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1061 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1062
1063 /* Step 5: 4th round of shift-multiply */
1064 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1065 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1066
1067 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1068 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1069
1070 /* Step 6: 5th round of shift-multiply */
1071 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1072 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1073
1074 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1075 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1076
1077 /* Step 7: 6th round of shift-multiply */
1078 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1079 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1080
1081 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1082 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1083
1084 /* Step 8: 7th round of shift-multiply */
1085 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1086 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1087
1088 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1089 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1090
1091 /* Step 9: 8th round of shift-multiply */
1092 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1093 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1094
1095 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1096 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* z = hi * coeff + lo */
1097
1098 /* Step 10: 9th round of shift-multiply */
1099 CY_CRYPTO_VU_LSR (base, hi, partial, sh256); /* hi = partial >> CURVE_SIZE = partial[511:256] */
1100 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[255:0] */
1101
1102 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi * coeff */
1103 CY_CRYPTO_VU_ADD (base, my_z, partial, my_z); /* z = hi * coeff + lo */
1104
1105 /* Step 11: Final reduction (compare to P-256 and reduce if necessary, based on CARRY flag) */
1106 CY_CRYPTO_VU_CMP_SUB (base, my_z, VR_P); /* C = (z >= VR_P) */
1107 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
1108
1109 CY_CRYPTO_VU_FREE_MEM(base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi) | CY_CRYPTO_VU_REG_BIT(coeff));
1110 CY_CRYPTO_VU_POP_REG(base);
1111
1112 return CY_CRYPTO_SUCCESS;
1113
1114 }
1115 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
1116
1117
1118 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
1119 /*******************************************************************************
1120 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P384
1121 ****************************************************************************//**
1122 *
1123 * Shift-multiply modular reduction algorithm.
1124 * a*b mod p
1125 * 0 <= a, b < P384
1126 *
1127 * \param base
1128 * The pointer to a Crypto instance.
1129 *
1130 * \param z
1131 * Result.
1132 *
1133 * \param x
1134 * Product.
1135 *
1136 * \return status code. See \ref cy_en_crypto_status_t.
1137 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P384(CRYPTO_Type * base,uint32_t z,uint32_t x)1138 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P384(CRYPTO_Type *base, uint32_t z, uint32_t x)
1139 {
1140 /* Pre-computed coefficient for shift-multiply modular reduction for P384 */
1141 const uint8_t P384_ShMul_COEFF[] = {
1142 0x01u, 0x00u, 0x00u, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
1143 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u,
1144 0x01u
1145 };
1146
1147 /* Setup */
1148 uint32_t partial = 0u;
1149 uint32_t hi = 1u;
1150 uint32_t sh96 = 2u;
1151 uint32_t sh384 = 3u;
1152 uint32_t my_z = 4u;
1153 uint32_t my_x = 5u;
1154 uint32_t coeff = 6u;
1155 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1156
1157 CY_CRYPTO_VU_PUSH_REG (base);
1158
1159 CY_CRYPTO_VU_LD_REG (base, my_z, z);
1160 CY_CRYPTO_VU_LD_REG (base, my_x, x);
1161
1162 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, partial, CY_CRYPTO_ECC_P384_SIZE + 129u);
1163 if(CY_CRYPTO_SUCCESS != tmpResult)
1164 {
1165 return tmpResult;
1166 }
1167
1168 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, hi, CY_CRYPTO_ECC_P384_SIZE + 96u);
1169 if(CY_CRYPTO_SUCCESS != tmpResult)
1170 {
1171 return tmpResult;
1172 }
1173
1174 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, coeff, 129u);
1175 if(CY_CRYPTO_SUCCESS != tmpResult)
1176 {
1177 return tmpResult;
1178 }
1179
1180 CY_CRYPTO_VU_SET_REG (base, sh96, 96u, 1u);
1181 CY_CRYPTO_VU_SET_REG (base, sh384, 384u, 1u);
1182
1183 Cy_Crypto_Core_Vu_SetMemValue (base, coeff, (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(P384_ShMul_COEFF), 129u);
1184
1185 /* Step 2: 1st round of shift-multiply
1186 * (Separate hi and lo (LSR hi>>CURVE_SIZE), multiply hi*c and add hi*coeff + lo)
1187 * hi*coeff + lo
1188 */
1189 CY_CRYPTO_VU_LSR (base, hi, my_x, sh384); /* hi = prod >> CURVE_SIZE = prod[767:384] */
1190 CY_CRYPTO_VU_MOV (base, my_z, my_x); /* z == lo = prod[383:0] */
1191
1192 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi*coeff */
1193 CY_CRYPTO_VU_ADD (base, partial, partial, my_z); /* partial = hi*coeff + lo */
1194
1195 /* Step 3: 2nd round of shift-multiply */
1196 CY_CRYPTO_VU_LSR (base, hi, partial, sh384); /* hi = partial>>CURVE_SIZE = partial[767:384] */
1197 CY_CRYPTO_VU_MOV (base, my_z, partial); /* z == lo = partial[383:0] */
1198
1199 CY_CRYPTO_VU_UMUL (base, partial, hi, coeff); /* partial = hi*coeff */
1200 CY_CRYPTO_VU_ADD (base, my_z, partial, my_z); /* z = hi*coeff + lo */
1201
1202 /* Step 4: Final reduction (compare to P-384 and reduce if necessary, based on CARRY flag) */
1203 CY_CRYPTO_VU_CMP_SUB (base, my_z, VR_P); /* C = (z >= VR_P) */
1204 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P);
1205
1206 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(partial) | CY_CRYPTO_VU_REG_BIT(hi) | CY_CRYPTO_VU_REG_BIT(coeff));
1207 CY_CRYPTO_VU_POP_REG (base);
1208
1209 return CY_CRYPTO_SUCCESS;
1210
1211 }
1212 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
1213
1214
1215 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
1216 /*******************************************************************************
1217 * Function Name: Cy_Crypto_Core_EC_SM_MUL_Red_P521
1218 ****************************************************************************//**
1219 *
1220 * Curve-specific multiplication modular reduction for P521; equivalent to shift-multiply method for P521.
1221 * 0 <= a, b < P521
1222 * P521 = 2^521 - 1
1223 * a*b = T = T1*2^521 + T0
1224 * T1 = t1041..t521
1225 * T0 = t520..t0
1226 * T mod p521 = T0 + T1 mod P521
1227 *
1228 * \param base
1229 * The pointer to a Crypto instance.
1230 *
1231 * \param z
1232 * Result = x mod P = a*b mod P [521 bits].
1233 *
1234 * \param x
1235 * Product = a*b [2*521 bits].
1236 *
1237 * \return status code. See \ref cy_en_crypto_status_t.
1238 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MUL_Red_P521(CRYPTO_Type * base,uint32_t z,uint32_t x)1239 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MUL_Red_P521(CRYPTO_Type *base, uint32_t z, uint32_t x)
1240 {
1241 uint32_t sh521 = 0u;
1242 uint32_t t0 = 1u;
1243 uint32_t my_z = 2u;
1244 uint32_t my_x = 3u;
1245 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1246
1247 CY_CRYPTO_VU_PUSH_REG (base);
1248
1249 CY_CRYPTO_VU_LD_REG (base, my_z, z);
1250 CY_CRYPTO_VU_LD_REG (base, my_x, x);
1251
1252 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t0, CY_CRYPTO_ECC_P521_SIZE); /* 521 */
1253 if(CY_CRYPTO_SUCCESS != tmpResult)
1254 {
1255 return tmpResult;
1256 }
1257 CY_CRYPTO_VU_SET_REG (base, sh521, 521u, 1u); /* sh521 = 521 */
1258
1259 CY_CRYPTO_VU_LSR (base, my_z, my_x, sh521); /* z = T1 */
1260
1261 CY_CRYPTO_VU_ADD (base, my_z, my_z, my_x); /* z = T1 + T0 */
1262
1263 /* T0 + T1 mod p */
1264 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, my_z, VR_P); /* C = (t2 >= VR_P) */
1265 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, my_z, my_z, VR_P); /* t2 = t2 - p, if C==1 (Carry is set) */
1266
1267 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t0));
1268 CY_CRYPTO_VU_POP_REG (base);
1269
1270 return CY_CRYPTO_SUCCESS;
1271 }
1272 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
1273
1274
1275 /*******************************************************************************
1276 * Function Name: Cy_Crypto_Core_EC_SM_MulRed
1277 ****************************************************************************//**
1278 *
1279 *
1280 *
1281 * \param base
1282 * The pointer to a Crypto instance.
1283 *
1284 * \param z
1285 * Result.
1286 *
1287 * \param x
1288 * Product.
1289 *
1290 * \param size
1291 * Size.
1292 *
1293 * \return status code. See \ref cy_en_crypto_status_t.
1294 *******************************************************************************/
Cy_Crypto_Core_EC_SM_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)1295 static cy_en_crypto_status_t Cy_Crypto_Core_EC_SM_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size)
1296 {
1297 (void)size; /* Suppress warning */
1298 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1299
1300 switch (eccMode)
1301 {
1302 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
1303 case CY_CRYPTO_ECC_ECP_SECP192R1:
1304 tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P192(base, z, x);
1305 break;
1306 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
1307 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
1308 case CY_CRYPTO_ECC_ECP_SECP224R1:
1309 tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P224(base, z, x);
1310 break;
1311 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
1312 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
1313 case CY_CRYPTO_ECC_ECP_SECP256R1:
1314 tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P256(base, z, x);
1315 break;
1316 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
1317 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
1318 case CY_CRYPTO_ECC_ECP_SECP384R1:
1319 tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P384(base, z, x);
1320 break;
1321 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
1322 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
1323 case CY_CRYPTO_ECC_ECP_SECP521R1:
1324 tmpResult = Cy_Crypto_Core_EC_SM_MUL_Red_P521(base, z, x);
1325 break;
1326 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
1327 default:
1328 /* Unsupported Eliptic Curve ID */
1329 break;
1330 }
1331
1332 return tmpResult;
1333
1334 }
1335
1336
1337 /***************************************************************
1338 * Generic Barrett modular reduction
1339 ***************************************************************/
1340
1341
1342 /*******************************************************************************
1343 * Function Name: Cy_Crypto_Core_EC_Bar_MulRed
1344 ****************************************************************************//**
1345 *
1346 * Barrett multiplication modular reduction.
1347 * t[b-1:0] = z_double >> size
1348 * t = t * VR_BARRETT
1349 * t = t + ((z_double >> size) << size) - for leading '1' Barrett bit.
1350 * t = t >> size
1351 * t = t * mod - r2 (not reduced)
1352 * u = z_double - t - r = r1 - r2 (not reduced)
1353 *
1354 * u = IF (u >= mod) u = u - mod - reduce r using mod
1355 * u = IF (u >= mod) u = u - mod
1356 *
1357 * z = a_double % mod
1358 *
1359 * Leaf function.
1360 *
1361 * \param base
1362 * The pointer to a Crypto instance.
1363 *
1364 * \param z
1365 * Register index for Barrett reduced value.
1366 *
1367 * \param x
1368 * Register index for non reduced value.
1369 *
1370 * \param size
1371 * Bit size.
1372 *
1373 * \return status code. See \ref cy_en_crypto_status_t.
1374 *******************************************************************************/
Cy_Crypto_Core_EC_Bar_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)1375 cy_en_crypto_status_t Cy_Crypto_Core_EC_Bar_MulRed(CRYPTO_Type *base,
1376 uint32_t z,
1377 uint32_t x,
1378 uint32_t size)
1379 {
1380
1381 uint32_t sh = 0u;
1382 uint32_t t1 = 1u;
1383 uint32_t t1_plus2 = 1u;
1384 uint32_t t2_plus2 = 0u;
1385 uint32_t t_double = 2u;
1386 uint32_t z_double = 3u;
1387 uint32_t my_z = 4u;
1388 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1389
1390 CY_CRYPTO_VU_PUSH_REG (base);
1391
1392 CY_CRYPTO_VU_LD_REG (base, my_z, z);
1393 CY_CRYPTO_VU_LD_REG (base, z_double, x);
1394
1395 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t_double, 2u * size);
1396 if(CY_CRYPTO_SUCCESS != tmpResult)
1397 {
1398 return tmpResult;
1399 }
1400
1401 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
1402 if(CY_CRYPTO_SUCCESS != tmpResult)
1403 {
1404 return tmpResult;
1405 }
1406 CY_CRYPTO_VU_SET_REG (base, sh, size, 1u); /* sh = k (k \equiv size) */
1407 CY_CRYPTO_VU_LSR (base, my_z, z_double, sh); /* a/b^{k} (q1*b) */
1408
1409 CY_CRYPTO_VU_UMUL (base, t_double, my_z, VR_BARRETT); /* a/b^{k}*VR_BARRETT (q2*b) */
1410 CY_CRYPTO_VU_LSR (base, t1, t_double, sh); /* q2*b/b^{k} = q2/b^{k-1} */
1411
1412 CY_CRYPTO_VU_UMUL (base, t_double, t1, VR_P);
1413
1414 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1));
1415
1416 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1_plus2, size + 2u);
1417 if(CY_CRYPTO_SUCCESS != tmpResult)
1418 {
1419 return tmpResult;
1420 }
1421
1422 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2_plus2, size + 2u);
1423 if(CY_CRYPTO_SUCCESS != tmpResult)
1424 {
1425 return tmpResult;
1426 }
1427 CY_CRYPTO_VU_SUB (base, t2_plus2, z_double, t_double);
1428
1429 CY_CRYPTO_VU_SUB (base, t1_plus2, t2_plus2, VR_P);
1430 CY_CRYPTO_VU_COND_SWAP_REG (base, CY_CRYPTO_VU_COND_CC, t1_plus2, t2_plus2);
1431
1432 CY_CRYPTO_VU_SUB (base, t2_plus2, t1_plus2, VR_P);
1433 CY_CRYPTO_VU_COND_MOV (base, CY_CRYPTO_VU_COND_CC, my_z, t1_plus2);
1434 CY_CRYPTO_VU_COND_MOV (base, CY_CRYPTO_VU_COND_CS, my_z, t2_plus2);
1435
1436 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t2_plus2) |
1437 CY_CRYPTO_VU_REG_BIT(t1_plus2) |
1438 CY_CRYPTO_VU_REG_BIT(t_double));
1439 CY_CRYPTO_VU_POP_REG (base);
1440
1441 return CY_CRYPTO_SUCCESS;
1442 }
1443
1444
1445 /***************************************************************
1446 * Multiplication reduction algorithm select
1447 ***************************************************************/
1448
1449
1450 /*******************************************************************************
1451 * Function Name: Cy_Crypto_Core_EC_MulRed
1452 ****************************************************************************//**
1453 *
1454 * \param base
1455 * The pointer to a Crypto instance.
1456 *
1457 * \param z
1458 * Result = x mod P = a*b mod P [224 bits].
1459 *
1460 * \param x
1461 * Product = a*b [2*224 bits].
1462 *
1463 * \param size
1464 * Bit size.
1465 *
1466 * \return status code. See \ref cy_en_crypto_status_t.
1467 *******************************************************************************/
Cy_Crypto_Core_EC_MulRed(CRYPTO_Type * base,uint32_t z,uint32_t x,uint32_t size)1468 static cy_en_crypto_status_t Cy_Crypto_Core_EC_MulRed(CRYPTO_Type *base, uint32_t z, uint32_t x, uint32_t size)
1469 {
1470 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1471
1472 switch (mul_red_alg_select)
1473 {
1474 case CY_CRYPTO_NIST_P_CURVE_SPECIFIC_RED_ALG:
1475 /* Curve-specific multiplication reduction algorithms */
1476 tmpResult = Cy_Crypto_Core_EC_CS_MulRed(base, z, x, size);
1477 break;
1478 case CY_CRYPTO_NIST_P_SHIFT_MUL_RED_ALG:
1479 /* Shift-multiply, curve-specific multiplication reduction algorithms */
1480 tmpResult = Cy_Crypto_Core_EC_SM_MulRed(base, z, x, size);
1481 break;
1482 default:
1483 /* Generic Barrett modular reduction */
1484 tmpResult = Cy_Crypto_Core_EC_Bar_MulRed(base, z, x, size);
1485 break;
1486 }
1487
1488 return tmpResult;
1489 }
1490
1491
1492 /*******************************************************************************
1493 * Function Name: Cy_Crypto_Core_EC_MulMod
1494 ****************************************************************************//**
1495 *
1496 * Modular multiplication in GF(VR_P).
1497 * Leaf function.
1498 *
1499 * \param base
1500 * The pointer to a Crypto instance.
1501 *
1502 * \param z
1503 * Result = a * b % mod. Register index for product value.
1504 *
1505 * \param a
1506 * Register index for multiplicand value.
1507 *
1508 * \param b
1509 * Register index for multiplier value.
1510 *
1511 * \param size
1512 * Bit size.
1513 *
1514 * \return status code. See \ref cy_en_crypto_status_t.
1515 *******************************************************************************/
Cy_Crypto_Core_EC_MulMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b,uint32_t size)1516 cy_en_crypto_status_t Cy_Crypto_Core_EC_MulMod( CRYPTO_Type *base,
1517 uint32_t z,
1518 uint32_t a,
1519 uint32_t b,
1520 uint32_t size)
1521 {
1522 uint32_t ab_double = 0u;
1523 uint32_t my_z = 1u;
1524 uint32_t my_a = 2u;
1525 uint32_t my_b = 3u;
1526 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1527
1528 CY_CRYPTO_VU_PUSH_REG (base);
1529
1530 CY_CRYPTO_VU_LD_REG(base, my_z, z);
1531 CY_CRYPTO_VU_LD_REG(base, my_a, a);
1532 CY_CRYPTO_VU_LD_REG(base, my_b, b);
1533
1534 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, ab_double, 2u * size);
1535 if(CY_CRYPTO_SUCCESS != tmpResult)
1536 {
1537 return tmpResult;
1538 }
1539 CY_CRYPTO_VU_UMUL (base, ab_double, my_a, my_b);
1540 Cy_Crypto_Core_Vu_WaitForComplete(base);
1541
1542 /* Modular Reduction: Barrett reduction or curve-specific or shift-multiply */
1543 tmpResult = Cy_Crypto_Core_EC_MulRed(base, my_z, ab_double, size);
1544 if(CY_CRYPTO_SUCCESS != tmpResult)
1545 {
1546 return tmpResult;
1547 }
1548 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(ab_double));
1549
1550 CY_CRYPTO_VU_POP_REG (base);
1551
1552 return CY_CRYPTO_SUCCESS;
1553 }
1554
1555
1556 /*******************************************************************************
1557 * Function Name: Cy_Crypto_Core_EC_AddMod
1558 ****************************************************************************//**
1559 *
1560 * Modular addition in GF(VR_P).
1561 *
1562 * \param base
1563 * The pointer to a Crypto instance.
1564 *
1565 * \param z
1566 * Result = a + b % mod. Register index for sum value
1567 *
1568 * \param a
1569 * Register index for augend a value.
1570 *
1571 * \param b
1572 * Register index for addend b value.
1573 *
1574 *******************************************************************************/
Cy_Crypto_Core_EC_AddMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b)1575 void Cy_Crypto_Core_EC_AddMod( CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t b)
1576 {
1577 CY_CRYPTO_VU_ADD (base, z, a, b); /* C = (sum >= 2^n) */
1578 CY_CRYPTO_VU_COND_CMP_SUB (base, CY_CRYPTO_VU_COND_CC, z, VR_P); /* C = (sum >= mod) */
1579 CY_CRYPTO_VU_COND_SUB (base, CY_CRYPTO_VU_COND_CS, z, z, VR_P);
1580 }
1581
1582
1583 /*******************************************************************************
1584 * Function Name: Cy_Crypto_Core_EC_SubMod
1585 ****************************************************************************//**
1586 *
1587 * Modular subtraction in GF(VR_P).
1588 *
1589 * \param base
1590 * The pointer to a Crypto instance.
1591 *
1592 * \param z
1593 * Result = a - b % mod. Register index for difference value.
1594 *
1595 * \param a
1596 * Register index for minuend a value.
1597 *
1598 * \param b
1599 * RRegister index for subtrahend b value.
1600 *
1601 *******************************************************************************/
Cy_Crypto_Core_EC_SubMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b)1602 void Cy_Crypto_Core_EC_SubMod( CRYPTO_Type *base, uint32_t z, uint32_t a, uint32_t b)
1603 {
1604 CY_CRYPTO_VU_SUB (base, z, a, b); /* C = (a >= b) */
1605 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_CC, z, z, VR_P);
1606 }
1607
1608
1609 /*******************************************************************************
1610 * Function Name: Cy_Crypto_Core_EC_HalfMod
1611 ****************************************************************************//**
1612 *
1613 * Modular halving in GF(VR_P).
1614 * Leaf function.
1615 *
1616 * \param base
1617 * The pointer to a Crypto instance.
1618 *
1619 * \param z
1620 * Result = a / 2 % mod. Register index for result value.
1621 *
1622 * \param a
1623 * Register index for value to be halved.
1624 *
1625 *******************************************************************************/
Cy_Crypto_Core_EC_HalfMod(CRYPTO_Type * base,uint32_t z,uint32_t a)1626 void Cy_Crypto_Core_EC_HalfMod( CRYPTO_Type *base, uint32_t z, uint32_t a)
1627 {
1628 CY_CRYPTO_VU_TST (base, a);
1629 CY_CRYPTO_VU_COND_ADD (base, CY_CRYPTO_VU_COND_ODD, a, a, VR_P);
1630 CY_CRYPTO_VU_LSR1_WITH_CARRY (base, z, a);
1631 }
1632
1633
1634 /*******************************************************************************
1635 * Function Name: Cy_Crypto_Core_EC_SquareMod
1636 ****************************************************************************//**
1637 *
1638 * Modular squaring in GF(VR_P).
1639 *
1640 * \param base
1641 * The pointer to a Crypto instance.
1642 *
1643 * \param z
1644 * Result = a * a % mod. Register index for product value.
1645 *
1646 * \param a
1647 * Register index for multiplicand and multiplier value.
1648 *
1649 * \param size
1650 * Bit size.
1651 *
1652 * \return status code. See \ref cy_en_crypto_status_t.
1653 *******************************************************************************/
Cy_Crypto_Core_EC_SquareMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t size)1654 cy_en_crypto_status_t Cy_Crypto_Core_EC_SquareMod( CRYPTO_Type *base,
1655 uint32_t z,
1656 uint32_t a,
1657 uint32_t size)
1658 {
1659 return Cy_Crypto_Core_EC_MulMod( base, z, a, a, size);
1660 }
1661
1662
1663 /*******************************************************************************
1664 * Function Name: Cy_Crypto_Core_EC_DivMod
1665 ****************************************************************************//**
1666 *
1667 * Modular division in GF(VR_P).
1668 * This algorithm works when "dividend" and "divisor" are relatively prime,
1669 * Reference: "From Euclid's GCD to Montgomery Multiplication to the Great Divide",
1670 * S.C. Schantz
1671 *
1672 * \param base
1673 * The pointer to a Crypto instance.
1674 *
1675 * \param z
1676 * Result = a / b % mod. Register index for quotient value.
1677 *
1678 * \param a
1679 * Register index for dividend value.
1680 *
1681 * \param b
1682 * Register index for divisor value.
1683 *
1684 * \param size
1685 * Bit size.
1686 *
1687 * \return status code. See \ref cy_en_crypto_status_t.
1688 *******************************************************************************/
Cy_Crypto_Core_EC_DivMod(CRYPTO_Type * base,uint32_t z,uint32_t a,uint32_t b,uint32_t size)1689 cy_en_crypto_status_t Cy_Crypto_Core_EC_DivMod( CRYPTO_Type *base,
1690 uint32_t z,
1691 uint32_t a,
1692 uint32_t b,
1693 uint32_t size)
1694 {
1695 uint32_t my_dividend = 7u;
1696 uint32_t my_divisor = 8u;
1697 uint32_t my_a = 9u;
1698 uint32_t my_b = 10u;
1699 uint32_t my_u = 11u;
1700 uint32_t my_v = 12u;
1701 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1702
1703 uint32_t zero;
1704 uint32_t carry;
1705 uint32_t a_even;
1706 uint32_t b_even;
1707
1708 uint32_t status0;
1709 uint32_t status1;
1710 uint32_t status2;
1711
1712 CY_CRYPTO_VU_PUSH_REG (base);
1713
1714 CY_CRYPTO_VU_LD_REG(base, my_dividend, a);
1715 CY_CRYPTO_VU_LD_REG(base, my_divisor, b);
1716 CY_CRYPTO_VU_LD_REG(base, my_u, z);
1717
1718 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_a, size);
1719 if(CY_CRYPTO_SUCCESS != tmpResult)
1720 {
1721 return tmpResult;
1722 }
1723
1724 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_b, size);
1725 if(CY_CRYPTO_SUCCESS != tmpResult)
1726 {
1727 return tmpResult;
1728 }
1729
1730 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_v, size);
1731 if(CY_CRYPTO_SUCCESS != tmpResult)
1732 {
1733 return tmpResult;
1734 }
1735
1736 CY_CRYPTO_VU_MOV (base, my_a, my_divisor);
1737 CY_CRYPTO_VU_MOV (base, my_b, VR_P);
1738 CY_CRYPTO_VU_MOV (base, my_u, my_dividend);
1739
1740 CY_CRYPTO_VU_SET_TO_ZERO (base, my_v);
1741
1742 while (true)
1743 {
1744 CY_CRYPTO_VU_CMP_SUB (base, my_a, my_b);
1745 status0 = Cy_Crypto_Core_Vu_StatusRead(base);
1746
1747 CY_CRYPTO_VU_TST (base, my_a);
1748 status1 = Cy_Crypto_Core_Vu_StatusRead(base);
1749
1750 CY_CRYPTO_VU_TST (base, my_b);
1751 status2 = Cy_Crypto_Core_Vu_StatusRead(base);
1752
1753 zero = status0 & CY_CRYPTO_VU_STATUS_ZERO_BIT; /* a == b */
1754 carry = status0 & CY_CRYPTO_VU_STATUS_CARRY_BIT; /* a >= b */
1755 a_even = status1 & CY_CRYPTO_VU_STATUS_EVEN_BIT;
1756 b_even = status2 & CY_CRYPTO_VU_STATUS_EVEN_BIT;
1757
1758 if (0u != zero)
1759 {
1760 break;
1761 }
1762
1763 if (0u != a_even)
1764 {
1765 CY_CRYPTO_VU_LSR1 (base, my_a, my_a);
1766 Cy_Crypto_Core_EC_HalfMod( base, my_u, my_u);
1767 }
1768 else if (0u != b_even)
1769 {
1770 CY_CRYPTO_VU_LSR1 (base, my_b, my_b);
1771 Cy_Crypto_Core_EC_HalfMod( base, my_v, my_v);
1772 }
1773 else if (0u != carry)
1774 { /* (a >= b) */
1775 CY_CRYPTO_VU_SUB (base, my_a, my_a, my_b);
1776 CY_CRYPTO_VU_LSR1 (base, my_a, my_a);
1777
1778 Cy_Crypto_Core_EC_SubMod( base, my_u, my_u, my_v);
1779 Cy_Crypto_Core_EC_HalfMod( base, my_u, my_u);
1780 }
1781 else
1782 {
1783 CY_CRYPTO_VU_SUB (base, my_b, my_b, my_a);
1784 CY_CRYPTO_VU_LSR1 (base, my_b, my_b);
1785
1786 Cy_Crypto_Core_EC_SubMod( base, my_v, my_v, my_u);
1787 Cy_Crypto_Core_EC_HalfMod( base, my_v, my_v);
1788 }
1789 }
1790
1791 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(my_a) | CY_CRYPTO_VU_REG_BIT(my_b) | CY_CRYPTO_VU_REG_BIT(my_v));
1792
1793 CY_CRYPTO_VU_POP_REG (base);
1794
1795 return CY_CRYPTO_SUCCESS;
1796 }
1797
1798
1799 /*******************************************************************************
1800 * Function Name: Cy_Crypto_Core_JacobianTransform
1801 ****************************************************************************//**
1802 *
1803 * Transformation from affine coordinates to Jacobian projective coordinates in GF(VR_P).
1804 *
1805 * \param base
1806 * The pointer to a Crypto instance.
1807 *
1808 * \param s_x
1809 * Register index for affine X coordinate and Jacobian projective X coordinate.
1810 *
1811 * \param s_y
1812 * Register index for affine Y coordinate and Jacobian projective Y coordinate.
1813 *
1814 * \param s_z
1815 * Register index for Jacobian projective Z coordinate.
1816 *
1817 *******************************************************************************/
Cy_Crypto_Core_JacobianTransform(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z)1818 void Cy_Crypto_Core_JacobianTransform(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t s_z)
1819 {
1820 (void)s_x; /* Suppress warning */
1821 (void)s_y; /* Suppress warning */
1822 CY_CRYPTO_VU_SET_TO_ONE (base, s_z);
1823 }
1824
1825
1826 /*******************************************************************************
1827 * Function Name: Cy_Crypto_Core_JacobianInvTransform
1828 ****************************************************************************//**
1829 *
1830 * Transformation from Jacobian projective coordinates to affine coordinates in GF(VR_P).
1831 * (s_x, s_y, s_z) -> (p_x, p_y), where p_x = s_x/s_z^2, p_y = s_y/s_z^3
1832 *
1833 * \param base
1834 * The pointer to a Crypto instance.
1835 *
1836 * \param s_x
1837 * Register index for affine X coordinate and Jacobian projective X coordinate.
1838 *
1839 * \param s_y
1840 * Register index for affine Y coordinate and Jacobian projective Y coordinate.
1841 *
1842 * \param s_z
1843 * Register index for Jacobian projective Z coordinate.
1844 *
1845 * \param size
1846 * Bit size.
1847 *
1848 * \return status code. See \ref cy_en_crypto_status_t.
1849 *******************************************************************************/
Cy_Crypto_Core_JacobianInvTransform(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t size)1850 cy_en_crypto_status_t Cy_Crypto_Core_JacobianInvTransform(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t s_z, uint32_t size)
1851 {
1852
1853 uint32_t t1 = 7u;
1854 uint32_t t2 = 8u;
1855 uint32_t t3 = 9u;
1856 uint32_t my_s_x = 10u;
1857 uint32_t my_s_y = 11u;
1858 uint32_t my_s_z = 12u;
1859 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1860
1861 CY_CRYPTO_VU_PUSH_REG (base);
1862
1863 CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
1864 CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
1865 CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
1866
1867 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
1868 if(CY_CRYPTO_SUCCESS != tmpResult)
1869 {
1870 return tmpResult;
1871 }
1872
1873 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, size);
1874 if(CY_CRYPTO_SUCCESS != tmpResult)
1875 {
1876 return tmpResult;
1877 }
1878
1879 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, size);
1880 if(CY_CRYPTO_SUCCESS != tmpResult)
1881 {
1882 return tmpResult;
1883 }
1884
1885 CY_CRYPTO_VU_SET_TO_ONE (base, t1); /* t1 = 1 */
1886
1887 tmpResult = Cy_Crypto_Core_EC_DivMod( base, t2, t1, my_s_z, size); /* t2 = 1/Z */
1888 if(CY_CRYPTO_SUCCESS != tmpResult)
1889 {
1890 return tmpResult;
1891 }
1892
1893 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t1, t2, size); /* t1 = 1/Z^2 */
1894 if(CY_CRYPTO_SUCCESS != tmpResult)
1895 {
1896 return tmpResult;
1897 }
1898
1899 tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_x, my_s_x, t1, size); /* my_s_x = X/Z^2 */
1900 if(CY_CRYPTO_SUCCESS != tmpResult)
1901 {
1902 return tmpResult;
1903 }
1904
1905 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t3, my_s_y, t1, size); /* t3 = Y/Z^2 */
1906 if(CY_CRYPTO_SUCCESS != tmpResult)
1907 {
1908 return tmpResult;
1909 }
1910
1911 tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_y, t3, t2, size); /* my_s_y = Y/Z^3 */
1912 if(CY_CRYPTO_SUCCESS != tmpResult)
1913 {
1914 return tmpResult;
1915 }
1916
1917 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2) | CY_CRYPTO_VU_REG_BIT(t3));
1918
1919 CY_CRYPTO_VU_POP_REG (base);
1920
1921 return CY_CRYPTO_SUCCESS;
1922 }
1923
1924
1925 /*******************************************************************************
1926 * Function Name: Cy_Crypto_Core_JacobianEcAdd
1927 ****************************************************************************//**
1928 *
1929 * Elliptic curve point addition on mixed Jacobian projective (s) / affine (t) coordinates in GF(VR_P).
1930 * Reference: "fast and regular algorithms for scalar multiplication over elliptic curves", M. Rivain.
1931 * Upper case register variables refer to Jacobian projective coordinate values.
1932 * Lower case register variables refer to affine coordinate values.
1933 *
1934 * \param base
1935 * The pointer to a Crypto instance.
1936 *
1937 * \param s_x
1938 * Register index for Jacobian projective X coordinate.
1939 *
1940 * \param s_y
1941 * Register index for Jacobian projective Y coordinate.
1942 *
1943 * \param s_z
1944 * Register index for Jacobian projective Z coordinate.
1945 *
1946 * \param t_x
1947 * Register index for affine X coordinate.
1948 *
1949 * \param t_y
1950 * Register index for affine Y coordinate.
1951 *
1952 * \param size
1953 * Bit size.
1954 *
1955 * \return status code. See \ref cy_en_crypto_status_t.
1956 *******************************************************************************/
Cy_Crypto_Core_JacobianEcAdd(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t t_x,uint32_t t_y,uint32_t size)1957 cy_en_crypto_status_t Cy_Crypto_Core_JacobianEcAdd(CRYPTO_Type *base,
1958 uint32_t s_x,
1959 uint32_t s_y,
1960 uint32_t s_z,
1961 uint32_t t_x,
1962 uint32_t t_y,
1963 uint32_t size
1964 )
1965 {
1966
1967 uint32_t t6 = 4u;
1968 uint32_t t7 = 5u;
1969 uint32_t t8 = 6u;
1970 uint32_t t9 = 7u;
1971 uint32_t my_s_x = 8u;
1972 uint32_t my_s_y = 9u;
1973 uint32_t my_s_z = 10u;
1974 uint32_t my_t_x = 11u;
1975 uint32_t my_t_y = 12u;
1976 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
1977
1978 CY_CRYPTO_VU_PUSH_REG (base);
1979
1980 CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
1981 CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
1982 CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
1983 CY_CRYPTO_VU_LD_REG(base, my_t_x, t_x);
1984 CY_CRYPTO_VU_LD_REG(base, my_t_y, t_y);
1985
1986 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t6, size);
1987 if(CY_CRYPTO_SUCCESS != tmpResult)
1988 {
1989 return tmpResult;
1990 }
1991
1992 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t7, size);
1993 if(CY_CRYPTO_SUCCESS != tmpResult)
1994 {
1995 return tmpResult;
1996 }
1997
1998 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t8, size);
1999 if(CY_CRYPTO_SUCCESS != tmpResult)
2000 {
2001 return tmpResult;
2002 }
2003
2004 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t9, size);
2005 if(CY_CRYPTO_SUCCESS != tmpResult)
2006 {
2007 return tmpResult;
2008 }
2009
2010 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t6, my_s_z, size); /* t6 = ZZ */
2011 if(CY_CRYPTO_SUCCESS != tmpResult)
2012 {
2013 return tmpResult;
2014 }
2015
2016 tmpResult =Cy_Crypto_Core_EC_MulMod( base, t8, my_t_x, t6, size); /* t8 = xZZ = B */
2017 if(CY_CRYPTO_SUCCESS != tmpResult)
2018 {
2019 return tmpResult;
2020 }
2021
2022 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t7, my_t_y, my_s_z, size); /* t7 = yZ */
2023 if(CY_CRYPTO_SUCCESS != tmpResult)
2024 {
2025 return tmpResult;
2026 }
2027 Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, t8); /* my_s_x = X - B = E */
2028
2029 tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_z, my_s_x, my_s_z, size); /* my_s_z = E*Z = Z3 */
2030 if(CY_CRYPTO_SUCCESS != tmpResult)
2031 {
2032 return tmpResult;
2033 }
2034
2035 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t9, t7, t6, size); /* t9 = yZZZ = D */
2036 if(CY_CRYPTO_SUCCESS != tmpResult)
2037 {
2038 return tmpResult;
2039 }
2040
2041 Cy_Crypto_Core_EC_SubMod( base, my_s_y, my_s_y, t9); /* my_s_y = Y - D = F */
2042 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t6, my_s_x, size); /* t6 = EE */
2043 if(CY_CRYPTO_SUCCESS != tmpResult)
2044 {
2045 return tmpResult;
2046 }
2047
2048 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t7, t8, t6, size); /* t7 = B*EE */
2049 if(CY_CRYPTO_SUCCESS != tmpResult)
2050 {
2051 return tmpResult;
2052 }
2053
2054 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t8, t6, my_s_x, size); /* t8 = EEE */
2055 if(CY_CRYPTO_SUCCESS != tmpResult)
2056 {
2057 return tmpResult;
2058 }
2059
2060 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t6, t9, t8, size); /* t6 = D*EEE */
2061 if(CY_CRYPTO_SUCCESS != tmpResult)
2062 {
2063 return tmpResult;
2064 }
2065
2066 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, my_s_x, my_s_y, size); /* my_s_x = FF */
2067 if(CY_CRYPTO_SUCCESS != tmpResult)
2068 {
2069 return tmpResult;
2070 }
2071 Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, t8); /* my_s_x = FF - EEE */
2072 Cy_Crypto_Core_EC_AddMod( base, t9, t7, t7); /* t9 = 2*B*EE */
2073 Cy_Crypto_Core_EC_SubMod( base, my_s_x, my_s_x, t9); /* my_s_x = FF - EEE - 2*B*EE = X3 */
2074 Cy_Crypto_Core_EC_SubMod( base, t7, t7, my_s_x); /* t7 = B*EE - X3 */
2075 tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_y, my_s_y, t7, size); /* my_s_y = F*(B*EE - X3) */
2076 if(CY_CRYPTO_SUCCESS != tmpResult)
2077 {
2078 return tmpResult;
2079 }
2080
2081 Cy_Crypto_Core_EC_SubMod( base, my_s_y, my_s_y, t6); /* my_s_y = F*(3*B*EE - FF + EEE) - D*EEE = Y3 */
2082
2083 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t6) | CY_CRYPTO_VU_REG_BIT(t7) |
2084 CY_CRYPTO_VU_REG_BIT(t8) | CY_CRYPTO_VU_REG_BIT(t9));
2085
2086 CY_CRYPTO_VU_POP_REG (base);
2087
2088 return CY_CRYPTO_SUCCESS;
2089 }
2090
2091
2092 /*******************************************************************************
2093 * Function Name: Cy_Crypto_Core_JacobianEcDouble
2094 ****************************************************************************//**
2095 *
2096 * Elliptic curve point doubling on Jacobian projective coordinates in GF(VR_P).
2097 *
2098 * \param base
2099 * The pointer to a Crypto instance.
2100 *
2101 * \param s_x
2102 * Register index for Jacobian projective X coordinate.
2103 *
2104 * \param s_y
2105 * Register index for Jacobian projective Y coordinate.
2106 *
2107 * \param s_z
2108 * Register index for Jacobian projective Z coordinate.
2109 *
2110 * \param size
2111 * Bit size.
2112 *
2113 * \return status code. See \ref cy_en_crypto_status_t.
2114 *******************************************************************************/
Cy_Crypto_Core_JacobianEcDouble(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t s_z,uint32_t size)2115 cy_en_crypto_status_t Cy_Crypto_Core_JacobianEcDouble(CRYPTO_Type *base,
2116 uint32_t s_x,
2117 uint32_t s_y,
2118 uint32_t s_z,
2119 uint32_t size
2120 )
2121 /* 4M + 4S + 10A */
2122 {
2123 uint32_t t1 = 1u;
2124 uint32_t t2 = 2u;
2125 uint32_t t3 = 3u;
2126 uint32_t t4 = 4u;
2127 uint32_t my_s_x = 5u;
2128 uint32_t my_s_y = 6u;
2129 uint32_t my_s_z = 7u;
2130 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2131
2132 CY_CRYPTO_VU_PUSH_REG (base);
2133
2134 CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
2135 CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
2136 CY_CRYPTO_VU_LD_REG(base, my_s_z, s_z);
2137
2138 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t1, size);
2139 if(CY_CRYPTO_SUCCESS != tmpResult)
2140 {
2141 return tmpResult;
2142 }
2143
2144 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t2, size);
2145 if(CY_CRYPTO_SUCCESS != tmpResult)
2146 {
2147 return tmpResult;
2148 }
2149
2150 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t3, size);
2151 if(CY_CRYPTO_SUCCESS != tmpResult)
2152 {
2153 return tmpResult;
2154 }
2155
2156 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t4, size);
2157 if(CY_CRYPTO_SUCCESS != tmpResult)
2158 {
2159 return tmpResult;
2160 }
2161
2162 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t4, my_s_y, size); /* t4 = Y^2 */
2163 if(CY_CRYPTO_SUCCESS != tmpResult)
2164 {
2165 return tmpResult;
2166 }
2167
2168 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t3, my_s_z, size); /* t3 = Z^2 */
2169 if(CY_CRYPTO_SUCCESS != tmpResult)
2170 {
2171 return tmpResult;
2172 }
2173
2174 tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_z, my_s_y, my_s_z, size); /* my_s_z = Y*Z */
2175 if(CY_CRYPTO_SUCCESS != tmpResult)
2176 {
2177 return tmpResult;
2178 }
2179
2180 tmpResult = Cy_Crypto_Core_EC_MulMod( base, my_s_y, my_s_x, t4, size); /* my_s_y = X*Y^2 = A */
2181 if(CY_CRYPTO_SUCCESS != tmpResult)
2182 {
2183 return tmpResult;
2184 }
2185 Cy_Crypto_Core_EC_AddMod( base, my_s_x, my_s_x, t3); /* my_s_x = X + Z^2 */
2186 Cy_Crypto_Core_EC_AddMod( base, t3, t3, t3); /* t3 = 2*Z^2 */
2187 Cy_Crypto_Core_EC_SubMod( base, t3, my_s_x, t3); /* t3 = (X + Z^2) - 2*Z^2 = X - Z^2 */
2188
2189 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t1, my_s_x, t3, size); /* t1 = (X + Z^2) * (X - Z^2) = X^2 - Z^4 */
2190 if(CY_CRYPTO_SUCCESS != tmpResult)
2191 {
2192 return tmpResult;
2193 }
2194
2195 Cy_Crypto_Core_EC_AddMod( base, t3, t1, t1); /* t3 = 2*(X^2 - Z^4) */
2196 Cy_Crypto_Core_EC_AddMod( base, t1, t1, t3); /* t1 = 3*(X^2 - Z^4) */
2197 Cy_Crypto_Core_EC_HalfMod( base, t1, t1); /* t1 = 3/2*(X^2 - Z^4) = B */
2198 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t3, t1, size); /* t3 = 9/4*(X^2 - Z^4) = B^2 */
2199 if(CY_CRYPTO_SUCCESS != tmpResult)
2200 {
2201 return tmpResult;
2202 }
2203
2204 Cy_Crypto_Core_EC_SubMod( base, t3, t3, my_s_y); /* t3 = B^2 - A */
2205 Cy_Crypto_Core_EC_SubMod( base, my_s_x, t3, my_s_y); /* my_s_x = B^2 - 2*A */
2206 Cy_Crypto_Core_EC_SubMod( base, my_s_y, my_s_y, my_s_x); /* my_s_y = A - (B^2 - 2*A) = 3*A - B^2 */
2207
2208 tmpResult = Cy_Crypto_Core_EC_MulMod( base, t2, t1, my_s_y, size); /* t2 = B*(3*A - B^2) */
2209 if(CY_CRYPTO_SUCCESS != tmpResult)
2210 {
2211 return tmpResult;
2212 }
2213
2214 tmpResult = Cy_Crypto_Core_EC_SquareMod( base, t1, t4, size); /* t1 = Y^4 */
2215 if(CY_CRYPTO_SUCCESS != tmpResult)
2216 {
2217 return tmpResult;
2218 }
2219
2220 Cy_Crypto_Core_EC_SubMod( base, my_s_y, t2, t1); /* my_s_y = B*(3*A - B^2) - Y^4 */
2221
2222 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(t1) | CY_CRYPTO_VU_REG_BIT(t2) |
2223 CY_CRYPTO_VU_REG_BIT(t3) | CY_CRYPTO_VU_REG_BIT(t4));
2224 CY_CRYPTO_VU_POP_REG (base);
2225
2226
2227 return CY_CRYPTO_SUCCESS;
2228 }
2229
2230
2231 /*******************************************************************************
2232 * Function Name: Cy_Crypto_Core_JacobianEcScalarMul
2233 ****************************************************************************//**
2234 *
2235 * Elliptic curve point multiplication on Jacobian projective coordinates in GF(VR_P).
2236 *
2237 * \param base
2238 * The pointer to a Crypto instance.
2239 *
2240 * \param s_x
2241 * Register index for affine X coordinate.
2242 *
2243 * \param s_y
2244 * Register index for affine Y coordinate.
2245 *
2246 * \param d
2247 * Register index for multiplication/exponentiation value.
2248 *
2249 * \param size
2250 * Bit size.
2251 *
2252 * \return status code. See \ref cy_en_crypto_status_t.
2253 *******************************************************************************/
Cy_Crypto_Core_JacobianEcScalarMul(CRYPTO_Type * base,uint32_t s_x,uint32_t s_y,uint32_t d,uint32_t size)2254 cy_en_crypto_status_t Cy_Crypto_Core_JacobianEcScalarMul(CRYPTO_Type *base, uint32_t s_x, uint32_t s_y, uint32_t d, uint32_t size)
2255 {
2256 int32_t i;
2257 uint32_t status;
2258 uint32_t carry;
2259 uint16_t clsame;
2260
2261 uint32_t clr = 5u;
2262 uint32_t t = 6u;
2263 uint32_t my_s_x = 7u;
2264 uint32_t my_s_y = 8u;
2265 uint32_t my_s_z = 9u;
2266 uint32_t my_t_x = 10u;
2267 uint32_t my_t_y = 11u;
2268 uint32_t my_d = 12u;
2269 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2270
2271 CY_CRYPTO_VU_PUSH_REG (base);
2272
2273 CY_CRYPTO_VU_LD_REG(base, my_s_x, s_x);
2274 CY_CRYPTO_VU_LD_REG(base, my_s_y, s_y);
2275 CY_CRYPTO_VU_LD_REG(base, my_d, d);
2276
2277 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, clr, size);
2278 if(CY_CRYPTO_SUCCESS != tmpResult)
2279 {
2280 return tmpResult;
2281 }
2282
2283 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, t, size);
2284 if(CY_CRYPTO_SUCCESS != tmpResult)
2285 {
2286 return tmpResult;
2287 }
2288
2289 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_s_z, size);
2290 if(CY_CRYPTO_SUCCESS != tmpResult)
2291 {
2292 return tmpResult;
2293 }
2294
2295 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_t_x, size);
2296 if(CY_CRYPTO_SUCCESS != tmpResult)
2297 {
2298 return tmpResult;
2299 }
2300
2301 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, my_t_y, size);
2302 if(CY_CRYPTO_SUCCESS != tmpResult)
2303 {
2304 return tmpResult;
2305 }
2306
2307 /* my_t_x has the same initial value of my_s_x, but does not point to the
2308 * same address in memory as my_s_x, i.e. different value after point doubling
2309 * my_t_x and my_t_y do not change from (original Jacobian projective coordinates of)
2310 * original base point
2311 */
2312 CY_CRYPTO_VU_MOV (base, my_t_x, my_s_x);
2313 CY_CRYPTO_VU_MOV (base, my_t_y, my_s_y);
2314
2315 /* Affine-to-Jacobian Transform. */
2316 CY_CRYPTO_VU_SET_TO_ONE (base, my_s_z);
2317
2318 /* EC scalar multiplication (irregular) operation. */
2319 CY_CRYPTO_VU_SET_TO_ZERO (base, clr);
2320 CY_CRYPTO_VU_CLSAME (base, t, my_d, clr);
2321
2322 /* This is needed, otherwise clsame is wrong */
2323 Cy_Crypto_Core_Vu_WaitForComplete(base);
2324
2325 clsame = Cy_Crypto_Core_Vu_RegDataPtrRead (base, t);
2326
2327 CY_CRYPTO_VU_LSL (base, my_d, my_d, t); /* Get rid of leading '0's */
2328 CY_CRYPTO_VU_LSL1 (base, my_d, my_d); /* Get rid of leading '1' */
2329
2330 /* Binary left-to-right algorithm
2331 * Perform point addition and point doubling to implement scalar multiplication
2332 * Scan the bits of the scalar from left to right; perform point doubling for each bit,
2333 * and perform point addition when the bit is set.
2334 * Carry set if current bit is equal to 1 (hence, perform point addition - point
2335 * doubling is always performed)
2336 */
2337 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to int32_t because result of composite expression can be negative');
2338 for (i = 0; i < ((int32_t)(size - clsame - 1u)); i++)
2339 {
2340 /* Carry set if current bit is equal to 1 (hence, perform point addition - point
2341 * doubling is always performed)
2342 */
2343 CY_CRYPTO_VU_LSL1 (base, my_d, my_d);
2344 status = Cy_Crypto_Core_Vu_StatusRead(base);
2345
2346 carry = status & CY_CRYPTO_VU_STATUS_CARRY_BIT;
2347
2348 tmpResult = Cy_Crypto_Core_JacobianEcDouble (base, my_s_x, my_s_y, my_s_z, size);
2349
2350 if(CY_CRYPTO_SUCCESS != tmpResult)
2351 {
2352 return tmpResult;
2353 }
2354
2355 if (carry != 0U)
2356 {
2357 tmpResult = Cy_Crypto_Core_JacobianEcAdd (base, my_s_x, my_s_y, my_s_z, my_t_x, my_t_y, size);
2358
2359 if(CY_CRYPTO_SUCCESS != tmpResult)
2360 {
2361 return tmpResult;
2362 }
2363 }
2364 }
2365
2366 /* Inverse transform */
2367 tmpResult = Cy_Crypto_Core_JacobianInvTransform(base, my_s_x, my_s_y, my_s_z, size);
2368 if(CY_CRYPTO_SUCCESS != tmpResult)
2369 {
2370 return tmpResult;
2371 }
2372
2373 CY_CRYPTO_VU_FREE_MEM (base, CY_CRYPTO_VU_REG_BIT(my_s_z) |
2374 CY_CRYPTO_VU_REG_BIT(my_t_x) | CY_CRYPTO_VU_REG_BIT(my_t_y) |
2375 CY_CRYPTO_VU_REG_BIT(clr) | CY_CRYPTO_VU_REG_BIT(t));
2376
2377 CY_CRYPTO_VU_POP_REG (base);
2378 return CY_CRYPTO_SUCCESS;
2379 }
2380
2381 /***************************************************************
2382 * Test methods
2383 ***************************************************************/
2384
2385
2386 /*******************************************************************************
2387 * Function Name: Cy_Crypto_Core_EC_NistP_SetMode
2388 ****************************************************************************//**
2389 *
2390 * Enable some curve specific features.
2391 *
2392 * \param bitsize
2393 * bitsize of the used NIST P curve.
2394 *
2395 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_SetMode(uint32_t bitsize)2396 void Cy_Crypto_Core_EC_NistP_SetMode(uint32_t bitsize)
2397 {
2398 switch (bitsize)
2399 {
2400 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED)
2401 case CY_CRYPTO_ECC_P192_SIZE:
2402 eccMode = CY_CRYPTO_ECC_ECP_SECP192R1;
2403 break;
2404 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP192R1_ENABLED) */
2405 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED)
2406 case CY_CRYPTO_ECC_P224_SIZE:
2407 eccMode = CY_CRYPTO_ECC_ECP_SECP224R1;
2408 break;
2409 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP224R1_ENABLED) */
2410 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED)
2411 case CY_CRYPTO_ECC_P256_SIZE:
2412 eccMode = CY_CRYPTO_ECC_ECP_SECP256R1;
2413 break;
2414 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP256R1_ENABLED) */
2415 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED)
2416 case CY_CRYPTO_ECC_P384_SIZE:
2417 eccMode = CY_CRYPTO_ECC_ECP_SECP384R1;
2418 break;
2419 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP384R1_ENABLED) */
2420 #if defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED)
2421 case CY_CRYPTO_ECC_P521_SIZE:
2422 eccMode = CY_CRYPTO_ECC_ECP_SECP521R1;
2423 break;
2424 #endif /* defined(CY_CRYPTO_CFG_ECP_DP_SECP521R1_ENABLED) */
2425 default:
2426 eccMode = CY_CRYPTO_ECC_ECP_NONE;
2427 break;
2428 }
2429 }
2430
2431
2432 /*******************************************************************************
2433 * Function Name: Cy_Crypto_Core_EC_NistP_SetRedAlg
2434 ****************************************************************************//**
2435 *
2436 * Select which reduction algorithm has to be used.
2437 *
2438 * \param alg
2439 * one of {CURVE_SPECIFIC_RED_ALG, SHIFT_MUL_RED_ALG, BARRETT_RED_ALG}.
2440 * See \ref cy_en_crypto_ecc_red_mul_algs_t.
2441 *
2442 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_SetRedAlg(cy_en_crypto_ecc_red_mul_algs_t alg)2443 void Cy_Crypto_Core_EC_NistP_SetRedAlg(cy_en_crypto_ecc_red_mul_algs_t alg)
2444 {
2445 mul_red_alg_select = alg;
2446 }
2447
2448
2449 /*******************************************************************************
2450 * Function Name: Cy_Crypto_Core_EC_NistP_PointMul
2451 ****************************************************************************//**
2452 *
2453 * Elliptic curve point multiplication in GF(p).
2454 *
2455 * \param base
2456 * The pointer to a Crypto instance.
2457 *
2458 * \param p_x
2459 * Register index for affine X coordinate of base point.
2460 *
2461 * \param p_y
2462 * Register index for affine Y coordinate of base point.
2463 *
2464 * \param p_d
2465 * Register index for multiplication value.
2466 *
2467 * \param p_order
2468 * Register index for order value..
2469 *
2470 * \param bitsize
2471 * Bit size of the used curve.
2472 *
2473 * \return status code. See \ref cy_en_crypto_status_t.
2474 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_PointMul(CRYPTO_Type * base,uint32_t p_x,uint32_t p_y,uint32_t p_d,uint32_t p_order,uint32_t bitsize)2475 cy_en_crypto_status_t Cy_Crypto_Core_EC_NistP_PointMul(CRYPTO_Type *base, uint32_t p_x, uint32_t p_y, uint32_t p_d, uint32_t p_order, uint32_t bitsize)
2476 {
2477 (void)p_order; /* Suppress warning */
2478 cy_en_crypto_status_t tmpResult = CY_CRYPTO_BAD_PARAMS;
2479
2480 tmpResult = Cy_Crypto_Core_JacobianEcScalarMul (base, p_x, p_y, p_d, bitsize);
2481 Cy_Crypto_Core_Vu_WaitForComplete(base);
2482
2483 return tmpResult;
2484 }
2485
2486
2487 /*******************************************************************************
2488 * Function Name: Cy_Crypto_Core_EC_NistP_PointMultiplication
2489 ****************************************************************************//**
2490 *
2491 * Elliptic curve point multiplication in GF(p).
2492 *
2493 * For CAT1C & CAT1D devices when D-Cache is enabled parameter ecpGX, ecpGY, ecpD, ecpQX & ecpQY must align and end in 32 byte boundary.
2494 *
2495 * \param base
2496 * The pointer to a Crypto instance.
2497 *
2498 * \param curveID
2499 * See \ref cy_en_crypto_ecc_curve_id_t.
2500 *
2501 * \param ecpGX
2502 * Register index for affine X coordinate of base point.
2503 *
2504 * \param ecpGY
2505 * Register index for affine Y coordinate of base point.
2506 *
2507 * \param ecpD
2508 * Register index for multiplication value.
2509 *
2510 * \param ecpQX
2511 * Register index for affine X coordinate of result point.
2512 *
2513 * \param ecpQY
2514 * Register index for affine Y coordinate of result point.
2515 *
2516 * \return status code. See \ref cy_en_crypto_status_t.
2517 *
2518 *******************************************************************************/
Cy_Crypto_Core_EC_NistP_PointMultiplication(CRYPTO_Type * base,cy_en_crypto_ecc_curve_id_t curveID,const uint8_t * ecpGX,const uint8_t * ecpGY,const uint8_t * ecpD,uint8_t * ecpQX,uint8_t * ecpQY)2519 cy_en_crypto_status_t Cy_Crypto_Core_EC_NistP_PointMultiplication(CRYPTO_Type *base,
2520 cy_en_crypto_ecc_curve_id_t curveID,
2521 const uint8_t *ecpGX,
2522 const uint8_t *ecpGY,
2523 const uint8_t *ecpD,
2524 uint8_t *ecpQX,
2525 uint8_t *ecpQY)
2526 {
2527 /* N.b. If using test vectors from "http://point-at-infinity.org/ecc/nisttv",
2528 * the 'k' values on the website are in decimal form, while the (x,y) result
2529 * coordinates are in hexadecimal form
2530 * Input format for 'd' scalar multiplier in this test is in hexadecimal form.
2531 * Hence, convert k_{dec} to d_{hex} for comparison of test values
2532 */
2533
2534 /* Setup additional registers */
2535 uint32_t VR_ORDER = 9u;
2536
2537 const uint8_t *p_polynomial = NULL;
2538 const uint8_t *p_barrett = NULL;
2539
2540 cy_stc_crypto_ecc_dp_type *eccDp = Cy_Crypto_Core_ECC_GetCurveParams(curveID);
2541
2542 cy_en_crypto_status_t tmpResult = CY_CRYPTO_NOT_SUPPORTED;
2543
2544 if (eccDp != NULL)
2545 {
2546 /* Setup curve specific parameters depending on mode */
2547 uint32_t bitsize;
2548
2549 p_polynomial = (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(eccDp->prime);
2550 p_barrett = (uint8_t const *)CY_REMAP_ADDRESS_FOR_CRYPTO(eccDp->barrett_p);
2551 bitsize = eccDp->size;
2552
2553 /* use Barrett reduction algorithm for operations modulo n (order of the base point) */
2554 Cy_Crypto_Core_EC_NistP_SetRedAlg(eccDp->algo);
2555 Cy_Crypto_Core_EC_NistP_SetMode(eccDp->size);
2556
2557 tmpResult = CY_CRYPTO_BAD_PARAMS;
2558
2559 if ((NULL != ecpGX) && (NULL != ecpGY) && (NULL != ecpD) && (NULL != ecpQX) && (NULL != ecpQY))
2560 {
2561 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
2562 /* Flush the cache */
2563 SCB_CleanDCache_by_Addr((volatile void *)ecpGX, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2564 SCB_CleanDCache_by_Addr((volatile void *)ecpGY, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2565 SCB_CleanDCache_by_Addr((volatile void *)ecpD, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2566 #endif
2567 /* Public parameters and characteristics of elliptic curve */
2568 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_D, bitsize); /* Scalar factor */
2569 if(CY_CRYPTO_SUCCESS != tmpResult)
2570 {
2571 return tmpResult;
2572 }
2573
2574 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_X, bitsize);
2575 if(CY_CRYPTO_SUCCESS != tmpResult)
2576 {
2577 return tmpResult;
2578 }
2579
2580 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_S_Y, bitsize);
2581 if(CY_CRYPTO_SUCCESS != tmpResult)
2582 {
2583 return tmpResult;
2584 }
2585
2586 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_P, bitsize);
2587 if(CY_CRYPTO_SUCCESS != tmpResult)
2588 {
2589 return tmpResult;
2590 }
2591
2592 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_BARRETT, bitsize + 1u);
2593 if(CY_CRYPTO_SUCCESS != tmpResult)
2594 {
2595 return tmpResult;
2596 }
2597
2598 tmpResult = CY_CRYPTO_VU_ALLOC_MEM (base, VR_ORDER, bitsize);
2599 if(CY_CRYPTO_SUCCESS != tmpResult)
2600 {
2601 return tmpResult;
2602 }
2603
2604 Cy_Crypto_Core_Vu_SetMemValue (base, VR_P, p_polynomial, bitsize);
2605
2606 /* Preparation (either use precalculated or calculated). */
2607 Cy_Crypto_Core_Vu_SetMemValue (base, VR_BARRETT, p_barrett, bitsize + 1u);
2608
2609 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_X, ecpGX, bitsize);
2610 Cy_Crypto_Core_Vu_SetMemValue (base, VR_S_Y, ecpGY, bitsize);
2611 Cy_Crypto_Core_Vu_SetMemValue (base, VR_D, ecpD, bitsize);
2612
2613 /* ECC calculation: d * G mod p */
2614 tmpResult = Cy_Crypto_Core_EC_NistP_PointMul(base, VR_S_X, VR_S_Y, VR_D, VR_ORDER, bitsize);
2615
2616 if(CY_CRYPTO_SUCCESS != tmpResult)
2617 {
2618 return tmpResult;
2619 }
2620 /* Get result P = (X,Y) = d.G from EC scalar multiplication */
2621 Cy_Crypto_Core_Vu_GetMemValue (base, ecpQX, VR_S_X, bitsize);
2622 Cy_Crypto_Core_Vu_GetMemValue (base, ecpQY, VR_S_Y, bitsize);
2623 #if (((CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)) || CY_CPU_CORTEX_M55)
2624 SCB_InvalidateDCache_by_Addr(ecpQX, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2625 SCB_InvalidateDCache_by_Addr(ecpQY, (int32_t)CY_CRYPTO_BYTE_SIZE_OF_BITS(bitsize));
2626 #endif
2627 /* Free memory */
2628 CY_CRYPTO_VU_FREE_MEM (base,
2629 CY_CRYPTO_VU_REG_BIT(VR_ORDER) |
2630 CY_CRYPTO_VU_REG_BIT(VR_BARRETT) |
2631 CY_CRYPTO_VU_REG_BIT(VR_P) |
2632 CY_CRYPTO_VU_REG_BIT(VR_S_Y) |
2633 CY_CRYPTO_VU_REG_BIT(VR_S_X) |
2634 CY_CRYPTO_VU_REG_BIT(VR_D));
2635
2636 tmpResult = CY_CRYPTO_SUCCESS;
2637 }
2638 }
2639
2640 return tmpResult;
2641 }
2642
2643 #endif /* defined (CY_CRYPTO_CFG_ECP_C) */
2644
2645 #if defined(__cplusplus)
2646 }
2647 #endif
2648
2649 #endif /* CY_IP_MXCRYPTO */
2650
2651
2652 /* [] END OF FILE */
2653