Team Fortress 2 Source Code as on 22/4/2020
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.

671 lines
24 KiB

  1. // eccrypto.h - written and placed in the public domain by Wei Dai
  2. //! \file eccrypto.h
  3. //! \brief Classes and functions for Elliptic Curves over prime and binary fields
  4. #ifndef CRYPTOPP_ECCRYPTO_H
  5. #define CRYPTOPP_ECCRYPTO_H
  6. #include "config.h"
  7. #include "cryptlib.h"
  8. #include "pubkey.h"
  9. #include "integer.h"
  10. #include "asn.h"
  11. #include "hmac.h"
  12. #include "sha.h"
  13. #include "gfpcrypt.h"
  14. #include "dh.h"
  15. #include "mqv.h"
  16. #include "ecp.h"
  17. #include "ec2n.h"
  18. NAMESPACE_BEGIN(CryptoPP)
  19. //! Elliptic Curve Parameters
  20. /*! This class corresponds to the ASN.1 sequence of the same name
  21. in ANSI X9.62 (also SEC 1).
  22. */
  23. template <class EC>
  24. class DL_GroupParameters_EC : public DL_GroupParametersImpl<EcPrecomputation<EC> >
  25. {
  26. typedef DL_GroupParameters_EC<EC> ThisClass;
  27. public:
  28. typedef EC EllipticCurve;
  29. typedef typename EllipticCurve::Point Point;
  30. typedef Point Element;
  31. typedef IncompatibleCofactorMultiplication DefaultCofactorOption;
  32. DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {}
  33. DL_GroupParameters_EC(const OID &oid)
  34. : m_compress(false), m_encodeAsOID(false) {Initialize(oid);}
  35. DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
  36. : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);}
  37. DL_GroupParameters_EC(BufferedTransformation &bt)
  38. : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);}
  39. void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
  40. {
  41. this->m_groupPrecomputation.SetCurve(ec);
  42. this->SetSubgroupGenerator(G);
  43. m_n = n;
  44. m_k = k;
  45. }
  46. void Initialize(const OID &oid);
  47. // NameValuePairs
  48. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
  49. void AssignFrom(const NameValuePairs &source);
  50. // GeneratibleCryptoMaterial interface
  51. //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values
  52. /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */
  53. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
  54. // DL_GroupParameters
  55. const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
  56. DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
  57. const Integer & GetSubgroupOrder() const {return m_n;}
  58. Integer GetCofactor() const;
  59. bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
  60. bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const;
  61. bool FastSubgroupCheckAvailable() const {return false;}
  62. void EncodeElement(bool reversible, const Element &element, byte *encoded) const
  63. {
  64. if (reversible)
  65. GetCurve().EncodePoint(encoded, element, m_compress);
  66. else
  67. element.x.Encode(encoded, GetEncodedElementSize(false));
  68. }
  69. virtual unsigned int GetEncodedElementSize(bool reversible) const
  70. {
  71. if (reversible)
  72. return GetCurve().EncodedPointSize(m_compress);
  73. else
  74. return GetCurve().GetField().MaxElementByteLength();
  75. }
  76. Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
  77. {
  78. Point result;
  79. if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true)))
  80. throw DL_BadElement();
  81. if (checkForGroupMembership && !ValidateElement(1, result, NULL))
  82. throw DL_BadElement();
  83. return result;
  84. }
  85. Integer ConvertElementToInteger(const Element &element) const;
  86. Integer GetMaxExponent() const {return GetSubgroupOrder()-1;}
  87. bool IsIdentity(const Element &element) const {return element.identity;}
  88. void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
  89. static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";}
  90. // ASN1Key
  91. OID GetAlgorithmID() const;
  92. // used by MQV
  93. Element MultiplyElements(const Element &a, const Element &b) const;
  94. Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
  95. // non-inherited
  96. // enumerate OIDs for recommended parameters, use OID() to get first one
  97. static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid);
  98. void BERDecode(BufferedTransformation &bt);
  99. void DEREncode(BufferedTransformation &bt) const;
  100. void SetPointCompression(bool compress) {m_compress = compress;}
  101. bool GetPointCompression() const {return m_compress;}
  102. void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
  103. bool GetEncodeAsOID() const {return m_encodeAsOID;}
  104. const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();}
  105. bool operator==(const ThisClass &rhs) const
  106. {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);}
  107. #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
  108. const Point& GetBasePoint() const {return this->GetSubgroupGenerator();}
  109. const Integer& GetBasePointOrder() const {return this->GetSubgroupOrder();}
  110. void LoadRecommendedParameters(const OID &oid) {Initialize(oid);}
  111. #endif
  112. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  113. virtual ~DL_GroupParameters_EC() {}
  114. #endif
  115. protected:
  116. unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();}
  117. unsigned int ExponentLength() const {return m_n.ByteCount();}
  118. OID m_oid; // set if parameters loaded from a recommended curve
  119. Integer m_n; // order of base point
  120. mutable Integer m_k; // cofactor
  121. mutable bool m_compress, m_encodeAsOID; // presentation details
  122. };
  123. //! EC public key
  124. template <class EC>
  125. class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
  126. {
  127. public:
  128. typedef typename EC::Point Element;
  129. void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
  130. {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
  131. void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
  132. {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);}
  133. // X509PublicKey
  134. void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
  135. void DEREncodePublicKey(BufferedTransformation &bt) const;
  136. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  137. virtual ~DL_PublicKey_EC() {}
  138. #endif
  139. };
  140. //! EC private key
  141. template <class EC>
  142. class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
  143. {
  144. public:
  145. typedef typename EC::Point Element;
  146. void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
  147. {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
  148. void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
  149. {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);}
  150. void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
  151. {this->GenerateRandom(rng, params);}
  152. void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
  153. {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
  154. // PKCS8PrivateKey
  155. void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
  156. void DEREncodePrivateKey(BufferedTransformation &bt) const;
  157. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  158. virtual ~DL_PrivateKey_EC() {}
  159. #endif
  160. };
  161. //! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a>
  162. template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
  163. struct ECDH
  164. {
  165. typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
  166. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  167. virtual ~ECDH() {}
  168. #endif
  169. };
  170. /// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a>
  171. template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
  172. struct ECMQV
  173. {
  174. typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
  175. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  176. virtual ~ECMQV() {}
  177. #endif
  178. };
  179. //! EC keys
  180. template <class EC>
  181. struct DL_Keys_EC
  182. {
  183. typedef DL_PublicKey_EC<EC> PublicKey;
  184. typedef DL_PrivateKey_EC<EC> PrivateKey;
  185. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  186. virtual ~DL_Keys_EC() {}
  187. #endif
  188. };
  189. template <class EC, class H>
  190. struct ECDSA;
  191. //! ECDSA keys
  192. template <class EC>
  193. struct DL_Keys_ECDSA
  194. {
  195. typedef DL_PublicKey_EC<EC> PublicKey;
  196. typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC, SHA256> > PrivateKey;
  197. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  198. virtual ~DL_Keys_ECDSA() {}
  199. #endif
  200. };
  201. //! ECDSA algorithm
  202. template <class EC>
  203. class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
  204. {
  205. public:
  206. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
  207. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  208. virtual ~DL_Algorithm_ECDSA() {}
  209. #endif
  210. };
  211. //! ECNR algorithm
  212. template <class EC>
  213. class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
  214. {
  215. public:
  216. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";}
  217. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  218. virtual ~DL_Algorithm_ECNR() {}
  219. #endif
  220. };
  221. //! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
  222. template <class EC, class H>
  223. struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
  224. {
  225. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  226. virtual ~ECDSA() {}
  227. #endif
  228. };
  229. //! ECNR
  230. template <class EC, class H = SHA>
  231. struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H>
  232. {
  233. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  234. virtual ~ECNR() {}
  235. #endif
  236. };
  237. //! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a>
  238. /*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2.
  239. The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best
  240. efficiency and security. */
  241. template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false>
  242. struct ECIES
  243. : public DL_ES<
  244. DL_Keys_EC<EC>,
  245. DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
  246. DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >,
  247. DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
  248. ECIES<EC> >
  249. {
  250. static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
  251. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  252. virtual ~ECIES() {}
  253. #endif
  254. #if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 30000)
  255. } __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue.")));
  256. #elif (CRYPTOPP_GCC_VERSION )
  257. } __attribute__((deprecated));
  258. #else
  259. };
  260. #endif
  261. NAMESPACE_END
  262. #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
  263. #include "eccrypto.cpp"
  264. #endif
  265. NAMESPACE_BEGIN(CryptoPP)
  266. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>;
  267. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>;
  268. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >;
  269. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >;
  270. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>;
  271. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>;
  272. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
  273. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
  274. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
  275. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
  276. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
  277. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
  278. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
  279. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
  280. NAMESPACE_END
  281. #endif
  282. #ifndef CRYPTOPP_ECCRYPTO_H
  283. #define CRYPTOPP_ECCRYPTO_H
  284. /*! \file
  285. */
  286. #include "cryptlib.h"
  287. #include "pubkey.h"
  288. #include "integer.h"
  289. #include "asn.h"
  290. #include "hmac.h"
  291. #include "sha.h"
  292. #include "gfpcrypt.h"
  293. #include "dh.h"
  294. #include "mqv.h"
  295. #include "ecp.h"
  296. #include "ec2n.h"
  297. NAMESPACE_BEGIN(CryptoPP)
  298. //! Elliptic Curve Parameters
  299. /*! This class corresponds to the ASN.1 sequence of the same name
  300. in ANSI X9.62 (also SEC 1).
  301. */
  302. template <class EC>
  303. class DL_GroupParameters_EC : public DL_GroupParametersImpl<EcPrecomputation<EC> >
  304. {
  305. typedef DL_GroupParameters_EC<EC> ThisClass;
  306. public:
  307. typedef EC EllipticCurve;
  308. typedef typename EllipticCurve::Point Point;
  309. typedef Point Element;
  310. typedef IncompatibleCofactorMultiplication DefaultCofactorOption;
  311. DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {}
  312. DL_GroupParameters_EC(const OID &oid)
  313. : m_compress(false), m_encodeAsOID(false) {Initialize(oid);}
  314. DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
  315. : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);}
  316. DL_GroupParameters_EC(BufferedTransformation &bt)
  317. : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);}
  318. void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
  319. {
  320. this->m_groupPrecomputation.SetCurve(ec);
  321. this->SetSubgroupGenerator(G);
  322. m_n = n;
  323. m_k = k;
  324. }
  325. void Initialize(const OID &oid);
  326. // NameValuePairs
  327. bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
  328. void AssignFrom(const NameValuePairs &source);
  329. // GeneratibleCryptoMaterial interface
  330. //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values
  331. /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */
  332. void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
  333. // DL_GroupParameters
  334. const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
  335. DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
  336. const Integer & GetSubgroupOrder() const {return m_n;}
  337. Integer GetCofactor() const;
  338. bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
  339. bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const;
  340. bool FastSubgroupCheckAvailable() const {return false;}
  341. void EncodeElement(bool reversible, const Element &element, byte *encoded) const
  342. {
  343. if (reversible)
  344. GetCurve().EncodePoint(encoded, element, m_compress);
  345. else
  346. element.x.Encode(encoded, GetEncodedElementSize(false));
  347. }
  348. virtual unsigned int GetEncodedElementSize(bool reversible) const
  349. {
  350. if (reversible)
  351. return GetCurve().EncodedPointSize(m_compress);
  352. else
  353. return GetCurve().GetField().MaxElementByteLength();
  354. }
  355. Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
  356. {
  357. Point result;
  358. if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true)))
  359. throw DL_BadElement();
  360. if (checkForGroupMembership && !ValidateElement(1, result, NULL))
  361. throw DL_BadElement();
  362. return result;
  363. }
  364. Integer ConvertElementToInteger(const Element &element) const;
  365. Integer GetMaxExponent() const {return GetSubgroupOrder()-1;}
  366. bool IsIdentity(const Element &element) const {return element.identity;}
  367. void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
  368. static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";}
  369. // ASN1Key
  370. OID GetAlgorithmID() const;
  371. // used by MQV
  372. Element MultiplyElements(const Element &a, const Element &b) const;
  373. Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
  374. // non-inherited
  375. // enumerate OIDs for recommended parameters, use OID() to get first one
  376. static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid);
  377. void BERDecode(BufferedTransformation &bt);
  378. void DEREncode(BufferedTransformation &bt) const;
  379. void SetPointCompression(bool compress) {m_compress = compress;}
  380. bool GetPointCompression() const {return m_compress;}
  381. void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
  382. bool GetEncodeAsOID() const {return m_encodeAsOID;}
  383. const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();}
  384. bool operator==(const ThisClass &rhs) const
  385. {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);}
  386. #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
  387. const Point& GetBasePoint() const {return this->GetSubgroupGenerator();}
  388. const Integer& GetBasePointOrder() const {return this->GetSubgroupOrder();}
  389. void LoadRecommendedParameters(const OID &oid) {Initialize(oid);}
  390. #endif
  391. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  392. virtual ~DL_GroupParameters_EC() {}
  393. #endif
  394. protected:
  395. unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();}
  396. unsigned int ExponentLength() const {return m_n.ByteCount();}
  397. OID m_oid; // set if parameters loaded from a recommended curve
  398. Integer m_n; // order of base point
  399. mutable Integer m_k; // cofactor
  400. mutable bool m_compress, m_encodeAsOID; // presentation details
  401. };
  402. //! EC public key
  403. template <class EC>
  404. class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
  405. {
  406. public:
  407. typedef typename EC::Point Element;
  408. void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
  409. {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
  410. void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
  411. {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);}
  412. // X509PublicKey
  413. void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
  414. void DEREncodePublicKey(BufferedTransformation &bt) const;
  415. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  416. virtual ~DL_PublicKey_EC() {}
  417. #endif
  418. };
  419. //! EC private key
  420. template <class EC>
  421. class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
  422. {
  423. public:
  424. typedef typename EC::Point Element;
  425. void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
  426. {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
  427. void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
  428. {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);}
  429. void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
  430. {this->GenerateRandom(rng, params);}
  431. void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
  432. {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
  433. // PKCS8PrivateKey
  434. void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
  435. void DEREncodePrivateKey(BufferedTransformation &bt) const;
  436. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  437. virtual ~DL_PrivateKey_EC() {}
  438. #endif
  439. };
  440. //! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a>
  441. template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
  442. struct ECDH
  443. {
  444. typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
  445. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  446. virtual ~ECDH() {}
  447. #endif
  448. };
  449. /// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a>
  450. template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
  451. struct ECMQV
  452. {
  453. typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
  454. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  455. virtual ~ECMQV() {}
  456. #endif
  457. };
  458. //! EC keys
  459. template <class EC>
  460. struct DL_Keys_EC
  461. {
  462. typedef DL_PublicKey_EC<EC> PublicKey;
  463. typedef DL_PrivateKey_EC<EC> PrivateKey;
  464. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  465. virtual ~DL_Keys_EC() {}
  466. #endif
  467. };
  468. template <class EC, class H>
  469. struct ECDSA;
  470. //! ECDSA keys
  471. template <class EC>
  472. struct DL_Keys_ECDSA
  473. {
  474. typedef DL_PublicKey_EC<EC> PublicKey;
  475. typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC, SHA256> > PrivateKey;
  476. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  477. virtual ~DL_Keys_ECDSA() {}
  478. #endif
  479. };
  480. //! ECDSA algorithm
  481. template <class EC>
  482. class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
  483. {
  484. public:
  485. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
  486. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  487. virtual ~DL_Algorithm_ECDSA() {}
  488. #endif
  489. };
  490. //! ECNR algorithm
  491. template <class EC>
  492. class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
  493. {
  494. public:
  495. static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";}
  496. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  497. virtual ~DL_Algorithm_ECNR() {}
  498. #endif
  499. };
  500. //! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
  501. template <class EC, class H>
  502. struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
  503. {
  504. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  505. virtual ~ECDSA() {}
  506. #endif
  507. };
  508. //! ECNR
  509. template <class EC, class H = SHA>
  510. struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H>
  511. {
  512. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  513. virtual ~ECNR() {}
  514. #endif
  515. };
  516. //! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a>
  517. /*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2.
  518. The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best
  519. efficiency and security. */
  520. template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false>
  521. struct ECIES
  522. : public DL_ES<
  523. DL_Keys_EC<EC>,
  524. DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
  525. DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >,
  526. DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
  527. ECIES<EC> >
  528. {
  529. static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
  530. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  531. virtual ~ECIES() {}
  532. #endif
  533. #if (CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_CLANG_VERSION >= 20800)
  534. } __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue")));
  535. #elif (CRYPTOPP_GCC_VERSION)
  536. } __attribute__((deprecated));
  537. #else
  538. };
  539. #endif
  540. NAMESPACE_END
  541. #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
  542. #include "eccrypto.cpp"
  543. #endif
  544. NAMESPACE_BEGIN(CryptoPP)
  545. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>;
  546. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>;
  547. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >;
  548. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >;
  549. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>;
  550. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>;
  551. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
  552. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
  553. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
  554. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
  555. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
  556. CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
  557. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
  558. CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
  559. NAMESPACE_END
  560. #endif