Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

iterhash.h

00001 #ifndef CRYPTOPP_ITERHASH_H
00002 #define CRYPTOPP_ITERHASH_H
00003 
00004 #include "cryptlib.h"
00005 #include "secblock.h"
00006 #include "misc.h"
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 template <class T, class BASE>
00011 class IteratedHashBase : public BASE
00012 {
00013 public:
00014         typedef T HashWordType;
00015 
00016         IteratedHashBase(unsigned int blockSize, unsigned int digestSize);
00017         unsigned int DigestSize() const {return m_digest.size() * sizeof(T);};
00018         unsigned int OptimalBlockSize() const {return BlockSize();}
00019         void Update(const byte *input, unsigned int length);
00020         byte * CreateUpdateSpace(unsigned int &size);
00021         void Restart();
00022 
00023 protected:
00024         T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);}
00025         T GetBitCountLo() const {return m_countLo << 3;}
00026 
00027         virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length);
00028         void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80);
00029         virtual void Init() =0;
00030         virtual void HashBlock(const T *input) =0;
00031 
00032         SecBlock<T> m_data;                     // Data buffer
00033         SecBlock<T> m_digest;           // Message digest
00034 
00035 private:
00036         T m_countLo, m_countHi;
00037 };
00038 
00039 #ifdef WORD64_AVAILABLE
00040 CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word64, HashTransformation>;
00041 CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word64, MessageAuthenticationCode>;
00042 #endif
00043 
00044 CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word32, HashTransformation>;
00045 CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase<word32, MessageAuthenticationCode>;
00046 
00047 //! .
00048 template <class T, class B, class BASE>
00049 class IteratedHashBase2 : public IteratedHashBase<T, BASE>
00050 {
00051 public:
00052         IteratedHashBase2(unsigned int blockSize, unsigned int digestSize)
00053                 : IteratedHashBase<T, BASE>(blockSize, digestSize) {}
00054 
00055         typedef B ByteOrderClass;
00056         typedef typename IteratedHashBase<T, BASE>::HashWordType HashWordType;
00057 
00058         inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount)
00059         {
00060                 ConditionalByteReverse(B::ToEnum(), out, in, byteCount);
00061         }
00062 
00063         void TruncatedFinal(byte *hash, unsigned int size);
00064 
00065 protected:
00066         void HashBlock(const HashWordType *input);
00067 
00068         virtual void vTransform(const HashWordType *data) =0;
00069 };
00070 
00071 //! .
00072 template <class T, class B, unsigned int S, class BASE = HashTransformation>
00073 class IteratedHash : public IteratedHashBase2<T, B, BASE>
00074 {
00075 public:
00076         enum {BLOCKSIZE = S};
00077 
00078 private:
00079         CRYPTOPP_COMPILE_ASSERT((BLOCKSIZE & (BLOCKSIZE - 1)) == 0);            // blockSize is a power of 2
00080 
00081 protected:
00082         IteratedHash(unsigned int digestSize) : IteratedHashBase2<T, B, BASE>(BLOCKSIZE, digestSize) {}
00083         unsigned int BlockSize() const {return BLOCKSIZE;}
00084 };
00085 
00086 template <class T, class B, unsigned int S, class M>
00087 class IteratedHashWithStaticTransform : public IteratedHash<T, B, S>
00088 {
00089 public:
00090         std::string AlgorithmName() const {return M::StaticAlgorithmName();}
00091 protected:
00092         IteratedHashWithStaticTransform(unsigned int digestSize) : IteratedHash<T, B, S>(digestSize) {}
00093         void vTransform(const T *data) {M::Transform(m_digest, data);}
00094 };
00095 
00096 // *************************************************************
00097 
00098 template <class T, class B, class BASE> void IteratedHashBase2<T, B, BASE>::TruncatedFinal(byte *hash, unsigned int size)
00099 {
00100         ThrowIfInvalidTruncatedSize(size);
00101 
00102         PadLastBlock(BlockSize() - 2*sizeof(HashWordType));
00103         CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType));
00104 
00105         m_data[m_data.size()-2] = B::ToEnum() ? GetBitCountHi() : GetBitCountLo();
00106         m_data[m_data.size()-1] = B::ToEnum() ? GetBitCountLo() : GetBitCountHi();
00107 
00108         vTransform(m_data);
00109         CorrectEndianess(m_digest, m_digest, DigestSize());
00110         memcpy(hash, m_digest, size);
00111 
00112         Restart();              // reinit for next use
00113 }
00114 
00115 template <class T, class B, class BASE> void IteratedHashBase2<T, B, BASE>::HashBlock(const HashWordType *input)
00116 {
00117         if (NativeByteOrderIs(B::ToEnum()))
00118                 vTransform(input);
00119         else
00120         {
00121                 ByteReverse(m_data.begin(), input, BlockSize());
00122                 vTransform(m_data);
00123         }
00124 }
00125 
00126 NAMESPACE_END
00127 
00128 #endif

Generated on Tue Jul 8 23:34:19 2003 for Crypto++ by doxygen 1.3.2