1*f0865ec9SKyle Evans /*
2*f0865ec9SKyle Evans * Copyright (C) 2017 - This file is part of libecc project
3*f0865ec9SKyle Evans *
4*f0865ec9SKyle Evans * Authors:
5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com>
6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7*f0865ec9SKyle Evans * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8*f0865ec9SKyle Evans *
9*f0865ec9SKyle Evans * Contributors:
10*f0865ec9SKyle Evans * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11*f0865ec9SKyle Evans * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12*f0865ec9SKyle Evans *
13*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license.
14*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project.
15*f0865ec9SKyle Evans */
16*f0865ec9SKyle Evans #include <libecc/libec.h>
17*f0865ec9SKyle Evans /* We include the printf external dependency for printf output */
18*f0865ec9SKyle Evans #include <libecc/external_deps/print.h>
19*f0865ec9SKyle Evans /* We include the time external dependency for performance measurement */
20*f0865ec9SKyle Evans #include <libecc/external_deps/time.h>
21*f0865ec9SKyle Evans
22*f0865ec9SKyle Evans /* The followin function picks a random Fp element x, where Fp is the
23*f0865ec9SKyle Evans * curve underlying prime field, and computes y in Fp such that:
24*f0865ec9SKyle Evans * y^2 = x^3 + ax + b, where a and b are the input elliptic
25*f0865ec9SKyle Evans * curve parameters.
26*f0865ec9SKyle Evans *
27*f0865ec9SKyle Evans * This means that (x, y) are the affine coordinates of a "random"
28*f0865ec9SKyle Evans * point on our curve. The function then outputs the projective
29*f0865ec9SKyle Evans * coordinates of (x, y), i.e. the triplet (x, y, 1).
30*f0865ec9SKyle Evans * PS: all our operations on points are done with projective coordinates.
31*f0865ec9SKyle Evans *
32*f0865ec9SKyle Evans * Computing y means computing a quadratic residue in Fp, for which we
33*f0865ec9SKyle Evans * use the Tonelli-Shanks algorithm implemented in the Fp source example
34*f0865ec9SKyle Evans * (fp_square_residue.c).
35*f0865ec9SKyle Evans */
36*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int get_random_point_on_curve(ec_params *curve_params, prj_pt *out_point);
get_random_point_on_curve(ec_params * curve_params,prj_pt * out_point)37*f0865ec9SKyle Evans int get_random_point_on_curve(ec_params *curve_params, prj_pt *out_point)
38*f0865ec9SKyle Evans {
39*f0865ec9SKyle Evans nn nn_tmp;
40*f0865ec9SKyle Evans int ret, is_oncurve;
41*f0865ec9SKyle Evans
42*f0865ec9SKyle Evans /* Inside our internal representation, curve_params->ec_curve
43*f0865ec9SKyle Evans * contains the curve coefficients a and b.
44*f0865ec9SKyle Evans * curve_params->ec_fp is the Fp context of the curve.
45*f0865ec9SKyle Evans */
46*f0865ec9SKyle Evans fp x, y, fp_tmp1, fp_tmp2;
47*f0865ec9SKyle Evans fp_ctx_src_t ctx;
48*f0865ec9SKyle Evans
49*f0865ec9SKyle Evans MUST_HAVE((curve_params != NULL), ret, err);
50*f0865ec9SKyle Evans
51*f0865ec9SKyle Evans nn_tmp.magic = WORD(0);
52*f0865ec9SKyle Evans x.magic = y.magic = fp_tmp1.magic = fp_tmp2.magic = WORD(0);
53*f0865ec9SKyle Evans
54*f0865ec9SKyle Evans /* Initialize our x value with the curve Fp context */
55*f0865ec9SKyle Evans ctx = &(curve_params->ec_fp);
56*f0865ec9SKyle Evans
57*f0865ec9SKyle Evans ret = fp_init(&x, ctx); EG(ret, err);
58*f0865ec9SKyle Evans ret = fp_init(&y, ctx); EG(ret, err);
59*f0865ec9SKyle Evans ret = fp_init(&fp_tmp1, ctx); EG(ret, err);
60*f0865ec9SKyle Evans ret = fp_init(&fp_tmp2, ctx); EG(ret, err);
61*f0865ec9SKyle Evans
62*f0865ec9SKyle Evans ret = nn_init(&nn_tmp, 0); EG(ret, err);
63*f0865ec9SKyle Evans ret = nn_set_word_value(&nn_tmp, WORD(3)); EG(ret, err);
64*f0865ec9SKyle Evans while (1) {
65*f0865ec9SKyle Evans /* Get a random Fp */
66*f0865ec9SKyle Evans ret = fp_get_random(&x, ctx); EG(ret, err);
67*f0865ec9SKyle Evans ret = fp_copy(&fp_tmp1, &x); EG(ret, err);
68*f0865ec9SKyle Evans ret = fp_copy(&fp_tmp2, &x); EG(ret, err);
69*f0865ec9SKyle Evans /* Compute x^3 + ax + b */
70*f0865ec9SKyle Evans ret = fp_pow(&fp_tmp1, &fp_tmp1, &nn_tmp); EG(ret, err);
71*f0865ec9SKyle Evans ret = fp_mul(&fp_tmp2, &fp_tmp2, &(curve_params->ec_curve.a)); EG(ret, err);
72*f0865ec9SKyle Evans ret = fp_add(&fp_tmp1, &fp_tmp1, &fp_tmp2); EG(ret, err);
73*f0865ec9SKyle Evans ret = fp_add(&fp_tmp1, &fp_tmp1, &(curve_params->ec_curve.b)); EG(ret, err);
74*f0865ec9SKyle Evans /*
75*f0865ec9SKyle Evans * Get any of the two square roots, corresponding to (x, y)
76*f0865ec9SKyle Evans * and (x, -y) both on the curve. If no square root exist,
77*f0865ec9SKyle Evans * go to next random Fp.
78*f0865ec9SKyle Evans */
79*f0865ec9SKyle Evans if (fp_sqrt(&y, &fp_tmp2, &fp_tmp1) == 0) {
80*f0865ec9SKyle Evans /* Check that we indeed satisfy the curve equation */
81*f0865ec9SKyle Evans ret = is_on_shortw_curve(&x, &y, &(curve_params->ec_curve), &is_oncurve); EG(ret, err);
82*f0865ec9SKyle Evans if (!is_oncurve) {
83*f0865ec9SKyle Evans /* This should not happen ... */
84*f0865ec9SKyle Evans ext_printf("Error: Tonelli-Shanks found a bad "
85*f0865ec9SKyle Evans "solution to curve equation ...\n");
86*f0865ec9SKyle Evans continue;
87*f0865ec9SKyle Evans }
88*f0865ec9SKyle Evans break;
89*f0865ec9SKyle Evans }
90*f0865ec9SKyle Evans }
91*f0865ec9SKyle Evans /* Now initialize our point with the coordinates (x, y, 1) */
92*f0865ec9SKyle Evans ret = fp_one(&fp_tmp1); EG(ret, err);
93*f0865ec9SKyle Evans ret = prj_pt_init_from_coords(out_point, &(curve_params->ec_curve), &x, &y,
94*f0865ec9SKyle Evans &fp_tmp1); EG(ret, err);
95*f0865ec9SKyle Evans
96*f0865ec9SKyle Evans err:
97*f0865ec9SKyle Evans fp_uninit(&x);
98*f0865ec9SKyle Evans fp_uninit(&y);
99*f0865ec9SKyle Evans fp_uninit(&fp_tmp1);
100*f0865ec9SKyle Evans fp_uninit(&fp_tmp2);
101*f0865ec9SKyle Evans nn_uninit(&nn_tmp);
102*f0865ec9SKyle Evans
103*f0865ec9SKyle Evans return ret;
104*f0865ec9SKyle Evans }
105*f0865ec9SKyle Evans
106*f0865ec9SKyle Evans #define PERF_SCALAR_MUL 40
107*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int check_curve(const u8 *curve_name);
check_curve(const u8 * curve_name)108*f0865ec9SKyle Evans int check_curve(const u8 *curve_name)
109*f0865ec9SKyle Evans {
110*f0865ec9SKyle Evans unsigned int i;
111*f0865ec9SKyle Evans u64 t1, t2;
112*f0865ec9SKyle Evans int ret, is_oncurve, isone, iszero;
113*f0865ec9SKyle Evans
114*f0865ec9SKyle Evans nn nn_k;
115*f0865ec9SKyle Evans /* libecc internal structure holding the curve parameters */
116*f0865ec9SKyle Evans ec_params curve_params;
117*f0865ec9SKyle Evans /* libecc internal structure holding projective points on curves */
118*f0865ec9SKyle Evans prj_pt A, B, C, D;
119*f0865ec9SKyle Evans prj_pt TMP;
120*f0865ec9SKyle Evans aff_pt T;
121*f0865ec9SKyle Evans u32 len;
122*f0865ec9SKyle Evans
123*f0865ec9SKyle Evans /* Importing a specific curve parameters from the constant static
124*f0865ec9SKyle Evans * buffers describing it:
125*f0865ec9SKyle Evans * It is possible to import a curves parameters by its name.
126*f0865ec9SKyle Evans */
127*f0865ec9SKyle Evans const ec_str_params *the_curve_const_parameters;
128*f0865ec9SKyle Evans
129*f0865ec9SKyle Evans nn_k.magic = WORD(0);
130*f0865ec9SKyle Evans A.magic = B.magic = C.magic = D.magic = WORD(0);
131*f0865ec9SKyle Evans TMP.magic = T.magic = WORD(0);
132*f0865ec9SKyle Evans
133*f0865ec9SKyle Evans MUST_HAVE((curve_name != NULL), ret, err);
134*f0865ec9SKyle Evans
135*f0865ec9SKyle Evans ret = local_strnlen((const char *)curve_name, MAX_CURVE_NAME_LEN, &len); EG(ret, err);
136*f0865ec9SKyle Evans len += 1;
137*f0865ec9SKyle Evans MUST_HAVE((len < 256), ret, err);
138*f0865ec9SKyle Evans ret = ec_get_curve_params_by_name(curve_name,
139*f0865ec9SKyle Evans (u8)len, &the_curve_const_parameters); EG(ret, err);
140*f0865ec9SKyle Evans
141*f0865ec9SKyle Evans
142*f0865ec9SKyle Evans /* Get out if getting the parameters went wrong */
143*f0865ec9SKyle Evans if (the_curve_const_parameters == NULL) {
144*f0865ec9SKyle Evans ext_printf("Error: error when importing curve %s "
145*f0865ec9SKyle Evans "parameters ...\n", curve_name);
146*f0865ec9SKyle Evans ret = -1;
147*f0865ec9SKyle Evans goto err;
148*f0865ec9SKyle Evans }
149*f0865ec9SKyle Evans /* Now map the curve parameters to our libecc internal representation */
150*f0865ec9SKyle Evans ret = import_params(&curve_params, the_curve_const_parameters); EG(ret, err);
151*f0865ec9SKyle Evans /* Get two random points on the curve */
152*f0865ec9SKyle Evans ret = get_random_point_on_curve(&curve_params, &A); EG(ret, err);
153*f0865ec9SKyle Evans ret = get_random_point_on_curve(&curve_params, &B); EG(ret, err);
154*f0865ec9SKyle Evans
155*f0865ec9SKyle Evans /*
156*f0865ec9SKyle Evans * Let's add the two points
157*f0865ec9SKyle Evans * C = A + B with regular point addition
158*f0865ec9SKyle Evans */
159*f0865ec9SKyle Evans ret = prj_pt_add(&C, &A, &B); EG(ret, err);
160*f0865ec9SKyle Evans
161*f0865ec9SKyle Evans /*
162*f0865ec9SKyle Evans * Check that the resulting additive point C = A+B is indeed on the
163*f0865ec9SKyle Evans * curve.
164*f0865ec9SKyle Evans */
165*f0865ec9SKyle Evans ret = prj_pt_to_aff(&T, &C); EG(ret, err);
166*f0865ec9SKyle Evans ret = prj_pt_is_on_curve(&C, &is_oncurve); EG(ret, err);
167*f0865ec9SKyle Evans if (!is_oncurve) {
168*f0865ec9SKyle Evans ext_printf("Error: C = A+B is not on the %s curve!\n",
169*f0865ec9SKyle Evans curve_params.curve_name);
170*f0865ec9SKyle Evans ret = -1;
171*f0865ec9SKyle Evans goto err;
172*f0865ec9SKyle Evans }
173*f0865ec9SKyle Evans ret = aff_pt_is_on_curve(&T, &is_oncurve); EG(ret, err);
174*f0865ec9SKyle Evans if (!is_oncurve) {
175*f0865ec9SKyle Evans ext_printf("Error: C = A+B is not on the %s curve!\n",
176*f0865ec9SKyle Evans curve_params.curve_name);
177*f0865ec9SKyle Evans ret = -1;
178*f0865ec9SKyle Evans goto err;
179*f0865ec9SKyle Evans }
180*f0865ec9SKyle Evans /* Same check with doubling
181*f0865ec9SKyle Evans * C = 2A = A+A
182*f0865ec9SKyle Evans */
183*f0865ec9SKyle Evans ret = prj_pt_dbl(&C, &A); EG(ret, err);
184*f0865ec9SKyle Evans
185*f0865ec9SKyle Evans /* Check that the resulting point C = 2A is indeed on the curve.
186*f0865ec9SKyle Evans *
187*f0865ec9SKyle Evans */
188*f0865ec9SKyle Evans ret = prj_pt_to_aff(&T, &C); EG(ret, err);
189*f0865ec9SKyle Evans ret = prj_pt_is_on_curve(&C, &is_oncurve); EG(ret, err);
190*f0865ec9SKyle Evans if (!is_oncurve) {
191*f0865ec9SKyle Evans ext_printf("Error: C = A+B is not on the %s curve!\n",
192*f0865ec9SKyle Evans curve_params.curve_name);
193*f0865ec9SKyle Evans ret = -1;
194*f0865ec9SKyle Evans goto err;
195*f0865ec9SKyle Evans }
196*f0865ec9SKyle Evans ret = aff_pt_is_on_curve(&T, &is_oncurve); EG(ret, err);
197*f0865ec9SKyle Evans if (!is_oncurve) {
198*f0865ec9SKyle Evans ext_printf("Error: C = A+B is not on the %s curve!\n",
199*f0865ec9SKyle Evans curve_params.curve_name);
200*f0865ec9SKyle Evans ret = -1;
201*f0865ec9SKyle Evans goto err;
202*f0865ec9SKyle Evans }
203*f0865ec9SKyle Evans /*
204*f0865ec9SKyle Evans * If the cofactor of the curve is 1, this means that the order of the
205*f0865ec9SKyle Evans * generator is the cardinal of the curve (and hence the order of the
206*f0865ec9SKyle Evans * curve points group). This means that for any point P on the curve,
207*f0865ec9SKyle Evans * we should have qP = 0 (the inifinity point, i.e. the zero neutral
208*f0865ec9SKyle Evans * element of the curve additive group).
209*f0865ec9SKyle Evans */
210*f0865ec9SKyle Evans ret = prj_pt_add(&C, &A, &B); EG(ret, err);
211*f0865ec9SKyle Evans ret = prj_pt_dbl(&D, &A); EG(ret, err);
212*f0865ec9SKyle Evans ret = nn_isone(&(curve_params.ec_gen_cofactor), &isone); EG(ret, err);
213*f0865ec9SKyle Evans if (isone) {
214*f0865ec9SKyle Evans ret = prj_pt_mul(&TMP, &(curve_params.ec_gen_order), &A); EG(ret, err);
215*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
216*f0865ec9SKyle Evans if (!iszero) {
217*f0865ec9SKyle Evans ext_printf("Error: qA is not 0! (regular mul)\n");
218*f0865ec9SKyle Evans ret = -1;
219*f0865ec9SKyle Evans goto err;
220*f0865ec9SKyle Evans }
221*f0865ec9SKyle Evans /**/
222*f0865ec9SKyle Evans ret = prj_pt_mul_blind(&TMP, &(curve_params.ec_gen_order), &A); EG(ret, err);
223*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
224*f0865ec9SKyle Evans if (!iszero) {
225*f0865ec9SKyle Evans ext_printf("Error: qA is not 0! (regular blind mul)\n");
226*f0865ec9SKyle Evans ret = -1;
227*f0865ec9SKyle Evans goto err;
228*f0865ec9SKyle Evans }
229*f0865ec9SKyle Evans /**/
230*f0865ec9SKyle Evans ret = prj_pt_mul(&TMP, &(curve_params.ec_gen_order), &B); EG(ret, err);
231*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
232*f0865ec9SKyle Evans if (!iszero) {
233*f0865ec9SKyle Evans ext_printf("Error: qB is not 0! (regular mul)\n");
234*f0865ec9SKyle Evans ret = -1;
235*f0865ec9SKyle Evans goto err;
236*f0865ec9SKyle Evans }
237*f0865ec9SKyle Evans /**/
238*f0865ec9SKyle Evans ret = prj_pt_mul_blind(&TMP, &(curve_params.ec_gen_order), &B); EG(ret, err);
239*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
240*f0865ec9SKyle Evans if (!iszero) {
241*f0865ec9SKyle Evans ext_printf("Error: qB is not 0! (regular blind mul)\n");
242*f0865ec9SKyle Evans ret = -1;
243*f0865ec9SKyle Evans goto err;
244*f0865ec9SKyle Evans }
245*f0865ec9SKyle Evans /**/
246*f0865ec9SKyle Evans ret = prj_pt_mul(&TMP, &(curve_params.ec_gen_order), &C); EG(ret, err);
247*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
248*f0865ec9SKyle Evans if (!iszero) {
249*f0865ec9SKyle Evans ext_printf("Error: qC is not 0! (regular mul)\n");
250*f0865ec9SKyle Evans ret = -1;
251*f0865ec9SKyle Evans goto err;
252*f0865ec9SKyle Evans }
253*f0865ec9SKyle Evans /**/
254*f0865ec9SKyle Evans ret = prj_pt_mul_blind(&TMP, &(curve_params.ec_gen_order), &C); EG(ret, err);
255*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
256*f0865ec9SKyle Evans if (!iszero) {
257*f0865ec9SKyle Evans ext_printf("Error: qC is not 0! (regular bind mul)\n");
258*f0865ec9SKyle Evans ret = -1;
259*f0865ec9SKyle Evans goto err;
260*f0865ec9SKyle Evans }
261*f0865ec9SKyle Evans /**/
262*f0865ec9SKyle Evans ret = prj_pt_mul(&TMP, &(curve_params.ec_gen_order), &D); EG(ret, err);
263*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
264*f0865ec9SKyle Evans if (!iszero) {
265*f0865ec9SKyle Evans ext_printf("Error: qD is not 0! (regular mul)\n");
266*f0865ec9SKyle Evans ret = -1;
267*f0865ec9SKyle Evans goto err;
268*f0865ec9SKyle Evans }
269*f0865ec9SKyle Evans /**/
270*f0865ec9SKyle Evans ret = prj_pt_mul_blind(&TMP, &(curve_params.ec_gen_order), &D); EG(ret, err);
271*f0865ec9SKyle Evans ret = prj_pt_iszero(&TMP, &iszero); EG(ret, err);
272*f0865ec9SKyle Evans if (!iszero) {
273*f0865ec9SKyle Evans ext_printf("Error: qD is not 0! (regular blind mul)\n");
274*f0865ec9SKyle Evans ret = -1;
275*f0865ec9SKyle Evans goto err;
276*f0865ec9SKyle Evans }
277*f0865ec9SKyle Evans }
278*f0865ec9SKyle Evans /* Let's do some performance tests for point addition and doubling!
279*f0865ec9SKyle Evans * We compute kA many times to have a decent performance measurement,
280*f0865ec9SKyle Evans * where k is chose random at each iteration. We also check that kA
281*f0865ec9SKyle Evans * is indeed on the curve.
282*f0865ec9SKyle Evans */
283*f0865ec9SKyle Evans ret = nn_init(&nn_k, 0); EG(ret, err);
284*f0865ec9SKyle Evans /**/
285*f0865ec9SKyle Evans if (get_ms_time(&t1)) {
286*f0865ec9SKyle Evans ext_printf("Error: cannot get time with get_ms_time\n");
287*f0865ec9SKyle Evans ret = -1;
288*f0865ec9SKyle Evans goto err;
289*f0865ec9SKyle Evans }
290*f0865ec9SKyle Evans for (i = 0; i < PERF_SCALAR_MUL; i++) {
291*f0865ec9SKyle Evans /* k = random mod (q) */
292*f0865ec9SKyle Evans ret = nn_get_random_mod(&nn_k, &(curve_params.ec_gen_order)); EG(ret, err);
293*f0865ec9SKyle Evans /* Compute kA with montgomery implementation w/o blinding */
294*f0865ec9SKyle Evans ret = prj_pt_mul(&TMP, &nn_k, &A); EG(ret, err);
295*f0865ec9SKyle Evans ret = prj_pt_to_aff(&T, &TMP); EG(ret, err);
296*f0865ec9SKyle Evans ret = prj_pt_is_on_curve(&TMP, &is_oncurve); EG(ret, err);
297*f0865ec9SKyle Evans if (!is_oncurve) {
298*f0865ec9SKyle Evans ext_printf("Error: kA is not on the %s curve!\n",
299*f0865ec9SKyle Evans curve_params.curve_name);
300*f0865ec9SKyle Evans nn_print("k=", &nn_k);
301*f0865ec9SKyle Evans ret = -1;
302*f0865ec9SKyle Evans goto err;
303*f0865ec9SKyle Evans }
304*f0865ec9SKyle Evans ret = aff_pt_is_on_curve(&T, &is_oncurve); EG(ret, err);
305*f0865ec9SKyle Evans if (!is_oncurve) {
306*f0865ec9SKyle Evans ext_printf("Error: kA is not on the %s curve!\n",
307*f0865ec9SKyle Evans curve_params.curve_name);
308*f0865ec9SKyle Evans nn_print("k=", &nn_k);
309*f0865ec9SKyle Evans ret = -1;
310*f0865ec9SKyle Evans goto err;
311*f0865ec9SKyle Evans }
312*f0865ec9SKyle Evans }
313*f0865ec9SKyle Evans if (get_ms_time(&t2)) {
314*f0865ec9SKyle Evans ext_printf("Error: cannot get time with get_ms_time\n");
315*f0865ec9SKyle Evans ret = -1;
316*f0865ec9SKyle Evans goto err;
317*f0865ec9SKyle Evans }
318*f0865ec9SKyle Evans ext_printf(" [*] Regular EC scalar multiplication took %f seconds "
319*f0865ec9SKyle Evans "on average\n",
320*f0865ec9SKyle Evans (double)(t2 - t1) / (double)(PERF_SCALAR_MUL * 1000ULL));
321*f0865ec9SKyle Evans /**/
322*f0865ec9SKyle Evans if (get_ms_time(&t1)) {
323*f0865ec9SKyle Evans ext_printf("Error: cannot get time with get_ms_time\n");
324*f0865ec9SKyle Evans ret = -1;
325*f0865ec9SKyle Evans goto err;
326*f0865ec9SKyle Evans }
327*f0865ec9SKyle Evans for (i = 0; i < PERF_SCALAR_MUL; i++) {
328*f0865ec9SKyle Evans /* k = random mod (q) */
329*f0865ec9SKyle Evans ret = nn_get_random_mod(&nn_k, &(curve_params.ec_gen_order)); EG(ret, err);
330*f0865ec9SKyle Evans /* Compute kA using montgomery implementation w/ blinding */
331*f0865ec9SKyle Evans ret = prj_pt_mul_blind(&TMP, &nn_k, &A); EG(ret, err);
332*f0865ec9SKyle Evans ret = prj_pt_to_aff(&T, &TMP); EG(ret, err);
333*f0865ec9SKyle Evans ret = prj_pt_is_on_curve(&TMP, &is_oncurve); EG(ret, err);
334*f0865ec9SKyle Evans if (!is_oncurve) {
335*f0865ec9SKyle Evans ext_printf("Error: kA is not on the %s curve!\n",
336*f0865ec9SKyle Evans curve_params.curve_name);
337*f0865ec9SKyle Evans nn_print("k=", &nn_k);
338*f0865ec9SKyle Evans ret = -1;
339*f0865ec9SKyle Evans goto err;
340*f0865ec9SKyle Evans }
341*f0865ec9SKyle Evans ret = aff_pt_is_on_curve(&T, &is_oncurve); EG(ret, err);
342*f0865ec9SKyle Evans if (!is_oncurve) {
343*f0865ec9SKyle Evans ext_printf("Error: kA is not on the %s curve!\n",
344*f0865ec9SKyle Evans curve_params.curve_name);
345*f0865ec9SKyle Evans nn_print("k=", &nn_k);
346*f0865ec9SKyle Evans ret = -1;
347*f0865ec9SKyle Evans goto err;
348*f0865ec9SKyle Evans }
349*f0865ec9SKyle Evans }
350*f0865ec9SKyle Evans if (get_ms_time(&t2)) {
351*f0865ec9SKyle Evans ext_printf("Error: cannot get time with get_ms_time\n");
352*f0865ec9SKyle Evans ret = -1;
353*f0865ec9SKyle Evans goto err;
354*f0865ec9SKyle Evans }
355*f0865ec9SKyle Evans ext_printf(" [*] Regular blind EC scalar multiplication took %f seconds "
356*f0865ec9SKyle Evans "on average\n",
357*f0865ec9SKyle Evans (double)(t2 - t1) / (double)(PERF_SCALAR_MUL * 1000ULL));
358*f0865ec9SKyle Evans
359*f0865ec9SKyle Evans err:
360*f0865ec9SKyle Evans prj_pt_uninit(&A);
361*f0865ec9SKyle Evans prj_pt_uninit(&B);
362*f0865ec9SKyle Evans prj_pt_uninit(&C);
363*f0865ec9SKyle Evans prj_pt_uninit(&D);
364*f0865ec9SKyle Evans prj_pt_uninit(&TMP);
365*f0865ec9SKyle Evans aff_pt_uninit(&T);
366*f0865ec9SKyle Evans nn_uninit(&nn_k);
367*f0865ec9SKyle Evans
368*f0865ec9SKyle Evans return ret;
369*f0865ec9SKyle Evans }
370*f0865ec9SKyle Evans
371*f0865ec9SKyle Evans #ifdef CURVE_BASIC_EXAMPLES
main(int argc,char * argv[])372*f0865ec9SKyle Evans int main(int argc, char *argv[])
373*f0865ec9SKyle Evans {
374*f0865ec9SKyle Evans unsigned int i;
375*f0865ec9SKyle Evans u8 curve_name[MAX_CURVE_NAME_LEN] = { 0 };
376*f0865ec9SKyle Evans FORCE_USED_VAR(argc);
377*f0865ec9SKyle Evans FORCE_USED_VAR(argv);
378*f0865ec9SKyle Evans
379*f0865ec9SKyle Evans /* Traverse all the possible curves we have at our disposal (known curves and
380*f0865ec9SKyle Evans * user defined curves).
381*f0865ec9SKyle Evans */
382*f0865ec9SKyle Evans for (i = 0; i < EC_CURVES_NUM; i++) {
383*f0865ec9SKyle Evans /* All our possible curves are in ../curves/curves_list.h
384*f0865ec9SKyle Evans * We can get the curve name from its internal type.
385*f0865ec9SKyle Evans */
386*f0865ec9SKyle Evans if(ec_get_curve_name_by_type(ec_maps[i].type, curve_name,
387*f0865ec9SKyle Evans sizeof(curve_name))){
388*f0865ec9SKyle Evans ext_printf("Error when treating %s\n", curve_name);
389*f0865ec9SKyle Evans return -1;
390*f0865ec9SKyle Evans }
391*f0865ec9SKyle Evans /* Check our curve! */
392*f0865ec9SKyle Evans ext_printf("[+] Checking curve %s\n", curve_name);
393*f0865ec9SKyle Evans if (check_curve(curve_name)) {
394*f0865ec9SKyle Evans ext_printf("Error: error performing check on "
395*f0865ec9SKyle Evans "curve %s\n", curve_name);
396*f0865ec9SKyle Evans return -1;
397*f0865ec9SKyle Evans }
398*f0865ec9SKyle Evans }
399*f0865ec9SKyle Evans return 0;
400*f0865ec9SKyle Evans }
401*f0865ec9SKyle Evans #endif
402