From b21162cf8e06f40baa1f58be6a8c17435cebc34d Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 Oct 2002 17:31:41 +0000 Subject: Initial revision git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- iterhash.h | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 iterhash.h (limited to 'iterhash.h') diff --git a/iterhash.h b/iterhash.h new file mode 100644 index 0000000..1ae9b15 --- /dev/null +++ b/iterhash.h @@ -0,0 +1,120 @@ +#ifndef CRYPTOPP_ITERHASH_H +#define CRYPTOPP_ITERHASH_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +class IteratedHashBase : public BASE +{ +public: + typedef T HashWordType; + + IteratedHashBase(unsigned int blockSize, unsigned int digestSize); + unsigned int DigestSize() const {return m_digest.size() * sizeof(T);}; + unsigned int OptimalBlockSize() const {return BlockSize();} + void Update(const byte *input, unsigned int length); + byte * CreateUpdateSpace(unsigned int &size); + void Restart(); + +protected: + T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} + T GetBitCountLo() const {return m_countLo << 3;} + + virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); + void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); + virtual void Init() =0; + virtual void HashBlock(const T *input) =0; + virtual unsigned int BlockSize() const =0; + + SecBlock m_data; // Data buffer + SecBlock m_digest; // Message digest + +private: + T m_countLo, m_countHi; +}; + +//! . +template +class IteratedHashBase2 : public IteratedHashBase +{ +public: + IteratedHashBase2(unsigned int blockSize, unsigned int digestSize) + : IteratedHashBase(blockSize, digestSize) {} + + typedef B ByteOrderClass; + typedef typename IteratedHashBase::HashWordType HashWordType; + + inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount) + { + ConditionalByteReverse(B::ToEnum(), out, in, byteCount); + } + + void TruncatedFinal(byte *hash, unsigned int size); + +protected: + void HashBlock(const HashWordType *input); + + virtual void vTransform(const HashWordType *data) =0; +}; + +//! . +template +class IteratedHash : public IteratedHashBase2 +{ +public: + enum {BLOCKSIZE = S}; + +private: + CRYPTOPP_COMPILE_ASSERT((BLOCKSIZE & (BLOCKSIZE - 1)) == 0); // blockSize is a power of 2 + +protected: + IteratedHash(unsigned int digestSize) : IteratedHashBase2(BLOCKSIZE, digestSize) {} + unsigned int BlockSize() const {return BLOCKSIZE;} +}; + +template +class IteratedHashWithStaticTransform : public IteratedHash +{ +protected: + IteratedHashWithStaticTransform(unsigned int digestSize) : IteratedHash(digestSize) {} + void vTransform(const T *data) {M::Transform(m_digest, data);} + std::string AlgorithmName() const {return M::StaticAlgorithmName();} +}; + +// ************************************************************* + +template void IteratedHashBase2::TruncatedFinal(byte *hash, unsigned int size) +{ + ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(BlockSize() - 2*sizeof(HashWordType)); + CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType)); + + m_data[m_data.size()-2] = B::ToEnum() ? GetBitCountHi() : GetBitCountLo(); + m_data[m_data.size()-1] = B::ToEnum() ? GetBitCountLo() : GetBitCountHi(); + + vTransform(m_data); + CorrectEndianess(m_digest, m_digest, DigestSize()); + memcpy(hash, m_digest, size); + + Restart(); // reinit for next use +} + +template void IteratedHashBase2::HashBlock(const HashWordType *input) +{ + if (NativeByteOrderIs(B::ToEnum())) + vTransform(input); + else + { + ByteReverse(m_data.begin(), input, BlockSize()); + vTransform(m_data); + } +} + +NAMESPACE_END + +#endif -- cgit v1.2.1