00001
00002
00003
00004
00005 #include "pch.h"
00006
00007 #ifndef CRYPTOPP_GENERATE_X64_MASM
00008
00009 #include "panama.h"
00010 #include "secblock.h"
00011 #include "misc.h"
00012 #include "cpu.h"
00013
00014 NAMESPACE_BEGIN(CryptoPP)
00015
00016 #if CRYPTOPP_MSC_VERSION
00017 # pragma warning(disable: 4731)
00018 #endif
00019
00020 template <class B>
00021 void Panama<B>::Reset()
00022 {
00023 memset(m_state, 0, m_state.SizeInBytes());
00024 #if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_PANAMA_ASM)
00025 m_state[17] = HasSSSE3();
00026 #endif
00027 }
00028
00029 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM
00030
00031 #ifdef CRYPTOPP_X64_MASM_AVAILABLE
00032 extern "C" {
00033 void Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y);
00034 }
00035 #elif CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && !defined(CRYPTOPP_DISABLE_PANAMA_ASM)
00036
00037 #ifdef CRYPTOPP_GENERATE_X64_MASM
00038 Panama_SSE2_Pull PROC FRAME
00039 rex_push_reg rdi
00040 alloc_stack(2*16)
00041 save_xmm128 xmm6, 0h
00042 save_xmm128 xmm7, 10h
00043 .endprolog
00044 #else
00045 void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y)
00046 {
00047 #if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
00048 asm __volatile__
00049 (
00050 INTEL_NOPREFIX
00051 AS_PUSH_IF86( bx)
00052 #else
00053 AS2( mov AS_REG_1, count)
00054 AS2( mov AS_REG_2, state)
00055 AS2( mov AS_REG_3, z)
00056 AS2( mov AS_REG_4, y)
00057 #endif
00058 #endif
00059
00060 #if CRYPTOPP_BOOL_X32
00061 #define REG_loopEnd r8d
00062 #elif CRYPTOPP_BOOL_X86
00063 #define REG_loopEnd [esp]
00064 #elif defined(CRYPTOPP_GENERATE_X64_MASM)
00065 #define REG_loopEnd rdi
00066 #else
00067 #define REG_loopEnd r8
00068 #endif
00069
00070 AS2( shl AS_REG_1, 5)
00071 ASJ( jz, 5, f)
00072 AS2( mov AS_REG_6d, [AS_REG_2+4*17])
00073 AS2( add AS_REG_1, AS_REG_6)
00074
00075 #if CRYPTOPP_BOOL_X64
00076 AS2( mov REG_loopEnd, AS_REG_1)
00077 #else
00078 AS_PUSH_IF86( bp)
00079
00080 AS_PUSH_IF86( cx)
00081 #endif
00082
00083 AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+0*16])
00084 AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_2+1*16])
00085 AS2( movdqa xmm2, XMMWORD_PTR [AS_REG_2+2*16])
00086 AS2( movdqa xmm3, XMMWORD_PTR [AS_REG_2+3*16])
00087 AS2( mov eax, dword ptr [AS_REG_2+4*16])
00088
00089 ASL(4)
00090
00091 #if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
00092 AS2( test AS_REG_6, 1)
00093 ASJ( jnz, 6, f)
00094 #endif
00095 AS2( movdqa xmm6, xmm2)
00096 AS2( movss xmm6, xmm3)
00097 ASS( pshufd xmm5, xmm6, 0, 3, 2, 1)
00098 AS2( movd xmm6, eax)
00099 AS2( movdqa xmm7, xmm3)
00100 AS2( movss xmm7, xmm6)
00101 ASS( pshufd xmm6, xmm7, 0, 3, 2, 1)
00102 #if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
00103 ASJ( jmp, 7, f)
00104 ASL(6)
00105 AS2( movdqa xmm5, xmm3)
00106 AS3( palignr xmm5, xmm2, 4)
00107 AS2( movd xmm6, eax)
00108 AS3( palignr xmm6, xmm3, 4)
00109 ASL(7)
00110 #endif
00111
00112 AS2( movd AS_REG_1d, xmm2)
00113 AS1( not AS_REG_1d)
00114 AS2( movd AS_REG_7d, xmm3)
00115 AS2( or AS_REG_1d, AS_REG_7d)
00116 AS2( xor eax, AS_REG_1d)
00117
00118 #define SSE2_Index(i) ASM_MOD(((i)*13+16), 17)
00119
00120 #define pi(i) \
00121 AS2( movd AS_REG_1d, xmm7)\
00122 AS2( rol AS_REG_1d, ASM_MOD((ASM_MOD(5*i,17)*(ASM_MOD(5*i,17)+1)/2), 32))\
00123 AS2( mov [AS_REG_2+SSE2_Index(ASM_MOD(5*(i), 17))*4], AS_REG_1d)
00124
00125 #define pi4(x, y, z, a, b, c, d) \
00126 AS2( pcmpeqb xmm7, xmm7)\
00127 AS2( pxor xmm7, x)\
00128 AS2( por xmm7, y)\
00129 AS2( pxor xmm7, z)\
00130 pi(a)\
00131 ASS( pshuflw xmm7, xmm7, 1, 0, 3, 2)\
00132 pi(b)\
00133 AS2( punpckhqdq xmm7, xmm7)\
00134 pi(c)\
00135 ASS( pshuflw xmm7, xmm7, 1, 0, 3, 2)\
00136 pi(d)
00137
00138 pi4(xmm1, xmm2, xmm3, 1, 5, 9, 13)
00139 pi4(xmm0, xmm1, xmm2, 2, 6, 10, 14)
00140 pi4(xmm6, xmm0, xmm1, 3, 7, 11, 15)
00141 pi4(xmm5, xmm6, xmm0, 4, 8, 12, 16)
00142
00143
00144 AS2( movdqa xmm4, xmm3)
00145 AS2( punpcklqdq xmm3, xmm2)
00146 AS2( punpckhdq xmm4, xmm2)
00147 AS2( movdqa xmm2, xmm1)
00148 AS2( punpcklqdq xmm1, xmm0)
00149 AS2( punpckhdq xmm2, xmm0)
00150
00151
00152 AS2( test AS_REG_3, AS_REG_3)
00153 ASJ( jz, 0, f)
00154 AS2( movdqa xmm6, xmm4)
00155 AS2( punpcklqdq xmm4, xmm2)
00156 AS2( punpckhqdq xmm6, xmm2)
00157 AS2( test AS_REG_4, 15)
00158 ASJ( jnz, 2, f)
00159 AS2( test AS_REG_4, AS_REG_4)
00160 ASJ( jz, 1, f)
00161 AS2( pxor xmm4, [AS_REG_4])
00162 AS2( pxor xmm6, [AS_REG_4+16])
00163 AS2( add AS_REG_4, 32)
00164 ASJ( jmp, 1, f)
00165 ASL(2)
00166 AS2( movdqu xmm0, [AS_REG_4])
00167 AS2( movdqu xmm2, [AS_REG_4+16])
00168 AS2( pxor xmm4, xmm0)
00169 AS2( pxor xmm6, xmm2)
00170 AS2( add AS_REG_4, 32)
00171 ASL(1)
00172 AS2( test AS_REG_3, 15)
00173 ASJ( jnz, 3, f)
00174 AS2( movdqa XMMWORD_PTR [AS_REG_3], xmm4)
00175 AS2( movdqa XMMWORD_PTR [AS_REG_3+16], xmm6)
00176 AS2( add AS_REG_3, 32)
00177 ASJ( jmp, 0, f)
00178 ASL(3)
00179 AS2( movdqu XMMWORD_PTR [AS_REG_3], xmm4)
00180 AS2( movdqu XMMWORD_PTR [AS_REG_3+16], xmm6)
00181 AS2( add AS_REG_3, 32)
00182 ASL(0)
00183
00184
00185 AS2( lea AS_REG_1, [AS_REG_6 + 32])
00186 AS2( and AS_REG_1, 31*32)
00187 AS2( lea AS_REG_7, [AS_REG_6 + (32-24)*32])
00188 AS2( and AS_REG_7, 31*32)
00189
00190 AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*8])
00191 AS2( pxor xmm3, xmm0)
00192 ASS( pshufd xmm0, xmm0, 2, 3, 0, 1)
00193 AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*8], xmm3)
00194 AS2( pxor xmm0, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+2*8])
00195 AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+2*8], xmm0)
00196
00197 AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+2*8])
00198 AS2( pxor xmm1, xmm4)
00199 AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+2*8], xmm1)
00200 AS2( pxor xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*8])
00201 AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*8], xmm4)
00202
00203
00204 AS2( movdqa xmm3, XMMWORD_PTR [AS_REG_2+3*16])
00205 AS2( movdqa xmm2, XMMWORD_PTR [AS_REG_2+2*16])
00206 AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_2+1*16])
00207 AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+0*16])
00208
00209 #if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
00210 AS2( test AS_REG_6, 1)
00211 ASJ( jnz, 8, f)
00212 #endif
00213 AS2( movd xmm6, eax)
00214 AS2( movdqa xmm7, xmm3)
00215 AS2( movss xmm7, xmm6)
00216 AS2( movdqa xmm6, xmm2)
00217 AS2( movss xmm6, xmm3)
00218 AS2( movdqa xmm5, xmm1)
00219 AS2( movss xmm5, xmm2)
00220 AS2( movdqa xmm4, xmm0)
00221 AS2( movss xmm4, xmm1)
00222 ASS( pshufd xmm7, xmm7, 0, 3, 2, 1)
00223 ASS( pshufd xmm6, xmm6, 0, 3, 2, 1)
00224 ASS( pshufd xmm5, xmm5, 0, 3, 2, 1)
00225 ASS( pshufd xmm4, xmm4, 0, 3, 2, 1)
00226 #if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE
00227 ASJ( jmp, 9, f)
00228 ASL(8)
00229 AS2( movd xmm7, eax)
00230 AS3( palignr xmm7, xmm3, 4)
00231 AS2( movq xmm6, xmm3)
00232 AS3( palignr xmm6, xmm2, 4)
00233 AS2( movq xmm5, xmm2)
00234 AS3( palignr xmm5, xmm1, 4)
00235 AS2( movq xmm4, xmm1)
00236 AS3( palignr xmm4, xmm0, 4)
00237 ASL(9)
00238 #endif
00239
00240 AS2( xor eax, 1)
00241 AS2( movd AS_REG_1d, xmm0)
00242 AS2( xor eax, AS_REG_1d)
00243 AS2( movd AS_REG_1d, xmm3)
00244 AS2( xor eax, AS_REG_1d)
00245
00246 AS2( pxor xmm3, xmm2)
00247 AS2( pxor xmm2, xmm1)
00248 AS2( pxor xmm1, xmm0)
00249 AS2( pxor xmm0, xmm7)
00250 AS2( pxor xmm3, xmm7)
00251 AS2( pxor xmm2, xmm6)
00252 AS2( pxor xmm1, xmm5)
00253 AS2( pxor xmm0, xmm4)
00254
00255
00256 AS2( lea AS_REG_1, [AS_REG_6 + (32-4)*32])
00257 AS2( and AS_REG_1, 31*32)
00258 AS2( lea AS_REG_7, [AS_REG_6 + 16*32])
00259 AS2( and AS_REG_7, 31*32)
00260
00261 AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*16])
00262 AS2( movdqa xmm5, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*16])
00263 AS2( movdqa xmm6, xmm4)
00264 AS2( punpcklqdq xmm4, xmm5)
00265 AS2( punpckhqdq xmm6, xmm5)
00266 AS2( pxor xmm3, xmm4)
00267 AS2( pxor xmm2, xmm6)
00268
00269 AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+1*16])
00270 AS2( movdqa xmm5, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+1*16])
00271 AS2( movdqa xmm6, xmm4)
00272 AS2( punpcklqdq xmm4, xmm5)
00273 AS2( punpckhqdq xmm6, xmm5)
00274 AS2( pxor xmm1, xmm4)
00275 AS2( pxor xmm0, xmm6)
00276
00277
00278 AS2( add AS_REG_6, 32)
00279 AS2( cmp AS_REG_6, REG_loopEnd)
00280 ASJ( jne, 4, b)
00281
00282
00283 AS2( mov [AS_REG_2+4*16], eax)
00284 AS2( movdqa XMMWORD_PTR [AS_REG_2+3*16], xmm3)
00285 AS2( movdqa XMMWORD_PTR [AS_REG_2+2*16], xmm2)
00286 AS2( movdqa XMMWORD_PTR [AS_REG_2+1*16], xmm1)
00287 AS2( movdqa XMMWORD_PTR [AS_REG_2+0*16], xmm0)
00288
00289 #if CRYPTOPP_BOOL_X32
00290 AS2( add esp, 8)
00291 AS_POP_IF86( bp)
00292 #elif CRYPTOPP_BOOL_X86
00293 AS2( add esp, 4)
00294 AS_POP_IF86( bp)
00295 #endif
00296 ASL(5)
00297
00298 #if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
00299 AS_POP_IF86( bx)
00300 ATT_PREFIX
00301 :
00302 #if CRYPTOPP_BOOL_X64
00303 : "D" (count), "S" (state), "d" (z), "c" (y)
00304 : "%r8", "%r9", "r10", "%eax", "memory", "cc", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7"
00305 #else
00306 : "c" (count), "d" (state), "S" (z), "D" (y)
00307 : "%eax", "memory", "cc"
00308 #endif
00309 );
00310 #endif
00311
00312 #ifdef CRYPTOPP_GENERATE_X64_MASM
00313 movdqa xmm6, [rsp + 0h]
00314 movdqa xmm7, [rsp + 10h]
00315 add rsp, 2*16
00316 pop rdi
00317 ret
00318 Panama_SSE2_Pull ENDP
00319 #else
00320 }
00321 #endif
00322 #endif // #ifdef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
00323
00324 #ifndef CRYPTOPP_GENERATE_X64_MASM
00325
00326 template <class B>
00327 void Panama<B>::Iterate(size_t count, const word32 *p, byte *output, const byte *input, KeystreamOperation operation)
00328 {
00329 word32 bstart = m_state[17];
00330 word32 *const aPtr = m_state;
00331 word32 cPtr[17];
00332
00333 #define bPtr ((byte *)(aPtr+20))
00334
00335
00336
00337
00338 #define a(i) aPtr[((i)*13+16) % 17] // 13 is inverse of 4 mod 17
00339 #define c(i) cPtr[((i)*13+16) % 17]
00340
00341 #define b(i, j) b##i[(j)*2%8 + (j)/4]
00342
00343
00344 #define US(i) {word32 t=b(0,i); b(0,i)=ConditionalByteReverse(B::ToEnum(), p[i])^t; b(25,(i+6)%8)^=t;}
00345 #define UL(i) {word32 t=b(0,i); b(0,i)=a(i+1)^t; b(25,(i+6)%8)^=t;}
00346
00347 #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)
00348
00349 #define T(i,x) a(i) = c(i) ^ c((i+1)%17) ^ c((i+4)%17) ^ x
00350 #define TS1S(i) T(i+1, ConditionalByteReverse(B::ToEnum(), p[i]))
00351 #define TS1L(i) T(i+1, b(4,i))
00352 #define TS2(i) T(i+9, b(16,i))
00353
00354 while (count--)
00355 {
00356 if (output)
00357 {
00358 #define PANAMA_OUTPUT(x) \
00359 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, a(0+9));\
00360 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, a(1+9));\
00361 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, a(2+9));\
00362 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a(3+9));\
00363 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 4, a(4+9));\
00364 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 5, a(5+9));\
00365 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 6, a(6+9));\
00366 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 7, a(7+9));
00367
00368 typedef word32 WordType;
00369 CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(PANAMA_OUTPUT, 4*8);
00370 }
00371
00372 word32 *const b16 = (word32 *)(bPtr+((bstart+16*32) & 31*32));
00373 word32 *const b4 = (word32 *)(bPtr+((bstart+(32-4)*32) & 31*32));
00374 bstart += 32;
00375 word32 *const b0 = (word32 *)(bPtr+((bstart) & 31*32));
00376 word32 *const b25 = (word32 *)(bPtr+((bstart+(32-25)*32) & 31*32));
00377
00378 if (p)
00379 {
00380 US(0); US(1); US(2); US(3); US(4); US(5); US(6); US(7);
00381 }
00382 else
00383 {
00384 UL(0); UL(1); UL(2); UL(3); UL(4); UL(5); UL(6); UL(7);
00385 }
00386
00387 GP(0);
00388 GP(1);
00389 GP(2);
00390 GP(3);
00391 GP(4);
00392 GP(5);
00393 GP(6);
00394 GP(7);
00395 GP(8);
00396 GP(9);
00397 GP(10);
00398 GP(11);
00399 GP(12);
00400 GP(13);
00401 GP(14);
00402 GP(15);
00403 GP(16);
00404
00405 T(0,1);
00406
00407 if (p)
00408 {
00409 TS1S(0); TS1S(1); TS1S(2); TS1S(3); TS1S(4); TS1S(5); TS1S(6); TS1S(7);
00410 p += 8;
00411 }
00412 else
00413 {
00414 TS1L(0); TS1L(1); TS1L(2); TS1L(3); TS1L(4); TS1L(5); TS1L(6); TS1L(7);
00415 }
00416
00417 TS2(0); TS2(1); TS2(2); TS2(3); TS2(4); TS2(5); TS2(6); TS2(7);
00418 }
00419 m_state[17] = bstart;
00420 }
00421
00422 namespace Weak {
00423 template <class B>
00424 size_t PanamaHash<B>::HashMultipleBlocks(const word32 *input, size_t length)
00425 {
00426 this->Iterate(length / this->BLOCKSIZE, input);
00427 return length % this->BLOCKSIZE;
00428 }
00429
00430 template <class B>
00431 void PanamaHash<B>::TruncatedFinal(byte *hash, size_t size)
00432 {
00433 this->ThrowIfInvalidTruncatedSize(size);
00434
00435 this->PadLastBlock(this->BLOCKSIZE, 0x01);
00436
00437 HashEndianCorrectedBlock(this->m_data);
00438
00439 this->Iterate(32);
00440
00441 FixedSizeSecBlock<word32, 8> buf;
00442 this->Iterate(1, NULL, buf.BytePtr(), NULL);
00443
00444 memcpy(hash, buf, size);
00445
00446 this->Restart();
00447 }
00448 }
00449
00450 template <class B>
00451 void PanamaCipherPolicy<B>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
00452 {
00453 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(length);
00454 assert(length==32);
00455 memcpy(m_key, key, 32);
00456 }
00457
00458 template <class B>
00459 void PanamaCipherPolicy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
00460 {
00461 CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(iv); CRYPTOPP_UNUSED(length);
00462 assert(length==32);
00463 this->Reset();
00464 this->Iterate(1, m_key);
00465 if (iv && IsAligned<word32>(iv))
00466 this->Iterate(1, (const word32 *)iv);
00467 else
00468 {
00469 FixedSizeSecBlock<word32, 8> buf;
00470 if (iv)
00471 memcpy(buf, iv, 32);
00472 else
00473 memset(buf, 0, 32);
00474 this->Iterate(1, buf);
00475 }
00476
00477 #if (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_PANAMA_ASM)
00478 if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2() && !IsP4())
00479 Panama_SSE2_Pull(32, this->m_state, NULL, NULL);
00480 else
00481 #endif
00482 this->Iterate(32);
00483 }
00484
00485 template <class B>
00486 unsigned int PanamaCipherPolicy<B>::GetAlignment() const
00487 {
00488 #if (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_PANAMA_ASM)
00489 if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2())
00490 return 16;
00491 else
00492 #endif
00493 return 1;
00494 }
00495
00496 template <class B>
00497 void PanamaCipherPolicy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
00498 {
00499 #if (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_PANAMA_ASM)
00500 if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2())
00501 Panama_SSE2_Pull(iterationCount, this->m_state, (word32 *)output, (const word32 *)input);
00502 else
00503 #endif
00504 this->Iterate(iterationCount, NULL, output, input, operation);
00505 }
00506
00507 template class Panama<BigEndian>;
00508 template class Panama<LittleEndian>;
00509
00510 template class Weak::PanamaHash<BigEndian>;
00511 template class Weak::PanamaHash<LittleEndian>;
00512
00513 template class PanamaCipherPolicy<BigEndian>;
00514 template class PanamaCipherPolicy<LittleEndian>;
00515
00516 NAMESPACE_END
00517
00518 #endif // #ifndef CRYPTOPP_GENERATE_X64_MASM