~zooko/cryptopp/trunk

« back to all changes in this revision

Viewing changes to panama.cpp

  • Committer: weidai
  • Date: 2007-05-04 15:36:15 UTC
  • Revision ID: svn-v4:57ff6487-cd31-0410-9ec3-f628ee90f5f0:trunk/c5:339
fix compile

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#include "pch.h"
4
4
#include "panama.h"
5
5
#include "misc.h"
 
6
#include "cpu.h"
6
7
 
7
8
NAMESPACE_BEGIN(CryptoPP)
8
9
 
9
10
template <class B>
10
11
void Panama<B>::Reset()
11
12
{
12
 
        m_bstart = 0;
13
 
        memset(m_state, 0, m_state.size()*4);
14
 
}
 
13
        memset(m_state, 0, m_state.SizeInBytes());
 
14
#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
 
15
        m_state[17] = HasSSSE3();
 
16
#endif
 
17
}
 
18
 
 
19
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
 
20
 
 
21
#pragma warning(disable: 4731)  // frame pointer register 'ebp' modified by inline assembly code
 
22
 
 
23
void Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y)
 
24
{
 
25
#ifdef __GNUC__
 
26
        __asm__ __volatile__
 
27
        (
 
28
                ".intel_syntax noprefix;"
 
29
        AS_PUSH(                bx)
 
30
#else
 
31
        AS2(    mov             WORD_REG(cx), count)
 
32
        AS2(    mov             WORD_REG(si), state)
 
33
        AS2(    mov             WORD_REG(di), z)
 
34
        AS2(    mov             WORD_REG(dx), y)
 
35
#endif
 
36
        AS2(    shl             WORD_REG(cx), 5)
 
37
        ASJ(    jz,             5, f)
 
38
        AS2(    mov             ebx, [WORD_REG(si)+4*17])
 
39
        AS2(    add             WORD_REG(cx), WORD_REG(bx))
 
40
 
 
41
        AS_PUSH(                bp)
 
42
        AS_PUSH(                cx)
 
43
 
 
44
        AS2(    movdqa  xmm0, [WORD_REG(si)+0*16])
 
45
        AS2(    movdqa  xmm1, [WORD_REG(si)+1*16])
 
46
        AS2(    movdqa  xmm2, [WORD_REG(si)+2*16])
 
47
        AS2(    movdqa  xmm3, [WORD_REG(si)+3*16])
 
48
        AS2(    mov             eax, [WORD_REG(si)+4*16])
 
49
 
 
50
        ASL(4)
 
51
        // gamma and pi
 
52
#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
 
53
        AS2(    test    WORD_REG(bx), 1)
 
54
        ASJ(    jnz,    6, f)
 
55
#endif
 
56
        AS2(    movdqa  xmm6, xmm2)
 
57
        AS2(    movss   xmm6, xmm3)
 
58
        ASS(    pshufd  xmm5, xmm6, 0, 3, 2, 1)
 
59
        AS2(    movd    xmm6, eax)
 
60
        AS2(    movdqa  xmm7, xmm3)
 
61
        AS2(    movss   xmm7, xmm6)
 
62
        ASS(    pshufd  xmm6, xmm7, 0, 3, 2, 1)
 
63
#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
 
64
        ASJ(    jmp,    7, f)
 
65
        ASL(6)
 
66
        AS2(    movdqa  xmm5, xmm3)
 
67
        AS3(    palignr xmm5, xmm2, 4)
 
68
        AS2(    movd    xmm6, eax)
 
69
        AS3(    palignr xmm6, xmm3, 4)
 
70
        ASL(7)
 
71
#endif
 
72
 
 
73
        AS2(    movd    ecx, xmm2)
 
74
        AS1(    not             ecx)
 
75
        AS2(    movd    ebp, xmm3)
 
76
        AS2(    or              ecx, ebp)
 
77
        AS2(    xor             eax, ecx)
 
78
 
 
79
#define SSE2_Index(i) ASM_MOD(((i)*13+16), 17)
 
80
 
 
81
#define pi(i)   \
 
82
        AS2(    movd    ecx, xmm7)\
 
83
        AS2(    rol             ecx, ASM_MOD((ASM_MOD(5*i,17)*(ASM_MOD(5*i,17)+1)/2), 32))\
 
84
        AS2(    mov             [WORD_REG(si)+SSE2_Index(ASM_MOD(5*(i), 17))*4], ecx)
 
85
 
 
86
#define pi4(x, y, z, a, b, c, d)        \
 
87
        AS2(    pcmpeqb xmm7, xmm7)\
 
88
        AS2(    pxor    xmm7, x)\
 
89
        AS2(    por             xmm7, y)\
 
90
        AS2(    pxor    xmm7, z)\
 
91
        pi(a)\
 
92
        ASS(    pshuflw xmm7, xmm7, 1, 0, 3, 2)\
 
93
        pi(b)\
 
94
        AS2(    punpckhqdq      xmm7, xmm7)\
 
95
        pi(c)\
 
96
        ASS(    pshuflw xmm7, xmm7, 1, 0, 3, 2)\
 
97
        pi(d)
 
98
 
 
99
        pi4(xmm1, xmm2, xmm3, 1, 5, 9, 13)
 
100
        pi4(xmm0, xmm1, xmm2, 2, 6, 10, 14)
 
101
        pi4(xmm6, xmm0, xmm1, 3, 7, 11, 15)
 
102
        pi4(xmm5, xmm6, xmm0, 4, 8, 12, 16)
 
103
 
 
104
        // output keystream and update buffer here to hide partial memory stalls between pi and theta
 
105
        AS2(    movdqa  xmm4, xmm3)
 
106
        AS2(    punpcklqdq      xmm3, xmm2)             // 1 5 2 6
 
107
        AS2(    punpckhdq       xmm4, xmm2)             // 9 10 13 14
 
108
        AS2(    movdqa  xmm2, xmm1)
 
109
        AS2(    punpcklqdq      xmm1, xmm0)             // 3 7 4 8
 
110
        AS2(    punpckhdq       xmm2, xmm0)             // 11 12 15 16
 
111
 
 
112
        // keystream
 
113
        AS2(    test    WORD_REG(di), WORD_REG(di))
 
114
        ASJ(    jz,             0, f)
 
115
        AS2(    movdqa  xmm6, xmm4)
 
116
        AS2(    punpcklqdq      xmm4, xmm2)
 
117
        AS2(    punpckhqdq      xmm6, xmm2)
 
118
        AS2(    test    WORD_REG(dx), 0xf)
 
119
        ASJ(    jnz,    2, f)
 
120
        AS2(    test    WORD_REG(dx), WORD_REG(dx))
 
121
        ASJ(    jz,             1, f)
 
122
        AS2(    pxor    xmm4, [WORD_REG(dx)])
 
123
        AS2(    pxor    xmm6, [WORD_REG(dx)+16])
 
124
        AS2(    add             WORD_REG(dx), 32)
 
125
        ASJ(    jmp,    1, f)
 
126
        ASL(2)
 
127
        AS2(    movdqu  xmm0, [WORD_REG(dx)])
 
128
        AS2(    movdqu  xmm2, [WORD_REG(dx)+16])
 
129
        AS2(    pxor    xmm4, xmm0)
 
130
        AS2(    pxor    xmm6, xmm2)
 
131
        AS2(    add             WORD_REG(dx), 32)
 
132
        ASL(1)
 
133
        AS2(    test    WORD_REG(di), 0xf)
 
134
        ASJ(    jnz,    3, f)
 
135
        AS2(    movdqa  [WORD_REG(di)], xmm4)
 
136
        AS2(    movdqa  [WORD_REG(di)+16], xmm6)
 
137
        AS2(    add             WORD_REG(di), 32)
 
138
        ASJ(    jmp,    0, f)
 
139
        ASL(3)
 
140
        AS2(    movdqu  [WORD_REG(di)], xmm4)
 
141
        AS2(    movdqu  [WORD_REG(di)+16], xmm6)
 
142
        AS2(    add             WORD_REG(di), 32)
 
143
        ASL(0)
 
144
 
 
145
        // buffer update
 
146
        AS2(    lea             WORD_REG(cx), [WORD_REG(bx) + 32])
 
147
        AS2(    and             WORD_REG(cx), 31*32)
 
148
        AS2(    lea             WORD_REG(bp), [WORD_REG(bx) + (32-24)*32])
 
149
        AS2(    and             WORD_REG(bp), 31*32)
 
150
 
 
151
        AS2(    movdqa  xmm0, [WORD_REG(si)+20*4+WORD_REG(cx)+0*8])
 
152
        AS2(    pxor    xmm3, xmm0)
 
153
        ASS(    pshufd  xmm0, xmm0, 2, 3, 0, 1)
 
154
        AS2(    movdqa  [WORD_REG(si)+20*4+WORD_REG(cx)+0*8], xmm3)
 
155
        AS2(    pxor    xmm0, [WORD_REG(si)+20*4+WORD_REG(bp)+2*8])
 
156
        AS2(    movdqa  [WORD_REG(si)+20*4+WORD_REG(bp)+2*8], xmm0)
 
157
 
 
158
        AS2(    movdqa  xmm4, [WORD_REG(si)+20*4+WORD_REG(cx)+2*8])
 
159
        AS2(    pxor    xmm1, xmm4)
 
160
        AS2(    movdqa  [WORD_REG(si)+20*4+WORD_REG(cx)+2*8], xmm1)
 
161
        AS2(    pxor    xmm4, [WORD_REG(si)+20*4+WORD_REG(bp)+0*8])
 
162
        AS2(    movdqa  [WORD_REG(si)+20*4+WORD_REG(bp)+0*8], xmm4)
 
163
 
 
164
        // theta
 
165
        AS2(    movdqa  xmm3, [WORD_REG(si)+3*16])
 
166
        AS2(    movdqa  xmm2, [WORD_REG(si)+2*16])
 
167
        AS2(    movdqa  xmm1, [WORD_REG(si)+1*16])
 
168
        AS2(    movdqa  xmm0, [WORD_REG(si)+0*16])
 
169
 
 
170
#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
 
171
        AS2(    test    WORD_REG(bx), 1)
 
172
        ASJ(    jnz,    8, f)
 
173
#endif
 
174
        AS2(    movd    xmm6, eax)
 
175
        AS2(    movdqa  xmm7, xmm3)
 
176
        AS2(    movss   xmm7, xmm6)
 
177
        AS2(    movdqa  xmm6, xmm2)
 
178
        AS2(    movss   xmm6, xmm3)
 
179
        AS2(    movdqa  xmm5, xmm1)
 
180
        AS2(    movss   xmm5, xmm2)
 
181
        AS2(    movdqa  xmm4, xmm0)
 
182
        AS2(    movss   xmm4, xmm1)
 
183
        ASS(    pshufd  xmm7, xmm7, 0, 3, 2, 1)
 
184
        ASS(    pshufd  xmm6, xmm6, 0, 3, 2, 1)
 
185
        ASS(    pshufd  xmm5, xmm5, 0, 3, 2, 1)
 
186
        ASS(    pshufd  xmm4, xmm4, 0, 3, 2, 1)
 
187
#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
 
188
        ASJ(    jmp,    9, f)
 
189
        ASL(8)
 
190
        AS2(    movd    xmm7, eax)
 
191
        AS3(    palignr xmm7, xmm3, 4)
 
192
        AS2(    movq    xmm6, xmm3)
 
193
        AS3(    palignr xmm6, xmm2, 4)
 
194
        AS2(    movq    xmm5, xmm2)
 
195
        AS3(    palignr xmm5, xmm1, 4)
 
196
        AS2(    movq    xmm4, xmm1)
 
197
        AS3(    palignr xmm4, xmm0, 4)
 
198
        ASL(9)
 
199
#endif
 
200
 
 
201
        AS2(    xor             eax, 1)
 
202
        AS2(    movd    ecx, xmm0)
 
203
        AS2(    xor             eax, ecx)
 
204
        AS2(    movd    ecx, xmm3)
 
205
        AS2(    xor             eax, ecx)
 
206
 
 
207
        AS2(    pxor    xmm3, xmm2)
 
208
        AS2(    pxor    xmm2, xmm1)
 
209
        AS2(    pxor    xmm1, xmm0)
 
210
        AS2(    pxor    xmm0, xmm7)
 
211
        AS2(    pxor    xmm3, xmm7)
 
212
        AS2(    pxor    xmm2, xmm6)
 
213
        AS2(    pxor    xmm1, xmm5)
 
214
        AS2(    pxor    xmm0, xmm4)
 
215
 
 
216
        // sigma
 
217
        AS2(    lea             WORD_REG(cx), [WORD_REG(bx) + (32-4)*32])
 
218
        AS2(    and             WORD_REG(cx), 31*32)
 
219
        AS2(    lea             WORD_REG(bp), [WORD_REG(bx) + 16*32])
 
220
        AS2(    and             WORD_REG(bp), 31*32)
 
221
 
 
222
        AS2(    movdqa  xmm4, [WORD_REG(si)+20*4+WORD_REG(cx)+0*16])
 
223
        AS2(    movdqa  xmm5, [WORD_REG(si)+20*4+WORD_REG(bp)+0*16])
 
224
        AS2(    movdqa  xmm6, xmm4)
 
225
        AS2(    punpcklqdq      xmm4, xmm5)
 
226
        AS2(    punpckhqdq      xmm6, xmm5)
 
227
        AS2(    pxor    xmm3, xmm4)
 
228
        AS2(    pxor    xmm2, xmm6)
 
229
 
 
230
        AS2(    movdqa  xmm4, [WORD_REG(si)+20*4+WORD_REG(cx)+1*16])
 
231
        AS2(    movdqa  xmm5, [WORD_REG(si)+20*4+WORD_REG(bp)+1*16])
 
232
        AS2(    movdqa  xmm6, xmm4)
 
233
        AS2(    punpcklqdq      xmm4, xmm5)
 
234
        AS2(    punpckhqdq      xmm6, xmm5)
 
235
        AS2(    pxor    xmm1, xmm4)
 
236
        AS2(    pxor    xmm0, xmm6)
 
237
 
 
238
        // loop
 
239
        AS2(    add             WORD_REG(bx), 32)
 
240
        AS2(    cmp             WORD_REG(bx), [WORD_REG(sp)])
 
241
        ASJ(    jne,    4, b)
 
242
 
 
243
        // save state
 
244
        AS2(    add             WORD_REG(sp), WORD_SZ)
 
245
        AS_POP(                 bp)
 
246
        AS2(    mov             [WORD_REG(si)+4*16], eax)
 
247
        AS2(    movdqa  [WORD_REG(si)+3*16], xmm3)
 
248
        AS2(    movdqa  [WORD_REG(si)+2*16], xmm2)
 
249
        AS2(    movdqa  [WORD_REG(si)+1*16], xmm1)
 
250
        AS2(    movdqa  [WORD_REG(si)+0*16], xmm0)
 
251
        ASL(5)
 
252
 
 
253
#ifdef __GNUC__
 
254
        AS_POP(                 bx)
 
255
        ".att_syntax prefix;"
 
256
                :
 
257
                : "c" (count), "S" (state), "D" (z), "d" (y)
 
258
                : "%eax", "memory", "cc"
 
259
        );
 
260
#endif
 
261
}
 
262
 
 
263
#endif
15
264
 
16
265
template <class B>
17
266
void Panama<B>::Iterate(size_t count, const word32 *p, word32 *z, const word32 *y)
18
267
{
19
 
        unsigned int bstart = m_bstart;
20
 
        word32 *const a = m_state;
21
 
#define c (a+17)
22
 
#define b ((Stage *)(a+34))
 
268
        word32 bstart = m_state[17];
 
269
        word32 *const aPtr = m_state;
 
270
        word32 cPtr[17];
 
271
 
 
272
#define bPtr ((byte *)(aPtr+20))
 
273
 
 
274
// reorder the state for SSE2
 
275
// a and c: 4 8 12 16 | 3 7 11 15 | 2 6 10 14 | 1 5 9 13 | 0
 
276
//                      xmm0            xmm1            xmm2            xmm3            eax
 
277
#define a(i) aPtr[((i)*13+16) % 17]             // 13 is inverse of 4 mod 17
 
278
#define c(i) cPtr[((i)*13+16) % 17]
 
279
// b: 0 4 | 1 5 | 2 6 | 3 7
 
280
#define b(i, j) b##i[(j)*2%8 + (j)/4]
23
281
 
24
282
// output
25
 
#define OA(i) z[i] = ConditionalByteReverse(B::ToEnum(), a[i+9])
26
 
#define OX(i) z[i] = y[i] ^ ConditionalByteReverse(B::ToEnum(), a[i+9])
 
283
#define OA(i) z[i] = ConditionalByteReverse(B::ToEnum(), a(i+9))
 
284
#define OX(i) z[i] = y[i] ^ ConditionalByteReverse(B::ToEnum(), a(i+9))
27
285
// buffer update
28
 
#define US(i) {word32 t=b0[i]; b0[i]=ConditionalByteReverse(B::ToEnum(), p[i])^t; b25[(i+6)%8]^=t;}
29
 
#define UL(i) {word32 t=b0[i]; b0[i]=a[i+1]^t; b25[(i+6)%8]^=t;}
 
286
#define US(i) {word32 t=b(0,i); b(0,i)=ConditionalByteReverse(B::ToEnum(), p[i])^t; b(25,(i+6)%8)^=t;}
 
287
#define UL(i) {word32 t=b(0,i); b(0,i)=a(i+1)^t; b(25,(i+6)%8)^=t;}
30
288
// gamma and pi
31
 
#define GP(i) c[5*i%17] = rotlFixed(a[i] ^ (a[(i+1)%17] | ~a[(i+2)%17]), ((5*i%17)*((5*i%17)+1)/2)%32)
 
289
#define GP(i) c(5*i%17) = rotlFixed(a(i) ^ (a((i+1)%17) | ~a((i+2)%17)), ((5*i%17)*((5*i%17)+1)/2)%32)
32
290
// theta and sigma
33
 
#define T(i,x) a[i] = c[i] ^ c[(i+1)%17] ^ c[(i+4)%17] ^ x
 
291
#define T(i,x) a(i) = c(i) ^ c((i+1)%17) ^ c((i+4)%17) ^ x
34
292
#define TS1S(i) T(i+1, ConditionalByteReverse(B::ToEnum(), p[i]))
35
 
#define TS1L(i) T(i+1, b4[i])
36
 
#define TS2(i) T(i+9, b16[i])
 
293
#define TS1L(i) T(i+1, b(4,i))
 
294
#define TS2(i) T(i+9, b(16,i))
37
295
 
38
296
        while (count--)
39
297
        {
51
309
                        z += 8;
52
310
                }
53
311
 
54
 
                word32 *const b16 = b[(bstart+16) % STAGES];
55
 
                word32 *const b4 = b[(bstart+4) % STAGES];
56
 
        bstart = (bstart + STAGES - 1) % STAGES;
57
 
                word32 *const b0 = b[bstart];
58
 
                word32 *const b25 = b[(bstart+25) % STAGES];
59
 
 
 
312
                word32 *const b16 = (word32 *)(bPtr+((bstart+16*32) & 31*32));
 
313
                word32 *const b4 = (word32 *)(bPtr+((bstart+(32-4)*32) & 31*32));
 
314
        bstart += 32;
 
315
                word32 *const b0 = (word32 *)(bPtr+((bstart) & 31*32));
 
316
                word32 *const b25 = (word32 *)(bPtr+((bstart+(32-25)*32) & 31*32));
60
317
 
61
318
                if (p)
62
319
                {
67
324
                        UL(0); UL(1); UL(2); UL(3); UL(4); UL(5); UL(6); UL(7);
68
325
                }
69
326
 
70
 
                GP(0); GP(1); GP(2); GP(3); GP(4); GP(5); GP(6); GP(7);
71
 
                GP(8); GP(9); GP(10); GP(11); GP(12); GP(13); GP(14); GP(15); GP(16);
 
327
                GP(0); 
 
328
                GP(1); 
 
329
                GP(2); 
 
330
                GP(3); 
 
331
                GP(4); 
 
332
                GP(5); 
 
333
                GP(6); 
 
334
                GP(7);
 
335
                GP(8); 
 
336
                GP(9); 
 
337
                GP(10); 
 
338
                GP(11); 
 
339
                GP(12); 
 
340
                GP(13); 
 
341
                GP(14); 
 
342
                GP(15); 
 
343
                GP(16);
72
344
 
73
345
                T(0,1);
74
346
 
84
356
 
85
357
                TS2(0); TS2(1); TS2(2); TS2(3); TS2(4); TS2(5); TS2(6); TS2(7);
86
358
        }
87
 
        m_bstart = bstart;
 
359
        m_state[17] = bstart;
88
360
}
89
361
 
90
362
template <class B>
91
 
size_t PanamaHash<B>::HashMultipleBlocks(const word32 *input, size_t length)
 
363
size_t Weak::PanamaHash<B>::HashMultipleBlocks(const word32 *input, size_t length)
92
364
{
93
365
        this->Iterate(length / this->BLOCKSIZE, input);
94
366
        return length % this->BLOCKSIZE;
95
367
}
96
368
 
97
369
template <class B>
98
 
void PanamaHash<B>::TruncatedFinal(byte *hash, size_t size)
 
370
void Weak::PanamaHash<B>::TruncatedFinal(byte *hash, size_t size)
99
371
{
100
372
        this->ThrowIfInvalidTruncatedSize(size);
101
373
 
105
377
 
106
378
        this->Iterate(32);      // pull
107
379
 
108
 
        ConditionalByteReverse(B::ToEnum(), this->m_state+9, this->m_state+9, DIGESTSIZE);
109
 
        memcpy(hash, this->m_state+9, size);
 
380
        FixedSizeSecBlock<word32, 8> buf;
 
381
        this->Iterate(1, NULL, buf, NULL);
 
382
 
 
383
        memcpy(hash, buf, size);
110
384
 
111
385
        this->Restart();                // reinit for next use
112
386
}
114
388
template <class B>
115
389
void PanamaCipherPolicy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
116
390
{
117
 
        FixedSizeSecBlock<word32, 8> buf;
 
391
        assert(length==32);
 
392
        memcpy(m_key, key, 32);
 
393
}
118
394
 
 
395
template <class B>
 
396
void PanamaCipherPolicy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *iv)
 
397
{
119
398
        this->Reset();
120
 
        memcpy(buf, key, 32);
121
 
        this->Iterate(1, buf);
122
 
        if (length == 64)
123
 
                memcpy(buf, key+32, 32);
124
 
        else
125
 
                memset(buf, 0, 32);
126
 
        this->Iterate(1, buf);
127
 
 
128
 
        this->Iterate(32);
129
 
}
 
399
        this->Iterate(1, m_key);
 
400
        if (iv && IsAligned<word32>(iv))
 
401
                this->Iterate(1, (const word32 *)iv);
 
402
        else
 
403
        {
 
404
                FixedSizeSecBlock<word32, 8> buf;
 
405
                if (iv)
 
406
                        memcpy(buf, iv, 32);
 
407
                else
 
408
                        memset(buf, 0, 32);
 
409
                this->Iterate(1, buf);
 
410
        }
 
411
 
 
412
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
 
413
        if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2())
 
414
                Panama_SSE2_Pull(32, this->m_state, NULL, NULL);
 
415
        else
 
416
#endif
 
417
                this->Iterate(32);
 
418
}
 
419
 
 
420
#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64
 
421
template <class B>
 
422
unsigned int PanamaCipherPolicy<B>::GetAlignment() const
 
423
{
 
424
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
 
425
        if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2())
 
426
                return 16;
 
427
        else
 
428
#endif
 
429
                return 1;
 
430
}
 
431
#endif
130
432
 
131
433
template <class B>
132
434
void PanamaCipherPolicy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
133
435
{
134
 
        this->Iterate(iterationCount, NULL, (word32 *)output, (const word32 *)input);
 
436
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
 
437
        if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2())
 
438
                Panama_SSE2_Pull(iterationCount, this->m_state, (word32 *)output, (const word32 *)input);
 
439
        else
 
440
#endif
 
441
                this->Iterate(iterationCount, NULL, (word32 *)output, (const word32 *)input);
135
442
}
136
443
 
137
444
template class Panama<BigEndian>;
138
445
template class Panama<LittleEndian>;
139
446
 
140
 
template class PanamaHash<BigEndian>;
141
 
template class PanamaHash<LittleEndian>;
 
447
template class Weak::PanamaHash<BigEndian>;
 
448
template class Weak::PanamaHash<LittleEndian>;
142
449
 
143
450
template class PanamaCipherPolicy<BigEndian>;
144
451
template class PanamaCipherPolicy<LittleEndian>;