#ifndef CRYPTOPP_ITERHASH_H #define CRYPTOPP_ITERHASH_H #include "cryptlib.h" #include "misc.h" NAMESPACE_BEGIN(CryptoPP) /*! The following classes are explicitly instantiated in iterhash.cpp IteratedHashBase IteratedHashBase // #ifdef WORD64_AVAILABLE */ template class IteratedHashBase : public HashModuleWithTruncation { public: typedef T HashWordType; IteratedHashBase(unsigned int blockSize, unsigned int digestSize); unsigned int DigestSize() const {return digest.size * sizeof(T);}; void Update(const byte *input, unsigned int length); protected: virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length); void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); void Reinit(); virtual void Init() =0; virtual void HashBlock(const T *input) =0; unsigned int blockSize; word32 countLo, countHi; // 64-bit bit count SecBlock data; // Data buffer SecBlock digest; // Message digest }; //! . template class IteratedHash : public IteratedHashBase { public: typedef T HashWordType; enum {HIGHFIRST = H, BLOCKSIZE = S}; IteratedHash(unsigned int digestSize) : IteratedHashBase(BLOCKSIZE, digestSize) {} inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount) { if (!CheckEndianess(HIGHFIRST)) byteReverse(out, in, byteCount); else if (in!=out) memcpy(out, in, byteCount); } void TruncatedFinal(byte *hash, unsigned int size) { assert(size <= DigestSize()); PadLastBlock(BLOCKSIZE - 2*sizeof(HashWordType)); CorrectEndianess(data, data, BLOCKSIZE - 2*sizeof(HashWordType)); data[data.size-2] = HIGHFIRST ? countHi : countLo; data[data.size-1] = HIGHFIRST ? countLo : countHi; vTransform(data); CorrectEndianess(digest, digest, DigestSize()); memcpy(hash, digest, size); Reinit(); // reinit for next use } protected: void HashBlock(const HashWordType *input) { if (CheckEndianess(HIGHFIRST)) vTransform(input); else { byteReverse(data.ptr, input, (unsigned int)BLOCKSIZE); vTransform(data); } } virtual void vTransform(const HashWordType *data) =0; }; NAMESPACE_END #endif