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/libarith.h> 17*f0865ec9SKyle Evans 18*f0865ec9SKyle Evans /* Declare our Miller-Rabin test implemented 19*f0865ec9SKyle Evans * in another module. 20*f0865ec9SKyle Evans */ 21*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET int miller_rabin(nn_src_t n, const unsigned int t, int *check); 22*f0865ec9SKyle Evans 23*f0865ec9SKyle Evans #ifdef FP_EXAMPLE 24*f0865ec9SKyle Evans int main(int argc, char *argv[]) 25*f0865ec9SKyle Evans { 26*f0865ec9SKyle Evans nn p; 27*f0865ec9SKyle Evans fp x, x_sqrt1, x_sqrt2; 28*f0865ec9SKyle Evans fp_ctx ctx; 29*f0865ec9SKyle Evans int ret, ret_sqr, isone, check, cmp; 30*f0865ec9SKyle Evans x.magic = x_sqrt1.magic = x_sqrt2.magic = WORD(0); 31*f0865ec9SKyle Evans ctx.magic = WORD(0); 32*f0865ec9SKyle Evans FORCE_USED_VAR(argc); 33*f0865ec9SKyle Evans FORCE_USED_VAR(argv); 34*f0865ec9SKyle Evans 35*f0865ec9SKyle Evans while (1) { 36*f0865ec9SKyle Evans /* Get a random prime p of maximum 521 bits */ 37*f0865ec9SKyle Evans ret = nn_init(&p, 0); EG(ret, err); 38*f0865ec9SKyle Evans while (1) { 39*f0865ec9SKyle Evans /* x = random with max size ~= (NN_MAX_BIT_LEN / 3) bytes. 40*f0865ec9SKyle Evans * This size limit is infered from the NN arithmetic primitives 41*f0865ec9SKyle Evans * maximum working size. See nn.h for more information about this. 42*f0865ec9SKyle Evans */ 43*f0865ec9SKyle Evans ret = nn_get_random_maxlen 44*f0865ec9SKyle Evans (&p, (u16)((NN_MAX_BIT_LEN / 3) / 8)); EG(ret, err); 45*f0865ec9SKyle Evans 46*f0865ec9SKyle Evans /* p = 1 is a marginal prime we don't want to deal with */ 47*f0865ec9SKyle Evans ret = nn_isone(&p, &isone); EG(ret, err); 48*f0865ec9SKyle Evans if(isone){ 49*f0865ec9SKyle Evans continue; 50*f0865ec9SKyle Evans } 51*f0865ec9SKyle Evans 52*f0865ec9SKyle Evans /* Check primality of p, and choose it if it is prime */ 53*f0865ec9SKyle Evans ret = miller_rabin(&p, 100, &check); EG(ret, err); 54*f0865ec9SKyle Evans if(check == 1){ 55*f0865ec9SKyle Evans break; 56*f0865ec9SKyle Evans } 57*f0865ec9SKyle Evans } 58*f0865ec9SKyle Evans nn_print("Prime p", &p); 59*f0865ec9SKyle Evans /* Initialize our Fp context from p */ 60*f0865ec9SKyle Evans ret = fp_ctx_init_from_p(&ctx, &p); EG(ret, err); 61*f0865ec9SKyle Evans /* Initialize x and its square roots */ 62*f0865ec9SKyle Evans ret = fp_init(&x, &ctx); EG(ret, err); 63*f0865ec9SKyle Evans ret = fp_init(&x_sqrt1, &ctx); EG(ret, err); 64*f0865ec9SKyle Evans ret = fp_init(&x_sqrt2, &ctx); EG(ret, err); 65*f0865ec9SKyle Evans 66*f0865ec9SKyle Evans /* Get a random value in Fp */ 67*f0865ec9SKyle Evans ret = fp_get_random(&x, &ctx); EG(ret, err); 68*f0865ec9SKyle Evans /* Compute its square in Fp */ 69*f0865ec9SKyle Evans ext_printf("Random before squaring:\n"); 70*f0865ec9SKyle Evans fp_print("x", &x); 71*f0865ec9SKyle Evans ext_printf("Random after squaring:\n"); 72*f0865ec9SKyle Evans ret = fp_sqr(&x, &x); EG(ret, err); 73*f0865ec9SKyle Evans nn_print("x^2", &(x.fp_val)); 74*f0865ec9SKyle Evans 75*f0865ec9SKyle Evans ret_sqr = fp_sqrt(&x_sqrt1, &x_sqrt2, &x); 76*f0865ec9SKyle Evans 77*f0865ec9SKyle Evans if (ret_sqr == 0) { 78*f0865ec9SKyle Evans /* Square roots found!, check them! */ 79*f0865ec9SKyle Evans fp_print("sqrt1", &x_sqrt1); 80*f0865ec9SKyle Evans ret = fp_sqr(&x_sqrt1, &x_sqrt1); EG(ret, err); 81*f0865ec9SKyle Evans ret = fp_cmp(&x, &x_sqrt1, &cmp); EG(ret, err); 82*f0865ec9SKyle Evans if (cmp == 0) { 83*f0865ec9SKyle Evans ext_printf("First found square OK!\n"); 84*f0865ec9SKyle Evans } else { 85*f0865ec9SKyle Evans ext_printf("First found square NOK: square " 86*f0865ec9SKyle Evans "is not the expected value ...\n"); 87*f0865ec9SKyle Evans } 88*f0865ec9SKyle Evans fp_print("sqrt2", &x_sqrt2); 89*f0865ec9SKyle Evans ret = fp_sqr(&x_sqrt2, &x_sqrt2); EG(ret, err); 90*f0865ec9SKyle Evans ret = fp_cmp(&x, &x_sqrt2, &cmp); EG(ret, err); 91*f0865ec9SKyle Evans if (cmp == 0) { 92*f0865ec9SKyle Evans ext_printf("Second found square OK!\n"); 93*f0865ec9SKyle Evans } else { 94*f0865ec9SKyle Evans ext_printf("Second found square NOK: square " 95*f0865ec9SKyle Evans "is not the expected value ...\n"); 96*f0865ec9SKyle Evans } 97*f0865ec9SKyle Evans 98*f0865ec9SKyle Evans } else { 99*f0865ec9SKyle Evans if (ret_sqr == -1) { 100*f0865ec9SKyle Evans /* This should not happen since we have forged our square */ 101*f0865ec9SKyle Evans ext_printf("Value n has no square over Fp\n"); 102*f0865ec9SKyle Evans ext_printf("(Note: this error can be due to " 103*f0865ec9SKyle Evans "Miller-Rabin providing a false " 104*f0865ec9SKyle Evans "positive prime ...)\n"); 105*f0865ec9SKyle Evans ext_printf("(though this should happen with " 106*f0865ec9SKyle Evans "negligible probability))\n"); 107*f0865ec9SKyle Evans nn_print("Check primality of p =", &p); 108*f0865ec9SKyle Evans /* Get out of the main loop */ 109*f0865ec9SKyle Evans break; 110*f0865ec9SKyle Evans } else { 111*f0865ec9SKyle Evans /* This should not happen since we have forged our square */ 112*f0865ec9SKyle Evans ext_printf("Tonelli-Shanks algorithm unkown " 113*f0865ec9SKyle Evans "error ...\n"); 114*f0865ec9SKyle Evans ext_printf("(Note: this error can be due to " 115*f0865ec9SKyle Evans "Miller-Rabin providing a false " 116*f0865ec9SKyle Evans "positive prime ...)\n"); 117*f0865ec9SKyle Evans ext_printf("(though this should happen with " 118*f0865ec9SKyle Evans "negligible probability))\n"); 119*f0865ec9SKyle Evans nn_print("Check primality of p =", &p); 120*f0865ec9SKyle Evans /* Get out of the main loop */ 121*f0865ec9SKyle Evans break; 122*f0865ec9SKyle Evans } 123*f0865ec9SKyle Evans } 124*f0865ec9SKyle Evans } 125*f0865ec9SKyle Evans 126*f0865ec9SKyle Evans return 0; 127*f0865ec9SKyle Evans err: 128*f0865ec9SKyle Evans ext_printf("Error: unkown error ...\n"); 129*f0865ec9SKyle Evans return -1; 130*f0865ec9SKyle Evans } 131*f0865ec9SKyle Evans #endif 132