You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
4.3 KiB

  1. #include "fr.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <gmp.h>
  5. #include <assert.h>
  6. mpz_t q;
  7. mpz_t zero;
  8. mpz_t one;
  9. mpz_t mask;
  10. size_t nBits;
  11. void Fr_toMpz(mpz_t r, PFrElement pE) {
  12. Fr_toNormal(pE);
  13. if (!(pE->type & Fr_LONG)) {
  14. mpz_set_si(r, pE->shortVal);
  15. if (pE->shortVal<0) {
  16. mpz_add(r, r, q);
  17. }
  18. } else {
  19. mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal);
  20. }
  21. }
  22. void Fr_fromMpz(PFrElement pE, mpz_t v) {
  23. if (mpz_fits_sint_p(v)) {
  24. pE->type = Fr_SHORT;
  25. pE->shortVal = mpz_get_si(v);
  26. } else {
  27. pE->type = Fr_LONG;
  28. for (int i=0; i<Fr_N64; i++) pE->longVal[i] = 0;
  29. mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
  30. }
  31. }
  32. void Fr_init() {
  33. mpz_init(q);
  34. mpz_import(q, Fr_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
  35. mpz_init_set_ui(zero, 0);
  36. mpz_init_set_ui(one, 1);
  37. nBits = mpz_sizeinbase (q, 2);
  38. mpz_init(mask);
  39. mpz_mul_2exp(mask, one, nBits-1);
  40. mpz_sub(mask, mask, one);
  41. }
  42. void Fr_str2element(PFrElement pE, char const *s) {
  43. mpz_t mr;
  44. mpz_init_set_str(mr, s, 10);
  45. Fr_fromMpz(pE, mr);
  46. }
  47. char *Fr_element2str(PFrElement pE) {
  48. mpz_t r;
  49. if (!(pE->type & Fr_LONG)) {
  50. if (pE->shortVal>=0) {
  51. char *r = new char[32];
  52. sprintf(r, "%d", pE->shortVal);
  53. return r;
  54. } else {
  55. mpz_init_set_si(r, pE->shortVal);
  56. mpz_add(r, r, q);
  57. mpz_clear(q);
  58. }
  59. } else {
  60. Fr_toNormal(pE);
  61. mpz_init(r);
  62. mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal);
  63. }
  64. char *res = mpz_get_str (0, 10, r);
  65. mpz_clear(r);
  66. return res;
  67. }
  68. void Fr_idiv(PFrElement r, PFrElement a, PFrElement b) {
  69. mpz_t ma;
  70. mpz_t mb;
  71. mpz_t mr;
  72. mpz_init(ma);
  73. mpz_init(mb);
  74. mpz_init(mr);
  75. Fr_toMpz(ma, a);
  76. // char *s1 = mpz_get_str (0, 10, ma);
  77. // printf("s1 %s\n", s1);
  78. Fr_toMpz(mb, b);
  79. // char *s2 = mpz_get_str (0, 10, mb);
  80. // printf("s2 %s\n", s2);
  81. mpz_fdiv_q(mr, ma, mb);
  82. // char *sr = mpz_get_str (0, 10, mr);
  83. // printf("r %s\n", sr);
  84. Fr_fromMpz(r, mr);
  85. }
  86. void Fr_mod(PFrElement r, PFrElement a, PFrElement b) {
  87. mpz_t ma;
  88. mpz_t mb;
  89. mpz_t mr;
  90. mpz_init(ma);
  91. mpz_init(mb);
  92. mpz_init(mr);
  93. Fr_toMpz(ma, a);
  94. Fr_toMpz(mb, b);
  95. mpz_fdiv_r(mr, ma, mb);
  96. Fr_fromMpz(r, mr);
  97. }
  98. void Fr_shl(PFrElement r, PFrElement a, PFrElement b) {
  99. mpz_t ma;
  100. mpz_t mb;
  101. mpz_t mr;
  102. mpz_init(ma);
  103. mpz_init(mb);
  104. mpz_init(mr);
  105. Fr_toMpz(ma, a);
  106. Fr_toMpz(mb, b);
  107. if (mpz_cmp_ui(mb, nBits) >= 0) {
  108. mpz_set(mr, zero);
  109. } else {
  110. mpz_mul_2exp(mr, ma, mpz_get_ui(mb));
  111. mpz_and(mr, mr, mask);
  112. }
  113. Fr_fromMpz(r, mr);
  114. }
  115. void Fr_shr(PFrElement r, PFrElement a, PFrElement b) {
  116. mpz_t ma;
  117. mpz_t mb;
  118. mpz_t mr;
  119. mpz_init(ma);
  120. mpz_init(mb);
  121. mpz_init(mr);
  122. Fr_toMpz(ma, a);
  123. Fr_toMpz(mb, b);
  124. if (mpz_cmp_ui(mb, nBits) >= 0) {
  125. mpz_set(mr, zero);
  126. } else {
  127. mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb));
  128. mpz_and(mr, mr, mask);
  129. }
  130. Fr_fromMpz(r, mr);
  131. }
  132. void Fr_pow(PFrElement r, PFrElement a, PFrElement b) {
  133. mpz_t ma;
  134. mpz_t mb;
  135. mpz_t mr;
  136. mpz_init(ma);
  137. mpz_init(mb);
  138. mpz_init(mr);
  139. Fr_toMpz(ma, a);
  140. Fr_toMpz(mb, b);
  141. mpz_powm(mr, ma, mb, q);
  142. Fr_fromMpz(r, mr);
  143. }
  144. void Fr_inv(PFrElement r, PFrElement a) {
  145. mpz_t ma;
  146. mpz_t mr;
  147. mpz_init(ma);
  148. mpz_init(mr);
  149. Fr_toMpz(ma, a);
  150. mpz_invert(mr, ma, q);
  151. Fr_fromMpz(r, mr);
  152. }
  153. void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
  154. FrElement tmp;
  155. Fr_inv(&tmp, b);
  156. Fr_mul(r, a, &tmp);
  157. }
  158. int Fr_isTrue(PFrElement pE) {
  159. if (!(pE->type & Fr_LONG)) return pE->shortVal != 0;
  160. for (int i=0; i< Fr_N64; i++) {
  161. if (pE->longVal[i]) return 1;
  162. }
  163. return 0;
  164. }
  165. int Fr_toInt(PFrElement pE) {
  166. Fr_toNormal(pE);
  167. if (!(pE->type & Fr_LONG)) {
  168. return pE->shortVal;
  169. } else {
  170. mpz_t ma;
  171. mpz_init(ma);
  172. Fr_toMpz(ma, pE);
  173. if (mpz_fits_sint_p(ma)) {
  174. return mpz_get_si(ma);
  175. }
  176. mpz_sub(ma, ma, q);
  177. if (mpz_fits_sint_p(ma)) {
  178. return mpz_get_si(ma);
  179. } else {
  180. assert(false);
  181. }
  182. }
  183. }