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> 00010 IteratedHashBase<T, BASE>::IteratedHashBase(unsigned int blockSize, unsigned int digestSize) 00011 : m_data(blockSize/sizeof(T)), m_digest(digestSize/sizeof(T)) 00012 , m_countHi(0), m_countLo(0) 00013 { 00014 } 00015 00016 template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte *input, unsigned int len) 00017 { 00018 HashWordType tmp = m_countLo; 00019 if ((m_countLo = tmp + len) < tmp) 00020 m_countHi++; // carry from low to high 00021 m_countHi += SafeRightShift<8*sizeof(HashWordType)>(len); 00022 00023 unsigned int blockSize = BlockSize(); 00024 unsigned int num = ModPowerOf2(tmp, blockSize); 00025 00026 if (num != 0) // process left over data 00027 { 00028 if ((num+len) >= blockSize) 00029 { 00030 memcpy((byte *)m_data.begin()+num, input, blockSize-num); 00031 HashBlock(m_data); 00032 input += (blockSize-num); 00033 len-=(blockSize - num); 00034 num=0; 00035 // drop through and do the rest 00036 } 00037 else 00038 { 00039 memcpy((byte *)m_data.begin()+num, input, len); 00040 return; 00041 } 00042 } 00043 00044 // now process the input data in blocks of blockSize bytes and save the leftovers to m_data 00045 if (len >= blockSize) 00046 { 00047 if (input == (byte *)m_data.begin()) 00048 { 00049 assert(len == blockSize); 00050 HashBlock(m_data); 00051 return; 00052 } 00053 else if (IsAligned<T>(input)) 00054 { 00055 unsigned int leftOver = HashMultipleBlocks((T *)input, len); 00056 input += (len - leftOver); 00057 len = leftOver; 00058 } 00059 else 00060 do 00061 { // copy input first if it's not aligned correctly 00062 memcpy(m_data, input, blockSize); 00063 HashBlock(m_data); 00064 input+=blockSize; 00065 len-=blockSize; 00066 } while (len >= blockSize); 00067 } 00068 00069 memcpy(m_data, input, len); 00070 } 00071 00072 template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(unsigned int &size) 00073 { 00074 unsigned int blockSize = BlockSize(); 00075 unsigned int num = ModPowerOf2(m_countLo, blockSize); 00076 size = blockSize - num; 00077 return (byte *)m_data.begin() + num; 00078 } 00079 00080 template <class T, class BASE> unsigned int IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, unsigned int length) 00081 { 00082 unsigned int blockSize = BlockSize(); 00083 do 00084 { 00085 HashBlock(input); 00086 input += blockSize/sizeof(T); 00087 length -= blockSize; 00088 } 00089 while (length >= blockSize); 00090 return length; 00091 } 00092 00093 template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst) 00094 { 00095 unsigned int blockSize = BlockSize(); 00096 unsigned int num = ModPowerOf2(m_countLo, blockSize); 00097 ((byte *)m_data.begin())[num++]=padFirst; 00098 if (num <= lastBlockSize) 00099 memset((byte *)m_data.begin()+num, 0, lastBlockSize-num); 00100 else 00101 { 00102 memset((byte *)m_data.begin()+num, 0, blockSize-num); 00103 HashBlock(m_data); 00104 memset(m_data, 0, lastBlockSize); 00105 } 00106 } 00107 00108 template <class T, class BASE> void IteratedHashBase<T, BASE>::Restart() 00109 { 00110 m_countLo = m_countHi = 0; 00111 Init(); 00112 } 00113 00114 #ifdef WORD64_AVAILABLE 00115 template class IteratedHashBase<word64, HashTransformation>; 00116 template class IteratedHashBase<word64, MessageAuthenticationCode>; 00117 #endif 00118 00119 template class IteratedHashBase<word32, HashTransformation>; 00120 template class IteratedHashBase<word32, MessageAuthenticationCode>; 00121 00122 NAMESPACE_END

Generated on Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7