00001
00002
00003 #include "pch.h"
00004
00005 #ifndef CRYPTOPP_IMPORTS
00006
00007 #include "iterhash.h"
00008 #include "misc.h"
00009
00010 NAMESPACE_BEGIN(CryptoPP)
00011
00012 template <class T, class BASE>
00013 IteratedHashBase<T, BASE>::IteratedHashBase(unsigned int blockSize, unsigned int digestSize)
00014 : m_data(blockSize/sizeof(T)), m_digest(digestSize/sizeof(T))
00015 , m_countHi(0), m_countLo(0)
00016 {
00017 }
00018
00019 template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte *input, unsigned int len)
00020 {
00021 HashWordType tmp = m_countLo;
00022 if ((m_countLo = tmp + len) < tmp)
00023 m_countHi++;
00024 m_countHi += SafeRightShift<8*sizeof(HashWordType)>(len);
00025
00026 unsigned int blockSize = BlockSize();
00027 unsigned int num = (unsigned int)(tmp & (blockSize-1));
00028
00029 if (num != 0)
00030 {
00031 if ((num+len) >= blockSize)
00032 {
00033 memcpy((byte *)m_data.begin()+num, input, blockSize-num);
00034 HashBlock(m_data);
00035 input += (blockSize-num);
00036 len-=(blockSize - num);
00037 num=0;
00038
00039 }
00040 else
00041 {
00042 memcpy((byte *)m_data.begin()+num, input, len);
00043 return;
00044 }
00045 }
00046
00047
00048
00049 if (len >= blockSize)
00050 {
00051 if (input == (byte *)m_data.begin())
00052 {
00053 assert(len == blockSize);
00054 HashBlock(m_data);
00055 return;
00056 }
00057 else if (IsAligned<T>(input))
00058 {
00059 unsigned int leftOver = HashMultipleBlocks((T *)input, len);
00060 input += (len - leftOver);
00061 len = leftOver;
00062 }
00063 else
00064 do
00065 {
00066 memcpy(m_data, input, blockSize);
00067 HashBlock(m_data);
00068 input+=blockSize;
00069 len-=blockSize;
00070 } while (len >= blockSize);
00071 }
00072
00073 memcpy(m_data, input, len);
00074 }
00075
00076 template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(unsigned int &size)
00077 {
00078 unsigned int blockSize = BlockSize();
00079 unsigned int num = ModPowerOf2(m_countLo, blockSize);
00080 size = blockSize - num;
00081 return (byte *)m_data.begin() + num;
00082 }
00083
00084 template <class T, class BASE> unsigned int IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, unsigned int length)
00085 {
00086 unsigned int blockSize = BlockSize();
00087 do
00088 {
00089 HashBlock(input);
00090 input += blockSize/sizeof(T);
00091 length -= blockSize;
00092 }
00093 while (length >= blockSize);
00094 return length;
00095 }
00096
00097 template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
00098 {
00099 unsigned int blockSize = BlockSize();
00100 unsigned int num = ModPowerOf2(m_countLo, blockSize);
00101 ((byte *)m_data.begin())[num++]=padFirst;
00102 if (num <= lastBlockSize)
00103 memset((byte *)m_data.begin()+num, 0, lastBlockSize-num);
00104 else
00105 {
00106 memset((byte *)m_data.begin()+num, 0, blockSize-num);
00107 HashBlock(m_data);
00108 memset(m_data, 0, lastBlockSize);
00109 }
00110 }
00111
00112 template <class T, class BASE> void IteratedHashBase<T, BASE>::Restart()
00113 {
00114 m_countLo = m_countHi = 0;
00115 Init();
00116 }
00117
00118 NAMESPACE_END
00119
00120 #endif