xtr.h 5.3 KB

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