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); 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); 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 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