source: git/src-cryptopp/tiger.cpp

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 6.5 KB
Line 
1// tiger.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "config.h"
5
6#include "tiger.h"
7#include "misc.h"
8#include "cpu.h"
9
10#if defined(CRYPTOPP_DISABLE_TIGER_ASM)
11# undef CRYPTOPP_X86_ASM_AVAILABLE
12# undef CRYPTOPP_X32_ASM_AVAILABLE
13# undef CRYPTOPP_X64_ASM_AVAILABLE
14# undef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE
15#endif
16
17NAMESPACE_BEGIN(CryptoPP)
18
19void Tiger::InitState(HashWordType *state)
20{
21        state[0] = W64LIT(0x0123456789ABCDEF);
22        state[1] = W64LIT(0xFEDCBA9876543210);
23        state[2] = W64LIT(0xF096A5B4C3B2E187);
24}
25
26void Tiger::TruncatedFinal(byte *hash, size_t size)
27{
28        ThrowIfInvalidTruncatedSize(size);
29
30        PadLastBlock(56, 0x01);
31        CorrectEndianess(m_data, m_data, 56);
32
33        m_data[7] = GetBitCountLo();
34
35        Transform(m_state, m_data);
36        CorrectEndianess(m_state, m_state, DigestSize());
37        memcpy(hash, m_state, size);
38
39        Restart();              // reinit for next use
40}
41
42void Tiger::Transform (word64 *digest, const word64 *X)
43{
44#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32)
45        if (HasSSE2())
46        {
47#ifdef __GNUC__
48                __asm__ __volatile__
49                (
50                INTEL_NOPREFIX
51                AS_PUSH_IF86(bx)
52#else
53        #if _MSC_VER < 1300
54                const word64 *t = table;
55                AS2(    mov             edx, t)
56        #else
57                AS2(    lea             edx, [table])
58        #endif
59                AS2(    mov             eax, digest)
60                AS2(    mov             esi, X)
61#endif
62                AS2(    movq    mm0, [eax])
63                AS2(    movq    mm1, [eax+1*8])
64                AS2(    movq    mm5, mm1)
65                AS2(    movq    mm2, [eax+2*8])
66                AS2(    movq    mm7, [edx+4*2048+0*8])
67                AS2(    movq    mm6, [edx+4*2048+1*8])
68                AS2(    mov             ecx, esp)
69                AS2(    and             esp, 0xfffffff0)
70                AS2(    sub             esp, 8*8)
71                AS_PUSH_IF86(cx)
72
73#define SSE2_round(a,b,c,x,mul) \
74                AS2(    pxor    c, [x])\
75                AS2(    movd    ecx, c)\
76                AS2(    movzx   edi, cl)\
77                AS2(    movq    mm3, [edx+0*2048+edi*8])\
78                AS2(    movzx   edi, ch)\
79                AS2(    movq    mm4, [edx+3*2048+edi*8])\
80                AS2(    shr             ecx, 16)\
81                AS2(    movzx   edi, cl)\
82                AS2(    pxor    mm3, [edx+1*2048+edi*8])\
83                AS2(    movzx   edi, ch)\
84                AS2(    pxor    mm4, [edx+2*2048+edi*8])\
85                AS3(    pextrw  ecx, c, 2)\
86                AS2(    movzx   edi, cl)\
87                AS2(    pxor    mm3, [edx+2*2048+edi*8])\
88                AS2(    movzx   edi, ch)\
89                AS2(    pxor    mm4, [edx+1*2048+edi*8])\
90                AS3(    pextrw  ecx, c, 3)\
91                AS2(    movzx   edi, cl)\
92                AS2(    pxor    mm3, [edx+3*2048+edi*8])\
93                AS2(    psubq   a, mm3)\
94                AS2(    movzx   edi, ch)\
95                AS2(    pxor    mm4, [edx+0*2048+edi*8])\
96                AS2(    paddq   b, mm4)\
97                SSE2_mul_##mul(b)
98
99#define SSE2_mul_5(b)   \
100                AS2(    movq    mm3, b)\
101                AS2(    psllq   b, 2)\
102                AS2(    paddq   b, mm3)
103
104#define SSE2_mul_7(b)   \
105                AS2(    movq    mm3, b)\
106                AS2(    psllq   b, 3)\
107                AS2(    psubq   b, mm3)
108
109#define SSE2_mul_9(b)   \
110                AS2(    movq    mm3, b)\
111                AS2(    psllq   b, 3)\
112                AS2(    paddq   b, mm3)
113
114#define label2_5 1
115#define label2_7 2
116#define label2_9 3
117
118#define SSE2_pass(A,B,C,mul,X)  \
119                AS2(    xor             ebx, ebx)\
120                ASL(mul)\
121                SSE2_round(A,B,C,X+0*8+ebx,mul)\
122                SSE2_round(B,C,A,X+1*8+ebx,mul)\
123                AS2(    cmp             ebx, 6*8)\
124                ASJ(    je,             label2_##mul, f)\
125                SSE2_round(C,A,B,X+2*8+ebx,mul)\
126                AS2(    add             ebx, 3*8)\
127                ASJ(    jmp,    mul, b)\
128                ASL(label2_##mul)
129
130#define SSE2_key_schedule(Y,X) \
131                AS2(    movq    mm3, [X+7*8])\
132                AS2(    pxor    mm3, mm6)\
133                AS2(    movq    mm4, [X+0*8])\
134                AS2(    psubq   mm4, mm3)\
135                AS2(    movq    [Y+0*8], mm4)\
136                AS2(    pxor    mm4, [X+1*8])\
137                AS2(    movq    mm3, mm4)\
138                AS2(    movq    [Y+1*8], mm4)\
139                AS2(    paddq   mm4, [X+2*8])\
140                AS2(    pxor    mm3, mm7)\
141                AS2(    psllq   mm3, 19)\
142                AS2(    movq    [Y+2*8], mm4)\
143                AS2(    pxor    mm3, mm4)\
144                AS2(    movq    mm4, [X+3*8])\
145                AS2(    psubq   mm4, mm3)\
146                AS2(    movq    [Y+3*8], mm4)\
147                AS2(    pxor    mm4, [X+4*8])\
148                AS2(    movq    mm3, mm4)\
149                AS2(    movq    [Y+4*8], mm4)\
150                AS2(    paddq   mm4, [X+5*8])\
151                AS2(    pxor    mm3, mm7)\
152                AS2(    psrlq   mm3, 23)\
153                AS2(    movq    [Y+5*8], mm4)\
154                AS2(    pxor    mm3, mm4)\
155                AS2(    movq    mm4, [X+6*8])\
156                AS2(    psubq   mm4, mm3)\
157                AS2(    movq    [Y+6*8], mm4)\
158                AS2(    pxor    mm4, [X+7*8])\
159                AS2(    movq    mm3, mm4)\
160                AS2(    movq    [Y+7*8], mm4)\
161                AS2(    paddq   mm4, [Y+0*8])\
162                AS2(    pxor    mm3, mm7)\
163                AS2(    psllq   mm3, 19)\
164                AS2(    movq    [Y+0*8], mm4)\
165                AS2(    pxor    mm3, mm4)\
166                AS2(    movq    mm4, [Y+1*8])\
167                AS2(    psubq   mm4, mm3)\
168                AS2(    movq    [Y+1*8], mm4)\
169                AS2(    pxor    mm4, [Y+2*8])\
170                AS2(    movq    mm3, mm4)\
171                AS2(    movq    [Y+2*8], mm4)\
172                AS2(    paddq   mm4, [Y+3*8])\
173                AS2(    pxor    mm3, mm7)\
174                AS2(    psrlq   mm3, 23)\
175                AS2(    movq    [Y+3*8], mm4)\
176                AS2(    pxor    mm3, mm4)\
177                AS2(    movq    mm4, [Y+4*8])\
178                AS2(    psubq   mm4, mm3)\
179                AS2(    movq    [Y+4*8], mm4)\
180                AS2(    pxor    mm4, [Y+5*8])\
181                AS2(    movq    [Y+5*8], mm4)\
182                AS2(    paddq   mm4, [Y+6*8])\
183                AS2(    movq    [Y+6*8], mm4)\
184                AS2(    pxor    mm4, [edx+4*2048+2*8])\
185                AS2(    movq    mm3, [Y+7*8])\
186                AS2(    psubq   mm3, mm4)\
187                AS2(    movq    [Y+7*8], mm3)
188
189#if CRYPTOPP_BOOL_X32
190                SSE2_pass(mm0, mm1, mm2, 5, esi)
191                SSE2_key_schedule(esp+8, esi)
192                SSE2_pass(mm2, mm0, mm1, 7, esp+8)
193                SSE2_key_schedule(esp+8, esp+8)
194                SSE2_pass(mm1, mm2, mm0, 9, esp+8)
195#else
196                SSE2_pass(mm0, mm1, mm2, 5, esi)
197                SSE2_key_schedule(esp+4, esi)
198                SSE2_pass(mm2, mm0, mm1, 7, esp+4)
199                SSE2_key_schedule(esp+4, esp+4)
200                SSE2_pass(mm1, mm2, mm0, 9, esp+4)
201#endif
202
203                AS2(    pxor    mm0, [eax+0*8])
204                AS2(    movq    [eax+0*8], mm0)
205                AS2(    psubq   mm1, mm5)
206                AS2(    movq    [eax+1*8], mm1)
207                AS2(    paddq   mm2, [eax+2*8])
208                AS2(    movq    [eax+2*8], mm2)
209
210                AS_POP_IF86(sp)
211                AS1(    emms)
212
213#ifdef __GNUC__
214                AS_POP_IF86(bx)
215                ATT_PREFIX
216                        :
217                        : "a" (digest), "S" (X), "d" (table)
218                        : "%ecx", "%edi", "memory", "cc"
219                );
220#endif
221        }
222        else
223#endif
224        {
225                word64 a = digest[0];
226                word64 b = digest[1];
227                word64 c = digest[2];
228                word64 Y[8];
229
230#define t1 (table)
231#define t2 (table+256)
232#define t3 (table+256*2)
233#define t4 (table+256*3)
234
235#define round(a,b,c,x,mul) \
236        c ^= x; \
237        a -= t1[GETBYTE(c,0)] ^ t2[GETBYTE(c,2)] ^ t3[GETBYTE(c,4)] ^ t4[GETBYTE(c,6)]; \
238        b += t4[GETBYTE(c,1)] ^ t3[GETBYTE(c,3)] ^ t2[GETBYTE(c,5)] ^ t1[GETBYTE(c,7)]; \
239        b *= mul
240
241#define pass(a,b,c,mul,X) {\
242        int i=0;\
243        while (true)\
244        {\
245                round(a,b,c,X[i+0],mul); \
246                round(b,c,a,X[i+1],mul); \
247                if (i==6)\
248                        break;\
249                round(c,a,b,X[i+2],mul); \
250                i+=3;\
251        }}
252
253#define key_schedule(Y,X) \
254        Y[0] = X[0] - (X[7]^W64LIT(0xA5A5A5A5A5A5A5A5)); \
255        Y[1] = X[1] ^ Y[0]; \
256        Y[2] = X[2] + Y[1]; \
257        Y[3] = X[3] - (Y[2] ^ ((~Y[1])<<19)); \
258        Y[4] = X[4] ^ Y[3]; \
259        Y[5] = X[5] + Y[4]; \
260        Y[6] = X[6] - (Y[5] ^ ((~Y[4])>>23)); \
261        Y[7] = X[7] ^ Y[6]; \
262        Y[0] += Y[7]; \
263        Y[1] -= Y[0] ^ ((~Y[7])<<19); \
264        Y[2] ^= Y[1]; \
265        Y[3] += Y[2]; \
266        Y[4] -= Y[3] ^ ((~Y[2])>>23); \
267        Y[5] ^= Y[4]; \
268        Y[6] += Y[5]; \
269        Y[7] -= Y[6] ^ W64LIT(0x0123456789ABCDEF)
270
271                pass(a,b,c,5,X);
272                key_schedule(Y,X);
273                pass(c,a,b,7,Y);
274                key_schedule(Y,Y);
275                pass(b,c,a,9,Y);
276
277                digest[0] = a ^ digest[0];
278                digest[1] = b - digest[1];
279                digest[2] = c + digest[2];
280        }
281}
282
283NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.