diff options
Diffstat (limited to '')
-rw-r--r-- | CryptoPP/eccrypto.h | 280 |
1 files changed, 280 insertions, 0 deletions
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 EC> +class DL_GroupParameters_EC : public DL_GroupParametersImpl<EcPrecomputation<EC> > +{ + typedef DL_GroupParameters_EC<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<Element> & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation<Element> & 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<Element> *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 EC> +class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> > +{ +public: + typedef typename EC::Point Element; + + void Initialize(const DL_GroupParameters_EC<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 EC> +class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> > +{ +public: + typedef typename EC::Point Element; + + void Initialize(const DL_GroupParameters_EC<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<EC> ¶ms) + {GenerateRandom(rng, params);} + void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n) + {GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));} + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; +}; + +//! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a> +template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption> +struct ECDH +{ + typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain; +}; + +/// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a> +template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption> +struct ECMQV +{ + typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain; +}; + +//! EC keys +template <class EC> +struct DL_Keys_EC +{ + typedef DL_PublicKey_EC<EC> PublicKey; + typedef DL_PrivateKey_EC<EC> PrivateKey; +}; + +template <class EC, class H> +struct ECDSA; + +//! ECDSA keys +template <class EC> +struct DL_Keys_ECDSA +{ + typedef DL_PublicKey_EC<EC> PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC>, ECDSA<EC, SHA256> > PrivateKey; +}; + +//! ECDSA algorithm +template <class EC> +class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point> +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} +}; + +//! ECNR algorithm +template <class EC> +class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point> +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} +}; + +//! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a> +template <class EC, class H> +struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H> +{ +}; + +//! ECNR +template <class EC, class H = SHA> +struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H> +{ +}; + +//! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a> +/*! 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 <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false> +struct ECIES + : public DL_ES< + DL_Keys_EC<EC>, + DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>, + DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >, + DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>, + ECIES<EC> > +{ + 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<ECP>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >; + +NAMESPACE_END + +#endif |