Path: blob/main/crypto/libecc/src/examples/basic/fp_square_residue.c
34889 views
/*1* Copyright (C) 2017 - This file is part of libecc project2*3* Authors:4* Ryad BENADJILA <[email protected]>5* Arnaud EBALARD <[email protected]>6* Jean-Pierre FLORI <[email protected]>7*8* Contributors:9* Nicolas VIVET <[email protected]>10* Karim KHALFALLAH <[email protected]>11*12* This software is licensed under a dual BSD and GPL v2 license.13* See LICENSE file at the root folder of the project.14*/15#include <libecc/libarith.h>1617/* Declare our Miller-Rabin test implemented18* in another module.19*/20ATTRIBUTE_WARN_UNUSED_RET int miller_rabin(nn_src_t n, const unsigned int t, int *check);2122#ifdef FP_EXAMPLE23int main(int argc, char *argv[])24{25nn p;26fp x, x_sqrt1, x_sqrt2;27fp_ctx ctx;28int ret, ret_sqr, isone, check, cmp;29x.magic = x_sqrt1.magic = x_sqrt2.magic = WORD(0);30ctx.magic = WORD(0);31FORCE_USED_VAR(argc);32FORCE_USED_VAR(argv);3334while (1) {35/* Get a random prime p of maximum 521 bits */36ret = nn_init(&p, 0); EG(ret, err);37while (1) {38/* x = random with max size ~= (NN_MAX_BIT_LEN / 3) bytes.39* This size limit is infered from the NN arithmetic primitives40* maximum working size. See nn.h for more information about this.41*/42ret = nn_get_random_maxlen43(&p, (u16)((NN_MAX_BIT_LEN / 3) / 8)); EG(ret, err);4445/* p = 1 is a marginal prime we don't want to deal with */46ret = nn_isone(&p, &isone); EG(ret, err);47if(isone){48continue;49}5051/* Check primality of p, and choose it if it is prime */52ret = miller_rabin(&p, 100, &check); EG(ret, err);53if(check == 1){54break;55}56}57nn_print("Prime p", &p);58/* Initialize our Fp context from p */59ret = fp_ctx_init_from_p(&ctx, &p); EG(ret, err);60/* Initialize x and its square roots */61ret = fp_init(&x, &ctx); EG(ret, err);62ret = fp_init(&x_sqrt1, &ctx); EG(ret, err);63ret = fp_init(&x_sqrt2, &ctx); EG(ret, err);6465/* Get a random value in Fp */66ret = fp_get_random(&x, &ctx); EG(ret, err);67/* Compute its square in Fp */68ext_printf("Random before squaring:\n");69fp_print("x", &x);70ext_printf("Random after squaring:\n");71ret = fp_sqr(&x, &x); EG(ret, err);72nn_print("x^2", &(x.fp_val));7374ret_sqr = fp_sqrt(&x_sqrt1, &x_sqrt2, &x);7576if (ret_sqr == 0) {77/* Square roots found!, check them! */78fp_print("sqrt1", &x_sqrt1);79ret = fp_sqr(&x_sqrt1, &x_sqrt1); EG(ret, err);80ret = fp_cmp(&x, &x_sqrt1, &cmp); EG(ret, err);81if (cmp == 0) {82ext_printf("First found square OK!\n");83} else {84ext_printf("First found square NOK: square "85"is not the expected value ...\n");86}87fp_print("sqrt2", &x_sqrt2);88ret = fp_sqr(&x_sqrt2, &x_sqrt2); EG(ret, err);89ret = fp_cmp(&x, &x_sqrt2, &cmp); EG(ret, err);90if (cmp == 0) {91ext_printf("Second found square OK!\n");92} else {93ext_printf("Second found square NOK: square "94"is not the expected value ...\n");95}9697} else {98if (ret_sqr == -1) {99/* This should not happen since we have forged our square */100ext_printf("Value n has no square over Fp\n");101ext_printf("(Note: this error can be due to "102"Miller-Rabin providing a false "103"positive prime ...)\n");104ext_printf("(though this should happen with "105"negligible probability))\n");106nn_print("Check primality of p =", &p);107/* Get out of the main loop */108break;109} else {110/* This should not happen since we have forged our square */111ext_printf("Tonelli-Shanks algorithm unkown "112"error ...\n");113ext_printf("(Note: this error can be due to "114"Miller-Rabin providing a false "115"positive prime ...)\n");116ext_printf("(though this should happen with "117"negligible probability))\n");118nn_print("Check primality of p =", &p);119/* Get out of the main loop */120break;121}122}123}124125return 0;126err:127ext_printf("Error: unkown error ...\n");128return -1;129}130#endif131132133