Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:02

0001 // eccrypto.h - originally written and placed in the public domain by Wei Dai

0002 //              deterministic signatures added by by Douglas Roark

0003 
0004 /// \file eccrypto.h

0005 /// \brief Classes and functions for Elliptic Curves over prime and binary fields

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 /// \brief Elliptic Curve Parameters

0035 /// \tparam EC elliptic curve field

0036 /// \details This class corresponds to the ASN.1 sequence of the same name

0037 ///  in ANSI X9.62 and SEC 1. EC is currently defined for ECP and EC2N.

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     /// \brief Construct an EC GroupParameters

0052     DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(true) {}
0053 
0054     /// \brief Construct an EC GroupParameters

0055     /// \param oid the OID of a curve

0056     DL_GroupParameters_EC(const OID &oid)
0057         : m_compress(false), m_encodeAsOID(true) {Initialize(oid);}
0058 
0059     /// \brief Construct an EC GroupParameters

0060     /// \param ec the elliptic curve

0061     /// \param G the base point

0062     /// \param n the order of the base point

0063     /// \param k the cofactor

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     /// \brief Construct an EC GroupParameters

0068     /// \param bt BufferedTransformation with group parameters

0069     DL_GroupParameters_EC(BufferedTransformation &bt)
0070         : m_compress(false), m_encodeAsOID(true) {BERDecode(bt);}
0071 
0072     /// \brief Initialize an EC GroupParameters using {EC,G,n,k}

0073     /// \param ec the elliptic curve

0074     /// \param G the base point

0075     /// \param n the order of the base point

0076     /// \param k the cofactor

0077     /// \details This Initialize() function overload initializes group parameters from existing parameters.

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     /// \brief Initialize a DL_GroupParameters_EC {EC,G,n,k}

0087     /// \param oid the OID of a curve

0088     /// \details This Initialize() function overload initializes group parameters from existing parameters.

0089     void Initialize(const OID &oid);
0090 
0091     // NameValuePairs

0092     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0093     void AssignFrom(const NameValuePairs &source);
0094 
0095     // GeneratibleCryptoMaterial interface

0096     /// this implementation doesn't actually generate a curve, it just initializes the parameters with existing values

0097     /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */
0098     void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
0099 
0100     // DL_GroupParameters

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     // ASN1Key

0138     OID GetAlgorithmID() const;
0139 
0140     // used by MQV

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     // non-inherited

0145 
0146     // enumerate OIDs for recommended parameters, use OID() to get first one

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;          // set if parameters loaded from a recommended curve

0168     Integer m_n;        // order of base point

0169     mutable Integer m_k;        // cofactor

0170     mutable bool m_compress, m_encodeAsOID;     // presentation details

0171 };
0172 
0173 inline std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj);
0174 
0175 /// \brief Elliptic Curve Discrete Log (DL) public key

0176 /// \tparam EC elliptic curve field

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     /// \brief Initialize an EC Public Key using {GP,Q}

0186     /// \param params group parameters

0187     /// \param Q the public point

0188     /// \details This Initialize() function overload initializes a public key from existing parameters.

0189     void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
0190         {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
0191 
0192     /// \brief Initialize an EC Public Key using {EC,G,n,Q}

0193     /// \param ec the elliptic curve

0194     /// \param G the base point

0195     /// \param n the order of the base point

0196     /// \param Q the public point

0197     /// \details This Initialize() function overload initializes a public key from existing parameters.

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     // X509PublicKey

0202     void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0203     void DEREncodePublicKey(BufferedTransformation &bt) const;
0204 };
0205 
0206 /// \brief Elliptic Curve Discrete Log (DL) private key

0207 /// \tparam EC elliptic curve field

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     /// \brief Initialize an EC Private Key using {GP,x}

0217     /// \param params group parameters

0218     /// \param x the private exponent

0219     /// \details This Initialize() function overload initializes a private key from existing parameters.

