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