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 Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7