0220     void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
0221         {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
0222 
0223     /// \brief Initialize an EC Private Key using {EC,G,n,x}

0224     /// \param ec the elliptic curve

0225     /// \param G the base point

0226     /// \param n the order of the base point

0227     /// \param x the private exponent

0228     /// \details This Initialize() function overload initializes a private key from existing parameters.

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     /// \brief Create an EC private key

0233     /// \param rng a RandomNumberGenerator derived class

0234     /// \param params the EC group parameters

0235     /// \details This function overload of Initialize() creates a new private key because it

0236     ///  takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,

0237     ///  then use one of the other Initialize() overloads.

0238     void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
0239         {this->GenerateRandom(rng, params);}
0240 
0241     /// \brief Create an EC private key

0242     /// \param rng a RandomNumberGenerator derived class

0243     /// \param ec the elliptic curve

0244     /// \param G the base point

0245     /// \param n the order of the base point

0246     /// \details This function overload of Initialize() creates a new private key because it

0247     ///  takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,

0248     ///  then use one of the other Initialize() overloads.

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     // PKCS8PrivateKey

0253     void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0254     void DEREncodePrivateKey(BufferedTransformation &bt) const;
0255 };
0256 
0257 // Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499

0258 template<class EC>
0259 DL_PrivateKey_EC<EC>::~DL_PrivateKey_EC() {}
0260 
0261 /// \brief Elliptic Curve Diffie-Hellman

0262 /// \tparam EC elliptic curve field

0263 /// \tparam COFACTOR_OPTION cofactor multiplication option

0264 /// \sa CofactorMultiplicationOption, <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">Elliptic Curve Diffie-Hellman, AKA ECDH</a>

0265 /// \since Crypto++ 3.0

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 /// \brief Elliptic Curve Menezes-Qu-Vanstone

0273 /// \tparam EC elliptic curve field

0274 /// \tparam COFACTOR_OPTION cofactor multiplication option

0275 /// \sa CofactorMultiplicationOption, <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV</a>

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 /// \brief Hashed Elliptic Curve Menezes-Qu-Vanstone

0283 /// \tparam EC elliptic curve field

0284 /// \tparam COFACTOR_OPTION cofactor multiplication option

0285 /// \details This implementation follows Hugo Krawczyk's <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance

0286 ///  Secure Diffie-Hellman Protocol</a>. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided.

0287 /// \sa CofactorMultiplicationOption

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 /// \brief Fully Hashed Elliptic Curve Menezes-Qu-Vanstone

0300 /// \tparam EC elliptic curve field

0301 /// \tparam COFACTOR_OPTION cofactor multiplication option

0302 /// \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's

0303 ///  <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie-Hellman Protocol</a>.

0304 ///  Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.

0305 /// \sa CofactorMultiplicationOption

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 /// \brief Elliptic Curve Discrete Log (DL) keys

0318 /// \tparam EC elliptic curve field

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 // Forward declaration; documented below

0327 template <class EC, class H>
0328 struct ECDSA;
0329 
0330 /// \brief Elliptic Curve DSA keys

0331 /// \tparam EC elliptic curve field

0332 /// \since Crypto++ 3.2

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 /// \brief Elliptic Curve DSA (ECDSA) signature algorithm

0341 /// \tparam EC elliptic curve field

0342 /// \since Crypto++ 3.2

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 /// \brief Elliptic Curve DSA (ECDSA) signature algorithm based on RFC 6979

0351 /// \tparam EC elliptic curve field

0352 /// \sa <a href="http://tools.ietf.org/rfc/rfc6979.txt">RFC 6979, Deterministic Usage of the

0353 ///  Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</a>

0354 /// \since Crypto++ 6.0

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 /// \brief Elliptic Curve NR (ECNR) signature algorithm

0363 /// \tparam EC elliptic curve field

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 /// \brief Elliptic Curve DSA (ECDSA) signature scheme

0372 /// \tparam EC elliptic curve field

0373 /// \tparam H HashTransformation derived class

0374 /// \sa <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>

0375 /// \since Crypto++ 3.2

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 /// \brief Elliptic Curve DSA (ECDSA) deterministic signature scheme

0382 /// \tparam EC elliptic curve field

