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
main(int argc,char * argv[])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