]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/ChainWalkContext.cpp
deb6f511e58e1eedb8b52366dbad02dfb0b60f9b
[freerainbowtables] / Client Applications / rcracki_mt / ChainWalkContext.cpp
1 /*\r
2  * rcracki_mt is a multithreaded implementation and fork of the original \r
3  * RainbowCrack\r
4  *\r
5  * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
6  * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
7  * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
8  * Copyright 2009, 2010, 2011 James Nobis <frt@quelrod.net>\r
9  * Copyright 2010 Yngve AAdlandsvik\r
10  *\r
11  * This file is part of rcracki_mt.\r
12  *\r
13  * rcracki_mt is free software: you can redistribute it and/or modify\r
14  * it under the terms of the GNU General Public License as published by\r
15  * the Free Software Foundation, either version 2 of the License, or\r
16  * (at your option) any later version.\r
17  *\r
18  * rcracki_mt is distributed in the hope that it will be useful,\r
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
21  * GNU General Public License for more details.\r
22  *\r
23  * You should have received a copy of the GNU General Public License\r
24  * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
25  */\r
26 \r
27 #if defined(_WIN32) && !defined(__GNUC__)\r
28         #pragma warning(disable : 4786 4267 4018)\r
29 #endif\r
30 \r
31 #include "ChainWalkContext.h"\r
32 \r
33 #include <ctype.h>\r
34 \r
35 //////////////////////////////////////////////////////////////////////\r
36 \r
37 string CChainWalkContext::m_sHashRoutineName;\r
38 HASHROUTINE CChainWalkContext::m_pHashRoutine;\r
39 int CChainWalkContext::m_nHashLen;\r
40 int CChainWalkContext::m_nPlainLenMinTotal = 0;\r
41 int CChainWalkContext::m_nPlainLenMaxTotal = 0;\r
42 int CChainWalkContext::m_nHybridCharset = 0;\r
43 bool CChainWalkContext::isOldRtFormat = false;\r
44 bool CChainWalkContext::isRti2RtFormat = false;\r
45 vector<stCharset> CChainWalkContext::m_vCharset;\r
46 uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];\r
47 uint64 CChainWalkContext::m_nPlainSpaceTotal;\r
48 unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN];\r
49 int CChainWalkContext::m_nSaltLen = 0;\r
50 int CChainWalkContext::m_nRainbowTableIndex;\r
51 uint64 CChainWalkContext::m_nReduceOffset;\r
52 \r
53 //////////////////////////////////////////////////////////////////////\r
54 \r
55 CChainWalkContext::CChainWalkContext()\r
56 {\r
57 }\r
58 \r
59 CChainWalkContext::~CChainWalkContext()\r
60 {\r
61 }\r
62 \r
63 bool CChainWalkContext::LoadCharset(string sName)\r
64 {\r
65         m_vCharset.clear();\r
66         if (sName == "byte")\r
67         {\r
68                 stCharset tCharset;\r
69                 int i;\r
70                 for (i = 0x00; i <= 0xff; i++)\r
71                         tCharset.m_PlainCharset[i] = (unsigned char) i;\r
72                 tCharset.m_nPlainCharsetLen = 256;\r
73                 tCharset.m_sPlainCharsetName = sName;\r
74                 tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff";\r
75                 m_vCharset.push_back(tCharset);\r
76                 return true;\r
77         }\r
78         if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets\r
79                 m_nHybridCharset = 1;           \r
80         else\r
81                 m_nHybridCharset = 0;\r
82         \r
83         bool readCharset = false;\r
84         vector<string> vLine;\r
85 \r
86         #ifdef BOINC\r
87                 if ( boinc_ReadLinesFromFile( "charset.txt", vLine ) )\r
88                         readCharset = true;\r
89         #else\r
90                 if ( ReadLinesFromFile("charset.txt", vLine) )\r
91                         readCharset = true;\r
92                 else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) )\r
93                         readCharset = true;\r
94         #endif\r
95 \r
96         if ( readCharset )\r
97         {\r
98                 uint32 i;\r
99                 for (i = 0; i < vLine.size(); i++)\r
100                 {\r
101                         // Filter comment\r
102                         if (vLine[i][0] == '#')\r
103                                 continue;\r
104 \r
105                         vector<string> vPart;\r
106                         if (SeperateString(vLine[i], "=", vPart))\r
107                         {\r
108                                 // sCharsetName\r
109                                 string sCharsetName = TrimString(vPart[0]);\r
110                                 if (sCharsetName == "")\r
111                                         continue;\r
112                                                                 \r
113                                 // sCharsetName charset check\r
114                                 bool fCharsetNameCheckPass = true;\r
115                                 uint32 j;\r
116                                 for (j = 0; j < sCharsetName.size(); j++)\r
117                                 {\r
118                                         if (   !isalpha(sCharsetName[j])\r
119                                                 && !isdigit(sCharsetName[j])\r
120                                                 && (sCharsetName[j] != '-'))\r
121                                         {\r
122                                                 fCharsetNameCheckPass = false;\r
123                                                 break;\r
124                                         }\r
125                                 }\r
126                                 if (!fCharsetNameCheckPass)\r
127                                 {\r
128                                         printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str());\r
129                                         continue;\r
130                                 }\r
131 \r
132                                 // sCharsetContent\r
133                                 string sCharsetContent = TrimString(vPart[1]);\r
134                                 if (sCharsetContent == "" || sCharsetContent == "[]")\r
135                                         continue;\r
136                                 if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']')\r
137                                 {\r
138                                         printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str());\r
139                                         continue;\r
140                                 }\r
141                                 sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2);\r
142                                 if (sCharsetContent.size() > 256)\r
143                                 {\r
144                                         printf("charset content %s too long\n", sCharsetContent.c_str());\r
145                                         continue;\r
146                                 }\r
147 \r
148                                 //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str());\r
149 \r
150                                 // Is it the wanted charset?\r
151                                 if(m_nHybridCharset == 1)\r
152                                 {\r
153                                         vector<tCharset> vCharsets;\r
154                                         GetHybridCharsets(sName, vCharsets);\r
155                                         if(sCharsetName == vCharsets[m_vCharset.size()].sName)\r
156                                         {\r
157                                                 stCharset tCharset;\r
158                                                 tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   \r
159                                                 memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);\r
160                                                 tCharset.m_sPlainCharsetName = sCharsetName;\r
161                                                 tCharset.m_sPlainCharsetContent = sCharsetContent;      \r
162                                                 tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin;\r
163                                                 tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax;\r
164                                                 m_vCharset.push_back(tCharset);\r
165                                                 if(vCharsets.size() == m_vCharset.size())\r
166                                                         return true;\r
167                                                 i = 0; // Start the lookup over again for the next charset\r
168                                         }                                               \r
169                                 }\r
170                                 else if (sCharsetName == sName)\r
171                                 {\r
172                                         stCharset tCharset;\r
173                                         tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   \r
174                                         memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);\r
175                                         tCharset.m_sPlainCharsetName = sCharsetName;\r
176                                         tCharset.m_sPlainCharsetContent = sCharsetContent;                                                      \r
177                                         m_vCharset.push_back(tCharset);\r
178                                         return true;\r
179                                 }\r
180                         }\r
181                 }\r
182                 printf("charset %s not found in charset.txt\n", sName.c_str());\r
183         }\r
184         else\r
185                 printf("can't open charset configuration file\n");\r
186 \r
187         return false;\r
188 }\r
189 \r
190 //////////////////////////////////////////////////////////////////////\r
191 \r
192 bool CChainWalkContext::SetHashRoutine(string sHashRoutineName)\r
193 {\r
194         CHashRoutine hr;\r
195         hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen);\r
196         if (m_pHashRoutine != NULL)\r
197         {\r
198                 m_sHashRoutineName = sHashRoutineName;\r
199                 return true;\r
200         }\r
201         else\r
202                 return false;\r
203 }\r
204 \r
205 bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax)\r
206 {\r
207         // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent\r
208         if (!LoadCharset(sCharsetName))\r
209                 return false;\r
210 \r
211         if(m_vCharset.size() == 1) // Not hybrid charset\r
212         {\r
213                 // m_nPlainLenMin, m_nPlainLenMax\r
214                 if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax)\r
215                 {\r
216                         printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax);\r
217                         return false;\r
218                 }\r
219                 m_vCharset[0].m_nPlainLenMin = nPlainLenMin;\r
220                 m_vCharset[0].m_nPlainLenMax = nPlainLenMax;\r
221         }\r
222         // m_nPlainSpaceUpToX\r
223         m_nPlainSpaceUpToX[0] = 0;\r
224         m_nPlainLenMaxTotal = 0;\r
225         m_nPlainLenMinTotal = 0;\r
226         uint64 nTemp = 1;\r
227         uint32 j, k = 1;\r
228         for(j = 0; j < m_vCharset.size(); j++)\r
229         {\r
230                 int i;\r
231                 m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax;\r
232                 m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin;\r
233                 for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++)\r
234                 {                       \r
235                         nTemp *= m_vCharset[j].m_nPlainCharsetLen;\r
236                         if (i < m_vCharset[j].m_nPlainLenMin)\r
237                                 m_nPlainSpaceUpToX[k] = 0;\r
238                         else\r
239                                 m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp;\r
240                         k++;\r
241                 }               \r
242         }\r
243         // m_nPlainSpaceTotal\r
244         m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];\r
245 \r
246         return true;\r
247 }\r
248 \r
249 bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex)\r
250 {\r
251         if (nRainbowTableIndex < 0)\r
252                 return false;\r
253         m_nRainbowTableIndex = nRainbowTableIndex;\r
254         m_nReduceOffset = 65536 * nRainbowTableIndex;\r
255 \r
256         return true;\r
257 }\r
258 \r
259 bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength)\r
260 {\r
261         memcpy(&m_Salt[0], Salt, nSaltLength);\r
262         \r
263         m_nSaltLen = nSaltLength;\r
264 //      m_sSalt = sSalt;\r
265         return true;\r
266 }\r
267 \r
268 bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount)\r
269 {\r
270         // something like lm_alpha#1-7_0_100x16_test.rt\r
271 \r
272 #ifdef _WIN32\r
273         string::size_type nIndex = sPathName.find_last_of('\\');\r
274 #else\r
275         string::size_type nIndex = sPathName.find_last_of('/');\r
276 #endif\r
277         if (nIndex != string::npos)\r
278                 sPathName = sPathName.substr(nIndex + 1);\r
279 \r
280         if (sPathName.size() < 3)\r
281         {\r
282                 printf("%s is not a rainbow table\n", sPathName.c_str());\r
283                 return false;\r
284         }\r
285         if (sPathName.substr(sPathName.size() - 5) == ".rti2")\r
286         {\r
287                 isRti2RtFormat = true;\r
288         }\r
289         else if (sPathName.substr(sPathName.size() - 4) == ".rti")\r
290         {\r
291                 isOldRtFormat = false;\r
292         }\r
293         else if (sPathName.substr(sPathName.size() - 3) == ".rt")\r
294         {\r
295                 isOldRtFormat = true;\r
296         }\r
297         else\r
298         {\r
299                 printf("%s is not a rainbow table\n", sPathName.c_str());\r
300                 return false;\r
301         }\r
302 \r
303         // Parse\r
304         vector<string> vPart;\r
305         if (!SeperateString(sPathName, "___x_", vPart))\r
306         {\r
307                 printf("filename %s not identified\n", sPathName.c_str());\r
308                 return false;\r
309         }\r
310 \r
311         string sHashRoutineName   = vPart[0];\r
312         int nRainbowTableIndex    = atoi(vPart[2].c_str());\r
313         nRainbowChainLen          = atoi(vPart[3].c_str());\r
314         nRainbowChainCount        = atoi(vPart[4].c_str());\r
315 \r
316         // Parse charset definition\r
317         string sCharsetDefinition = vPart[1];\r
318         string sCharsetName;\r
319         int nPlainLenMin = 0, nPlainLenMax = 0;         \r
320 \r
321 //      printf("Charset: %s", sCharsetDefinition.c_str());\r
322         \r
323         if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table\r
324         {\r
325                 sCharsetName = sCharsetDefinition;\r
326         }\r
327         else\r
328         {\r
329                 if ( sCharsetDefinition.find('#') == string::npos )             // For backward compatibility, "#1-7" is implied\r
330                 {                       \r
331                         sCharsetName = sCharsetDefinition;\r
332                         nPlainLenMin = 1;\r
333                         nPlainLenMax = 7;\r
334                 }\r
335                 else\r
336                 {\r
337                         vector<string> vCharsetDefinitionPart;\r
338                         if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart))\r
339                         {\r
340                                 printf("filename %s not identified\n", sPathName.c_str());\r
341                                 return false;   \r
342                         }\r
343                         else\r
344                         {\r
345                                 sCharsetName = vCharsetDefinitionPart[0];\r
346                                 nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str());\r
347                                 nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str());\r
348                         }\r
349                 }\r
350         }\r
351         // Setup\r
352         if (!SetHashRoutine(sHashRoutineName))\r
353         {\r
354                 printf("hash routine %s not supported\n", sHashRoutineName.c_str());\r
355                 return false;\r
356         }\r
357         if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))\r
358                 return false;\r
359         if (!SetRainbowTableIndex(nRainbowTableIndex))\r
360         {\r
361                 printf("invalid rainbow table index %d\n", nRainbowTableIndex);\r
362                 return false;\r
363         }\r
364         m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];\r
365         return true;\r
366 }\r
367 \r
368 string CChainWalkContext::GetHashRoutineName()\r
369 {\r
370         return m_sHashRoutineName;\r
371 }\r
372 \r
373 int CChainWalkContext::GetHashLen()\r
374 {\r
375         return m_nHashLen;\r
376 }\r
377 \r
378 string CChainWalkContext::GetPlainCharsetName()\r
379 {\r
380         return m_vCharset[0].m_sPlainCharsetName;\r
381 }\r
382 \r
383 string CChainWalkContext::GetPlainCharsetContent()\r
384 {\r
385         return m_vCharset[0].m_sPlainCharsetContent;\r
386 }\r
387 \r
388 int CChainWalkContext::GetPlainLenMin()\r
389 {\r
390         return m_vCharset[0].m_nPlainLenMin;\r
391 }\r
392 \r
393 int CChainWalkContext::GetPlainLenMax()\r
394 {\r
395         return m_vCharset[0].m_nPlainLenMax;\r
396 }\r
397 \r
398 uint64 CChainWalkContext::GetPlainSpaceTotal()\r
399 {\r
400         return m_nPlainSpaceTotal;\r
401 }\r
402 \r
403 int CChainWalkContext::GetRainbowTableIndex()\r
404 {\r
405         return m_nRainbowTableIndex;\r
406 }\r
407 \r
408 void CChainWalkContext::Dump()\r
409 {\r
410         printf("hash routine: %s\n", m_sHashRoutineName.c_str());\r
411         printf("hash length: %d\n", m_nHashLen);\r
412 \r
413         printf( "m_vCharset[0].m_nPlainCharSetLen: %d\n", m_vCharset[0].m_nPlainCharsetLen );\r
414         printf( "m_vCharset[1].m_nPlainCharSetLen: %d\n", m_vCharset[1].m_nPlainCharsetLen );\r
415 \r
416         printf("plain charset: ");\r
417         unsigned int i;\r
418         \r
419         for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)\r
420         {\r
421                 if (isprint(m_vCharset[0].m_PlainCharset[i]))\r
422                         printf("%c", m_vCharset[0].m_PlainCharset[i]);\r
423                 else\r
424                         printf("?");\r
425         }\r
426         printf("\n");\r
427 \r
428         printf("plain charset in hex: ");\r
429         for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)\r
430                 printf("%02x ", m_vCharset[0].m_PlainCharset[i]);\r
431         printf("\n");\r
432 \r
433         printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax);\r
434         printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str());\r
435         //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str());\r
436         //for (i = 0; i <= m_nPlainLenMax; i++)\r
437         //      printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str());\r
438         printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str());\r
439 \r
440         printf("rainbow table index: %d\n", m_nRainbowTableIndex);\r
441         printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str());\r
442         printf("\n");\r
443 }\r
444 \r
445 void CChainWalkContext::SetIndex(uint64 nIndex)\r
446 {\r
447         m_nIndex = nIndex;\r
448 }\r
449 \r
450 void CChainWalkContext::SetHash(unsigned char* pHash)\r
451 {\r
452         memcpy(m_Hash, pHash, m_nHashLen);\r
453 }\r
454 \r
455 void CChainWalkContext::IndexToPlain()\r
456 {\r
457         int i;\r
458         m_nPlainLen = 0;\r
459 ///*\r
460         for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--)\r
461         {\r
462                 if (m_nIndex >= m_nPlainSpaceUpToX[i])\r
463                 {\r
464                         m_nPlainLen = i + 1;\r
465                         break;\r
466                 }\r
467         }\r
468 \r
469         // this is an optimized version of the above\r
470 /*\r
471         for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1\r
472                 && m_nIndex < m_nPlainSpaceUpToX[i]; i--)\r
473         { }\r
474         \r
475         m_nPlainLen = i + 1;\r
476 */\r
477 \r
478         if(m_nPlainLen == 0)\r
479                 m_nPlainLen = m_nPlainLenMinTotal;\r
480         uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1];\r
481 \r
482 // this is the generic code for non x86/x86_64 platforms\r
483 #if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__)\r
484         \r
485         // generic version (slow for non 64-bit platforms and gcc < 4.5.x)\r
486         for (i = m_nPlainLen - 1; i >= 0; i--)\r
487         {\r
488                 int nCharsetLen = 0;\r
489                 for(uint32 j = 0; j < m_vCharset.size(); j++)\r
490                 {\r
491                         nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
492                         if(i < nCharsetLen) // We found the correct charset\r
493                         {\r
494                                 m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];\r
495                                 nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;\r
496                                 break;\r
497                         }\r
498                 }\r
499         }\r
500 \r
501 #elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)\r
502 \r
503         // Fast ia32 version\r
504         for (i = m_nPlainLen - 1; i >= 0; i--)\r
505         {\r
506                 // 0x100000000 = 2^32\r
507 #ifdef _M_IX86\r
508                 if (nIndexOfX < 0x100000000I64)\r
509                         break;\r
510 #else\r
511                 if (nIndexOfX < 0x100000000llu)\r
512                         break;\r
513 #endif\r
514 \r
515                 int nCharsetLen = 0;\r
516                 for(uint32 j = 0; j < m_vCharset.size(); j++)\r
517                 {\r
518                         nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
519                         if(i < nCharsetLen) // We found the correct charset\r
520                         {\r
521                                 m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];\r
522                                 nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;\r
523                                 break;\r
524                         }\r
525                 }\r
526         }\r
527 \r
528         uint32 nIndexOfX32 = (uint32)nIndexOfX;\r
529         for (; i >= 0; i--)\r
530         {\r
531                 int nCharsetLen = 0;\r
532                 for(uint32 j = 0; j < m_vCharset.size(); j++)\r
533                 {\r
534                         nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
535                         if(i < nCharsetLen) // We found the correct charset\r
536                         {\r
537 \r
538 //              m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen];\r
539 //              nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen;\r
540 \r
541 //      moving nPlainCharsetLen into the asm body and avoiding the extra temp\r
542 //      variable results in a performance gain\r
543 //                              unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;\r
544                                 unsigned int nTemp;\r
545 \r
546 #if defined(_WIN32) && !defined(__GNUC__)\r
547                 // VC++ still needs this\r
548                 unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;\r
549 \r
550                 __asm\r
551                 {\r
552                         mov eax, nIndexOfX32\r
553                         xor edx, edx\r
554                         div nPlainCharsetLen\r
555                         mov nIndexOfX32, eax\r
556                         mov nTemp, edx\r
557                 }\r
558                 m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];\r
559 #else\r
560                 __asm__ __volatile__ ("xor %%edx, %%edx;"\r
561                                                                 "divl %3;"\r
562                                                                 : "=a"(nIndexOfX32), "=d"(nTemp)\r
563                                                                 : "a"(nIndexOfX32), "rm"(m_vCharset[j].m_nPlainCharsetLen)\r
564                                                                 : );\r
565                 m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];\r
566 #endif\r
567                 break;\r
568                         }\r
569                 }\r
570         }\r
571 #endif\r
572 }\r
573 \r
574 void CChainWalkContext::PlainToHash()\r
575 {       \r
576         m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash);\r
577 }\r
578 \r
579 void CChainWalkContext::HashToIndex(int nPos)\r
580 {\r
581         m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal;\r
582 }\r
583 \r
584 uint64 CChainWalkContext::GetIndex()\r
585 {\r
586         return m_nIndex;\r
587 }\r
588 const uint64 *CChainWalkContext::GetIndexPtr()\r
589 {\r
590         return &m_nIndex;\r
591 }\r
592 \r
593 string CChainWalkContext::GetPlain()\r
594 {\r
595         string sRet;\r
596         int i;\r
597         for (i = 0; i < m_nPlainLen; i++)\r
598         {\r
599                 char c = m_Plain[i];\r
600                 sRet += c;\r
601         }\r
602         \r
603         return sRet;\r
604 }\r
605 \r
606 string CChainWalkContext::GetBinary()\r
607 {\r
608         return HexToStr(m_Plain, m_nPlainLen);\r
609 }\r
610 \r
611 string CChainWalkContext::GetHash()\r
612 {\r
613         return HexToStr(m_Hash, m_nHashLen);\r
614 }\r
615 \r
616 bool CChainWalkContext::CheckHash(unsigned char* pHash)\r
617 {\r
618         if (memcmp(m_Hash, pHash, m_nHashLen) == 0)\r
619                 return true;\r
620 \r
621         return false;\r
622 }\r
623 \r
624 bool CChainWalkContext::isOldFormat()\r
625 {\r
626         return isOldRtFormat;\r
627 }\r
628 \r
629 bool CChainWalkContext::isRti2Format()\r
630 {\r
631         return isRti2RtFormat;\r
632 }\r