00001
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++;
00020 countHi += len >> (8*sizeof(HashWordType)-3);
00021
00022 assert((blockSize & (blockSize-1)) == 0);
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
00035 }
00036 else
00037 {
00038 memcpy((byte *)data.ptr+num, input, len);
00039 return;
00040 }
00041 }
00042
00043
00044
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 {
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
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