From 539364846a89987ac2679988653f50332cb91d26 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Thu, 30 Aug 2012 21:06:13 +0000 Subject: Implemented 1.3.2 protocol encryption using CryptoPP, up to Client Status packet (http://wiki.vg/Protocol_FAQ step 14) git-svn-id: http://mc-server.googlecode.com/svn/trunk@808 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- CryptoPP/eccrypto.h | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 CryptoPP/eccrypto.h (limited to 'CryptoPP/eccrypto.h') diff --git a/CryptoPP/eccrypto.h b/CryptoPP/eccrypto.h new file mode 100644 index 000000000..b359e033e --- /dev/null +++ b/CryptoPP/eccrypto.h @@ -0,0 +1,280 @@ +#ifndef CRYPTOPP_ECCRYPTO_H +#define CRYPTOPP_ECCRYPTO_H + +/*! \file +*/ + +#include "pubkey.h" +#include "integer.h" +#include "asn.h" +#include "hmac.h" +#include "sha.h" +#include "gfpcrypt.h" +#include "dh.h" +#include "mqv.h" +#include "ecp.h" +#include "ec2n.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Elliptic Curve Parameters +/*! This class corresponds to the ASN.1 sequence of the same name + in ANSI X9.62 (also SEC 1). +*/ +template +class DL_GroupParameters_EC : public DL_GroupParametersImpl > +{ + typedef DL_GroupParameters_EC ThisClass; + +public: + typedef EC EllipticCurve; + typedef typename EllipticCurve::Point Point; + typedef Point Element; + typedef IncompatibleCofactorMultiplication DefaultCofactorOption; + + DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {} + DL_GroupParameters_EC(const OID &oid) + : m_compress(false), m_encodeAsOID(false) {Initialize(oid);} + DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) + : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);} + DL_GroupParameters_EC(BufferedTransformation &bt) + : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);} + + void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) + { + this->m_groupPrecomputation.SetCurve(ec); + SetSubgroupGenerator(G); + m_n = n; + m_k = k; + } + void Initialize(const OID &oid); + + // NameValuePairs + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // GeneratibleCryptoMaterial interface + //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values + /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + // DL_GroupParameters + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} + const Integer & GetSubgroupOrder() const {return m_n;} + Integer GetCofactor() const; + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation *precomp) const; + bool FastSubgroupCheckAvailable() const {return false;} + void EncodeElement(bool reversible, const Element &element, byte *encoded) const + { + if (reversible) + GetCurve().EncodePoint(encoded, element, m_compress); + else + element.x.Encode(encoded, GetEncodedElementSize(false)); + } + unsigned int GetEncodedElementSize(bool reversible) const + { + if (reversible) + return GetCurve().EncodedPointSize(m_compress); + else + return GetCurve().GetField().MaxElementByteLength(); + } + Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const + { + Point result; + if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true))) + throw DL_BadElement(); + if (checkForGroupMembership && !ValidateElement(1, result, NULL)) + throw DL_BadElement(); + return result; + } + Integer ConvertElementToInteger(const Element &element) const; + Integer GetMaxExponent() const {return GetSubgroupOrder()-1;} + bool IsIdentity(const Element &element) const {return element.identity;} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";} + + // ASN1Key + OID GetAlgorithmID() const; + + // used by MQV + Element MultiplyElements(const Element &a, const Element &b) const; + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; + + // non-inherited + + // enumerate OIDs for recommended parameters, use OID() to get first one + static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid); + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + void SetPointCompression(bool compress) {m_compress = compress;} + bool GetPointCompression() const {return m_compress;} + + void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;} + bool GetEncodeAsOID() const {return m_encodeAsOID;} + + const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();} + + bool operator==(const ThisClass &rhs) const + {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);} + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + const Point& GetBasePoint() const {return GetSubgroupGenerator();} + const Integer& GetBasePointOrder() const {return GetSubgroupOrder();} + void LoadRecommendedParameters(const OID &oid) {Initialize(oid);} +#endif + +protected: + unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();} + unsigned int ExponentLength() const {return m_n.ByteCount();} + + OID m_oid; // set if parameters loaded from a recommended curve + Integer m_n; // order of base point + bool m_compress, m_encodeAsOID; + mutable Integer m_k; // cofactor +}; + +//! EC public key +template +class DL_PublicKey_EC : public DL_PublicKeyImpl > +{ +public: + typedef typename EC::Point Element; + + void Initialize(const DL_GroupParameters_EC ¶ms, const Element &Q) + {this->AccessGroupParameters() = params; SetPublicElement(Q);} + void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q) + {this->AccessGroupParameters().Initialize(ec, G, n); SetPublicElement(Q);} + + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; +}; + +//! EC private key +template +class DL_PrivateKey_EC : public DL_PrivateKeyImpl > +{ +public: + typedef typename EC::Point Element; + + void Initialize(const DL_GroupParameters_EC ¶ms, const Integer &x) + {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);} + void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x) + {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);} + void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC ¶ms) + {GenerateRandom(rng, params);} + void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n) + {GenerateRandom(rng, DL_GroupParameters_EC(ec, G, n));} + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; +}; + +//! Elliptic Curve Diffie-Hellman, AKA ECDH +template ::DefaultCofactorOption> +struct ECDH +{ + typedef DH_Domain, COFACTOR_OPTION> Domain; +}; + +/// Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV +template ::DefaultCofactorOption> +struct ECMQV +{ + typedef MQV_Domain, COFACTOR_OPTION> Domain; +}; + +//! EC keys +template +struct DL_Keys_EC +{ + typedef DL_PublicKey_EC PublicKey; + typedef DL_PrivateKey_EC PrivateKey; +}; + +template +struct ECDSA; + +//! ECDSA keys +template +struct DL_Keys_ECDSA +{ + typedef DL_PublicKey_EC PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA > PrivateKey; +}; + +//! ECDSA algorithm +template +class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} +}; + +//! ECNR algorithm +template +class DL_Algorithm_ECNR : public DL_Algorithm_NR +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} +}; + +//! ECDSA +template +struct ECDSA : public DL_SS, DL_Algorithm_ECDSA, DL_SignatureMessageEncodingMethod_DSA, H> +{ +}; + +//! ECNR +template +struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMessageEncodingMethod_NR, H> +{ +}; + +//! Elliptic Curve Integrated Encryption Scheme, AKA ECIES +/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2. + The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best + efficiency and security. */ +template +struct ECIES + : public DL_ES< + DL_Keys_EC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE>, + ECIES > +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "eccrypto.cpp" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA >; + +NAMESPACE_END + +#endif -- cgit v1.2.3