15
18
if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0)
16
19
throw HashInputTooLong(this->AlgorithmName());
18
unsigned int blockSize = BlockSize();
21
unsigned int blockSize = this->BlockSize();
19
22
unsigned int num = ModPowerOf2(oldCountLo, blockSize);
23
T* dataBuf = this->DataBuf();
24
byte* data = (byte *)dataBuf;
21
26
if (num != 0) // process left over data
23
if ((num+len) >= blockSize)
28
if (num+len >= blockSize)
25
memcpy((byte *)m_data.begin()+num, input, blockSize-num);
30
memcpy(data+num, input, blockSize-num);
27
32
input += (blockSize-num);
28
len-=(blockSize - num);
33
len -= (blockSize-num);
30
35
// drop through and do the rest
34
memcpy((byte *)m_data.begin()+num, input, len);
39
memcpy(data+num, input, len);
56
61
{ // copy input first if it's not aligned correctly
57
memcpy(m_data, input, blockSize);
62
memcpy(data, input, blockSize);
61
66
} while (len >= blockSize);
64
memcpy(m_data, input, len);
69
memcpy(data, input, len);
67
72
template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(size_t &size)
69
unsigned int blockSize = BlockSize();
74
unsigned int blockSize = this->BlockSize();
70
75
unsigned int num = ModPowerOf2(m_countLo, blockSize);
71
76
size = blockSize - num;
72
return (byte *)m_data.begin() + num;
77
return (byte *)DataBuf() + num;
75
80
template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, size_t length)
77
unsigned int blockSize = BlockSize();
78
bool noReverse = NativeByteOrderIs(GetByteOrder());
82
unsigned int blockSize = this->BlockSize();
83
bool noReverse = NativeByteOrderIs(this->GetByteOrder());
84
T* dataBuf = this->DataBuf();
82
HashEndianCorrectedBlock(input);
88
this->HashEndianCorrectedBlock(input);
85
ByteReverse(this->m_data.begin(), input, this->BlockSize());
86
HashEndianCorrectedBlock(this->m_data);
91
ByteReverse(dataBuf, input, this->BlockSize());
92
this->HashEndianCorrectedBlock(dataBuf);
89
95
input += blockSize/sizeof(T);
96
102
template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
98
unsigned int blockSize = BlockSize();
104
unsigned int blockSize = this->BlockSize();
99
105
unsigned int num = ModPowerOf2(m_countLo, blockSize);
100
((byte *)m_data.begin())[num++]=padFirst;
106
T* dataBuf = this->DataBuf();
107
byte* data = (byte *)dataBuf;
108
data[num++] = padFirst;
101
109
if (num <= lastBlockSize)
102
memset((byte *)m_data.begin()+num, 0, lastBlockSize-num);
110
memset(data+num, 0, lastBlockSize-num);
105
memset((byte *)m_data.begin()+num, 0, blockSize-num);
107
memset(m_data, 0, lastBlockSize);
113
memset(data+num, 0, blockSize-num);
115
memset(data, 0, lastBlockSize);
119
127
this->ThrowIfInvalidTruncatedSize(size);
121
PadLastBlock(this->BlockSize() - 2*sizeof(HashWordType));
129
T* dataBuf = this->DataBuf();
130
T* stateBuf = this->StateBuf();
131
unsigned int blockSize = this->BlockSize();
122
132
ByteOrder order = this->GetByteOrder();
123
ConditionalByteReverse<HashWordType>(order, this->m_data, this->m_data, this->BlockSize() - 2*sizeof(HashWordType));
125
this->m_data[this->m_data.size()-2] = order ? this->GetBitCountHi() : this->GetBitCountLo();
126
this->m_data[this->m_data.size()-1] = order ? this->GetBitCountLo() : this->GetBitCountHi();
128
HashEndianCorrectedBlock(this->m_data);
129
ConditionalByteReverse<HashWordType>(order, this->m_digest, this->m_digest, this->DigestSize());
130
memcpy(digest, this->m_digest, size);
134
PadLastBlock(blockSize - 2*sizeof(HashWordType));
135
ConditionalByteReverse<HashWordType>(order, dataBuf, dataBuf, blockSize - 2*sizeof(HashWordType));
137
dataBuf[blockSize/sizeof(T)-2] = order ? this->GetBitCountHi() : this->GetBitCountLo();
138
dataBuf[blockSize/sizeof(T)-1] = order ? this->GetBitCountLo() : this->GetBitCountHi();
140
HashEndianCorrectedBlock(dataBuf);
141
ConditionalByteReverse<HashWordType>(order, stateBuf, stateBuf, this->DigestSize());
142
memcpy(digest, stateBuf, size);
132
144
this->Restart(); // reinit for next use
148
template class IteratedHashBase<word64, HashTransformation>;
149
template class IteratedHashBase<word64, MessageAuthenticationCode>;
151
template class IteratedHashBase<word32, HashTransformation>;
152
template class IteratedHashBase<word32, MessageAuthenticationCode>;