00001
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++;
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)
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
00029 }
00030 else
00031 {
00032 memcpy((byte *)m_data.begin()+num, input, len);
00033 return;
00034 }
00035 }
00036
00037
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 {
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