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

iterhash.cpp

00001 // iterhash.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "iterhash.h"
00005 #include "misc.h"
00006 
00007 NAMESPACE_BEGIN(CryptoPP)
00008 
00009 template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte *input, unsigned int len)
00010 {
00011         HashWordType tmp = m_countLo;
00012         if ((m_countLo = tmp + len) < tmp)
00013                 m_countHi++;             // carry from low to high
00014         m_countHi += SafeRightShift<8*sizeof(HashWordType)>(len);
00015 
00016         unsigned int blockSize = BlockSize();
00017         unsigned int num = ModPowerOf2(tmp, blockSize);
00018 
00019         if (num != 0)   // process left over data
00020         {
00021                 if ((num+len) >= blockSize)
00022                 {
00023                         memcpy((byte *)m_data.begin()+num, input, blockSize-num);
00024                         HashBlock(m_data);
00025                         input += (blockSize-num);
00026                         len-=(blockSize - num);
00027                         num=0;
00028                         // drop through and do the rest
00029                 }
00030                 else
00031                 {
00032                         memcpy((byte *)m_data.begin()+num, input, len);
00033                         return;
00034                 }
00035         }
00036 
00037         // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
00038         if (len >= blockSize)
00039         {
00040                 if (input == (byte *)m_data.begin())
00041                 {
00042                         assert(len == blockSize);
00043                         HashBlock(m_data);
00044                         return;
00045                 }
00046                 else if (IsAligned<T>(input))
00047                 {
00048                         unsigned int leftOver = HashMultipleBlocks((T *)input, len);
00049                         input += (len - leftOver);
00050                         len = leftOver;
00051                 }
00052                 else
00053                         do
00054                         {   // copy input first if it's not aligned correctly
00055                                 memcpy(m_data, input, blockSize);
00056                                 HashBlock(m_data);
00057                                 input+=blockSize;
00058                                 len-=blockSize;
00059                         } while (len >= blockSize);
00060         }
00061 
00062         memcpy(m_data, input, len);
00063 }
00064 
00065 template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(unsigned int &size)
00066 {
00067         unsigned int blockSize = BlockSize();
00068         unsigned int num = ModPowerOf2(m_countLo, blockSize);
00069         size = blockSize - num;
00070         return (byte *)m_data.begin() + num;
00071 }
00072 
00073 template <class T, class BASE> unsigned int IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, unsigned int length)
00074 {
00075         unsigned int blockSize = BlockSize();
00076         do
00077         {
00078                 HashBlock(input);
00079                 input += blockSize/sizeof(T);
00080                 length -= blockSize;
00081         }
00082         while (length >= blockSize);
00083         return length;
00084 }
00085 
00086 template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
00087 {
00088         unsigned int blockSize = BlockSize();
00089         unsigned int num = ModPowerOf2(m_countLo, blockSize);
00090         ((byte *)m_data.begin())[num++]=padFirst;
00091         if (num <= lastBlockSize)
00092                 memset((byte *)m_data.begin()+num, 0, lastBlockSize-num);
00093         else
00094         {
00095                 memset((byte *)m_data.begin()+num, 0, blockSize-num);
00096                 HashBlock(m_data);
00097                 memset(m_data, 0, lastBlockSize);
00098         }
00099 }
00100 
00101 template <class T, class BASE> void IteratedHashBase<T, BASE>::Restart()
00102 {
00103         m_countLo = m_countHi = 0;
00104         Init();
00105 }
00106 
00107 NAMESPACE_END

Generated on Sat Apr 2 21:53:52 2005 for Crypto++ by  doxygen 1.3.9.1