powmod.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /**
  2. \file powmod.cpp
  3. \author daniel.demmler@ec-spride.de
  4. \copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
  5. Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Lesser General Public License as published
  8. by the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. ABY is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. \brief PowMod Implementation
  17. */
  18. #include "powmod.h"
  19. #include <cstdlib>
  20. #define POWMOD_DEBUG 0
  21. #if POWMOD_DEBUG
  22. #include <cstdio>
  23. #endif
  24. mpz_t* m_table_g;
  25. mpz_t* m_table_h;
  26. mpz_t* m_prod;
  27. mpz_t m_mod;
  28. size_t m_numberOfElements_g, m_numberOfElements_h;
  29. void fbpowmod_init_g(const mpz_t base, const mpz_t mod, size_t bitsize) {
  30. m_numberOfElements_g = bitsize;
  31. mpz_init(m_mod);
  32. mpz_set(m_mod, mod);
  33. m_table_g = (mpz_t*) malloc(sizeof(mpz_t) * bitsize);
  34. for (size_t i = 0; i < bitsize; i++) {
  35. mpz_init(m_table_g[i]);
  36. }
  37. mpz_set(m_table_g[0], base);
  38. for (size_t u = 1; u < bitsize; u++) {
  39. mpz_mul(m_table_g[u], m_table_g[u - 1], m_table_g[u - 1]);
  40. mpz_mod(m_table_g[u], m_table_g[u], mod);
  41. }
  42. }
  43. void fbpowmod_init_h(const mpz_t base, const mpz_t mod, size_t bitsize) {
  44. m_numberOfElements_h = bitsize;
  45. mpz_init(m_mod);
  46. mpz_set(m_mod, mod);
  47. m_table_h = (mpz_t*) malloc(sizeof(mpz_t) * bitsize);
  48. for (size_t i = 0; i < bitsize; i++) {
  49. mpz_init(m_table_h[i]);
  50. }
  51. mpz_set(m_table_h[0], base);
  52. for (size_t u = 1; u < bitsize; u++) {
  53. mpz_mul(m_table_h[u], m_table_h[u - 1], m_table_h[u - 1]);
  54. mpz_mod(m_table_h[u], m_table_h[u], mod);
  55. }
  56. }
  57. void fbpowmod_g(mpz_t result, const mpz_t exp) {
  58. auto top = mpz_sizeinbase(exp, 2);
  59. if (top <= m_numberOfElements_g) {
  60. mpz_set_ui(result, 1);
  61. for (size_t u = 0; u < top; u++) {
  62. if (mpz_tstbit(exp, u)) {
  63. mpz_mul(result, result, m_table_g[u]);
  64. mpz_mod(result, result, m_mod);
  65. }
  66. }
  67. } else {
  68. printf("(g) Exponent too big for pre-computed fixed-base powmod! %zu %zu\n", top, m_numberOfElements_g);
  69. }
  70. }
  71. void fbpowmod_h(mpz_t result, const mpz_t exp) {
  72. auto top = mpz_sizeinbase(exp, 2);
  73. if (top <= m_numberOfElements_h) {
  74. mpz_set_ui(result, 1);
  75. for (size_t u = 0; u < top; u++) {
  76. if (mpz_tstbit(exp, u)) {
  77. mpz_mul(result, result, m_table_h[u]);
  78. mpz_mod(result, result, m_mod);
  79. }
  80. }
  81. } else {
  82. printf("Exponent too big for pre-computed fixed-base powmod! %zu %zu\n", top, m_numberOfElements_h);
  83. }
  84. }
  85. void dbpowmod(mpz_t ret, const mpz_t b1, const mpz_t e1, const mpz_t b2, const mpz_t e2, const mpz_t mod) {
  86. unsigned char index;
  87. mpz_t prod[3];
  88. auto size = (mpz_cmp(e1, e2) > 0) ? mpz_sizeinbase(e1, 2) : mpz_sizeinbase(e2, 2);
  89. #if POWMOD_DEBUG
  90. printf("size: %zu\n", size);
  91. #endif
  92. mpz_init_set(prod[0], b1);
  93. mpz_init_set(prod[1], b2);
  94. mpz_init(prod[2]);
  95. mpz_mul(prod[2], b1, b2);
  96. mpz_mod(prod[2], prod[2], mod);
  97. mpz_set_ui(ret, 1);
  98. for (ssize_t i = size - 1; i >= 0; i--) {
  99. index = (mpz_tstbit(e2, i) << 1) + mpz_tstbit(e1, i);
  100. #if POWMOD_DEBUG
  101. gmp_printf("%d | %Zd", index, ret);
  102. #endif
  103. mpz_mul(ret, ret, ret);
  104. mpz_mod(ret, ret, mod);
  105. #if POWMOD_DEBUG
  106. gmp_printf(" - sq:%Zd", ret);
  107. #endif
  108. if (index) {
  109. mpz_mul(ret, prod[index - 1], ret);
  110. mpz_mod(ret, ret, mod);
  111. }
  112. #if POWMOD_DEBUG
  113. gmp_printf(" - end:%Zd\n", ret);
  114. #endif
  115. }
  116. mpz_clears(prod[0], prod[1], prod[2], NULL);
  117. }
  118. void fbdbpowmod_init(const mpz_t b1, const mpz_t b2, const mpz_t mod, size_t) {
  119. mpz_init(m_mod);
  120. mpz_set(m_mod, mod);
  121. m_prod = (mpz_t*) malloc(sizeof(mpz_t) * 3);
  122. mpz_init_set(m_prod[0], b1);
  123. mpz_init_set(m_prod[1], b2);
  124. mpz_init(m_prod[2]);
  125. mpz_mul(m_prod[2], b1, b2);
  126. mpz_mod(m_prod[2], m_prod[2], mod);
  127. }
  128. void fbdbpowmod(mpz_t ret, const mpz_t e1, const mpz_t e2) {
  129. unsigned char index;
  130. auto size = (mpz_cmp(e1, e2) > 0) ? mpz_sizeinbase(e1, 2) : mpz_sizeinbase(e2, 2);
  131. mpz_set_ui(ret, 1);
  132. for (ssize_t i = size - 1; i >= 0; i--) {
  133. index = (mpz_tstbit(e2, i) << 1) + mpz_tstbit(e1, i);
  134. mpz_mul(ret, ret, ret);
  135. mpz_mod(ret, ret, m_mod);
  136. if (index) {
  137. mpz_mul(ret, m_prod[index - 1], ret);
  138. mpz_mod(ret, ret, m_mod);
  139. }
  140. }
  141. }