• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

tiger.cpp

00001 // tiger.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "tiger.h"
00005 #include "misc.h"
00006 #include "cpu.h"
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 void Tiger::InitState(HashWordType *state)
00011 {
00012         state[0] = W64LIT(0x0123456789ABCDEF);
00013         state[1] = W64LIT(0xFEDCBA9876543210);
00014         state[2] = W64LIT(0xF096A5B4C3B2E187);
00015 }
00016 
00017 void Tiger::TruncatedFinal(byte *hash, size_t size)
00018 {
00019         ThrowIfInvalidTruncatedSize(size);
00020 
00021         PadLastBlock(56, 0x01);
00022         CorrectEndianess(m_data, m_data, 56);
00023 
00024         m_data[7] = GetBitCountLo();
00025 
00026         Transform(m_state, m_data);
00027         CorrectEndianess(m_state, m_state, DigestSize());
00028         memcpy(hash, m_state, size);
00029 
00030         Restart();              // reinit for next use
00031 }
00032 
00033 void Tiger::Transform (word64 *digest, const word64 *X)
00034 {
00035 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
00036         if (HasSSE2())
00037         {
00038 #ifdef __GNUC__
00039                 __asm__ __volatile__
00040                 (
00041                 ".intel_syntax noprefix;"
00042                 AS1(    push    ebx)
00043 #else
00044         #if _MSC_VER < 1300
00045                 const word64 *t = table;
00046                 AS2(    mov             edx, t)
00047         #else
00048                 AS2(    lea             edx, [table])
00049         #endif
00050                 AS2(    mov             eax, digest)
00051                 AS2(    mov             esi, X)
00052 #endif
00053                 AS2(    movq    mm0, [eax])
00054                 AS2(    movq    mm1, [eax+1*8])
00055                 AS2(    movq    mm5, mm1)
00056                 AS2(    movq    mm2, [eax+2*8])
00057                 AS2(    movq    mm7, [edx+4*2048+0*8])
00058                 AS2(    movq    mm6, [edx+4*2048+1*8])
00059                 AS2(    mov             ecx, esp)
00060                 AS2(    and             esp, 0xfffffff0)
00061                 AS2(    sub             esp, 8*8)
00062                 AS1(    push    ecx)
00063 
00064 #define SSE2_round(a,b,c,x,mul) \
00065                 AS2(    pxor    c, [x])\
00066                 AS2(    movd    ecx, c)\
00067                 AS2(    movzx   edi, cl)\
00068                 AS2(    movq    mm3, [edx+0*2048+edi*8])\
00069                 AS2(    movzx   edi, ch)\
00070                 AS2(    movq    mm4, [edx+3*2048+edi*8])\
00071                 AS2(    shr             ecx, 16)\
00072                 AS2(    movzx   edi, cl)\
00073                 AS2(    pxor    mm3, [edx+1*2048+edi*8])\
00074                 AS2(    movzx   edi, ch)\
00075                 AS2(    pxor    mm4, [edx+2*2048+edi*8])\
00076                 AS3(    pextrw  ecx, c, 2)\
00077                 AS2(    movzx   edi, cl)\
00078                 AS2(    pxor    mm3, [edx+2*2048+edi*8])\
00079                 AS2(    movzx   edi, ch)\
00080                 AS2(    pxor    mm4, [edx+1*2048+edi*8])\
00081                 AS3(    pextrw  ecx, c, 3)\
00082                 AS2(    movzx   edi, cl)\
00083                 AS2(    pxor    mm3, [edx+3*2048+edi*8])\
00084                 AS2(    psubq   a, mm3)\
00085                 AS2(    movzx   edi, ch)\
00086                 AS2(    pxor    mm4, [edx+0*2048+edi*8])\
00087                 AS2(    paddq   b, mm4)\
00088                 SSE2_mul_##mul(b)
00089 
00090 #define SSE2_mul_5(b)   \
00091                 AS2(    movq    mm3, b)\
00092                 AS2(    psllq   b, 2)\
00093                 AS2(    paddq   b, mm3)
00094 
00095 #define SSE2_mul_7(b)   \
00096                 AS2(    movq    mm3, b)\
00097                 AS2(    psllq   b, 3)\
00098                 AS2(    psubq   b, mm3)
00099 
00100 #define SSE2_mul_9(b)   \
00101                 AS2(    movq    mm3, b)\
00102                 AS2(    psllq   b, 3)\
00103                 AS2(    paddq   b, mm3)
00104 
00105 #define label2_5 1
00106 #define label2_7 2
00107 #define label2_9 3
00108 
00109 #define SSE2_pass(A,B,C,mul,X)  \
00110                 AS2(    xor             ebx, ebx)\
00111                 ASL(mul)\
00112                 SSE2_round(A,B,C,X+0*8+ebx,mul)\
00113                 SSE2_round(B,C,A,X+1*8+ebx,mul)\
00114                 AS2(    cmp             ebx, 6*8)\
00115                 ASJ(    je,             label2_##mul, f)\
00116                 SSE2_round(C,A,B,X+2*8+ebx,mul)\
00117                 AS2(    add             ebx, 3*8)\
00118                 ASJ(    jmp,    mul, b)\
00119                 ASL(label2_##mul)
00120 
00121 #define SSE2_key_schedule(Y,X) \
00122                 AS2(    movq    mm3, [X+7*8])\
00123                 AS2(    pxor    mm3, mm6)\
00124                 AS2(    movq    mm4, [X+0*8])\
00125                 AS2(    psubq   mm4, mm3)\
00126                 AS2(    movq    [Y+0*8], mm4)\
00127                 AS2(    pxor    mm4, [X+1*8])\
00128                 AS2(    movq    mm3, mm4)\
00129                 AS2(    movq    [Y+1*8], mm4)\
00130                 AS2(    paddq   mm4, [X+2*8])\
00131                 AS2(    pxor    mm3, mm7)\
00132                 AS2(    psllq   mm3, 19)\
00133                 AS2(    movq    [Y+2*8], mm4)\
00134                 AS2(    pxor    mm3, mm4)\
00135                 AS2(    movq    mm4, [X+3*8])\
00136                 AS2(    psubq   mm4, mm3)\
00137                 AS2(    movq    [Y+3*8], mm4)\
00138                 AS2(    pxor    mm4, [X+4*8])\
00139                 AS2(    movq    mm3, mm4)\
00140                 AS2(    movq    [Y+4*8], mm4)\
00141                 AS2(    paddq   mm4, [X+5*8])\
00142                 AS2(    pxor    mm3, mm7)\
00143                 AS2(    psrlq   mm3, 23)\
00144                 AS2(    movq    [Y+5*8], mm4)\
00145                 AS2(    pxor    mm3, mm4)\
00146                 AS2(    movq    mm4, [X+6*8])\
00147                 AS2(    psubq   mm4, mm3)\
00148                 AS2(    movq    [Y+6*8], mm4)\
00149                 AS2(    pxor    mm4, [X+7*8])\
00150                 AS2(    movq    mm3, mm4)\
00151                 AS2(    movq    [Y+7*8], mm4)\
00152                 AS2(    paddq   mm4, [Y+0*8])\
00153                 AS2(    pxor    mm3, mm7)\
00154                 AS2(    psllq   mm3, 19)\
00155                 AS2(    movq    [Y+0*8], mm4)\
00156                 AS2(    pxor    mm3, mm4)\
00157                 AS2(    movq    mm4, [Y+1*8])\
00158                 AS2(    psubq   mm4, mm3)\
00159                 AS2(    movq    [Y+1*8], mm4)\
00160                 AS2(    pxor    mm4, [Y+2*8])\
00161                 AS2(    movq    mm3, mm4)\
00162                 AS2(    movq    [Y+2*8], mm4)\
00163                 AS2(    paddq   mm4, [Y+3*8])\
00164                 AS2(    pxor    mm3, mm7)\
00165                 AS2(    psrlq   mm3, 23)\
00166                 AS2(    movq    [Y+3*8], mm4)\
00167                 AS2(    pxor    mm3, mm4)\
00168                 AS2(    movq    mm4, [Y+4*8])\
00169                 AS2(    psubq   mm4, mm3)\
00170                 AS2(    movq    [Y+4*8], mm4)\
00171                 AS2(    pxor    mm4, [Y+5*8])\
00172                 AS2(    movq    [Y+5*8], mm4)\
00173                 AS2(    paddq   mm4, [Y+6*8])\
00174                 AS2(    movq    [Y+6*8], mm4)\
00175                 AS2(    pxor    mm4, [edx+4*2048+2*8])\
00176                 AS2(    movq    mm3, [Y+7*8])\
00177                 AS2(    psubq   mm3, mm4)\
00178                 AS2(    movq    [Y+7*8], mm3)
00179 
00180                 SSE2_pass(mm0, mm1, mm2, 5, esi)
00181                 SSE2_key_schedule(esp+4, esi)
00182                 SSE2_pass(mm2, mm0, mm1, 7, esp+4)
00183                 SSE2_key_schedule(esp+4, esp+4)
00184                 SSE2_pass(mm1, mm2, mm0, 9, esp+4)
00185 
00186                 AS2(    pxor    mm0, [eax+0*8])
00187                 AS2(    movq    [eax+0*8], mm0)
00188                 AS2(    psubq   mm1, mm5)
00189                 AS2(    movq    [eax+1*8], mm1)
00190                 AS2(    paddq   mm2, [eax+2*8])
00191                 AS2(    movq    [eax+2*8], mm2)
00192 
00193                 AS1(    pop             esp)
00194                 AS1(    emms)
00195 #ifdef __GNUC__
00196                 AS1(    pop             ebx)
00197                 ".att_syntax prefix;"
00198                         :
00199                         : "a" (digest), "S" (X), "d" (table)
00200                         : "%ecx", "%edi", "memory", "cc"
00201                 );
00202 #endif
00203         }
00204         else
00205 #endif
00206         {
00207                 word64 a = digest[0];
00208                 word64 b = digest[1];
00209                 word64 c = digest[2];
00210                 word64 Y[8];
00211 
00212 #define t1 (table)
00213 #define t2 (table+256)
00214 #define t3 (table+256*2)
00215 #define t4 (table+256*3)
00216 
00217 #define round(a,b,c,x,mul) \
00218         c ^= x; \
00219         a -= t1[GETBYTE(c,0)] ^ t2[GETBYTE(c,2)] ^ t3[GETBYTE(c,4)] ^ t4[GETBYTE(c,6)]; \
00220         b += t4[GETBYTE(c,1)] ^ t3[GETBYTE(c,3)] ^ t2[GETBYTE(c,5)] ^ t1[GETBYTE(c,7)]; \
00221         b *= mul
00222 
00223 #define pass(a,b,c,mul,X) {\
00224         int i=0;\
00225         while (true)\
00226         {\
00227                 round(a,b,c,X[i+0],mul); \
00228                 round(b,c,a,X[i+1],mul); \
00229                 if (i==6)\
00230                         break;\
00231                 round(c,a,b,X[i+2],mul); \
00232                 i+=3;\
00233         }}
00234 
00235 #define key_schedule(Y,X) \
00236         Y[0] = X[0] - (X[7]^W64LIT(0xA5A5A5A5A5A5A5A5)); \
00237         Y[1] = X[1] ^ Y[0]; \
00238         Y[2] = X[2] + Y[1]; \
00239         Y[3] = X[3] - (Y[2] ^ ((~Y[1])<<19)); \
00240         Y[4] = X[4] ^ Y[3]; \
00241         Y[5] = X[5] + Y[4]; \
00242         Y[6] = X[6] - (Y[5] ^ ((~Y[4])>>23)); \
00243         Y[7] = X[7] ^ Y[6]; \
00244         Y[0] += Y[7]; \
00245         Y[1] -= Y[0] ^ ((~Y[7])<<19); \
00246         Y[2] ^= Y[1]; \
00247         Y[3] += Y[2]; \
00248         Y[4] -= Y[3] ^ ((~Y[2])>>23); \
00249         Y[5] ^= Y[4]; \
00250         Y[6] += Y[5]; \
00251         Y[7] -= Y[6] ^ W64LIT(0x0123456789ABCDEF)
00252 
00253                 pass(a,b,c,5,X);
00254                 key_schedule(Y,X);
00255                 pass(c,a,b,7,Y);
00256                 key_schedule(Y,Y);
00257                 pass(b,c,a,9,Y);
00258 
00259                 digest[0] = a ^ digest[0];
00260                 digest[1] = b - digest[1];
00261                 digest[2] = c + digest[2];
00262         }
00263 }
00264 
00265 NAMESPACE_END

Generated on Mon Aug 9 2010 15:56:38 for Crypto++ by  doxygen 1.7.1