Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound 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 
00006 NAMESPACE_BEGIN(CryptoPP)
00007 
00008 template <class T>
00009 IteratedHashBase<T>::IteratedHashBase(unsigned int blockSize, unsigned int digestSize)
00010         : blockSize(blockSize), countLo(0), countHi(0)
00011         , data(blockSize/sizeof(T)), digest(digestSize/sizeof(T))
00012 {
00013 }
00014 
00015 template <class T> void IteratedHashBase<T>::Update(const byte *input, unsigned int len)
00016 {
00017         HashWordType tmp = countLo;
00018         if ((countLo = tmp + ((word32)len << 3)) < tmp)
00019                 countHi++;             // Carry from low to high
00020         countHi += len >> (8*sizeof(HashWordType)-3);
00021 
00022         assert((blockSize & (blockSize-1)) == 0);       // blockSize is a power of 2
00023         unsigned int num = (unsigned int)(tmp >> 3) & (blockSize-1);
00024 
00025         if (num != 0)
00026         {
00027                 if ((num+len) >= blockSize)
00028                 {
00029                         memcpy((byte *)data.ptr+num, input, blockSize-num);
00030                         HashBlock(data);
00031                         input += (blockSize-num);
00032                         len-=(blockSize - num);
00033                         num=0;
00034                         // drop through and do the rest
00035                 }
00036                 else
00037                 {
00038                         memcpy((byte *)data.ptr+num, input, len);
00039                         return;
00040                 }
00041         }
00042 
00043         // we now can process the input data in blocks of blockSize
00044         // chars and save the leftovers to this->data.
00045         if (len >= blockSize)
00046         {
00047                 if (IsAligned<T>(input))
00048                 {
00049                         unsigned int leftOver = HashMultipleBlocks((T *)input, len);
00050                         input += (len - leftOver);
00051                         len = leftOver;
00052                 }
00053                 else
00054                         do
00055                         {   // copy input first if it's not aligned correctly
00056                                 memcpy(data, input, blockSize);
00057                                 HashBlock(data);
00058                                 input+=blockSize;
00059                                 len-=blockSize;
00060                         } while (len >= blockSize);
00061         }
00062 
00063         memcpy(data, input, len);
00064 }
00065 
00066 template <class T> unsigned int IteratedHashBase<T>::HashMultipleBlocks(const T *input, unsigned int length)
00067 {
00068         do
00069         {
00070                 HashBlock(input);
00071                 input += blockSize/sizeof(T);
00072                 length -= blockSize;
00073         }
00074         while (length >= blockSize);
00075         return length;
00076 }
00077 
00078 template <class T> void IteratedHashBase<T>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
00079 {
00080         unsigned int num = (unsigned int)(countLo >> 3) & (blockSize-1);
00081         assert(num < blockSize);
00082         ((byte *)data.ptr)[num++]=padFirst;
00083         if (num <= lastBlockSize)
00084                 memset((byte *)data.ptr+num, 0, lastBlockSize-num);
00085         else
00086         {
00087                 memset((byte *)data.ptr+num, 0, blockSize-num);
00088                 HashBlock(data);
00089                 memset(data, 0, lastBlockSize);
00090         }
00091 }
00092 
00093 template <class T> void IteratedHashBase<T>::Reinit()
00094 {
00095         countLo = countHi = 0;
00096         Init();
00097 }
00098 
00099 // provide empty definitions to avoid instantiation warnings
00100 template <class T> void IteratedHashBase<T>::Init() {}
00101 template <class T> void IteratedHashBase<T>::HashBlock(const T *input) {}
00102 
00103 #ifdef WORD64_AVAILABLE
00104 template class IteratedHashBase<word64>;
00105 #endif
00106 
00107 template class IteratedHashBase<word32>;
00108 
00109 NAMESPACE_END

Generated at Mon Jan 15 01:16:33 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000