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