-
-
Save Hermann-SW/eb4a34d2db450a35cdaa3cb1708aac1f to your computer and use it in GitHub Desktop.
Determines f^i(y) with f(x) = (x^2 + a) mod n fast, using gmplib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* gcc -O3 -Wall -Wextra -pedantic -fomit-frame-pointer -m64 -mtune=skylake -march=broadwell -o fn fn.c -lgmp | |
./fn n a y i | |
Determines f^i(y) with f(x) = (x^2 + a) mod n | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <inttypes.h> | |
#include <time.h> | |
#include <sys/time.h> | |
#include <assert.h> | |
#include <gmp.h> | |
void fn(mpz_t n, mpz_t y, unsigned long i) | |
{ | |
mpz_t t, t2; | |
mpz_inits (t, t2, NULL); | |
for (; i > 0; --i) | |
{ | |
mpz_mul (t, y, y); | |
mpz_add_ui (y, t, 1); | |
mpz_mod (y, y, n); | |
} | |
gmp_printf ("%Zd\n", y); | |
} | |
int main (int argc, char *argv[]) | |
{ | |
mpz_t n, y; | |
unsigned long i; | |
assert(argc==4); | |
mpz_inits(n, y, i, NULL); | |
struct timespec t0, t1; | |
mpz_set_str (n, argv[1], 0); | |
mpz_set_str (y, argv[2], 0); | |
assert(atol(argv[3]) >= 0); | |
i = (unsigned long) atol(argv[3]); | |
clock_gettime(CLOCK_REALTIME, &t0); | |
fn(n, y, i); | |
clock_gettime(CLOCK_REALTIME, &t1); | |
printf(" %ldns\n", (t1.tv_sec-t0.tv_sec) * 1000000000 + t1.tv_nsec - t0.tv_nsec); | |
exit (0); | |
} |
Revision 2 fixes lint complaint:
https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=317340&p=1899285#p1899285
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=312344&p=1898988#p1898988
Used to compute values for different i (in square brackets) in this ρ digraph (i=216698+4782220904 took 5.5 minutes):