From c6e8a61b8b7dac8ac33bf12a4b9a0b510232da83 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Tue, 12 Feb 2019 19:51:37 -0500 Subject: Add SHAKE-128 and SHAKE-256 (GH #805, PR #806) --- shake.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 shake.h (limited to 'shake.h') diff --git a/shake.h b/shake.h new file mode 100644 index 00000000..6f1e7786 --- /dev/null +++ b/shake.h @@ -0,0 +1,80 @@ +// shake.h - originally written and placed in the public domain by Jeffrey Walton + +/// \file shake.h +/// \brief Classes for SHAKE message digests +/// \sa SHA3, SHAKE128, SHAKE256, +/// FIPS 202, +/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +/// \since Crypto++ 8.1 + +#ifndef CRYPTOPP_SHAKE_H +#define CRYPTOPP_SHAKE_H + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SHAKE message digest base class +/// \details SHAKE is the base class for SHAKE128 and SHAKE258. +/// Library users should instantiate a derived class, and only use SHAKE +/// as a base class reference or pointer. +/// \sa SHA3, SHAKE128, SHAKE256, +/// FIPS 202, +/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions +/// \since Crypto++ 8.1 +class SHAKE : public HashTransformation +{ +public: + /// \brief Construct a SHAKE + /// \param digestSize the digest size, in bytes + /// \details SHAKE is the base class for SHAKE128 and SHAKE256. + /// Library users should instantiate a derived class, and only use SHAKE + /// as a base class reference or pointer. + /// \since Crypto++ 8.1 + SHAKE(unsigned int digestSize) : m_digestSize(digestSize) {Restart();} + unsigned int DigestSize() const {return m_digestSize;} + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + + void Update(const byte *input, size_t length); + void Restart(); + void TruncatedFinal(byte *hash, size_t size); + +protected: + inline unsigned int r() const {return BlockSize();} + + FixedSizeSecBlock m_state; + unsigned int m_digestSize, m_counter; +}; + +/// \brief SHAKE message digest template +/// \tparam T_Strength the strength of the digest +/// \since Crypto++ 8.1 +template +class SHAKE_Final : public SHAKE +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = (T_Strength == 128 ? 32 : 64)) + CRYPTOPP_CONSTANT(BLOCKSIZE = (T_Strength == 128 ? 1344/8 : 1088/8)) + static std::string StaticAlgorithmName() { return "SHAKE-" + IntToString(T_Strength); } + + /// \brief Construct a SHAKE-X message digest + SHAKE_Final() : SHAKE(DIGESTSIZE) {} + unsigned int BlockSize() const { return BLOCKSIZE; } + +private: + CRYPTOPP_COMPILE_ASSERT(T_Strength == 128 || T_Strength == 256); + CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math +}; + +/// \brief SHAKE128 message digest +/// \since Crypto++ 8.1 +class SHAKE128 : public SHAKE_Final<128> {}; + +/// \brief SHAKE256 message digest +/// \since Crypto++ 8.1 +class SHAKE256 : public SHAKE_Final<256> {}; + +NAMESPACE_END + +#endif -- cgit v1.2.1