1
// tiger.cpp - written and placed in the public domain by Wei Dai
8
NAMESPACE_BEGIN(CryptoPP)
10
void Tiger::InitState(HashWordType *state)
12
state[0] = W64LIT(0x0123456789ABCDEF);
13
state[1] = W64LIT(0xFEDCBA9876543210);
14
state[2] = W64LIT(0xF096A5B4C3B2E187);
17
void Tiger::TruncatedFinal(byte *hash, size_t size)
19
ThrowIfInvalidTruncatedSize(size);
21
PadLastBlock(56, 0x01);
22
CorrectEndianess(m_data, m_data, 56);
24
m_data[7] = GetBitCountLo();
26
Transform(m_state, m_data);
27
CorrectEndianess(m_state, m_state, DigestSize());
28
memcpy(hash, m_state, size);
30
Restart(); // reinit for next use
33
void Tiger::Transform (word64 *digest, const word64 *X)
35
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
41
".intel_syntax noprefix;"
45
const word64 *t = table;
48
AS2( lea edx, [table])
54
AS2( movq mm1, [eax+1*8])
56
AS2( movq mm2, [eax+2*8])
57
AS2( movq mm7, [edx+4*2048+0*8])
58
AS2( movq mm6, [edx+4*2048+1*8])
60
AS2( and esp, 0xfffffff0)
64
#define SSE2_round(a,b,c,x,mul) \
68
AS2( movq mm3, [edx+0*2048+edi*8])\
70
AS2( movq mm4, [edx+3*2048+edi*8])\
73
AS2( pxor mm3, [edx+1*2048+edi*8])\
75
AS2( pxor mm4, [edx+2*2048+edi*8])\
76
AS3( pextrw ecx, c, 2)\
78
AS2( pxor mm3, [edx+2*2048+edi*8])\
80
AS2( pxor mm4, [edx+1*2048+edi*8])\
81
AS3( pextrw ecx, c, 3)\
83
AS2( pxor mm3, [edx+3*2048+edi*8])\
86
AS2( pxor mm4, [edx+0*2048+edi*8])\
90
#define SSE2_mul_5(b) \
95
#define SSE2_mul_7(b) \
100
#define SSE2_mul_9(b) \
109
#define SSE2_pass(A,B,C,mul,X) \
112
SSE2_round(A,B,C,X+0*8+ebx,mul)\
113
SSE2_round(B,C,A,X+1*8+ebx,mul)\
115
ASJ( je, label2_##mul, f)\
116
SSE2_round(C,A,B,X+2*8+ebx,mul)\
121
#define SSE2_key_schedule(Y,X) \
122
AS2( movq mm3, [X+7*8])\
124
AS2( movq mm4, [X+0*8])\
125
AS2( psubq mm4, mm3)\
126
AS2( movq [Y+0*8], mm4)\
127
AS2( pxor mm4, [X+1*8])\
129
AS2( movq [Y+1*8], mm4)\
130
AS2( paddq mm4, [X+2*8])\
133
AS2( movq [Y+2*8], mm4)\
135
AS2( movq mm4, [X+3*8])\
136
AS2( psubq mm4, mm3)\
137
AS2( movq [Y+3*8], mm4)\
138
AS2( pxor mm4, [X+4*8])\
140
AS2( movq [Y+4*8], mm4)\
141
AS2( paddq mm4, [X+5*8])\
144
AS2( movq [Y+5*8], mm4)\
146
AS2( movq mm4, [X+6*8])\
147
AS2( psubq mm4, mm3)\
148
AS2( movq [Y+6*8], mm4)\
149
AS2( pxor mm4, [X+7*8])\
151
AS2( movq [Y+7*8], mm4)\
152
AS2( paddq mm4, [Y+0*8])\
155
AS2( movq [Y+0*8], mm4)\
157
AS2( movq mm4, [Y+1*8])\
158
AS2( psubq mm4, mm3)\
159
AS2( movq [Y+1*8], mm4)\
160
AS2( pxor mm4, [Y+2*8])\
162
AS2( movq [Y+2*8], mm4)\
163
AS2( paddq mm4, [Y+3*8])\
166
AS2( movq [Y+3*8], mm4)\
168
AS2( movq mm4, [Y+4*8])\
169
AS2( psubq mm4, mm3)\
170
AS2( movq [Y+4*8], mm4)\
171
AS2( pxor mm4, [Y+5*8])\
172
AS2( movq [Y+5*8], mm4)\
173
AS2( paddq mm4, [Y+6*8])\
174
AS2( movq [Y+6*8], mm4)\
175
AS2( pxor mm4, [edx+4*2048+2*8])\
176
AS2( movq mm3, [Y+7*8])\
177
AS2( psubq mm3, mm4)\
178
AS2( movq [Y+7*8], mm3)
180
SSE2_pass(mm0, mm1, mm2, 5, esi)
181
SSE2_key_schedule(esp+4, esi)
182
SSE2_pass(mm2, mm0, mm1, 7, esp+4)
183
SSE2_key_schedule(esp+4, esp+4)
184
SSE2_pass(mm1, mm2, mm0, 9, esp+4)
186
AS2( pxor mm0, [eax+0*8])
187
AS2( movq [eax+0*8], mm0)
189
AS2( movq [eax+1*8], mm1)
190
AS2( paddq mm2, [eax+2*8])
191
AS2( movq [eax+2*8], mm2)
197
".att_syntax prefix;"
199
: "a" (digest), "S" (X), "d" (table)
200
: "%ecx", "%edi", "memory", "cc"
207
word64 a = digest[0];
208
word64 b = digest[1];
209
word64 c = digest[2];
213
#define t2 (table+256)
214
#define t3 (table+256*2)
215
#define t4 (table+256*3)
217
#define round(a,b,c,x,mul) \
219
a -= t1[GETBYTE(c,0)] ^ t2[GETBYTE(c,2)] ^ t3[GETBYTE(c,4)] ^ t4[GETBYTE(c,6)]; \
220
b += t4[GETBYTE(c,1)] ^ t3[GETBYTE(c,3)] ^ t2[GETBYTE(c,5)] ^ t1[GETBYTE(c,7)]; \
223
#define pass(a,b,c,mul,X) {\
227
round(a,b,c,X[i+0],mul); \
228
round(b,c,a,X[i+1],mul); \
231
round(c,a,b,X[i+2],mul); \
235
#define key_schedule(Y,X) \
236
Y[0] = X[0] - (X[7]^W64LIT(0xA5A5A5A5A5A5A5A5)); \
237
Y[1] = X[1] ^ Y[0]; \
238
Y[2] = X[2] + Y[1]; \
239
Y[3] = X[3] - (Y[2] ^ ((~Y[1])<<19)); \
240
Y[4] = X[4] ^ Y[3]; \
241
Y[5] = X[5] + Y[4]; \
242
Y[6] = X[6] - (Y[5] ^ ((~Y[4])>>23)); \
243
Y[7] = X[7] ^ Y[6]; \
245
Y[1] -= Y[0] ^ ((~Y[7])<<19); \
248
Y[4] -= Y[3] ^ ((~Y[2])>>23); \
251
Y[7] -= Y[6] ^ W64LIT(0x0123456789ABCDEF)
259
digest[0] = a ^ digest[0];
260
digest[1] = b - digest[1];
261
digest[2] = c + digest[2];