Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class 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         unsigned int OptimalDataAlignment() const {return sizeof(T);}
00020         void Update(const byte *input, unsigned int length);
00021         byte * CreateUpdateSpace(unsigned int &size);
00022         void Restart();
00023 
00024 protected:
00025         T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);}
00026         T GetBitCountLo() const {return m_countLo << 3;}
00027 
00028         virtual unsigned int HashMultipleBlocks(const T *input, unsigned int length);
00029         void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80);
00030         virtual void Init() =0;
00031         virtual void HashBlock(const T *input) =0;
00032         virtual unsigned int BlockSize() const =0;
00033 
00034         SecBlock<T> m_data;                     // Data buffer
00035         SecBlock<T> m_digest;           // Message digest
00036 
00037 private:
00038         T m_countLo, m_countHi;
00039 };
00040 
00041 //! .
00042 template <class T, class B, class BASE>
00043 class IteratedHashBase2 : public IteratedHashBase<T, BASE>
00044 {
00045 public:
00046         IteratedHashBase2(unsigned int blockSize, unsigned int digestSize)
00047                 : IteratedHashBase<T, BASE>(blockSize, digestSize) {}
00048 
00049         typedef B ByteOrderClass;
00050         typedef typename IteratedHashBase<T, BASE>::HashWordType HashWordType;
00051 
00052         inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, unsigned int byteCount)
00053         {
00054                 ConditionalByteReverse(B::ToEnum(), out, in, byteCount);
00055         }
00056 
00057         void TruncatedFinal(byte *hash, unsigned int size);
00058 
00059 protected:
00060         void HashBlock(const HashWordType *input);
00061 
00062         virtual void vTransform(const HashWordType *data) =0;
00063 };
00064 
00065 //! .
00066 template <class T, class B, unsigned int S, class BASE = HashTransformation>
00067 class IteratedHash : public IteratedHashBase2<T, B, BASE>
00068 {
00069 public:
00070         enum {BLOCKSIZE = S};
00071 
00072 private:
00073         CRYPTOPP_COMPILE_ASSERT((BLOCKSIZE & (BLOCKSIZE - 1)) == 0);            // blockSize is a power of 2
00074 
00075 protected:
00076         IteratedHash(unsigned int digestSize) : IteratedHashBase2<T, B, BASE>(BLOCKSIZE, digestSize) {}
00077         unsigned int BlockSize() const {return BLOCKSIZE;}
00078 };
00079 
00080 template <class T, class B, unsigned int S, class M>
00081 class IteratedHashWithStaticTransform : public IteratedHash<T, B, S>
00082 {
00083 protected:
00084         IteratedHashWithStaticTransform(unsigned int digestSize) : IteratedHash<T, B, S>(digestSize) {}
00085         void vTransform(const T *data) {M::Transform(m_digest, data);}
00086         std::string AlgorithmName() const {return M::StaticAlgorithmName();}
00087 };
00088 
00089 // *************************************************************
00090 
00091 template <class T, class B, class BASE> void IteratedHashBase2<T, B, BASE>::TruncatedFinal(byte *hash, unsigned int size)
00092 {
00093         ThrowIfInvalidTruncatedSize(size);
00094 
00095         PadLastBlock(BlockSize() - 2*sizeof(HashWordType));
00096         CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType));
00097 
00098         m_data[m_data.size()-2] = B::ToEnum() ? GetBitCountHi() : GetBitCountLo();
00099         m_data[m_data.size()-1] = B::ToEnum() ? GetBitCountLo() : GetBitCountHi();
00100 
00101         vTransform(m_data);
00102         CorrectEndianess(m_digest, m_digest, DigestSize());
00103         memcpy(hash, m_digest, size);
00104 
00105         Restart();              // reinit for next use
00106 }
00107 
00108 template <class T, class B, class BASE> void IteratedHashBase2<T, B, BASE>::HashBlock(const HashWordType *input)
00109 {
00110         if (NativeByteOrderIs(B::ToEnum()))
00111                 vTransform(input);
00112         else
00113         {
00114                 ByteReverse(m_data.begin(), input, BlockSize());
00115                 vTransform(m_data);
00116         }
00117 }
00118 
00119 NAMESPACE_END
00120 
00121 #endif

Generated on Mon Apr 19 18:12:31 2004 for Crypto++ by doxygen 1.3.6-20040222