2 RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
4 Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
8 #pragma warning(disable : 4786 4267 4018)
11 #include "CrackEngine.h"
14 #include "RTI2Reader.h"
16 CCrackEngine::CCrackEngine()
20 resumeSession = false;
22 keepPrecalcFiles = false;
24 sSessionPathName = "";
25 sProgressPathName = "";
28 CCrackEngine::~CCrackEngine()
32 //////////////////////////////////////////////////////////////////////
34 void CCrackEngine::ResetStatistics()
36 m_fTotalDiskAccessTime = 0.0f;
37 m_fTotalCryptanalysisTime = 0.0f;
38 m_nTotalChainWalkStep = 0;
39 m_nTotalFalseAlarm = 0;
40 m_nTotalChainWalkStepDueToFalseAlarm = 0;
41 // m_nTotalFalseAlarmSkipped = 0;
44 int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)
47 int nHigh = nRainbowChainCount - 1;
50 int nMid = (nLow + nHigh) / 2;
51 if (nIndex == pChain[nMid].nIndexE)
53 else if (nIndex < pChain[nMid].nIndexE)
62 RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)
64 uint64 nPrefix = nIndex >> 16;
69 if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file
75 int nBHigh = nIndexSize - 1;
76 while (nBLow <= nBHigh)
78 int nBMid = (nBLow + nBHigh) / 2;
79 if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
84 nLow = pIndex[nBMid].nFirstChain;
85 nHigh = nLow + pIndex[nBMid].nChainCount;
86 if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead)
88 if(nHigh > nIndexStart + nChainCountRead)
89 nHigh = nIndexStart + nChainCountRead;
91 else if(nLow < nIndexStart && nHigh >= nIndexStart)
99 else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
106 for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)
108 int nSIndex = ((int)nIndex) & 0x0000FFFF;
110 if (nSIndex == pChain[i].nIndexE)
114 else if(pChain[i].nIndexE > nSIndex)
121 // not used currently, leaving code for future checkpoints
122 //bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
124 // CChainWalkContext cwc;
125 // //uint64 nIndexS = pChain->nIndexS >> 16;
126 // uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
127 // cwc.SetIndex(nIndexS);
129 // for (nPos = 0; nPos < nGuessedPos; nPos++)
131 // cwc.IndexToPlain();
132 // cwc.PlainToHash();
133 // cwc.HashToIndex(nPos);
134 // // Not using checkpoints atm
139 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)
141 // m_nTotalFalseAlarmSkipped += 10000 - 5000;
142 //// printf("CheckPoint caught false alarm at position 7600\n");
147 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)
149 //// printf("CheckPoint caught false alarm at position 8200\n");
150 // m_nTotalFalseAlarmSkipped += 10000 - 6000;
156 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)
158 //// printf("CheckPoint caught false alarm at position 8700\n");
159 // m_nTotalFalseAlarmSkipped += 10000 - 7600;
165 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)
167 //// printf("CheckPoint caught false alarm at position 9000\n");
168 // m_nTotalFalseAlarmSkipped += 10000 - 8200;
174 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)
176 //// printf("CheckPoint caught false alarm at position 9300\n");
177 // m_nTotalFalseAlarmSkipped += 10000 - 8700;
183 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)
185 //// printf("CheckPoint caught false alarm at position 9600\n");
186 // m_nTotalFalseAlarmSkipped += 10000 - 9000;
192 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)
194 //// printf("CheckPoint caught false alarm at position 9600\n");
195 // m_nTotalFalseAlarmSkipped += 10000 - 9300;
200 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))
202 //// printf("CheckPoint caught false alarm at position 9600\n");
203 // m_nTotalFalseAlarmSkipped += 10000 - 9600;
210 // cwc.IndexToPlain();
211 // cwc.PlainToHash();
212 // if (cwc.CheckHash(pHash))
214 // printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
215 // hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
222 //bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
224 // CChainWalkContext cwc;
225 // cwc.SetIndex(pChain->nIndexS);
227 // for (nPos = 0; nPos < nGuessedPos; nPos++)
229 // cwc.IndexToPlain();
230 // cwc.PlainToHash();
231 // cwc.HashToIndex(nPos);
233 // cwc.IndexToPlain();
234 // cwc.PlainToHash();
235 // if (cwc.CheckHash(pHash))
237 // printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
238 // hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
245 void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,
246 int nRainbowChainCount,
248 int& nMatchingIndexEFrom,
249 int& nMatchingIndexETo)
251 nMatchingIndexEFrom = nMatchingIndexE;
252 nMatchingIndexETo = nMatchingIndexE;
253 while (nMatchingIndexEFrom > 0)
255 if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
256 nMatchingIndexEFrom--;
260 while (nMatchingIndexETo < nRainbowChainCount - 1)
262 if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
269 void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)
271 vector<string> vHash;
272 hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
273 printf("searching for %d hash%s...\n", vHash.size(),
274 vHash.size() > 1 ? "es" : "");
276 int nChainWalkStep = 0;
278 int nChainWalkStepDueToFalseAlarm = 0;
280 vector<rcrackiThread*> threadPool;
281 vector<pthread_t> pThreads;
284 pthread_attr_init(&attr);
285 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
288 param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
289 pthread_attr_setschedparam (&attr, ¶m);
291 // else set it to 5 or something (for linux)?
293 bool pausing = false;
296 for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
306 printf( "\nPausing, press P again to continue... ");
307 clock_t t1 = clock();
316 printf( " [Continuing]\n");
318 clock_t t2 = clock();
319 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
320 m_fTotalCryptanalysisTime -= fTime;
328 printf( "\nPress 'P' to pause...\n");
332 int c = tty_getchar();
337 printf( "\nPausing, press 'p' again to continue... ");
338 clock_t t1 = clock();
341 if ((c = tty_getchar()) >= 0)
346 printf( " [Continuing]\n");
348 clock_t t2 = clock();
349 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
350 m_fTotalCryptanalysisTime -= fTime;
357 printf( "\nPress 'p' to pause...\n");
361 unsigned char TargetHash[MAX_HASH_LEN];
363 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
364 if (nHashLen != CChainWalkContext::GetHashLen())
365 printf("debug: nHashLen mismatch\n");
368 bool fNewlyGenerated;
369 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
371 CChainWalkContext::GetHashRoutineName(),
372 CChainWalkContext::GetPlainCharsetName(),
373 CChainWalkContext::GetPlainLenMin(),
374 CChainWalkContext::GetPlainLenMax(),
375 CChainWalkContext::GetRainbowTableIndex(),
380 //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
381 // vHash[nHashIndex].c_str());
386 //printf("Pre-calculating hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
387 printf("Pre-calculating hash %d of %d.%-20s\r", nHashIndex+1, vHash.size(), "");
392 for (thread_ID = 0; thread_ID < maxThreads; thread_ID++)
394 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
398 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
400 if( returnValue != 0 )
402 printf("pThread creation failed, returnValue: %d\n", returnValue);
406 pThreads.push_back(pThread);
409 threadPool.push_back(r_Thread);
413 printf("r_Thread creation failed!\n");
417 //printf("%d r_Threads created\t\t\n", threadPool.size());
419 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
421 pthread_t pThread = pThreads[thread_ID];
422 int returnValue = pthread_join(pThread, NULL);
423 if( returnValue != 0 )
425 printf("pThread join failed, returnValue: %d\n", returnValue);
428 rcrackiThread* rThread = threadPool[thread_ID];
429 nChainWalkStep += rThread->GetChainWalkStep();
432 //printf("\t\t\t\t\r");
433 printf("%-50s\r", "");
438 //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
439 printf("Checking false alarms for hash %d of %d.%-20s\r", nHashIndex+1, vHash.size(), "");
445 for (i = 0; i < maxThreads; i++)
447 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);
448 threadPool.push_back(r_Thread);
453 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
455 uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
457 // Search matching nIndexE
458 int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);
459 if (nMatchingIndexE != -1)
461 int nMatchingIndexEFrom, nMatchingIndexETo;
462 GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,
464 nMatchingIndexEFrom, nMatchingIndexETo);
466 for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)
468 rcrackiThread* rThread = threadPool[thread_ID];
469 rThread->AddAlarmCheckO(pChain + i, nPos);
470 if (thread_ID < maxThreads - 1 ) {
479 for (thread_ID = 0; thread_ID < maxThreads; thread_ID++)
481 rcrackiThread* r_Thread = threadPool[thread_ID];
484 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
486 if( returnValue != 0 )
488 printf("pThread creation failed, returnValue: %d\n", returnValue);
492 pThreads.push_back(pThread);
496 //printf("%d r_Threads created\t\t\n", threadPool.size());
498 bool foundHashInThread = false;
499 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
501 rcrackiThread* rThread = threadPool[thread_ID];
502 pthread_t pThread = pThreads[thread_ID];
504 int returnValue = pthread_join(pThread, NULL);
505 if( returnValue != 0 )
507 printf("pThread join failed, returnValue: %d\n", returnValue);
510 nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
511 nFalseAlarm += rThread->GetnFalseAlarm();
513 if (rThread->FoundHash() && !foundHashInThread) {
514 //printf("\t\t\t\t\t\t\r");
515 printf("%-50s\r", "");
517 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
520 if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
521 printf("Couldn't write this result to file!\n");
523 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
525 FILE* file = fopen(sSessionPathName.c_str(), "a");
528 string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
529 fputs (buffer.c_str(), file);
533 m_cws.DiscardWalk(pStartPosIndexE);
534 foundHashInThread = true;
542 //printf("\t\t\t\t\t\t\t\r");
543 printf("%-50s\r", "");
546 pthread_attr_destroy(&attr);
548 //printf("debug: chain walk step: %d\n", nChainWalkStep);
549 //printf("debug: false alarm: %d\n", nFalseAlarm);
550 //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
552 m_nTotalChainWalkStep += nChainWalkStep;
553 m_nTotalFalseAlarm += nFalseAlarm;
554 m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
557 void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)
559 vector<string> vHash;
560 //vector<uint64 *> vIndices;
561 //vector<RainbowChain *> vChains;
562 hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
563 printf("searching for %d hash%s...\n", vHash.size(),
564 vHash.size() > 1 ? "es" : "");
566 int nChainWalkStep = 0;
568 int nChainWalkStepDueToFalseAlarm = 0;
570 vector<rcrackiThread*> threadPool;
571 vector<pthread_t> pThreads;
574 pthread_attr_init(&attr);
575 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
578 param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
579 pthread_attr_setschedparam (&attr, ¶m);
581 // else set it to 5 or something (for linux)?
583 bool pausing = false;
586 for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
596 printf( "\nPausing, press P again to continue... ");
597 clock_t t1 = clock();
606 printf( " [Continuing]\n");
608 clock_t t2 = clock();
609 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
610 m_fTotalCryptanalysisTime -= fTime;
618 printf( "\nPress 'P' to pause...\n");
622 int c = tty_getchar();
627 printf( "\nPausing, press 'p' again to continue... ");
628 clock_t t1 = clock();
631 if ((c = tty_getchar()) >= 0)
636 printf( " [Continuing]\n");
638 clock_t t2 = clock();
639 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
640 m_fTotalCryptanalysisTime -= fTime;
647 printf( "\nPress 'p' to pause...\n");
651 unsigned char TargetHash[MAX_HASH_LEN];
653 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
654 if (nHashLen != CChainWalkContext::GetHashLen())
655 printf("debug: nHashLen mismatch\n");
658 bool fNewlyGenerated;
659 // printf("Requesting walk...");
662 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
664 CChainWalkContext::GetHashRoutineName(),
665 CChainWalkContext::GetPlainCharsetName(),
666 CChainWalkContext::GetPlainLenMin(),
667 CChainWalkContext::GetPlainLenMax(),
668 CChainWalkContext::GetRainbowTableIndex(),
673 // printf("done!\n");
674 // printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
675 // vHash[nHashIndex].c_str());
679 //printf("Pre-calculating hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
680 printf("Pre-calculating hash %d of %d.%-20s\r", nHashIndex+1, vHash.size(), "");
685 for (thread_ID = 0; thread_ID < maxThreads; thread_ID++)
687 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
691 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
693 if( returnValue != 0 )
695 printf("pThread creation failed, returnValue: %d\n", returnValue);
699 pThreads.push_back(pThread);
702 threadPool.push_back(r_Thread);
706 printf("r_Thread creation failed!\n");
710 //printf("%d r_Threads created\t\t\n", threadPool.size());
712 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
714 pthread_t pThread = pThreads[thread_ID];
715 int returnValue = pthread_join(pThread, NULL);
716 if( returnValue != 0 )
718 printf("pThread join failed, returnValue: %d\n", returnValue);
721 rcrackiThread* rThread = threadPool[thread_ID];
722 nChainWalkStep += rThread->GetChainWalkStep();
725 m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);
727 //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());
728 //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());
730 printf("%-50s\r", "");
738 //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
739 printf("Checking false alarms for hash %d of %d.%-20s\r", nHashIndex+1, vHash.size(), "");
742 for (i = 0; i < maxThreads; i++)
744 rcrackiThread* r_Thread = new rcrackiThread(TargetHash);
745 threadPool.push_back(r_Thread);
750 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
752 uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
754 // Search matching nIndexE
755 RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);
756 if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)
758 rcrackiThread* rThread = threadPool[thread_ID];
759 rThread->AddAlarmCheck(pChainFound, nPos);
760 if (thread_ID < maxThreads - 1 ) {
768 for (thread_ID = 0; thread_ID < maxThreads; thread_ID++)
770 rcrackiThread* r_Thread = threadPool[thread_ID];
773 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
775 if( returnValue != 0 )
777 printf("pThread creation failed, returnValue: %d\n", returnValue);
781 pThreads.push_back(pThread);
785 //printf("%d r_Threads created\t\t\n", threadPool.size());
787 bool foundHashInThread = false;
788 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
790 rcrackiThread* rThread = threadPool[thread_ID];
791 pthread_t pThread = pThreads[thread_ID];
793 int returnValue = pthread_join(pThread, NULL);
794 if( returnValue != 0 )
796 printf("pThread join failed, returnValue: %d\n", returnValue);
799 nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
800 nFalseAlarm += rThread->GetnFalseAlarm();
802 if (rThread->FoundHash() && !foundHashInThread) {
803 //printf("\t\t\t\t\t\t\r");
804 printf("%-50s\r", "");
805 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
808 if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
809 printf("Couldn't write this result to file!\n");
811 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
813 FILE* file = fopen(sSessionPathName.c_str(), "a");
816 string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
817 fputs (buffer.c_str(), file);
821 m_cws.DiscardWalk(pStartPosIndexE);
822 foundHashInThread = true;
831 //printf("\t\t\t\t\r");
832 //printf("pChainFounds: %d\n", pChainsFound.size());
835 //printf("\t\t\t\t\t\t\t\r");
836 printf("%-50s\r", "");
839 pthread_attr_destroy(&attr);
841 //printf("debug: chain walk step: %d\n", nChainWalkStep);
842 //printf("debug: false alarm: %d\n", nFalseAlarm);
843 //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
845 m_nTotalChainWalkStep += nChainWalkStep;
846 m_nTotalFalseAlarm += nFalseAlarm;
847 m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
850 void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)
852 // Did we already go through this file in this session?
855 vector<string> sessionFinishedPathNames;
856 if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))
859 for (i = 0; i < sessionFinishedPathNames.size(); i++)
861 if (sessionFinishedPathNames[i] == sPathName)
863 printf("Skipping %s\n", sPathName.c_str());
872 int nIndex = sPathName.find_last_of('\\');
874 int nIndex = sPathName.find_last_of('/');
878 sFileName = sPathName.substr(nIndex + 1);
880 sFileName = sPathName;
883 printf("%s:\n", sFileName.c_str());
886 int nRainbowChainLen, nRainbowChainCount;
887 if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))
889 //printf("keyspace: %u\n", CChainWalkContext::GetPlainSpaceTotal());
891 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
893 printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());
898 FILE* file = fopen(sPathName.c_str(), "rb");
902 bool doOldFormat = CChainWalkContext::isOldFormat();
903 bool doNewFormat = CChainWalkContext::isNewFormat();
905 bool fVerified = false;
906 unsigned int nFileLen = GetFileLen(file);
913 //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)
914 if ((nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != nFileLen) && doNewFormat == false)
915 printf("file length mismatch\n");
918 fseek(file, 0, SEEK_SET);
920 unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;
921 if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);
923 static CMemoryPool mp(bytesForChainWalkSet);
924 unsigned int nAllocatedSize;
925 if (doNewFormat || doOldFormat)
929 pReader = new RTI2Reader(sPathName);
932 if (debug) printf("Debug: This is a table in the old .rt format.\n");
933 RainbowChainO* pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);
934 if (debug) printf("Allocated %u bytes, filelen %u\n", nAllocatedSize, nFileLen);
937 nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
939 //fseek(file, 0, SEEK_SET);
940 //bool fVerified = false;
941 while (true) // Chunk read loop
943 if (ftell(file) == nFileLen)
947 if (debug) printf("reading...\n");
948 unsigned int nDataRead = 0;
949 clock_t t1 = clock();
952 nDataRead = nAllocatedSize / 16;
953 pReader->ReadChains(nDataRead, pChain);
954 nDataRead *= 8; // Convert from chains read to bytes
955 if(nDataRead == 0) // No more data
959 nDataRead = fread(pChain, 1, nAllocatedSize, file);
961 clock_t t2 = clock();
962 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
963 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
964 m_fTotalDiskAccessTime += fTime;
966 int nRainbowChainCountRead = nDataRead / 16;
968 // Verify table chunk
971 printf("verifying the file...\n");
974 int nIndexToVerify = nRainbowChainCountRead / 2;
975 CChainWalkContext cwc;
976 cwc.SetIndex(pChain[nIndexToVerify].nIndexS);
978 for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
982 cwc.HashToIndex(nPos);
984 if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)
986 printf("rainbow chain length verify fail\n");
992 for (i = 0; i < nRainbowChainCountRead - 1; i++)
994 if (pChain[i].nIndexE > pChain[i + 1].nIndexE)
997 if (i != nRainbowChainCountRead - 1)
999 printf("this file is not sorted\n");
1006 // Search table chunk
1008 SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);
1010 fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
1011 printf("cryptanalysis time: %.2f s\n", fTime);
1012 m_fTotalCryptanalysisTime += fTime;
1014 // Already finished?
1015 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
1020 printf("memory allocation fail\n");
1026 static CMemoryPool mpIndex(bytesForChainWalkSet);
1027 unsigned int nAllocatedSizeIndex;
1029 //int nIndexSize = 0;
1030 //IndexChain *pIndex = NULL;
1032 FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");
1035 // File length check
1036 unsigned int nFileLenIndex = GetFileLen(fIndex);
1037 unsigned int nRows = nFileLenIndex / 11;
1038 unsigned int nSize = nRows * sizeof(IndexChain);
1039 //printf("Debug: 8\n");
1040 if (nFileLenIndex % 11 != 0)
1041 printf("index file length mismatch (%u bytes)\n", nFileLenIndex);
1044 //printf("index nSize: %d\n", nSize);
1045 //pIndex = (IndexChain*)new unsigned char[nSize];
1046 IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);
1047 if (debug) printf("Debug: Allocated %u bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
1049 if (pIndex != NULL && nAllocatedSizeIndex > 0)
1051 nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain); // Round to sizeOfIndexChain boundary
1053 fseek(fIndex, 0, SEEK_SET);
1054 int nProcessedIndexChains = 0;
1056 while (true) // Index chunk read loop
1058 if (ftell(fIndex) == nFileLenIndex)
1062 if (debug) printf("Debug: Setting index to 0x00 in memory, %u bytes\n", nAllocatedSizeIndex);
1063 memset(pIndex, 0x00, nAllocatedSizeIndex);
1064 printf("reading index... ");
1065 clock_t t1 = clock();
1066 unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);
1067 clock_t t2 = clock();
1069 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
1070 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
1071 m_fTotalDiskAccessTime += fTime;
1073 //nIndexSize = nFileLenIndex / 11;
1074 int nIndexChainCountRead = nDataRead / sizeof(IndexChain);
1076 unsigned int nCoveredRainbowTableChains = 0;
1077 for(int i = 0; i < nIndexChainCountRead; i++)
1079 nCoveredRainbowTableChains += pIndex[i].nChainCount;
1082 //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);
1083 RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);
1084 if (debug) printf("Debug: Allocated %u bytes for %u chains, filelen %u\n", nAllocatedSize, nCoveredRainbowTableChains, nFileLen);
1086 if (pChain != NULL && nAllocatedSize > 0)
1088 nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
1090 //fseek(file, 0, SEEK_SET);
1091 //bool fVerified = false;
1092 int nProcessedChains = 0;
1093 while (true) // Chunk read loop
1095 if (ftell(file) == nFileLen)
1098 if (nProcessedChains >= nCoveredRainbowTableChains)
1102 if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");
1103 memset(pChain, 0x00, nAllocatedSize);
1104 printf("reading table... ");
1105 clock_t t1 = clock();
1106 unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);
1107 clock_t t2 = clock();
1109 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
1110 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
1111 m_fTotalDiskAccessTime += fTime;
1112 int nRainbowChainCountRead = nDataRead / sizeOfChain;
1113 // Verify table chunk (Too lazy to implement this)
1117 printf("verifying the file...\n");
1119 // Chain length test
1120 int nIndexToVerify = nRainbowChainCountRead / 2;
1121 CChainWalkContext cwc;
1123 nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
1125 //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());
1126 cwc.SetIndex(nIndexS);
1129 for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
1133 cwc.HashToIndex(nPos);
1135 uint64 nEndPoint = 0;
1137 //for(int i = 0; i < nIndexSize; i++)
1138 for(int i = 0; i < nIndexChainCountRead; i++)
1140 if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index
1141 { // Now we need to seek nIndexToVerify into the chains
1142 nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes
1143 //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());
1144 //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);
1145 //printf("nChainCount: %d\n", pIndex[i].nChainCount);
1146 nEndPoint += pChain[nIndexToVerify].nIndexE;
1151 if (cwc.GetIndex() != nEndPoint)
1153 printf("rainbow chain length verify fail\n");
1160 // Search table chunk
1162 float preTime = m_fTotalCryptanalysisTime;
1164 SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);
1165 float postTime = m_fTotalCryptanalysisTime;
1167 fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
1168 printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);
1169 m_fTotalCryptanalysisTime += fTime;
1170 nProcessedChains += nRainbowChainCountRead;
1171 // Already finished?
1172 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
1176 else printf("memory allocation failed for rainbow table\n");
1181 else printf("memory allocation failed for index\n");
1186 printf("Can't load index\n");
1196 if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());
1197 FILE* file = fopen(sProgressPathName.c_str(), "a");
1200 string buffer = sPathName + "\n";
1201 fputs (buffer.c_str(), file);
1206 printf("can't open file\n");
1209 void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, bool resume, bool bDebug)
1214 resumeSession = resume;
1217 maxThreads = i_maxThreads;
1221 // Sort vPathName (CChainWalkSet need it)
1223 for (i = 0; i < vPathName.size() - 1; i++)
1224 for (j = 0; j < vPathName.size() - i - 1; j++)
1226 if (vPathName[j] > vPathName[j + 1])
1229 sTemp = vPathName[j];
1230 vPathName[j] = vPathName[j + 1];
1231 vPathName[j + 1] = sTemp;
1236 for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)
1238 SearchRainbowTable(vPathName[i], hs);
1242 // delete precalc files
1243 if (!keepPrecalcFiles)
1244 m_cws.removePrecalcFiles();
1251 void CCrackEngine::setOutputFile(string sPathName)
1254 outputFile = sPathName;
1257 void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)
1259 sSessionPathName = sSession;
1260 sProgressPathName = sProgress;
1261 sPrecalcPathName = sPrecalc;
1262 keepPrecalcFiles = keepPrecalc;
1265 float CCrackEngine::GetStatTotalDiskAccessTime()
1267 return m_fTotalDiskAccessTime;
1269 /*float CCrackEngine::GetWastedTime()
1271 return m_fIndexTime;
1273 float CCrackEngine::GetStatTotalCryptanalysisTime()
1275 return m_fTotalCryptanalysisTime;
1278 int CCrackEngine::GetStatTotalChainWalkStep()
1280 return m_nTotalChainWalkStep;
1283 int CCrackEngine::GetStatTotalFalseAlarm()
1285 return m_nTotalFalseAlarm;
1288 int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()
1290 return m_nTotalChainWalkStepDueToFalseAlarm;