fbase.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "config.h"
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <gmp.h>
  5. #include "fbase.h"
  6. #include "group.h"
  7. fbase_ptr fb_init()
  8. {
  9. fbase_ptr pb = (fbase_ptr) calloc(FB_FRAMES, sizeof(fbase_unit));
  10. for (size_t j = 0; j < FB_FRAMES; j++) {
  11. for (size_t i = 0; i <= FB_MASK; i++) {
  12. mpz_init(pb[j][i]);
  13. }
  14. }
  15. return pb;
  16. }
  17. void fb_set_small(fbase_t pb, const mpz_t n)
  18. {
  19. mpz_t e;
  20. mpz_init(e);
  21. for (size_t j = 0; j < (FB_FRAMES)/2; j++) {
  22. for (size_t i = 0; i <= FB_MASK; i++) {
  23. uint64_t e = (0x01 << (FB_BASE)*j) * i;
  24. powmp_ui(pb[j][i], n, e);
  25. /* force size to be constant. */
  26. _mpz_realloc(pb[j][i], 24);
  27. SIZ(pb[j][i]) = 24;
  28. }
  29. }
  30. mpz_clear(e);
  31. }
  32. void fb_copy(fbase_t dst, fbase_t source)
  33. {
  34. for (size_t j = 0; j < FB_FRAMES; j++) {
  35. for (size_t i = 0; i <= FB_MASK; i++) {
  36. mpz_set(dst[j][i], source[j][i]);
  37. /* force size to be constant */
  38. _mpz_realloc(dst[j][i], 24);
  39. SIZ(dst[j][i]) = 24;
  40. }
  41. }
  42. }
  43. void fb_set(fbase_t pb, const mpz_t n)
  44. {
  45. mpz_t e;
  46. mpz_init(e);
  47. for (size_t j = 0; j < FB_FRAMES; j++) {
  48. for (size_t i = 0; i <= FB_MASK; i++) {
  49. mpz_set_ui(e, 1);
  50. mpz_mul_2exp(e, e, (FB_BASE)*j);
  51. mpz_mul_ui(e, e, i);
  52. mpz_powm(pb[j][i], n, e, p);
  53. }
  54. }
  55. mpz_clear(e);
  56. }
  57. void fb_clear(fbase_t pb)
  58. {
  59. for (size_t j = 0; j < FB_FRAMES; j++) {
  60. for (size_t i = 0; i <= FB_MASK; i++) {
  61. mpz_clear(pb[j][i]);
  62. }
  63. }
  64. free(pb);
  65. }
  66. void __attribute__((optimize("unroll-loops")))
  67. fb_powmp_ui(mpz_t rop, fbase_t pb, const uint64_t exp)
  68. {
  69. #define e(i) ((exp >> (i * (FB_BASE))) & (FB_MASK))
  70. mpz_mul_modp(rop, pb[0][e(0)], pb[1][e(1)]);
  71. for (size_t j = 2; j < FB_FRAMES; j++) {
  72. if (e(j) != 0) {
  73. mpz_mul_modp(rop, rop, pb[j][e(j)]);
  74. }
  75. }
  76. }