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 Fri Aug 27 22:01:20 2004 for Crypto++ by doxygen 1.3.8