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>
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++;
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)
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
00036 }
00037
else
00038 {
00039 memcpy((byte *)m_data.begin()+num, input, len);
00040
return;
00041 }
00042 }
00043
00044
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 {
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