Counter Strike : Global Offensive Source Code
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.

215 lines
5.1 KiB

  1. #ifndef CRYPTOPP_XTR_H
  2. #define CRYPTOPP_XTR_H
  3. /** \file
  4. "The XTR public key system" by Arjen K. Lenstra and Eric R. Verheul
  5. */
  6. #include "modarith.h"
  7. NAMESPACE_BEGIN(CryptoPP)
  8. //! an element of GF(p^2)
  9. class GFP2Element
  10. {
  11. public:
  12. GFP2Element() {}
  13. GFP2Element(const Integer &c1, const Integer &c2) : c1(c1), c2(c2) {}
  14. GFP2Element(const byte *encodedElement, unsigned int size)
  15. : c1(encodedElement, size/2), c2(encodedElement+size/2, size/2) {}
  16. void Encode(byte *encodedElement, unsigned int size)
  17. {
  18. c1.Encode(encodedElement, size/2);
  19. c2.Encode(encodedElement+size/2, size/2);
  20. }
  21. bool operator==(const GFP2Element &rhs) const {return c1 == rhs.c1 && c2 == rhs.c2;}
  22. bool operator!=(const GFP2Element &rhs) const {return !operator==(rhs);}
  23. void swap(GFP2Element &a)
  24. {
  25. c1.swap(a.c1);
  26. c2.swap(a.c2);
  27. }
  28. static const GFP2Element & Zero();
  29. Integer c1, c2;
  30. };
  31. //! GF(p^2), optimal normal basis
  32. template <class F>
  33. class GFP2_ONB : public AbstractRing<GFP2Element>
  34. {
  35. public:
  36. typedef F BaseField;
  37. GFP2_ONB(const Integer &p) : modp(p)
  38. {
  39. if (p%3 != 2)
  40. throw InvalidArgument("GFP2_ONB: modulus must be equivalent to 2 mod 3");
  41. }
  42. const Integer& GetModulus() const {return modp.GetModulus();}
  43. GFP2Element ConvertIn(const Integer &a) const
  44. {
  45. t = modp.Inverse(modp.ConvertIn(a));
  46. return GFP2Element(t, t);
  47. }
  48. GFP2Element ConvertIn(const GFP2Element &a) const
  49. {return GFP2Element(modp.ConvertIn(a.c1), modp.ConvertIn(a.c2));}
  50. GFP2Element ConvertOut(const GFP2Element &a) const
  51. {return GFP2Element(modp.ConvertOut(a.c1), modp.ConvertOut(a.c2));}
  52. bool Equal(const GFP2Element &a, const GFP2Element &b) const
  53. {
  54. return modp.Equal(a.c1, b.c1) && modp.Equal(a.c2, b.c2);
  55. }
  56. const Element& Identity() const
  57. {
  58. return GFP2Element::Zero();
  59. }
  60. const Element& Add(const Element &a, const Element &b) const
  61. {
  62. result.c1 = modp.Add(a.c1, b.c1);
  63. result.c2 = modp.Add(a.c2, b.c2);
  64. return result;
  65. }
  66. const Element& Inverse(const Element &a) const
  67. {
  68. result.c1 = modp.Inverse(a.c1);
  69. result.c2 = modp.Inverse(a.c2);
  70. return result;
  71. }
  72. const Element& Double(const Element &a) const
  73. {
  74. result.c1 = modp.Double(a.c1);
  75. result.c2 = modp.Double(a.c2);
  76. return result;
  77. }
  78. const Element& Subtract(const Element &a, const Element &b) const
  79. {
  80. result.c1 = modp.Subtract(a.c1, b.c1);
  81. result.c2 = modp.Subtract(a.c2, b.c2);
  82. return result;
  83. }
  84. Element& Accumulate(Element &a, const Element &b) const
  85. {
  86. modp.Accumulate(a.c1, b.c1);
  87. modp.Accumulate(a.c2, b.c2);
  88. return a;
  89. }
  90. Element& Reduce(Element &a, const Element &b) const
  91. {
  92. modp.Reduce(a.c1, b.c1);
  93. modp.Reduce(a.c2, b.c2);
  94. return a;
  95. }
  96. bool IsUnit(const Element &a) const
  97. {
  98. return a.c1.NotZero() || a.c2.NotZero();
  99. }
  100. const Element& MultiplicativeIdentity() const
  101. {
  102. result.c1 = result.c2 = modp.Inverse(modp.MultiplicativeIdentity());
  103. return result;
  104. }
  105. const Element& Multiply(const Element &a, const Element &b) const
  106. {
  107. t = modp.Add(a.c1, a.c2);
  108. t = modp.Multiply(t, modp.Add(b.c1, b.c2));
  109. result.c1 = modp.Multiply(a.c1, b.c1);
  110. result.c2 = modp.Multiply(a.c2, b.c2);
  111. result.c1.swap(result.c2);
  112. modp.Reduce(t, result.c1);
  113. modp.Reduce(t, result.c2);
  114. modp.Reduce(result.c1, t);
  115. modp.Reduce(result.c2, t);
  116. return result;
  117. }
  118. const Element& MultiplicativeInverse(const Element &a) const
  119. {
  120. return result = Exponentiate(a, modp.GetModulus()-2);
  121. }
  122. const Element& Square(const Element &a) const
  123. {
  124. const Integer &ac1 = (&a == &result) ? (t = a.c1) : a.c1;
  125. result.c1 = modp.Multiply(modp.Subtract(modp.Subtract(a.c2, a.c1), a.c1), a.c2);
  126. result.c2 = modp.Multiply(modp.Subtract(modp.Subtract(ac1, a.c2), a.c2), ac1);
  127. return result;
  128. }
  129. Element Exponentiate(const Element &a, const Integer &e) const
  130. {
  131. Integer edivp, emodp;
  132. Integer::Divide(emodp, edivp, e, modp.GetModulus());
  133. Element b = PthPower(a);
  134. return AbstractRing<GFP2Element>::CascadeExponentiate(a, emodp, b, edivp);
  135. }
  136. const Element & PthPower(const Element &a) const
  137. {
  138. result = a;
  139. result.c1.swap(result.c2);
  140. return result;
  141. }
  142. void RaiseToPthPower(Element &a) const
  143. {
  144. a.c1.swap(a.c2);
  145. }
  146. // a^2 - 2a^p
  147. const Element & SpecialOperation1(const Element &a) const
  148. {
  149. assert(&a != &result);
  150. result = Square(a);
  151. modp.Reduce(result.c1, a.c2);
  152. modp.Reduce(result.c1, a.c2);
  153. modp.Reduce(result.c2, a.c1);
  154. modp.Reduce(result.c2, a.c1);
  155. return result;
  156. }
  157. // x * z - y * z^p
  158. const Element & SpecialOperation2(const Element &x, const Element &y, const Element &z) const
  159. {
  160. assert(&x != &result && &y != &result && &z != &result);
  161. t = modp.Add(x.c2, y.c2);
  162. result.c1 = modp.Multiply(z.c1, modp.Subtract(y.c1, t));
  163. modp.Accumulate(result.c1, modp.Multiply(z.c2, modp.Subtract(t, x.c1)));
  164. t = modp.Add(x.c1, y.c1);
  165. result.c2 = modp.Multiply(z.c2, modp.Subtract(y.c2, t));
  166. modp.Accumulate(result.c2, modp.Multiply(z.c1, modp.Subtract(t, x.c2)));
  167. return result;
  168. }
  169. protected:
  170. BaseField modp;
  171. mutable GFP2Element result;
  172. mutable Integer t;
  173. };
  174. void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits);
  175. GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p);
  176. NAMESPACE_END
  177. #endif