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.

285 lines
8.7 KiB

  1. #ifndef CRYPTOPP_ALGEBRA_H
  2. #define CRYPTOPP_ALGEBRA_H
  3. #include "config.h"
  4. NAMESPACE_BEGIN(CryptoPP)
  5. class Integer;
  6. // "const Element&" returned by member functions are references
  7. // to internal data members. Since each object may have only
  8. // one such data member for holding results, the following code
  9. // will produce incorrect results:
  10. // abcd = group.Add(group.Add(a,b), group.Add(c,d));
  11. // But this should be fine:
  12. // abcd = group.Add(a, group.Add(b, group.Add(c,d));
  13. //! Abstract Group
  14. template <class T> class CRYPTOPP_NO_VTABLE AbstractGroup
  15. {
  16. public:
  17. typedef T Element;
  18. virtual ~AbstractGroup() {}
  19. virtual bool Equal(const Element &a, const Element &b) const =0;
  20. virtual const Element& Identity() const =0;
  21. virtual const Element& Add(const Element &a, const Element &b) const =0;
  22. virtual const Element& Inverse(const Element &a) const =0;
  23. virtual bool InversionIsFast() const {return false;}
  24. virtual const Element& Double(const Element &a) const;
  25. virtual const Element& Subtract(const Element &a, const Element &b) const;
  26. virtual Element& Accumulate(Element &a, const Element &b) const;
  27. virtual Element& Reduce(Element &a, const Element &b) const;
  28. virtual Element ScalarMultiply(const Element &a, const Integer &e) const;
  29. virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
  30. virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
  31. };
  32. //! Abstract Ring
  33. template <class T> class CRYPTOPP_NO_VTABLE AbstractRing : public AbstractGroup<T>
  34. {
  35. public:
  36. typedef T Element;
  37. AbstractRing() {m_mg.m_pRing = this;}
  38. AbstractRing(const AbstractRing &source) {m_mg.m_pRing = this;}
  39. AbstractRing& operator=(const AbstractRing &source) {return *this;}
  40. virtual bool IsUnit(const Element &a) const =0;
  41. virtual const Element& MultiplicativeIdentity() const =0;
  42. virtual const Element& Multiply(const Element &a, const Element &b) const =0;
  43. virtual const Element& MultiplicativeInverse(const Element &a) const =0;
  44. virtual const Element& Square(const Element &a) const;
  45. virtual const Element& Divide(const Element &a, const Element &b) const;
  46. virtual Element Exponentiate(const Element &a, const Integer &e) const;
  47. virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
  48. virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
  49. virtual const AbstractGroup<T>& MultiplicativeGroup() const
  50. {return m_mg;}
  51. private:
  52. class MultiplicativeGroupT : public AbstractGroup<T>
  53. {
  54. public:
  55. const AbstractRing<T>& GetRing() const
  56. {return *m_pRing;}
  57. bool Equal(const Element &a, const Element &b) const
  58. {return GetRing().Equal(a, b);}
  59. const Element& Identity() const
  60. {return GetRing().MultiplicativeIdentity();}
  61. const Element& Add(const Element &a, const Element &b) const
  62. {return GetRing().Multiply(a, b);}
  63. Element& Accumulate(Element &a, const Element &b) const
  64. {return a = GetRing().Multiply(a, b);}
  65. const Element& Inverse(const Element &a) const
  66. {return GetRing().MultiplicativeInverse(a);}
  67. const Element& Subtract(const Element &a, const Element &b) const
  68. {return GetRing().Divide(a, b);}
  69. Element& Reduce(Element &a, const Element &b) const
  70. {return a = GetRing().Divide(a, b);}
  71. const Element& Double(const Element &a) const
  72. {return GetRing().Square(a);}
  73. Element ScalarMultiply(const Element &a, const Integer &e) const
  74. {return GetRing().Exponentiate(a, e);}
  75. Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
  76. {return GetRing().CascadeExponentiate(x, e1, y, e2);}
  77. void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
  78. {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);}
  79. const AbstractRing<T> *m_pRing;
  80. };
  81. MultiplicativeGroupT m_mg;
  82. };
  83. // ********************************************************
  84. //! Base and Exponent
  85. template <class T, class E = Integer>
  86. struct BaseAndExponent
  87. {
  88. public:
  89. BaseAndExponent() {}
  90. BaseAndExponent(const T &basex, const E &exponentx) : base(basex), exponent(exponentx) {}
  91. bool operator<(const BaseAndExponent<T, E> &rhs) const {return exponent < rhs.exponent;}
  92. T base;
  93. E exponent;
  94. };
  95. // VC60 workaround: incomplete member template support
  96. template <class Element, class Iterator>
  97. Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end);
  98. template <class Element, class Iterator>
  99. Element GeneralCascadeExponentiation(const AbstractRing<Element> &ring, Iterator begin, Iterator end);
  100. // ********************************************************
  101. //! Abstract Euclidean Domain
  102. template <class T> class CRYPTOPP_NO_VTABLE AbstractEuclideanDomain : public AbstractRing<T>
  103. {
  104. public:
  105. typedef T Element;
  106. virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0;
  107. virtual const Element& Mod(const Element &a, const Element &b) const =0;
  108. virtual const Element& Gcd(const Element &a, const Element &b) const;
  109. protected:
  110. mutable Element result;
  111. };
  112. // ********************************************************
  113. //! EuclideanDomainOf
  114. template <class T> class EuclideanDomainOf : public AbstractEuclideanDomain<T>
  115. {
  116. public:
  117. typedef T Element;
  118. EuclideanDomainOf() {}
  119. bool Equal(const Element &a, const Element &b) const
  120. {return a==b;}
  121. const Element& Identity() const
  122. {return Element::Zero();}
  123. const Element& Add(const Element &a, const Element &b) const
  124. {return result = a+b;}
  125. Element& Accumulate(Element &a, const Element &b) const
  126. {return a+=b;}
  127. const Element& Inverse(const Element &a) const
  128. {return result = -a;}
  129. const Element& Subtract(const Element &a, const Element &b) const
  130. {return result = a-b;}
  131. Element& Reduce(Element &a, const Element &b) const
  132. {return a-=b;}
  133. const Element& Double(const Element &a) const
  134. {return result = a.Doubled();}
  135. const Element& MultiplicativeIdentity() const
  136. {return Element::One();}
  137. const Element& Multiply(const Element &a, const Element &b) const
  138. {return result = a*b;}
  139. const Element& Square(const Element &a) const
  140. {return result = a.Squared();}
  141. bool IsUnit(const Element &a) const
  142. {return a.IsUnit();}
  143. const Element& MultiplicativeInverse(const Element &a) const
  144. {return result = a.MultiplicativeInverse();}
  145. const Element& Divide(const Element &a, const Element &b) const
  146. {return result = a/b;}
  147. const Element& Mod(const Element &a, const Element &b) const
  148. {return result = a%b;}
  149. void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
  150. {Element::Divide(r, q, a, d);}
  151. bool operator==(const EuclideanDomainOf<T> &rhs) const
  152. {return true;}
  153. private:
  154. mutable Element result;
  155. };
  156. //! Quotient Ring
  157. template <class T> class QuotientRing : public AbstractRing<typename T::Element>
  158. {
  159. public:
  160. typedef T EuclideanDomain;
  161. typedef typename T::Element Element;
  162. QuotientRing(const EuclideanDomain &domain, const Element &modulus)
  163. : m_domain(domain), m_modulus(modulus) {}
  164. const EuclideanDomain & GetDomain() const
  165. {return m_domain;}
  166. const Element& GetModulus() const
  167. {return m_modulus;}
  168. bool Equal(const Element &a, const Element &b) const
  169. {return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Identity());}
  170. const Element& Identity() const
  171. {return m_domain.Identity();}
  172. const Element& Add(const Element &a, const Element &b) const
  173. {return m_domain.Add(a, b);}
  174. Element& Accumulate(Element &a, const Element &b) const
  175. {return m_domain.Accumulate(a, b);}
  176. const Element& Inverse(const Element &a) const
  177. {return m_domain.Inverse(a);}
  178. const Element& Subtract(const Element &a, const Element &b) const
  179. {return m_domain.Subtract(a, b);}
  180. Element& Reduce(Element &a, const Element &b) const
  181. {return m_domain.Reduce(a, b);}
  182. const Element& Double(const Element &a) const
  183. {return m_domain.Double(a);}
  184. bool IsUnit(const Element &a) const
  185. {return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));}
  186. const Element& MultiplicativeIdentity() const
  187. {return m_domain.MultiplicativeIdentity();}
  188. const Element& Multiply(const Element &a, const Element &b) const
  189. {return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);}
  190. const Element& Square(const Element &a) const
  191. {return m_domain.Mod(m_domain.Square(a), m_modulus);}
  192. const Element& MultiplicativeInverse(const Element &a) const;
  193. bool operator==(const QuotientRing<T> &rhs) const
  194. {return m_domain == rhs.m_domain && m_modulus == rhs.m_modulus;}
  195. protected:
  196. EuclideanDomain m_domain;
  197. Element m_modulus;
  198. };
  199. NAMESPACE_END
  200. #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
  201. #include "algebra.cpp"
  202. #endif
  203. #endif