From cf81d8a09998a879969e6096c68c068f971e9784 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Mon, 5 Sep 2016 03:13:45 -0400 Subject: [PATCH] Add constexpr-ness to seckey.h classes. Coarse grained benchmarking with GCC 4.8 at -O2 using 'time' and 'cryptest.exe' shows we shaved about 100ms to 150ms off the running time. We are ready to break the 1-second mark for the running time (its elluded me for some time now) --- seckey.h | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/seckey.h b/seckey.h index 8a801306..46099f00 100644 --- a/seckey.h +++ b/seckey.h @@ -66,18 +66,20 @@ public: CRYPTOPP_CONSTANT(MIN_ROUNDS = N) //! \brief The maximum number of rounds for the algorithm provided as a constant. CRYPTOPP_CONSTANT(MAX_ROUNDS = M) - //! \brief The default number of rounds for the algorithm based on key length + //! \brief The default number of rounds for the algorithm based on key length //! provided by a static function. //! \param keylength the size of the key, in bytes //! \details keylength is unused in the default implementation. - static unsigned int StaticGetDefaultRounds(size_t keylength) - {CRYPTOPP_UNUSED(keylength); return DEFAULT_ROUNDS;} + CRYPTOPP_CONSTEXPR static unsigned int StaticGetDefaultRounds(size_t keylength) + {return CRYPTOPP_UNUSED(keylength), DEFAULT_ROUNDS;} protected: //! \brief Validates the number of rounds for an algorithm. //! \param rounds the canddiate number of rounds //! \param alg an Algorithm object used if the number of rounds are invalid //! \throws InvalidRounds if the number of rounds are invalid + //! \details ThrowIfInvalidRounds() validates the number of rounds and throws if invalid. + //! The function is not a C++11 constexpr due to the potential throw operation. inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) { if (M == INT_MAX) // Coverity and result_independent_of_operands @@ -97,6 +99,8 @@ protected: //! \param alg an Algorithm object used if the number of rounds are invalid //! \returns the number of rounds for the algorithm //! \throws InvalidRounds if the number of rounds are invalid + //! \details GetRoundsAndThrowIfInvalid() validates the number of rounds and throws if invalid. + //! The function is not a C++11 constexpr due to the potential throw operation. inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) { int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); @@ -140,8 +144,8 @@ public: //! \param keylength the size of the key, in bytes //! \details The default implementation returns KEYLENGTH. keylength is unused //! in the default implementation. - static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) - {CRYPTOPP_UNUSED(keylength); return KEYLENGTH;} + CRYPTOPP_CONSTEXPR static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + {return CRYPTOPP_UNUSED(keylength), KEYLENGTH;} }; //! \class VariableKeyLength @@ -192,6 +196,7 @@ public: //! then keylength is returned. Otherwise, the function returns keylength rounded //! \a down to the next smaller multiple of KEYLENGTH_MULTIPLE. //! \details keylength is provided in bytes, not bits. + // TODO: Figure out how to make this CRYPTOPP_CONSTEXPR static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) { if (keylength < (size_t)MIN_KEYLENGTH) @@ -240,7 +245,7 @@ public: //! then keylength is returned. Otherwise, the function returns keylength rounded //! \a down to the next smaller multiple of KEYLENGTH_MULTIPLE. //! \details keylength is provided in bytes, not bits. - static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + CRYPTOPP_CONSTEXPR static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) {return T::StaticGetValidKeyLength(keylength);} }; @@ -257,19 +262,19 @@ class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE public: //! \brief The minimum key length used by the algorithm //! \returns minimum key length used by the algorithm, in bytes - size_t MinKeyLength() const + CRYPTOPP_CONSTEXPR size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;} //! \brief The maximum key length used by the algorithm //! \returns maximum key length used by the algorithm, in bytes - size_t MaxKeyLength() const + CRYPTOPP_CONSTEXPR size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;} - + //! \brief The default key length used by the algorithm //! \returns default key length used by the algorithm, in bytes - size_t DefaultKeyLength() const + CRYPTOPP_CONSTEXPR size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;} - + //! \brief Provides a valid key length for the algorithm //! \param keylength the size of the key, in bytes //! \returns the valid key lenght, in bytes @@ -278,17 +283,17 @@ public: //! then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE, //! then keylength is returned. Otherwise, the function returns a \a lower multiple of //! KEYLENGTH_MULTIPLE. - size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);} + CRYPTOPP_CONSTEXPR size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);} //! \brief The default IV requirements for the algorithm //! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement //! in cryptlib.h for allowed values. - SimpleKeyingInterface::IV_Requirement IVRequirement() const + CRYPTOPP_CONSTEXPR SimpleKeyingInterface::IV_Requirement IVRequirement() const {return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;} - + //! \brief The default initialization vector length for the algorithm //! \details IVSize is provided in bytes, not bits. The default implementation uses IV_LENGTH, which is 0. - unsigned int IVSize() const + CRYPTOPP_CONSTEXPR unsigned int IVSize() const {return INFO::IV_LENGTH;} }; @@ -323,7 +328,7 @@ public: //! SimpleKeyingInterface::SetKey. BlockCipherFinal(const byte *key) {this->SetKey(key, this->DEFAULT_KEYLENGTH);} - + //! \brief Construct a BlockCipherFinal //! \param key a byte array used to key the cipher //! \param length the length of the byte array @@ -331,7 +336,7 @@ public: //! SimpleKeyingInterface::SetKey. BlockCipherFinal(const byte *key, size_t length) {this->SetKey(key, length);} - + //! \brief Construct a BlockCipherFinal //! \param key a byte array used to key the cipher //! \param length the length of the byte array @@ -344,7 +349,7 @@ public: //! \brief Provides the direction of the cipher //! \returns true if DIR is ENCRYPTION, false otherwise //! \sa GetCipherDirection(), IsPermutation() - bool IsForwardTransformation() const {return DIR == ENCRYPTION;} + CRYPTOPP_CONSTEXPR bool IsForwardTransformation() const {return DIR == ENCRYPTION;} }; //! \class MessageAuthenticationCodeImpl @@ -388,7 +393,7 @@ public: //! \brief Provides Encryption and Decryption typedefs used by derived classes to //! implement a block cipher //! \details These objects usually should not be used directly. See CipherModeDocumentation -//! instead. Each class derived from this one defines two types, Encryption and Decryption, +//! instead. Each class derived from this one defines two types, Encryption and Decryption, //! both of which implement the BlockCipher interface. struct BlockCipherDocumentation { @@ -401,7 +406,7 @@ struct BlockCipherDocumentation //! \class SymmetricCipherDocumentation //! \brief Provides Encryption and Decryption typedefs used by derived classes to //! implement a symmetric cipher -//! \details Each class derived from this one defines two types, Encryption and Decryption, +//! \details Each class derived from this one defines two types, Encryption and Decryption, //! both of which implement the SymmetricCipher interface. Two types of classes derive //! from this class: stream ciphers and block cipher modes. Stream ciphers can be used //! alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation @@ -417,7 +422,7 @@ struct SymmetricCipherDocumentation //! \class AuthenticatedSymmetricCipherDocumentation //! \brief Provides Encryption and Decryption typedefs used by derived classes to //! implement an authenticated encryption cipher -//! \details Each class derived from this one defines two types, Encryption and Decryption, +//! \details Each class derived from this one defines two types, Encryption and Decryption, //! both of which implement the AuthenticatedSymmetricCipher interface. struct AuthenticatedSymmetricCipherDocumentation { @@ -428,7 +433,7 @@ struct AuthenticatedSymmetricCipherDocumentation }; NAMESPACE_END - + #if CRYPTOPP_MSC_VERSION # pragma warning(pop) #endif