From c3e2e0fb25fd1fa25e3a6e8eadb9ef78e8158be9 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Tue, 18 Oct 2016 17:01:28 -0400 Subject: [PATCH] Align with BouncyCastle and Botan for DLIES and ECIES. Updated documentation --- eccrypto.h | 109 +++++++++++++++++++----- gfpcrypt.h | 246 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 254 insertions(+), 101 deletions(-) diff --git a/eccrypto.h b/eccrypto.h index 75f26b87..9432fbf7 100644 --- a/eccrypto.h +++ b/eccrypto.h @@ -147,7 +147,9 @@ protected: mutable bool m_compress, m_encodeAsOID; // presentation details }; -//! EC public key +//! \class DL_PublicKey_EC +//! \brief Elliptic Curve Discrete Log (DL) public key +//! \tparam EC elliptic curve field template class DL_PublicKey_EC : public DL_PublicKeyImpl > { @@ -168,7 +170,9 @@ public: void DEREncodePublicKey(BufferedTransformation &bt) const; }; -//! EC private key +//! \class DL_PrivateKey_EC +//! \brief Elliptic Curve Discrete Log (DL) private key +//! \tparam EC elliptic curve field template class DL_PrivateKey_EC : public DL_PrivateKeyImpl > { @@ -193,7 +197,11 @@ public: void DEREncodePrivateKey(BufferedTransformation &bt) const; }; -//! Elliptic Curve Diffie-Hellman, AKA ECDH +//! \class ECDH +//! \brief Elliptic Curve Diffie-Hellman +//! \tparam EC elliptic curve field +//! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option" +//! \sa Elliptic Curve Diffie-Hellman, AKA ECDH template ::DefaultCofactorOption> struct ECDH { @@ -204,7 +212,11 @@ struct ECDH #endif }; -/// Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV +//! \class ECMQV +//! \brief Elliptic Curve Menezes-Qu-Vanstone +//! \tparam EC elliptic curve field +//! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option" +/// \sa Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV template ::DefaultCofactorOption> struct ECMQV { @@ -215,7 +227,10 @@ struct ECMQV #endif }; -//! \brief Hashed Menezes-Qu-Vanstone in ECP or EC2N +//! \class ECHMQV +//! \brief Hashed Elliptic Curve Menezes-Qu-Vanstone +//! \tparam EC elliptic curve field +//! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option" //! \details This implementation follows Hugo Krawczyk's HMQV: A High-Performance //! Secure Diffie-Hellman Protocol. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. template ::DefaultCofactorOption, class HASH = SHA256> @@ -233,7 +248,10 @@ typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA256 typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECHMQV384; typedef ECHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECHMQV512; -//! \brief Fully Hashed Menezes-Qu-Vanstone in ECP or EC2N +//! \class ECFHMQV +//! \brief Fully Hashed Elliptic Curve Menezes-Qu-Vanstone +//! \tparam EC elliptic curve field +//! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option" //! \details This implementation follows Augustin P. Sarr and Philippe Elbaz–Vincent, and Jean–Claude Bajard's //! A Secure and Efficient Authenticated Diffie-Hellman Protocol. //! Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. @@ -252,7 +270,9 @@ typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA25 typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA384 >::Domain ECFHMQV384; typedef ECFHMQV< ECP, DL_GroupParameters_EC< ECP >::DefaultCofactorOption, SHA512 >::Domain ECFHMQV512; -//! EC keys +//! \class DL_Keys_EC +//! \brief Elliptic Curve Discrete Log (DL) keys +//! \tparam EC elliptic curve field template struct DL_Keys_EC { @@ -264,10 +284,16 @@ struct DL_Keys_EC #endif }; +//! \class ECDSA +//! \brief Elliptic Curve DSA +//! \tparam EC elliptic curve field +//! \tparam H HashTransformation derived class template struct ECDSA; -//! ECDSA keys +//! \class DL_Keys_ECDSA +//! \brief Elliptic Curve DSA keys +//! \tparam EC elliptic curve field template struct DL_Keys_ECDSA { @@ -279,7 +305,9 @@ struct DL_Keys_ECDSA #endif }; -//! ECDSA algorithm +//! \class DL_Algorithm_ECDSA +//! \brief Elliptic Curve DSA (ECDSA) signature algorithm +//! \tparam EC elliptic curve field template class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA { @@ -291,7 +319,9 @@ public: #endif }; -//! ECNR algorithm +//! \class DL_Algorithm_ECNR +//! \brief Elliptic Curve NR (ECNR) signature algorithm +//! \tparam EC elliptic curve field template class DL_Algorithm_ECNR : public DL_Algorithm_NR { @@ -303,7 +333,11 @@ public: #endif }; -//! ECDSA +//! \class ECDSA +//! \brief Elliptic Curve DSA (ECDSA) signature scheme +//! \tparam EC elliptic curve field +//! \tparam H HashTransformation derived class +//! \sa ECDSA template struct ECDSA : public DL_SS, DL_Algorithm_ECDSA, DL_SignatureMessageEncodingMethod_DSA, H> { @@ -312,7 +346,10 @@ struct ECDSA : public DL_SS, DL_Algorithm_ECDSA, DL_Signat #endif }; -//! ECNR +//! \class ECNR +//! \brief Elliptic Curve NR (ECNR) signature scheme +//! \tparam EC elliptic curve field +//! \tparam H HashTransformation derived class template struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMessageEncodingMethod_NR, H> { @@ -321,17 +358,48 @@ struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMe #endif }; -//! 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 + +//! \class ECIES +//! \brief Elliptic Curve Integrated Encryption Scheme +//! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option" +//! \tparam HASH HashTransformation derived class used for key drivation and MAC computation +//! \tparam DHAES_MODE flag indicating if the MAC includes additional context parameters such as u·V, v·U and label +//! \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits +//! \details ECIES is an Elliptic Curve based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation +//! Method (KEM) with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is +//! IND-CCA2, which is a strong notion of security. +//! You should prefer an Integrated Encryption Scheme over homegrown schemes. +//! \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom +//! 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 Ecryption +//! Schemes with NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +//! \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the ECIES template class with +//! NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +//! \details If you desire an Integrated Encryption Scheme with Bouncy Castle 1.55 and Botan 1.11 compatibility, then use the ECIES +//! template class with NoCofactorMultiplication, DHAES_MODE=true and LABEL_OCTETS=false. +//! \details Bouncy Castle 1.55 and Botan 1.11 compatibility are the default template parameters. The combination of +//! IncompatibleCofactorMultiplication and DHAES_MODE=true is recommended for best efficiency and security. +//! SHA1 is used for compatibility reasons, but it can be changed of if desired. SHA-256 or another hash will likely improve the +//! security provided by the MAC. The hash is also used in the key derivation function as a PRF. +//! \details Below is an example of constructing a Crypto++ 4.2 compatible ECIES encryptor and decryptor. +//!
+//!     AutoSeededRandomPool prng;
+//!     DL_PrivateKey_EC key;
+//!     key.Initialize(prng, ASN1::secp160r1());
+//!
+//!     ECIES::Decryptor decryptor(key);
+//!     ECIES::Encryptor encryptor(decryptor);
+//! 
+//! \sa DLIES, Elliptic Curve Integrated Encryption Scheme (ECIES), +//! Martínez, Encinas, and Ávila's A Survey of the Elliptic +//! Curve Integrated Encryption Schemes +//! \since Crypto++ 4.0 +template struct ECIES : public DL_ES< DL_Keys_EC, DL_KeyAgreementAlgorithm_DH, - DL_KeyDerivationAlgorithm_P1363 >, - DL_EncryptionAlgorithm_Xor, DHAES_MODE>, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, ECIES > { static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized @@ -339,8 +407,7 @@ struct ECIES #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~ECIES() {} #endif - -} CRYPTOPP_DEPRECATED ("ECIES will be changing in the near future due to an interop issue"); +}; NAMESPACE_END diff --git a/gfpcrypt.h b/gfpcrypt.h index 4cdf3b06..f97599a0 100644 --- a/gfpcrypt.h +++ b/gfpcrypt.h @@ -27,12 +27,18 @@ NAMESPACE_BEGIN(CryptoPP) CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters; -//! _ +//! \class DL_GroupParameters_IntegerBased +//! \brief Integer-based GroupParameters specialization class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial > { typedef DL_GroupParameters_IntegerBased ThisClass; public: + +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_GroupParameters_IntegerBased() {} +#endif + void Initialize(const DL_GroupParameters_IntegerBased ¶ms) {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} void Initialize(RandomNumberGenerator &rng, unsigned int pbits) @@ -84,10 +90,6 @@ public: void SetSubgroupOrder(const Integer &q) {m_q = q; ParametersChanged();} -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_GroupParameters_IntegerBased() {} -#endif - protected: Integer ComputeGroupOrder(const Integer &modulus) const {return modulus-(GetFieldType() == 1 ? 1 : -1);} @@ -100,7 +102,10 @@ private: Integer m_q; }; -//! _ +//! \class DL_GroupParameters_IntegerBasedImpl +//! \brief Integer-based GroupParameters default implementation +//! \tparam GROUP_PRECOMP group parameters precomputation specialization +//! \tparam BASE_PRECOMP base class precomputation specialization template > class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl { @@ -109,6 +114,10 @@ class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupPa public: typedef typename GROUP_PRECOMP::Element Element; +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_GroupParameters_IntegerBasedImpl() {} +#endif + // GeneratibleCryptoMaterial interface bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return GetValueHelper(this, name, valueType, pValue).Assignable();} @@ -132,18 +141,20 @@ public: {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} bool operator!=(const DL_GroupParameters_IntegerBasedImpl &rhs) const {return !operator==(rhs);} - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_GroupParameters_IntegerBasedImpl() {} -#endif }; CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl; -//! GF(p) group parameters +//! \class DL_GroupParameters_GFP +//! \brief GF(p) group parameters class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl { public: + +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_GroupParameters_GFP() {} +#endif + // DL_GroupParameters bool IsIdentity(const Integer &element) const {return element == Integer::One();} void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; @@ -158,15 +169,12 @@ public: Element MultiplyElements(const Element &a, const Element &b) const; Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_GroupParameters_GFP() {} -#endif - protected: int GetFieldType() const {return 1;} }; -//! GF(p) group parameters that default to same primes +//! \class DL_GroupParameters_GFP +//! \brief GF(p) group parameters that default to safe primes class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP { public: @@ -180,13 +188,19 @@ protected: unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} }; -//! GDSA algorithm +//! \class DL_Algorithm_GDSA +//! \brief GDSA algorithm +//! \tparam T FieldElement type or class template class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm { public: CRYPTOPP_CONSTEXPR static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_Algorithm_GDSA() {} +#endif + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const { const Integer &q = params.GetSubgroupOrder(); @@ -208,21 +222,23 @@ public: // verify r == (g^u1 * y^u2 mod p) mod q return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; } - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_Algorithm_GDSA() {} -#endif }; CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; -//! NR algorithm +//! \class DL_Algorithm_NR +//! \brief NR algorithm +//! \tparam T FieldElement type or class template class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm { public: CRYPTOPP_CONSTEXPR static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";} +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_Algorithm_NR() {} +#endif + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const { const Integer &q = params.GetSubgroupOrder(); @@ -240,18 +256,20 @@ public: // check r == (m_g^s * m_y^r + m) mod m_q return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; } - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_Algorithm_NR() {} -#endif }; -/*! DSA public key format is defined in 7.3.3 of RFC 2459. The - private key format is defined in 12.9 of PKCS #11 v2.10. */ +//! \class DL_PublicKey_GFP +//! \brief Discrete Log (DL) public key in GF(p) groups +//! \tparam GP GroupParameters derived class +//! \details DSA public key format is defined in 7.3.3 of RFC 2459. The private key format is defined in 12.9 of PKCS #11 v2.10. template class DL_PublicKey_GFP : public DL_PublicKeyImpl { public: +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_PublicKey_GFP() {} +#endif + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y) {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} void Initialize(const Integer &p, const Integer &g, const Integer &y) @@ -264,17 +282,19 @@ public: {this->SetPublicElement(Integer(bt));} void DEREncodePublicKey(BufferedTransformation &bt) const {this->GetPublicElement().DEREncode(bt);} - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_PublicKey_GFP() {} -#endif }; -//! DL private key (in GF(p) groups) +//! \class DL_PrivateKey_GFP +//! \brief Discrete Log (DL) private key in GF(p) groups +//! \tparam GP GroupParameters derived class template class DL_PrivateKey_GFP : public DL_PrivateKeyImpl { public: +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_PrivateKey_GFP() {} +#endif + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) {this->GenerateRandomWithKeySize(rng, modulusBits);} void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) @@ -287,13 +307,10 @@ public: {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_PrivateKey_GFP() {} -#endif }; -//! DL signing/verification keys (in GF(p) groups) +//! \class DL_SignatureKeys_GFP +//! \brief Discrete Log (DL) signing/verification keys in GF(p) groups struct DL_SignatureKeys_GFP { typedef DL_GroupParameters_GFP GroupParameters; @@ -305,7 +322,8 @@ struct DL_SignatureKeys_GFP #endif }; -//! DL encryption/decryption keys (in GF(p) groups) +//! \class DL_CryptoKeys_GFP +//! \brief Discrete Log (DL) encryption/decryption keys in GF(p) groups struct DL_CryptoKeys_GFP { typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; @@ -317,11 +335,19 @@ struct DL_CryptoKeys_GFP #endif }; -//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format +//! \class DL_PublicKey_GFP_OldFormat +//! \brief Discrete Log (DL) public key in GF(p) groups +//! \tparam BASE GroupParameters derived class +//! \deprecated This implementation uses a non-standard Crypto++ key format. New implementations +//! should use DL_PublicKey_GFP and DL_PrivateKey_GFP template class DL_PublicKey_GFP_OldFormat : public BASE { public: +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_PublicKey_GFP_OldFormat() {} +#endif + void BERDecode(BufferedTransformation &bt) { BERSequenceDecoder seq(bt); @@ -354,17 +380,21 @@ public: this->GetPublicElement().DEREncode(seq); seq.MessageEnd(); } - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_PublicKey_GFP_OldFormat() {} -#endif }; -//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format +//! \class DL_PrivateKey_GFP_OldFormat +//! \brief Discrete Log (DL) private key in GF(p) groups +//! \tparam BASE GroupParameters derived class +//! \deprecated This implementation uses a non-standard Crypto++ key format. New implementations +//! should use DL_PublicKey_GFP and DL_PrivateKey_GFP template class DL_PrivateKey_GFP_OldFormat : public BASE { public: +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_PrivateKey_GFP_OldFormat() {} +#endif + void BERDecode(BufferedTransformation &bt) { BERSequenceDecoder seq(bt); @@ -399,13 +429,12 @@ public: this->GetPrivateExponent().DEREncode(seq); seq.MessageEnd(); } - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_PrivateKey_GFP_OldFormat() {} -#endif }; -//! DSA-1363 +//! \class GDSA +//! \brief DSA signature scheme +//! \tparam H HashTransformation derived class +//! \sa DSA-1363 template struct GDSA : public DL_SS< DL_SignatureKeys_GFP, @@ -418,7 +447,10 @@ struct GDSA : public DL_SS< #endif }; -//! NR +//! \class NR +//! \brief NR signature scheme +//! \tparam H HashTransformation derived class +//! \sa NR template struct NR : public DL_SS< DL_SignatureKeys_GFP, @@ -431,10 +463,17 @@ struct NR : public DL_SS< #endif }; -//! DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard +//! \class DL_GroupParameters_DSA +//! \brief DSA group parameters +//! \details These are GF(p) group parameters that are allowed by the DSA standard +//! \sa DL_Keys_DSA class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP { public: +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_GroupParameters_DSA() {} +#endif + /*! also checks that the lengths of p and q are allowed by the DSA standard */ bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ @@ -445,16 +484,14 @@ public: {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_GroupParameters_DSA() {} -#endif }; template class DSA2; -//! DSA keys +//! \class DL_Keys_DSA +//! \brief DSA keys +//! \sa DL_GroupParameters_DSA struct DL_Keys_DSA { typedef DL_PublicKey_GFP PublicKey; @@ -465,8 +502,11 @@ struct DL_Keys_DSA #endif }; -//! DSA, as specified in FIPS 186-3 -// class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class) +//! \class DSA2 +//! \brief DSA signature scheme +//! \tparam H HashTransformation derived class +//! \details The class is named DSA2 instead of DSA for backwards compatibility because DSA was a non-template class. +//! \sa DSA, as specified in FIPS 186-3 template class DSA2 : public DL_SS< DL_Keys_DSA, @@ -478,13 +518,13 @@ class DSA2 : public DL_SS< public: static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();} -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; -#endif - #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 virtual ~DSA2() {} #endif + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024}; +#endif }; //! DSA with SHA-1, typedef'd for backwards compatibility @@ -494,18 +534,35 @@ CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP; CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP; CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA2 >; -//! the XOR encryption method, for use with DL-based cryptosystems -template +//! \class DL_EncryptionAlgorithm_Xor +//! \brief P1363 based XOR Encryption Method +//! \tparam MAC MessageAuthenticationCode derived class used for MAC computation +//! \tparam DHAES_MODE flag indicating DHAES mode +//! \tparam LABEL_OCTETS flag indicating the label is octet count +//! \details DL_EncryptionAlgorithm_Xor is based on an early P1363 draft, which itself appears to be based on an +//! early Certicom SEC-1 draft (or an early SEC-1 draft was based on a P1363 draft). Crypto++ 4.2 used it in its Integrated +//! Ecryption Schemes with NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +//! \details If you need this method for Crypto++ 4.2 compatibility, then use the ECIES template class with +//! NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +//! \details If you need this method for Bouncy Castle 1.55 and Botan 1.11 compatibility, then use the ECIES template class with +//! NoCofactorMultiplication, DHAES_MODE=ture and LABEL_OCTETS=false. +//! \details Bouncy Castle 1.55 and Botan 1.11 compatibility are the default template parameters. +//! \since Crypto++ 4.0 +template class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm { public: +#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 + virtual ~DL_EncryptionAlgorithm_Xor() {} +#endif + bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} size_t GetSymmetricKeyLength(size_t plaintextLength) const - {return plaintextLength + MAC::DEFAULT_KEYLENGTH;} + {return plaintextLength + static_cast(MAC::DIGESTSIZE);} size_t GetSymmetricCiphertextLength(size_t plaintextLength) const - {return plaintextLength + MAC::DIGESTSIZE;} + {return plaintextLength + static_cast(MAC::DIGESTSIZE);} size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const - {return (unsigned int)SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);} + {return SaturatingSubtract(ciphertextLength, static_cast(MAC::DIGESTSIZE));} void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const { CRYPTOPP_UNUSED(rng); @@ -532,8 +589,8 @@ public: mac.Update(encodingParameters.begin(), encodingParameters.size()); if (DHAES_MODE) { - byte L[8] = {0,0,0,0}; - PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); + byte L[8]; + PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); mac.Update(L, 8); } mac.Final(ciphertext + plaintextLength); @@ -561,8 +618,8 @@ public: mac.Update(encodingParameters.begin(), encodingParameters.size()); if (DHAES_MODE) { - byte L[8] = {0,0,0,0}; - PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); + byte L[8]; + PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size()))); mac.Update(L, 8); } if (!mac.Verify(ciphertext + plaintextLength)) @@ -573,10 +630,6 @@ public: return DecodingResult(plaintextLength); } - -#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 - virtual ~DL_EncryptionAlgorithm_Xor() {} -#endif }; //! _ @@ -610,14 +663,47 @@ public: #endif }; -//! Discrete Log Integrated Encryption Scheme, AKA DLIES -template +//! \class DLIES +//! \brief Discrete Log Integrated Encryption Scheme +//! \tparam COFACTOR_OPTION \ref CofactorMultiplicationOption "cofactor multiplication option" +//! \tparam HASH HashTransformation derived class used for key drivation and MAC computation +//! \tparam DHAES_MODE flag indicating if the MAC includes addition context parameters such as the label +//! \tparam LABEL_OCTETS flag indicating if the label size is specified in octets or bits +//! \details DLIES is an Integer based Integrated Encryption Scheme (IES). The scheme combines a Key Encapsulation Method (KEM) +//! with a Data Encapsulation Method (DEM) and a MAC tag. The scheme is +//! IND-CCA2, which is a strong notion of security. +//! You should prefer an Integrated Encryption Scheme over homegrown schemes. +//! \details The library's original implementation is based on an early P1363 draft, which itself appears to be based on an early Certicom +//! 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 Ecryption +//! Schemes with NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +//! \details If you desire an Integrated Encryption Scheme with Crypto++ 4.2 compatibility, then use the DLIES template class with +//! NoCofactorMultiplication, DHAES_MODE=false and LABEL_OCTETS=true. +//! \details If you desire an Integrated Encryption Scheme with Bouncy Castle 1.55 and Botan 1.11 compatibility, then use the DLIES +//! template class with NoCofactorMultiplication, DHAES_MODE=true and LABEL_OCTETS=false. +//! \details Bouncy Castle 1.55 and Botan 1.11 compatibility are the default template parameters. The combination of +//! IncompatibleCofactorMultiplication and DHAES_MODE=true is recommended for best efficiency and security. +//! SHA1 is used for compatibility reasons, but it can be changed of if desired. SHA-256 or another hash will likely improve the +//! security provided by the MAC. The hash is also used in the key derivation function as a PRF. +//! \details Below is an example of constructing a Crypto++ 4.2 compatible DLIES encryptor and decryptor. +//!
+//!     AutoSeededRandomPool prng;
+//!     DL_PrivateKey_GFP key;
+//!     key.Initialize(prng, 2048);
+//!
+//!     DLIES::Decryptor decryptor(key);
+//!     DLIES::Encryptor encryptor(decryptor);
+//! 
+//! \sa ECIES, Discrete Log Integrated Encryption Scheme (DLIES), +//! Martínez, Encinas, and Ávila's A Survey of the Elliptic +//! Curve Integrated Encryption Schemes +//! \since Crypto++ 4.0 +template struct DLIES : public DL_ES< DL_CryptoKeys_GFP, DL_KeyAgreementAlgorithm_DH, - DL_KeyDerivationAlgorithm_P1363 >, - DL_EncryptionAlgorithm_Xor, DHAES_MODE>, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE, LABEL_OCTETS>, DLIES<> > { static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized