~zooko/cryptopp/trunk

« back to all changes in this revision

Viewing changes to iterhash.cpp

  • Committer: weidai
  • Date: 2009-03-02 02:39:17 UTC
  • Revision ID: svn-v4:57ff6487-cd31-0410-9ec3-f628ee90f5f0:trunk/c5:433
changes for 5.6: 
    - added AuthenticatedSymmetricCipher interface class and Filter wrappers
    - added CCM, GCM (with SSE2 assembly), CMAC, and SEED
    - improved AES speed on x86 and x64
    - removed WORD64_AVAILABLE; compiler 64-bit int support is now required

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// iterhash.cpp - written and placed in the public domain by Wei Dai
2
2
 
3
 
#include "pch.h"
 
3
#ifndef __GNUC__
 
4
#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
 
5
#endif
 
6
 
4
7
#include "iterhash.h"
5
8
#include "misc.h"
6
9
 
15
18
        if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0)
16
19
                throw HashInputTooLong(this->AlgorithmName());
17
20
 
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;
20
25
 
21
26
        if (num != 0)   // process left over data
22
27
        {
23
 
                if ((num+len) >= blockSize)
 
28
                if (num+len >= blockSize)
24
29
                {
25
 
                        memcpy((byte *)m_data.begin()+num, input, blockSize-num);
26
 
                        HashBlock(m_data);
 
30
                        memcpy(data+num, input, blockSize-num);
 
31
                        HashBlock(dataBuf);
27
32
                        input += (blockSize-num);
28
 
                        len-=(blockSize - num);
29
 
                        num=0;
 
33
                        len -= (blockSize-num);
 
34
                        num = 0;
30
35
                        // drop through and do the rest
31
36
                }
32
37
                else
33
38
                {
34
 
                        memcpy((byte *)m_data.begin()+num, input, len);
 
39
                        memcpy(data+num, input, len);
35
40
                        return;
36
41
                }
37
42
        }
39
44
        // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
40
45
        if (len >= blockSize)
41
46
        {
42
 
                if (input == (byte *)m_data.begin())
 
47
                if (input == data)
43
48
                {
44
49
                        assert(len == blockSize);
45
 
                        HashBlock(m_data);
 
50
                        HashBlock(dataBuf);
46
51
                        return;
47
52
                }
48
53
                else if (IsAligned<T>(input))
54
59
                else
55
60
                        do
56
61
                        {   // copy input first if it's not aligned correctly
57
 
                                memcpy(m_data, input, blockSize);
58
 
                                HashBlock(m_data);
 
62
                                memcpy(data, input, blockSize);
 
63
                                HashBlock(dataBuf);
59
64
                                input+=blockSize;
60
65
                                len-=blockSize;
61
66
                        } while (len >= blockSize);
62
67
        }
63
68
 
64
 
        memcpy(m_data, input, len);
 
69
        memcpy(data, input, len);
65
70
}
66
71
 
67
72
template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(size_t &size)
68
73
{
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;
73
78
}
74
79
 
75
80
template <class T, class BASE> size_t IteratedHashBase<T, BASE>::HashMultipleBlocks(const T *input, size_t length)
76
81
{
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();
79
85
        do
80
86
        {
81
87
                if (noReverse)
82
 
                        HashEndianCorrectedBlock(input);
 
88
                        this->HashEndianCorrectedBlock(input);
83
89
                else
84
90
                {
85
 
                        ByteReverse(this->m_data.begin(), input, this->BlockSize());
86
 
                        HashEndianCorrectedBlock(this->m_data);
 
91
                        ByteReverse(dataBuf, input, this->BlockSize());
 
92
                        this->HashEndianCorrectedBlock(dataBuf);
87
93
                }
88
94
 
89
95
                input += blockSize/sizeof(T);
95
101
 
96
102
template <class T, class BASE> void IteratedHashBase<T, BASE>::PadLastBlock(unsigned int lastBlockSize, byte padFirst)
97
103
{
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);
103
111
        else
104
112
        {
105
 
                memset((byte *)m_data.begin()+num, 0, blockSize-num);
106
 
                HashBlock(m_data);
107
 
                memset(m_data, 0, lastBlockSize);
 
113
                memset(data+num, 0, blockSize-num);
 
114
                HashBlock(dataBuf);
 
115
                memset(data, 0, lastBlockSize);
108
116
        }
109
117
}
110
118
 
118
126
{
119
127
        this->ThrowIfInvalidTruncatedSize(size);
120
128
 
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));
124
 
 
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();
127
 
 
128
 
        HashEndianCorrectedBlock(this->m_data);
129
 
        ConditionalByteReverse<HashWordType>(order, this->m_digest, this->m_digest, this->DigestSize());
130
 
        memcpy(digest, this->m_digest, size);
 
133
 
 
134
        PadLastBlock(blockSize - 2*sizeof(HashWordType));
 
135
        ConditionalByteReverse<HashWordType>(order, dataBuf, dataBuf, blockSize - 2*sizeof(HashWordType));
 
136
 
 
137
        dataBuf[blockSize/sizeof(T)-2] = order ? this->GetBitCountHi() : this->GetBitCountLo();
 
138
        dataBuf[blockSize/sizeof(T)-1] = order ? this->GetBitCountLo() : this->GetBitCountHi();
 
139
 
 
140
        HashEndianCorrectedBlock(dataBuf);
 
141
        ConditionalByteReverse<HashWordType>(order, stateBuf, stateBuf, this->DigestSize());
 
142
        memcpy(digest, stateBuf, size);
131
143
 
132
144
        this->Restart();                // reinit for next use
133
145
}
134
146
 
 
147
#ifdef __GNUC__
 
148
        template class IteratedHashBase<word64, HashTransformation>;
 
149
        template class IteratedHashBase<word64, MessageAuthenticationCode>;
 
150
 
 
151
        template class IteratedHashBase<word32, HashTransformation>;
 
152
        template class IteratedHashBase<word32, MessageAuthenticationCode>;
 
153
#endif
 
154
 
135
155
NAMESPACE_END