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