Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
6.0 KiB

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