0383 /// \tparam H HashTransformation derived class

0384 /// \sa <a href="http://tools.ietf.org/rfc/rfc6979.txt">Deterministic Usage of the

0385 ///  Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</a>

0386 /// \since Crypto++ 6.0

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 /// \brief Elliptic Curve NR (ECNR) signature scheme

0399 /// \tparam EC elliptic curve field

0400 /// \tparam H HashTransformation derived class

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 /// \brief Elliptic Curve German DSA key for ISO/IEC 15946

0414 /// \tparam EC elliptic curve field

0415 /// \sa ECGDSA

0416 /// \since Crypto++ 6.0

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     /// \brief Initialize an EC Private Key using {GP,x}

0426     /// \param params group parameters

0427     /// \param x the private exponent

0428     /// \details This Initialize() function overload initializes a private key from existing parameters.

0429     void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
0430     {
0431         this->AccessGroupParameters() = params;
0432         this->SetPrivateExponent(x);
0433         CRYPTOPP_ASSERT(x>=1 && x<=params.GetSubgroupOrder()-1);
0434     }
0435 
0436     /// \brief Initialize an EC Private Key using {EC,G,n,x}

0437     /// \param ec the elliptic curve

0438     /// \param G the base point

0439     /// \param n the order of the base point

0440     /// \param x the private exponent

0441     /// \details This Initialize() function overload initializes a private key from existing parameters.

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     /// \brief Create an EC private key

0450     /// \param rng a RandomNumberGenerator derived class

0451     /// \param params the EC group parameters

0452     /// \details This function overload of Initialize() creates a new private key because it

0453     ///  takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,

0454     ///  then use one of the other Initialize() overloads.

0455     void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
0456         {this->GenerateRandom(rng, params);}
0457 
0458     /// \brief Create an EC private key

0459     /// \param rng a RandomNumberGenerator derived class

0460     /// \param ec the elliptic curve

0461     /// \param G the base point

0462     /// \param n the order of the base point

0463     /// \details This function overload of Initialize() creates a new private key because it

0464     ///  takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,

0465     ///  then use one of the other Initialize() overloads.

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     // PKCS8PrivateKey

0491     void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0492     void DEREncodePrivateKey(BufferedTransformation &bt) const;
0493 };
0494 
0495 /// \brief Elliptic Curve German DSA key for ISO/IEC 15946

0496 /// \tparam EC elliptic curve field

0497 /// \sa ECGDSA

0498 /// \since Crypto++ 6.0

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     /// \brief Initialize an EC Public Key using {GP,Q}

0510     /// \param params group parameters

0511     /// \param Q the public point

0512     /// \details This Initialize() function overload initializes a public key from existing parameters.

