File indexing completed on 2025-01-18 09:55:02
0001
0002
0003
0004
0005
0006
0007 #ifndef CRYPTOPP_ECCRYPTO_H
0008 #define CRYPTOPP_ECCRYPTO_H
0009
0010 #include "config.h"
0011 #include "cryptlib.h"
0012 #include "pubkey.h"
0013 #include "integer.h"
0014 #include "asn.h"
0015 #include "hmac.h"
0016 #include "sha.h"
0017 #include "gfpcrypt.h"
0018 #include "dh.h"
0019 #include "mqv.h"
0020 #include "hmqv.h"
0021 #include "fhmqv.h"
0022 #include "ecp.h"
0023 #include "ec2n.h"
0024
0025 #include <iosfwd>
0026
0027 #if CRYPTOPP_MSC_VERSION
0028 # pragma warning(push)
0029 # pragma warning(disable: 4231 4275)
0030 #endif
0031
0032 NAMESPACE_BEGIN(CryptoPP)
0033
0034
0035
0036
0037
0038 template <class EC>
0039 class DL_GroupParameters_EC : public DL_GroupParametersImpl<EcPrecomputation<EC> >
0040 {
0041 typedef DL_GroupParameters_EC<EC> ThisClass;
0042
0043 public:
0044 typedef EC EllipticCurve;
0045 typedef typename EllipticCurve::Point Point;
0046 typedef Point Element;
0047 typedef IncompatibleCofactorMultiplication DefaultCofactorOption;
0048
0049 virtual ~DL_GroupParameters_EC() {}
0050
0051
0052 DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(true) {}
0053
0054
0055
0056 DL_GroupParameters_EC(const OID &oid)
0057 : m_compress(false), m_encodeAsOID(true) {Initialize(oid);}
0058
0059
0060
0061
0062
0063
0064 DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
0065 : m_compress(false), m_encodeAsOID(true) {Initialize(ec, G, n, k);}
0066
0067
0068
0069 DL_GroupParameters_EC(BufferedTransformation &bt)
0070 : m_compress(false), m_encodeAsOID(true) {BERDecode(bt);}
0071
0072
0073
0074
0075
0076
0077
0078 void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
0079 {
0080 this->m_groupPrecomputation.SetCurve(ec);
0081 this->SetSubgroupGenerator(G);
0082 m_n = n;
0083 m_k = k;
0084 }
0085
0086
0087
0088
0089 void Initialize(const OID &oid);
0090
0091
0092 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0093 void AssignFrom(const NameValuePairs &source);
0094
0095
0096
0097
0098 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
0099
0100
0101 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
0102 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
0103 const Integer & GetSubgroupOrder() const {return m_n;}
0104 Integer GetCofactor() const;
0105 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
0106 bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const;
0107 bool FastSubgroupCheckAvailable() const {return false;}
0108 void EncodeElement(bool reversible, const Element &element, byte *encoded) const
0109 {
0110 if (reversible)
0111 GetCurve().EncodePoint(encoded, element, m_compress);
0112 else
0113 element.x.Encode(encoded, GetEncodedElementSize(false));
0114 }
0115 virtual unsigned int GetEncodedElementSize(bool reversible) const
0116 {
0117 if (reversible)
0118 return GetCurve().EncodedPointSize(m_compress);
0119 else
0120 return GetCurve().GetField().MaxElementByteLength();
0121 }
0122 Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
0123 {
0124 Point result;
0125 if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true)))
0126 throw DL_BadElement();
0127 if (checkForGroupMembership && !ValidateElement(1, result, NULLPTR))
0128 throw DL_BadElement();
0129 return result;
0130 }
0131 Integer ConvertElementToInteger(const Element &element) const;
0132 Integer GetMaxExponent() const {return GetSubgroupOrder()-1;}
0133 bool IsIdentity(const Element &element) const {return element.identity;}
0134 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
0135 static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";}
0136
0137
0138 OID GetAlgorithmID() const;
0139
0140
0141 Element MultiplyElements(const Element &a, const Element &b) const;
0142 Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
0143
0144
0145
0146
0147 static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid);
0148
0149 void BERDecode(BufferedTransformation &bt);
0150 void DEREncode(BufferedTransformation &bt) const;
0151
0152 void SetPointCompression(bool compress) {m_compress = compress;}
0153 bool GetPointCompression() const {return m_compress;}
0154
0155 void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
0156 bool GetEncodeAsOID() const {return m_encodeAsOID;}
0157
0158 const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();}
0159
0160 bool operator==(const ThisClass &rhs) const
0161 {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);}
0162
0163 protected:
0164 unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();}
0165 unsigned int ExponentLength() const {return m_n.ByteCount();}
0166
0167 OID m_oid;
0168 Integer m_n;
0169 mutable Integer m_k;
0170 mutable bool m_compress, m_encodeAsOID;
0171 };
0172
0173 inline std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj);
0174
0175
0176
0177 template <class EC>
0178 class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
0179 {
0180 public:
0181 typedef typename EC::Point Element;
0182
0183 virtual ~DL_PublicKey_EC() {}
0184
0185
0186
0187
0188
0189 void Initialize(const DL_GroupParameters_EC<EC> ¶ms, const Element &Q)
0190 {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
0191
0192
0193
0194
0195
0196
0197
0198 void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
0199 {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);}
0200
0201
0202 void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0203 void DEREncodePublicKey(BufferedTransformation &bt) const;
0204 };
0205
0206
0207
0208 template <class EC>
0209 class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
0210 {
0211 public:
0212 typedef typename EC::Point Element;
0213
0214 virtual ~DL_PrivateKey_EC();
0215
0216
0217
0218
0219
0220 void Initialize(const DL_GroupParameters_EC<EC> ¶ms, const Integer &x)
0221 {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
0222
0223
0224
0225
0226
0227
0228
0229 void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
0230 {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);}
0231
0232
0233
0234
0235
0236
0237
0238 void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> ¶ms)
0239 {this->GenerateRandom(rng, params);}
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
0250 {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
0251
0252
0253 void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0254 void DEREncodePrivateKey(BufferedTransformation &bt) const;
0255 };
0256
0257
0258 template<class EC>
0259 DL_PrivateKey_EC<EC>::~DL_PrivateKey_EC() {}
0260
0261
0262
0263
0264
0265
0266 template <class EC, class COFACTOR_OPTION = typename DL_GroupParameters_EC<EC>::DefaultCofactorOption>
0267 struct ECDH
0268 {
0269 typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
0270 };
0271
0272
0273
0274
0275
0276 template <class EC, class COFACTOR_OPTION = typename DL_GroupParameters_EC<EC>::DefaultCofactorOption>
0277 struct ECMQV
0278 {
0279 typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
0280 };
0281
0282
0283
0284
0285
0286
0287
0288 template <class EC, class COFACTOR_OPTION = typename DL_GroupParameters_EC<EC>::DefaultCofactorOption, class HASH = SHA256>
0289 struct ECHMQV
0290 {
0291 typedef HMQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION, HASH> Domain;
0292 };
0293
0294 typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain ECHMQV160;
0295 typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain ECHMQV256;
0296 typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECHMQV384;
0297 typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECHMQV512;
0298
0299
0300
0301
0302
0303
0304
0305
0306 template <class EC, class COFACTOR_OPTION = typename DL_GroupParameters_EC<EC>::DefaultCofactorOption, class HASH = SHA256>
0307 struct ECFHMQV
0308 {
0309 typedef FHMQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION, HASH> Domain;
0310 };
0311
0312 typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA1 >::Domain ECFHMQV160;
0313 typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 >::Domain ECFHMQV256;
0314 typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECFHMQV384;
0315 typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECFHMQV512;
0316
0317
0318
0319 template <class EC>
0320 struct DL_Keys_EC
0321 {
0322 typedef DL_PublicKey_EC<EC> PublicKey;
0323 typedef DL_PrivateKey_EC<EC> PrivateKey;
0324 };
0325
0326
0327 template <class EC, class H>
0328 struct ECDSA;
0329
0330
0331
0332
0333 template <class EC>
0334 struct DL_Keys_ECDSA
0335 {
0336 typedef DL_PublicKey_EC<EC> PublicKey;
0337 typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC, SHA256> > PrivateKey;
0338 };
0339
0340
0341
0342
0343 template <class EC>
0344 class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
0345 {
0346 public:
0347 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
0348 };
0349
0350
0351
0352
0353
0354
0355 template <class EC, class H>
0356 class DL_Algorithm_ECDSA_RFC6979 : public DL_Algorithm_DSA_RFC6979<typename EC::Point, H>
0357 {
0358 public:
0359 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECDSA-RFC6979";}
0360 };
0361
0362
0363
0364 template <class EC>
0365 class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
0366 {
0367 public:
0368 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECNR";}
0369 };
0370
0371
0372
0373
0374
0375
0376 template <class EC, class H>
0377 struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
0378 {
0379 };
0380
0381
0382
0383
0384
0385
0386
0387 template <class EC, class H>
0388 struct ECDSA_RFC6979 : public DL_SS<
0389 DL_Keys_ECDSA<EC>,
0390 DL_Algorithm_ECDSA_RFC6979<EC, H>,
0391 DL_SignatureMessageEncodingMethod_DSA,
0392 H,
0393 ECDSA_RFC6979<EC,H> >
0394 {
0395 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("ECDSA-RFC6979/") + H::StaticAlgorithmName();}
0396 };
0397
0398
0399
0400
0401 template <class EC, class H = SHA1>
0402 struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H>
0403 {
0404 };
0405
0406
0407
0408 template <class EC>
0409 class DL_PublicKey_ECGDSA;
0410 template <class EC>
0411 class DL_PrivateKey_ECGDSA;
0412
0413
0414
0415
0416
0417 template <class EC>
0418 class DL_PrivateKey_ECGDSA : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
0419 {
0420 public:
0421 typedef typename EC::Point Element;
0422
0423 virtual ~DL_PrivateKey_ECGDSA() {}
0424
0425
0426
0427
0428
0429 void Initialize(const DL_GroupParameters_EC<EC> ¶ms, const Integer &x)
0430 {
0431 this->AccessGroupParameters() = params;
0432 this->SetPrivateExponent(x);
0433 CRYPTOPP_ASSERT(x>=1 && x<=params.GetSubgroupOrder()-1);
0434 }
0435
0436
0437
0438
0439
0440
0441
0442 void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
0443 {
0444 this->AccessGroupParameters().Initialize(ec, G, n);
0445 this->SetPrivateExponent(x);
0446 CRYPTOPP_ASSERT(x>=1 && x<=this->AccessGroupParameters().GetSubgroupOrder()-1);
0447 }
0448
0449
0450
0451
0452
0453
0454
0455 void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> ¶ms)
0456 {this->GenerateRandom(rng, params);}
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466 void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
0467 {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
0468
0469 virtual void MakePublicKey(DL_PublicKey_ECGDSA<EC> &pub) const
0470 {
0471 const DL_GroupParameters<Element>& params = this->GetAbstractGroupParameters();
0472 pub.AccessAbstractGroupParameters().AssignFrom(params);
0473 const Integer &xInv = this->GetPrivateExponent().InverseMod(params.GetSubgroupOrder());
0474 pub.SetPublicElement(params.ExponentiateBase(xInv));
0475 CRYPTOPP_ASSERT(xInv.NotZero());
0476 }
0477
0478 virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
0479 {
0480 return GetValueHelper<DL_PrivateKey_ECGDSA<EC>,
0481 DL_PrivateKey_ECGDSA<EC> >(this, name, valueType, pValue).Assignable();
0482 }
0483
0484 virtual void AssignFrom(const NameValuePairs &source)
0485 {
0486 AssignFromHelper<DL_PrivateKey_ECGDSA<EC>,
0487 DL_PrivateKey_ECGDSA<EC> >(this, source);
0488 }
0489
0490
0491 void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0492 void DEREncodePrivateKey(BufferedTransformation &bt) const;
0493 };
0494
0495
0496
0497
0498
0499 template <class EC>
0500 class DL_PublicKey_ECGDSA : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
0501 {
0502 typedef DL_PublicKey_ECGDSA<EC> ThisClass;
0503
0504 public:
0505 typedef typename EC::Point Element;
0506
0507 virtual ~DL_PublicKey_ECGDSA() {}
0508
0509
0510
0511
0512
0513 void Initialize(const DL_GroupParameters_EC<EC> ¶ms, const Element &Q)
0514 {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
0515
0516
0517
0518
0519
0520
0521
0522 void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
0523 {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);}
0524
0525 virtual void AssignFrom(const NameValuePairs &source)
0526 {
0527 DL_PrivateKey_ECGDSA<EC> *pPrivateKey = NULLPTR;
0528 if (source.GetThisPointer(pPrivateKey))
0529 pPrivateKey->MakePublicKey(*this);
0530 else
0531 {
0532 this->AccessAbstractGroupParameters().AssignFrom(source);
0533 AssignFromHelper(this, source)
0534 CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
0535 }
0536 }
0537
0538
0539 virtual void SetPublicElement(const Element &y)
0540 {this->AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
0541
0542
0543 void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0544 void DEREncodePublicKey(BufferedTransformation &bt) const;
0545 };
0546
0547
0548
0549
0550
0551 template <class EC>
0552 struct DL_Keys_ECGDSA
0553 {
0554 typedef DL_PublicKey_ECGDSA<EC> PublicKey;
0555 typedef DL_PrivateKey_ECGDSA<EC> PrivateKey;
0556 };
0557
0558
0559
0560
0561
0562 template <class EC>
0563 class DL_Algorithm_ECGDSA : public DL_Algorithm_GDSA_ISO15946<typename EC::Point>
0564 {
0565 public:
0566 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECGDSA";}
0567 };
0568
0569
0570
0571
0572
0573
0574
0575
0576 template <class EC, class H>
0577 struct ECGDSA : public DL_SS<
0578 DL_Keys_ECGDSA<EC>,
0579 DL_Algorithm_ECGDSA<EC>,
0580 DL_SignatureMessageEncodingMethod_DSA,
0581 H>
0582 {
0583 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("ECGDSA-ISO15946/") + H::StaticAlgorithmName();}
0584 };
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607 template <class EC, class HASH = SHA1, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true, bool LABEL_OCTETS = false>
0608 struct ECIES
0609 : public DL_ES<
0610 DL_Keys_EC<EC>,
0611 DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
0612 DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<HASH> >,
0613 DL_EncryptionAlgorithm_Xor<HMAC<HASH>, DHAES_MODE, LABEL_OCTETS>,
0614 ECIES<EC> >
0615 {
0616
0617 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES";}
0618 };
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640 template <class EC, class HASH = SHA1, class COFACTOR_OPTION = NoCofactorMultiplication>
0641 struct ECIES_P1363
0642 : public DL_ES<
0643 DL_Keys_EC<EC>,
0644 DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
0645 DL_KeyDerivationAlgorithm_P1363<typename EC::Point, false, P1363_KDF2<HASH> >,
0646 DL_EncryptionAlgorithm_Xor<HMAC<HASH>, false, true>,
0647 ECIES<EC> >
0648 {
0649
0650 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES-P1363";}
0651 };
0652
0653 NAMESPACE_END
0654
0655 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
0656 #include "eccrypto.cpp"
0657 #endif
0658
0659 NAMESPACE_BEGIN(CryptoPP)
0660
0661 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>;
0662 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>;
0663 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >;
0664 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >;
0665 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>;
0666 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>;
0667 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_ECGDSA<ECP>;
0668 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_ECGDSA<EC2N>;
0669 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
0670 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
0671 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
0672 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
0673 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_ECGDSA<ECP>;
0674 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_ECGDSA<EC2N>;
0675 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
0676 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
0677 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
0678 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
0679
0680 NAMESPACE_END
0681
0682 #if CRYPTOPP_MSC_VERSION
0683 # pragma warning(pop)
0684 #endif
0685
0686 #endif