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.

280 lines
10 KiB

  1. #ifndef CRYPTOPP_ECCRYPTO_H
  2. #define CRYPTOPP_ECCRYPTO_H
  3. /*! \file
  4. */
  5. #include "pubkey.h"
  6. #include "integer.h"
  7. #include "asn.h"
  8. #include "hmac.h"
  9. #include "sha.h"
  10. #include "gfpcrypt.h"
  11. #include "dh.h"
  12. #include "mqv.h"
  13. #include "ecp.h"
  14. #include "ec2n.h"
  15. NAMESPACE_BEGIN(CryptoPP)
  16. //! Elliptic Curve Parameters
  17. /*! This class corresponds to the ASN.1 sequence of the same name
  18. in ANSI X9.62 (also SEC 1).
  19. */
  20. template <class EC>
  21. class DL_GroupParameters_EC : public DL_GroupParametersImpl<EcPrecomputation<EC> >
  22. {
  23. typedef DL_GroupParameters_EC<EC> ThisClass;
  24. public:
  25. typedef EC EllipticCurve;
  26. typedef typename EllipticCurve::Point Point;
  27. typedef Point Element;
  28. typedef IncompatibleCofactorMultiplication DefaultCofactorOption;
  29. DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {}
  30. DL_GroupParameters_EC(const OID &oid)
  31. : m_compress(false), m_encodeAsOID(false) {Initialize(oid);}
  32. DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
  33. : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);}
  34. DL_GroupParameters_EC(BufferedTransformation &bt)
  35. : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);}
  36. void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
  37. {
  38. this->m_groupPrecomputation.SetCurve(ec);
  39. SetSubgroupGenerator(G);
  40. m_n = n;
  41. m_k = k;
  42. }
  43. void Initialize(const OID &oid);
  44. // NameValuePairs
  45. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
  46. void AssignFrom(const NameValuePairs &source);
  47. // GeneratibleCryptoMaterial interface
  48. //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values
  49. /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */
  50. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
  51. // DL_GroupParameters
  52. const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
  53. DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
  54. const Integer & GetSubgroupOrder() const {return m_n;}
  55. Integer GetCofactor() const;
  56. bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
  57. bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const;
  58. bool FastSubgroupCheckAvailable() const {return false;}
  59. void EncodeElement(bool reversible, const Element &element, byte *encoded) const
  60. {
  61. if (reversible)
  62. GetCurve().EncodePoint(encoded, element, m_compress);
  63. else
  64. element.x.Encode(encoded, GetEncodedElementSize(false));
  65. }
  66. unsigned int GetEncodedElementSize(bool reversible) const
  67. {
  68. if (reversible)
  69. return GetCurve().EncodedPointSize(m_compress);
  70. else
  71. return GetCurve().GetField().MaxElementByteLength();
  72. }
  73. Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
  74. {
  75. Point result;
  76. if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true)))
  77. throw DL_BadElement();
  78. if (checkForGroupMembership && !ValidateElement(1, result, NULL))
  79. throw DL_BadElement();
  80. return result;
  81. }
  82. Integer ConvertElementToInteger(const Element &element) const;
  83. Integer GetMaxExponent() const {return GetSubgroupOrder()-1;}
  84. bool IsIdentity(const Element &element) const {return element.identity;}
  85. void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
  86. static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";}
  87. // ASN1Key
  88. OID GetAlgorithmID() const;
  89. // used by MQV
  90. Element MultiplyElements(const Element &a, const Element &b) const;
  91. Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
  92. // non-inherited
  93. // enumerate OIDs for recommended parameters, use OID() to get first one
  94. static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid);
  95. void BERDecode(BufferedTransformation &bt);
  96. void DEREncode(BufferedTransformation &bt) const;
  97. void SetPointCompression(bool compress) {m_compress = compress;}
  98. bool GetPointCompression() const {return m_compress;}
  99. void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
  100. bool GetEncodeAsOID() const {return m_encodeAsOID;}
  101. const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();}
  102. bool operator==(const ThisClass &rhs) const
  103. {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);}
  104. #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
  105. const Point& GetBasePoint() const {return GetSubgroupGenerator();}
  106. const Integer& GetBasePointOrder() const {return GetSubgroupOrder();}
  107. void LoadRecommendedParameters(const OID &oid) {Initialize(oid);}
  108. #endif
  109. protected:
  110. unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();}
  111. unsigned int ExponentLength() const {return m_n.ByteCount();}
  112. OID m_oid; // set if parameters loaded from a recommended curve
  113. Integer m_n; // order of base point
  114. bool m_compress, m_encodeAsOID;
  115. mutable Integer m_k; // cofactor
  116. };
  117. //! EC public key
  118. template <class EC>
  119. class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
  120. {
  121. public:
  122. typedef typename EC::Point Element;
  123. void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
  124. {this->AccessGroupParameters() = params; SetPublicElement(Q);}
  125. void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
  126. {this->AccessGroupParameters().Initialize(ec, G, n); SetPublicElement(Q);}
  127. // X509PublicKey
  128. void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
  129. void DEREncodePublicKey(BufferedTransformation &bt) const;
  130. };
  131. //! EC private key
  132. template <class EC>
  133. class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
  134. {
  135. public:
  136. typedef typename EC::Point Element;
  137. void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
  138. {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
  139. void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
  140. {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);}
  141. void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
  142. {GenerateRandom(rng, params);}
  143. void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
  144. {GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
  145. // PKCS8PrivateKey
  146. void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
  147. void DEREncodePrivateKey(BufferedTransformation &bt) const;
  148. };
  149. //! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a>
  150. template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
  151. struct ECDH
  152. {
  153. typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
  154. };
  155. /// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a>
  156. template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
  157. struct ECMQV
  158. {
  159. typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
  160. };
  161. //! EC keys
  162. template <class EC>
  163. struct DL_Keys_EC
  164. {
  165. typedef DL_PublicKey_EC<EC> PublicKey;
  166. typedef DL_PrivateKey_EC<EC> PrivateKey;
  167. };
  168. template <class EC, class H>
  169. struct ECDSA;
  170. //! ECDSA keys
  171. template <class EC>
  172. struct DL_Keys_ECDSA
  173. {
  174. typedef DL_PublicKey_EC<EC> PublicKey;
  175. typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC, SHA256> > PrivateKey;
  176. };
  177. //! ECDSA algorithm
  178. template <class EC>
  179. class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
  180. {
  181. public:
  182. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
  183. };
  184. //! ECNR algorithm
  185. template <class EC>
  186. class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
  187. {
  188. public:
  189. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";}
  190. };
  191. //! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
  192. template <class EC, class H>
  193. struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
  194. {
  195. };
  196. //! ECNR
  197. template <class EC, class H = SHA>
  198. struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H>
  199. {
  200. };
  201. //! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a>
  202. /*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2.
  203. The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best
  204. efficiency and security. */
  205. template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false>
  206. struct ECIES
  207. : public DL_ES<
  208. DL_Keys_EC<EC>,
  209. DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
  210. DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >,
  211. DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
  212. ECIES<EC> >
  213. {
  214. static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
  215. };
  216. NAMESPACE_END
  217. #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
  218. #include "eccrypto.cpp"
  219. #endif
  220. NAMESPACE_BEGIN(CryptoPP)
  221. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>;
  222. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>;
  223. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >;
  224. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >;
  225. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>;
  226. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>;
  227. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
  228. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
  229. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
  230. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
  231. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
  232. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
  233. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
  234. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
  235. NAMESPACE_END
  236. #endif