123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- #define _GNU_SOURCE
- #include <assert.h>
- #include <stdint.h>
- #include <unistd.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <sys/time.h>
- #include <gmp.h>
- const static char* p_str =
- "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- "505CAF";
- mpz_t p;
- mpz_t modxp;
- /* this goes in a separate file, hold on */
- gmp_randstate_t _rstate;
- unsigned long int _rseed;
- #include <linux/random.h>
- #include <sys/syscall.h>
- #define INIT_TIMEIT() \
- struct timeval __start, __end; \
- double __sdiff = 0, __udiff = 0
- #define START_TIMEIT() \
- gettimeofday(&__start, NULL)
- #define END_TIMEIT() \
- gettimeofday(&__end, NULL); \
- __sdiff += (__end.tv_sec - __start.tv_sec); \
- __udiff += (__end.tv_usec - __start.tv_usec)
- #define GET_TIMEIT() \
- __sdiff + __udiff * 1e-6
- #define TIMEIT_FORMAT "%lf"
- static inline ssize_t
- getrandom(void *buffer, size_t length, unsigned int flags)
- {
- return syscall(SYS_getrandom, buffer, length, flags);
- }
- void mpz_entropy_init()
- {
- gmp_randinit_default(_rstate);
- getrandom(&_rseed, sizeof(unsigned long int), GRND_NONBLOCK);
- gmp_randseed_ui(_rstate, _rseed);
- }
- typedef struct pbase {
- mpz_t base;
- mpz_t T[4][256];
- } pbase_t;
- void naif_fbpowm(mpz_t rop, const pbase_t pb, uint32_t exp)
- {
- mpz_set(rop, pb.base);
- mpz_powm_ui(rop, rop, exp, p);
- }
- void fbprecompute(pbase_t *pb)
- {
- for (size_t j = 0; j < 4; j++) {
- for (size_t i = 0; i <= 0xFF; i++) {
- uint64_t e = (0x01 << 8*j) * i;
- mpz_t *t = pb->T[j];
- mpz_init(t[i]);
- mpz_powm_ui(t[i], pb->base, e, p);
- }
- }
- }
- static inline
- void fbpowm(mpz_t rop, const pbase_t * const pb, uint32_t exp)
- {
- const uint8_t *e = (uint8_t *) &exp;
- mpz_mul(rop, pb->T[0][e[0]], pb->T[1][e[1]]);
- mpz_mod(rop, rop, p);
- mpz_mul(rop, rop, pb->T[2][e[2]]);
- mpz_mod(rop, rop, p);
- mpz_mul(rop, rop, pb->T[3][e[3]]);
- mpz_mod(rop, rop, p);
- }
- int main()
- {
- mpz_t x;
- uint32_t exp;
- mpz_init_set_str(p, p_str, 0);
- mpz_entropy_init();
- mpz_init(x);
- /* the size of the cyclic subgrup <2>
- * is #\GG / gcd(#\GG, 2) */
- mpz_init_set(modxp, p);
- mpz_sub_ui(modxp, modxp, 1);
- mpz_div_2exp(modxp, modxp, 1);
- pbase_t pb;
- mpz_init_set_ui(pb.base, 2);
- // mpz_urandomm(pb.base, _rstate, p);
- fbprecompute(&pb);
- mpz_t expected;
- mpz_init(expected);
- INIT_TIMEIT();
- for (int i = 0; i < (int) 1e4; i++) {
- getrandom(&exp, sizeof(exp), GRND_NONBLOCK);
- START_TIMEIT();
- fbpowm(x, &pb, exp);
- END_TIMEIT();
- //naif_fbpowm(expected, pb, exp);
- //assert(!mpz_cmp(expected, x));
- }
- printf(TIMEIT_FORMAT "\n", GET_TIMEIT());
- mpz_clear(x);
- mpz_clear(pb.base);
- return 0;
- }
|