hss.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #define _GNU_SOURCE
  2. #include <assert.h>
  3. #include <stdint.h>
  4. #include <unistd.h>
  5. #include <stdbool.h>
  6. #include <stdio.h>
  7. #include <sys/time.h>
  8. #include <gmp.h>
  9. const static char* p_str =
  10. "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
  11. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
  12. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
  13. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
  14. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
  15. "505CAF";
  16. mpz_t p;
  17. mpz_t modxp;
  18. /* this goes in a separate file, hold on */
  19. gmp_randstate_t _rstate;
  20. unsigned long int _rseed;
  21. #include <linux/random.h>
  22. #include <sys/syscall.h>
  23. #define INIT_TIMEIT() \
  24. struct timeval __start, __end; \
  25. double __sdiff = 0, __udiff = 0
  26. #define START_TIMEIT() \
  27. gettimeofday(&__start, NULL)
  28. #define END_TIMEIT() \
  29. gettimeofday(&__end, NULL); \
  30. __sdiff += (__end.tv_sec - __start.tv_sec); \
  31. __udiff += (__end.tv_usec - __start.tv_usec)
  32. #define GET_TIMEIT() \
  33. __sdiff + __udiff * 1e-6
  34. #define TIMEIT_FORMAT "%lf"
  35. static inline ssize_t
  36. getrandom(void *buffer, size_t length, unsigned int flags)
  37. {
  38. return syscall(SYS_getrandom, buffer, length, flags);
  39. }
  40. void mpz_entropy_init()
  41. {
  42. gmp_randinit_default(_rstate);
  43. getrandom(&_rseed, sizeof(unsigned long int), GRND_NONBLOCK);
  44. gmp_randseed_ui(_rstate, _rseed);
  45. }
  46. typedef struct pbase {
  47. mpz_t base;
  48. mpz_t T[4][256];
  49. } pbase_t;
  50. void naif_fbpowm(mpz_t rop, const pbase_t pb, uint32_t exp)
  51. {
  52. mpz_set(rop, pb.base);
  53. mpz_powm_ui(rop, rop, exp, p);
  54. }
  55. void fbprecompute(pbase_t *pb)
  56. {
  57. for (size_t j = 0; j < 4; j++) {
  58. for (size_t i = 0; i <= 0xFF; i++) {
  59. uint64_t e = (0x01 << 8*j) * i;
  60. mpz_t *t = pb->T[j];
  61. mpz_init(t[i]);
  62. mpz_powm_ui(t[i], pb->base, e, p);
  63. }
  64. }
  65. }
  66. static inline
  67. void fbpowm(mpz_t rop, const pbase_t * const pb, uint32_t exp)
  68. {
  69. const uint8_t *e = (uint8_t *) &exp;
  70. mpz_mul(rop, pb->T[0][e[0]], pb->T[1][e[1]]);
  71. mpz_mod(rop, rop, p);
  72. mpz_mul(rop, rop, pb->T[2][e[2]]);
  73. mpz_mod(rop, rop, p);
  74. mpz_mul(rop, rop, pb->T[3][e[3]]);
  75. mpz_mod(rop, rop, p);
  76. }
  77. int main()
  78. {
  79. mpz_t x;
  80. uint32_t exp;
  81. mpz_init_set_str(p, p_str, 0);
  82. mpz_entropy_init();
  83. mpz_init(x);
  84. /* the size of the cyclic subgrup <2>
  85. * is #\GG / gcd(#\GG, 2) */
  86. mpz_init_set(modxp, p);
  87. mpz_sub_ui(modxp, modxp, 1);
  88. mpz_div_2exp(modxp, modxp, 1);
  89. pbase_t pb;
  90. mpz_init_set_ui(pb.base, 2);
  91. // mpz_urandomm(pb.base, _rstate, p);
  92. fbprecompute(&pb);
  93. mpz_t expected;
  94. mpz_init(expected);
  95. INIT_TIMEIT();
  96. for (int i = 0; i < (int) 1e4; i++) {
  97. getrandom(&exp, sizeof(exp), GRND_NONBLOCK);
  98. START_TIMEIT();
  99. fbpowm(x, &pb, exp);
  100. END_TIMEIT();
  101. //naif_fbpowm(expected, pb, exp);
  102. //assert(!mpz_cmp(expected, x));
  103. }
  104. printf(TIMEIT_FORMAT "\n", GET_TIMEIT());
  105. mpz_clear(x);
  106. mpz_clear(pb.base);
  107. return 0;
  108. }