monotone

monotone Mtn Source Tree

Root/cryptopp/iterhash.cpp

1// iterhash.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "iterhash.h"
5#include "misc.h"
6
7NAMESPACE_BEGIN(CryptoPP)
8
9template <class T, class BASE>
10IteratedHashBase<T, BASE>::IteratedHashBase(unsigned int blockSize, unsigned int digestSize)
11: m_data(blockSize/sizeof(T)), m_digest(digestSize/sizeof(T))
12, m_countHi(0), m_countLo(0)
13{
14}
15
16template <class T, class BASE> void IteratedHashBase<T, BASE>::Update(const byte *input, unsigned int len)
17{
18HashWordType tmp = m_countLo;
19if ((m_countLo = tmp + len) < tmp)
20m_countHi++; // carry from low to high
21m_countHi += SafeRightShift<8*sizeof(HashWordType)>(len);
22
23unsigned int blockSize = BlockSize();
24unsigned int num = ModPowerOf2(tmp, blockSize);
25
26if (num != 0)// process left over data
27{
28if ((num+len) >= blockSize)
29{
30memcpy((byte *)m_data.begin()+num, input, blockSize-num);
31HashBlock(m_data);
32input += (blockSize-num);
33len-=(blockSize - num);
34num=0;
35// drop through and do the rest
36}
37else
38{
39memcpy((byte *)m_data.begin()+num, input, len);
40return;
41}
42}
43
44// now process the input data in blocks of blockSize bytes and save the leftovers to m_data
45if (len >= blockSize)
46{
47if (input == (byte *)m_data.begin())
48{
49assert(len == blockSize);
50HashBlock(m_data);
51return;
52}
53else if (IsAligned<T>(input))
54{
55unsigned int leftOver = HashMultipleBlocks((T *)input, len);
56input += (len - leftOver);
57len = leftOver;
58}
59else
60do
61{ // copy input first if it's not aligned correctly
62memcpy(m_data, input, blockSize);
63HashBlock(m_data);
64input+=blockSize;
65len-=blockSize;
66} while (len >= blockSize);
67}
68
69memcpy(m_data, input, len);
70}
71
72template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(unsigned int &size)
73{
74unsigned int blockSize = BlockSize();
75unsigned int num = ModPowerOf2(m_countLo, blockSize);
76size = blockSize - num;
77return (byte *)m_data.begin() + num;
78}
79
80template <class T, class BASE> unsigned int IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, unsigned int length)
81{
82unsigned int blockSize = BlockSize();
83do
84{
85HashBlock(input);
86input += blockSize/sizeof(T);
87length -= blockSize;
88}
89while (length >= blockSize);
90return length;
91}
92
93template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
94{
95unsigned int blockSize = BlockSize();
96unsigned int num = ModPowerOf2(m_countLo, blockSize);
97((byte *)m_data.begin())[num++]=padFirst;
98if (num <= lastBlockSize)
99memset((byte *)m_data.begin()+num, 0, lastBlockSize-num);
100else
101{
102memset((byte *)m_data.begin()+num, 0, blockSize-num);
103HashBlock(m_data);
104memset(m_data, 0, lastBlockSize);
105}
106}
107
108template <class T, class BASE> void IteratedHashBase<T, BASE>::Restart()
109{
110m_countLo = m_countHi = 0;
111Init();
112}
113
114#ifdef WORD64_AVAILABLE
115template class IteratedHashBase<word64, HashTransformation>;
116template class IteratedHashBase<word64, MessageAuthenticationCode>;
117#endif
118
119template class IteratedHashBase<word32, HashTransformation>;
120template class IteratedHashBase<word32, MessageAuthenticationCode>;
121
122NAMESPACE_END

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status