group.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <stdint.h>
  3. #include <gmp.h>
  4. /**
  5. * p is our prime modulus, and is 2^n - g
  6. * where g is referred to as "gamma" (built-in function in C, so transliterated)
  7. */
  8. extern const char* p_str;
  9. extern mpz_t p, q;
  10. extern const uint64_t gg;
  11. typedef __uint128_t uint128_t;
  12. void group_init();
  13. void group_clear();
  14. /* some gmp internal funcitons to speed up modulus… */
  15. #define SIZ(x) ((x)->_mp_size)
  16. #define PTR(x) ((x)->_mp_d)
  17. #define MPN_COPY(dst, src, l) \
  18. do { \
  19. for (int i = 0; i < l; i++) (dst)[i] = (src)[i]; \
  20. } while(0)
  21. #define MPN_ZERO(dst, l) \
  22. do { \
  23. for (size_t i = 0; i < l; i++) (dst)[i] = 0; \
  24. } while(0)
  25. #define MPN_NORMALIZE(DST, NLIMBS) \
  26. do { \
  27. while (1) \
  28. { \
  29. if ((DST)[(NLIMBS) - 1] != 0) \
  30. break; \
  31. (NLIMBS)--; \
  32. } \
  33. } while (0)
  34. static inline
  35. void remp(mpz_t rop)
  36. {
  37. int32_t limbs = SIZ(rop) - 24;
  38. while (limbs > 0) {
  39. /* note: this declarations MUST happen after checking
  40. * for positivity of limbs. */
  41. uint64_t a[limbs+1];
  42. /* copy the most significant part of rop into a,
  43. * then set it to zero */
  44. for (int i = 24; i < SIZ(rop); i++) {
  45. a[i-24] = PTR(rop)[i];
  46. PTR(rop)[i] = 0;
  47. }
  48. a[limbs] = 0;
  49. mpn_addmul_1(PTR(rop), a, limbs+1, gg);
  50. MPN_NORMALIZE(PTR(rop), SIZ(rop));
  51. limbs = SIZ(rop) - 24;
  52. }
  53. if (mpn_cmp(PTR(rop), PTR(p), SIZ(rop)) >= 0) {
  54. mpn_sub(PTR(rop), PTR(rop), 24, PTR(p), 24);
  55. MPN_NORMALIZE(PTR(rop), SIZ(rop));
  56. }
  57. }
  58. void powmp_ui(mpz_t rop, const mpz_t base, uint64_t exp);
  59. void mul_modp(mpz_t rop, mpz_t op1, mpz_t op2);
  60. #define mpz_mul_modp(rop, op1, op2) \
  61. do { \
  62. mpz_mul(rop, op1, op2); \
  63. remp(rop); \
  64. } while (0)
  65. #define mpz_mul_ui_modp(rop, op1, op2) \
  66. do { \
  67. mpz_mul_ui(rop, op1, op2); \
  68. remp(rop); \
  69. } while (0)