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