0513     void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
0514         {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
0515 
0516     /// \brief Initialize an EC Public Key using {EC,G,n,Q}

0517     /// \param ec the elliptic curve

0518     /// \param G the base point

0519     /// \param n the order of the base point

0520     /// \param Q the public point

0521     /// \details This Initialize() function overload initializes a public key from existing parameters.

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     // DL_PublicKey<T>

0539     virtual void SetPublicElement(const Element &y)
0540         {this->AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
0541 
0542     // X509PublicKey

0543     void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0544     void DEREncodePublicKey(BufferedTransformation &bt) const;
0545 };
0546 
0547 /// \brief Elliptic Curve German DSA keys for ISO/IEC 15946

0548 /// \tparam EC elliptic curve field

0549 /// \sa ECGDSA

0550 /// \since Crypto++ 6.0

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 /// \brief Elliptic Curve German DSA signature algorithm

0559 /// \tparam EC elliptic curve field

0560 /// \sa ECGDSA

0561 /// \since Crypto++ 6.0

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 /// \brief Elliptic Curve German Digital Signature Algorithm signature scheme

0570 /// \tparam EC elliptic curve field

0571 /// \tparam H HashTransformation derived class

0572 /// \sa Erwin Hess, Marcus Schafheutle, and Pascale Serf <A

0573 ///  HREF="http://www.teletrust.de/fileadmin/files/oid/ecgdsa_final.pdf">The Digital Signature Scheme

0574 ///  ECGDSA (October 24, 2006)</A>

0575 /// \since Crypto++ 6.0

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 /// \brief Elliptic Curve Integrated Encryption Scheme

0589 /// \tparam COFACTOR_OPTION cofactor multiplication option

0590 /// \tparam HASH HashTransformation derived class used for key derivation and MAC computation

0591 /// \tparam DHAES_MODE flag indicating if the MAC includes additional context parameters such as <em>u·V</em>, <em>v·U</em> and label

0592 /// \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits

0593 /// \details ECIES is an Elliptic Curve based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation

0594 ///  Method (KEM) with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is

0595 ///  <A HREF="http://en.wikipedia.org/wiki/ciphertext_indistinguishability">IND-CCA2</A>, which is a strong notion of security.

0596 ///  You should prefer an Integrated Encryption Scheme over homegrown schemes.

0597 /// \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the ECIES_P1363.

0598 ///  If you desire an Integrated Encryption Scheme compatible with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES

0599 ///  template class with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=true</tt> and <tt>LABEL_OCTETS=false</tt>.

0600 /// \details The default template parameters ensure compatibility with Bouncy Castle 1.54 and Botan 1.11. The combination of

0601 ///  <tt>IncompatibleCofactorMultiplication</tt> and <tt>DHAES_MODE=true</tt> is recommended for best efficiency and security.

0602 ///  SHA1 is used for compatibility reasons, but it can be changed if desired.

0603 /// \sa DLIES, ECIES_P1363, <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">Elliptic Curve Integrated Encryption Scheme (ECIES)</a>,

0604 ///  Martínez, Encinas, and Ávila's <A HREF="http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf">A Survey of the Elliptic

0605 ///  Curve Integrated Encryption Schemes</A>

0606 /// \since Crypto++ 4.0, Crypto++ 5.7 for Bouncy Castle and Botan compatibility

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     // TODO: fix this after name is standardized

0617     CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES";}
0618 };
0619 
0620 /// \brief Elliptic Curve Integrated Encryption Scheme for P1363

0621 /// \tparam COFACTOR_OPTION cofactor multiplication option

0622 /// \tparam HASH HashTransformation derived class used for key derivation and MAC computation

0623 /// \details ECIES_P1363 is an Elliptic Curve based Integrated Encryption Scheme (IES) for P1363. The scheme combines a Key Encapsulation

0624 ///  Method (KEM) with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is

0625 ///  <A HREF="http://en.wikipedia.org/wiki/ciphertext_indistinguishability">IND-CCA2</A>, which is a strong notion of security.

0626 ///  You should prefer an Integrated Encryption Scheme over homegrown schemes.

0627 /// \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom

0628 ///  SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used the early draft in its Integrated Enryption

0629 ///  Schemes with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=false</tt> and <tt>LABEL_OCTETS=true</tt>.

0630 /// \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the ECIES_P1363.

0631 ///  If you desire an Integrated Encryption Scheme compatible with Bouncy Castle 1.54 and Botan 1.11 compatibility, then use the ECIES

0632 ///  template class with <tt>NoCofactorMultiplication</tt>, <tt>DHAES_MODE=true</tt> and <tt>LABEL_OCTETS=false</tt>.

0633 /// \details The default template parameters ensure compatibility with P1363. The combination of

0634 ///  <tt>IncompatibleCofactorMultiplication</tt> and <tt>DHAES_MODE=true</tt> is recommended for best efficiency and security.

0635 ///  SHA1 is used for compatibility reasons, but it can be changed if desired.

0636 /// \sa DLIES, ECIES, <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">Elliptic Curve Integrated Encryption Scheme (ECIES)</a>,

0637 ///  Martínez, Encinas, and Ávila's <A HREF="http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf">A Survey of the Elliptic

0638 ///  Curve Integrated Encryption Schemes</A>

0639 /// \since Crypto++ 4.0

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     // TODO: fix this after name is standardized

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