Scalar.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #include "Scalar.hpp"
  2. #include <iostream>
  3. extern const scalar_t bn_n;
  4. mpz_class Scalar::mpz_bn_p = 0;
  5. mpz_class Scalar::mpz_bn_n = 0;
  6. Scalar::Scalar()
  7. {
  8. element = 0;
  9. }
  10. Scalar::Scalar(const scalar_t& input)
  11. {
  12. set(input);
  13. }
  14. Scalar::Scalar(mpz_class input)
  15. {
  16. set(input);
  17. }
  18. void Scalar::init()
  19. {
  20. mpz_bn_p = mpz_class("8FB501E34AA387F9AA6FECB86184DC21EE5B88D120B5B59E185CAC6C5E089667", 16);
  21. mpz_bn_n = mpz_class("8FB501E34AA387F9AA6FECB86184DC212E8D8E12F82B39241A2EF45B57AC7261", 16);
  22. }
  23. void Scalar::set(const scalar_t& input)
  24. {
  25. std::stringstream bufferstream;
  26. std::string buffer;
  27. mpz_class temp;
  28. bufferstream << std::hex << input[3] << input[2] << input[1] << input[0];
  29. bufferstream >> buffer;
  30. temp.set_str(buffer, 16);
  31. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_p.get_mpz_t());
  32. element = temp;
  33. }
  34. void Scalar::set(mpz_class input)
  35. {
  36. mpz_class temp = input;
  37. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_p.get_mpz_t());
  38. element = temp;
  39. }
  40. void Scalar::set_random()
  41. {
  42. scalar_t temp;
  43. /* When we ask for a random number,
  44. * we really mean a seed to find a random element of a group
  45. * and the order of the curve either is bn_n or is divided by it
  46. * (not bn_p) */
  47. scalar_setrandom(temp, bn_n);
  48. set(temp);
  49. }
  50. mpz_class Scalar::toInt() const
  51. {
  52. return element;
  53. }
  54. Scalar Scalar::operator+(const Scalar& b) const
  55. {
  56. return this->curveAdd(b);
  57. }
  58. Scalar Scalar::operator-(const Scalar& b) const
  59. {
  60. return this->curveSub(b);
  61. }
  62. Scalar Scalar::operator*(const Scalar& b) const
  63. {
  64. return this->curveMult(b);
  65. }
  66. Scalar Scalar::operator/(const Scalar& b) const
  67. {
  68. return this->curveMult(b.curveMultInverse());
  69. }
  70. Scalar Scalar::operator-() const
  71. {
  72. return Scalar(0).curveSub(*this);
  73. }
  74. Scalar& Scalar::operator++()
  75. {
  76. *this = this->curveAdd(Scalar(1));
  77. return *this;
  78. }
  79. Scalar Scalar::operator++(int)
  80. {
  81. Scalar retval = *this;
  82. *this = this->curveAdd(Scalar(1));
  83. return retval;
  84. }
  85. Scalar& Scalar::operator--()
  86. {
  87. *this = this->curveSub(Scalar(1));
  88. return *this;
  89. }
  90. Scalar Scalar::operator--(int)
  91. {
  92. Scalar retval = *this;
  93. *this = this->curveSub(Scalar(1));
  94. return retval;
  95. }
  96. Scalar Scalar::fieldAdd(const Scalar& b) const
  97. {
  98. mpz_class temp = element + b.element;
  99. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_p.get_mpz_t());
  100. return Scalar(temp);
  101. }
  102. Scalar Scalar::fieldSub(const Scalar& b) const
  103. {
  104. mpz_class temp = element - b.element;
  105. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_p.get_mpz_t());
  106. return Scalar(temp);
  107. }
  108. Scalar Scalar::fieldMult(const Scalar& b) const
  109. {
  110. mpz_class temp = element * b.element;
  111. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_p.get_mpz_t());
  112. return Scalar(temp);
  113. }
  114. Scalar Scalar::fieldMultInverse() const
  115. {
  116. mpz_class temp;
  117. mpz_invert(temp.get_mpz_t(), element.get_mpz_t(), mpz_bn_p.get_mpz_t());
  118. return Scalar(temp);
  119. }
  120. Scalar Scalar::curveAdd(const Scalar& b) const
  121. {
  122. mpz_class temp = element + b.element;
  123. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_n.get_mpz_t());
  124. return Scalar(temp);
  125. }
  126. Scalar Scalar::curveSub(const Scalar& b) const
  127. {
  128. mpz_class temp = element - b.element;
  129. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_n.get_mpz_t());
  130. return Scalar(temp);
  131. }
  132. Scalar Scalar::curveMult(const Scalar& b) const
  133. {
  134. mpz_class temp = element * b.element;
  135. mpz_mod(temp.get_mpz_t(), temp.get_mpz_t(), mpz_bn_n.get_mpz_t());
  136. return Scalar(temp);
  137. }
  138. Scalar Scalar::curveMultInverse() const
  139. {
  140. mpz_class temp;
  141. mpz_invert(temp.get_mpz_t(), element.get_mpz_t(), mpz_bn_n.get_mpz_t());
  142. return Scalar(temp);
  143. }
  144. void Scalar::mult(curvepoint_fp_t rop, const curvepoint_fp_t& op1) const
  145. {
  146. SecretScalar secret_element = to_scalar_t();
  147. curvepoint_fp_scalarmult_vartime(rop, op1, secret_element.expose());
  148. }
  149. void Scalar::mult(twistpoint_fp2_t rop, const twistpoint_fp2_t& op1) const
  150. {
  151. SecretScalar secret_element = to_scalar_t();
  152. twistpoint_fp2_scalarmult_vartime(rop, op1, secret_element.expose());
  153. }
  154. void Scalar::mult(fp12e_t rop, const fp12e_t& op1) const
  155. {
  156. SecretScalar secret_element = to_scalar_t();
  157. fp12e_pow_vartime(rop, op1, secret_element.expose());
  158. }
  159. bool Scalar::operator==(const Scalar& b) const
  160. {
  161. return element == b.element;
  162. }
  163. bool Scalar::operator<(const Scalar& b) const
  164. {
  165. return element < b.element;
  166. }
  167. bool Scalar::operator<=(const Scalar& b) const
  168. {
  169. return element <= b.element;
  170. }
  171. bool Scalar::operator>(const Scalar& b) const
  172. {
  173. return element > b.element;
  174. }
  175. bool Scalar::operator>=(const Scalar& b) const
  176. {
  177. return element >= b.element;
  178. }
  179. bool Scalar::operator!=(const Scalar& b) const
  180. {
  181. return element != b.element;
  182. }
  183. Scalar::SecretScalar::SecretScalar()
  184. { }
  185. Scalar::SecretScalar::SecretScalar(const Scalar& input)
  186. {
  187. set(input.element);
  188. }
  189. Scalar::SecretScalar::SecretScalar(mpz_class input)
  190. {
  191. set(input);
  192. }
  193. const scalar_t& Scalar::SecretScalar::expose() const
  194. {
  195. return element;
  196. }
  197. void Scalar::SecretScalar::set(mpz_class input)
  198. {
  199. std::stringstream buffer;
  200. char temp[17];
  201. buffer << std::setfill('0') << std::setw(64) << input.get_str(16);
  202. for (int i = 3; i >= 0; i--)
  203. {
  204. buffer.get(temp, 17);
  205. element[i] = strtoull(temp, NULL, 16);
  206. }
  207. }
  208. Scalar::SecretScalar Scalar::to_scalar_t() const
  209. {
  210. return SecretScalar(element);
  211. }
  212. std::ostream& operator<<(std::ostream& os, const Scalar& output)
  213. {
  214. os << output.element;
  215. return os;
  216. }
  217. std::istream& operator>>(std::istream& is, Scalar& input)
  218. {
  219. is >> input.element;
  220. return is;
  221. }