]> git.sesse.net Git - freerainbowtables/blobdiff - BOINC software/BOINC client apps/distrrtgen_cuda/distrrtgen.cpp
distrrtgen_cuda code added
[freerainbowtables] / BOINC software / BOINC client apps / distrrtgen_cuda / distrrtgen.cpp
diff --git a/BOINC software/BOINC client apps/distrrtgen_cuda/distrrtgen.cpp b/BOINC software/BOINC client apps/distrrtgen_cuda/distrrtgen.cpp
new file mode 100644 (file)
index 0000000..001e54a
--- /dev/null
@@ -0,0 +1,373 @@
+// This file is part of BOINC.
+// http://boinc.berkeley.edu
+// Copyright (C) 2008 University of California
+//
+// BOINC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// BOINC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
+
+// This program serves as both
+// - An example BOINC application, illustrating the use of the BOINC API
+// - A program for testing various features of BOINC
+//
+// NOTE: this file exists as both
+// boinc/apps/upper_case.C
+// and
+// boinc_samples/example_app/uc2.C
+// If you update one, please update the other!
+
+// The program converts a mixed-case file to upper case:
+// read "in", convert to upper case, write to "out"
+//
+// command line options
+// -run_slow: sleep 1 second after each character
+// -cpu_time N: use about N CPU seconds after copying files
+// -early_exit: exit(10) after 30 chars
+// -early_crash: crash after 30 chars
+//
+
+#ifdef _WIN32
+#include "boinc_win.h"
+#else
+#include "config.h"
+#include <cstdio>
+#include <cctype>
+#include <ctime>
+#include <cstring>
+#include <cstdlib>
+#include <csignal>
+#include <unistd.h>
+#endif
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include "str_util.h"
+#include "util.h"
+#include "filesys.h"
+#include "boinc_api.h"
+#include "Public.h"
+// Rainbowcrack code
+#include "ChainWalkContext.h"
+//typedef unsigned int uint32;
+//typedef unsigned __int64 uint64;
+#include "rcuda.h"
+#include "rcuda_ext.h"
+
+
+using std::string;
+
+/*
+bool early_exit = false;
+bool early_crash = false;
+bool early_sleep = false;
+double cpu_time = 20, comp_result;
+*/
+int QuickSortPartition(RainbowChainCP* pChain, int nLow, int nHigh)
+{
+       int nRandomIndex = nLow + ((unsigned int)rand() * (RAND_MAX + 1) + (unsigned int)rand()) % (nHigh - nLow + 1);
+       RainbowChainCP TempChain;
+       TempChain = pChain[nLow];
+       pChain[nLow] = pChain[nRandomIndex];
+       pChain[nRandomIndex] = TempChain;
+
+       TempChain = pChain[nLow];
+       uint64 nPivotKey = pChain[nLow].nIndexE;
+       while (nLow < nHigh)
+       {
+               while (nLow < nHigh && pChain[nHigh].nIndexE >= nPivotKey)
+                       nHigh--;
+               pChain[nLow] = pChain[nHigh];
+               while (nLow < nHigh && pChain[nLow].nIndexE <= nPivotKey)
+                       nLow++;
+               pChain[nHigh] = pChain[nLow];
+       }
+       pChain[nLow] = TempChain;
+       return nLow;
+}
+
+void QuickSort(RainbowChainCP* pChain, int nLow, int nHigh)
+{
+       if (nLow < nHigh)
+       {
+               int nPivotLoc = QuickSortPartition(pChain, nLow, nHigh);
+               QuickSort(pChain, nLow, nPivotLoc - 1);
+               QuickSort(pChain, nPivotLoc + 1, nHigh);
+       }
+}
+
+int main(int argc, char **argv) {    
+    int retval;
+    double fd;
+    char output_path[512], chkpt_path[512];
+    FILE* state;       
+    retval = boinc_init();
+    if (retval) {
+        fprintf(stderr, "boinc_init returned %d\n", retval);
+        exit(retval);
+    }
+       
+
+    // get size of input file (used to compute fraction done)
+    //
+    //file_size(input_path, fsize);
+
+    // See if there's a valid checkpoint file.
+    // If so seek input file and truncate output file
+    //
+
+
+       if(argc < 10)
+       {
+               fprintf(stderr, "Not enough parameters");
+               return -1;
+       }
+       string sHashRoutineName, sCharsetName, sSalt, sCheckPoints;
+       uint32 nRainbowChainCount, nPlainLenMin, nPlainLenMax, nRainbowTableIndex, nRainbowChainLen;
+       uint64 nChainStart;
+       sHashRoutineName = argv[1];
+       sCharsetName = argv[2];
+       nPlainLenMin = atoi(argv[3]);
+       nPlainLenMax = atoi(argv[4]);
+       nRainbowTableIndex = atoi(argv[5]);
+       nRainbowChainLen = atoi(argv[6]);
+       nRainbowChainCount = atoi(argv[7]);
+#ifdef _WIN32
+
+       nChainStart = _atoi64(argv[8]);
+
+#else
+       nChainStart = atoll(argv[8]);
+#endif
+       sCheckPoints = argv[9];
+       vector<int> vCPPositions;
+       char *cp = strtok((char *)sCheckPoints.c_str(), ",");
+       while(cp != NULL)
+       {
+               vCPPositions.push_back(atoi(cp));
+               cp = strtok(NULL, ",");
+       }
+       if(argc == 11)
+       {
+               sSalt = argv[10];
+       }
+       //std::cout << "Starting ChainGenerator" << std::endl;
+       // Setup CChainWalkContext
+       //std::cout << "ChainGenerator started." << std::endl;
+
+       if (!CChainWalkContext::SetHashRoutine(sHashRoutineName))
+       {
+               fprintf(stderr, "hash routine %s not supported\n", sHashRoutineName.c_str());
+               return 1;
+       }
+       //std::cout << "Hash routine validated" << std::endl;
+
+       if (!CChainWalkContext::SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))
+       {       
+               std::cerr << "charset " << sCharsetName << " not supported" << std::endl;
+               return 2;
+       }
+       //std::cout << "Plain charset validated" << std::endl;
+
+       if (!CChainWalkContext::SetRainbowTableIndex(nRainbowTableIndex))
+       {
+               std::cerr << "invalid rainbow table index " << nRainbowTableIndex << std::endl;
+               return 3;
+       }
+       //std::cout << "Rainbowtable index validated" << std::endl;
+
+       if(sHashRoutineName == "mscache")// || sHashRoutineName == "lmchall" || sHashRoutineName == "halflmchall")
+       {
+               // Convert username to unicode
+               const char *szSalt = sSalt.c_str();
+               int salt_length = strlen(szSalt);
+               unsigned char cur_salt[256];
+               for (int i=0; i<salt_length; i++)
+               {
+                       cur_salt[i*2] = szSalt[i];
+                       cur_salt[i*2+1] = 0x00;
+               }
+               CChainWalkContext::SetSalt(cur_salt, salt_length*2);
+       }
+       else if(sHashRoutineName == "halflmchall")
+       { // The salt is hardcoded into the hash routine
+       //      CChainWalkContext::SetSalt((unsigned char*)&salt, 8);
+       }
+       else if(sHashRoutineName == "oracle")
+       {
+               CChainWalkContext::SetSalt((unsigned char *)sSalt.c_str(), sSalt.length());
+       }
+       //std::cout << "Opening chain file" << std::endl;
+
+       
+       // Open file
+//     fclose(fopen(sFilename.c_str(), "a"));
+//     FILE* file = fopen(sFilename.c_str(), "r+b");
+    boinc_resolve_filename("result", output_path, sizeof(output_path));
+       fclose(boinc_fopen(output_path, "a"));
+       FILE *outfile = boinc_fopen(output_path, "r+b");
+       
+       if (outfile == NULL)
+       {
+               std::cerr << "failed to create " << output_path << std::endl;
+               return 4;
+       }
+       
+       
+       // Check existing chains
+       unsigned int nDataLen = (unsigned int)GetFileLen(outfile);
+       unsigned int nFileLen;
+       
+       // Round to boundary
+       nDataLen = nDataLen / 18 * 18;
+       if ((int)nDataLen == nRainbowChainCount * 18)
+       {               
+               std::cerr << "precomputation of this rainbow table already finished" << std::endl;
+               fclose(outfile);
+               return 0;
+       }
+
+       fseek(outfile, nDataLen, SEEK_SET);
+       size_t nReturn;
+       CChainWalkContext cwc;
+       uint64 nIndex[2];
+
+//     std::cout << "Starting to generate chains" << std::endl;
+       int maxCalcBuffSize = rcuda::GetChainsBufferSize(5000);
+       uint64 *calcBuff = new uint64[2*maxCalcBuffSize];
+       int ii;
+
+       CudaCWCExtender ex(&cwc);
+       rcuda::RCudaTask cuTask;
+       std::vector<unsigned char> stPlain;
+       ex.Init();
+time_t tStart, tStartFinal, tEndFinal;
+time_t tEnd;
+       tStartFinal = time(NULL);
+       for(int nCurrentCalculatedChains = nDataLen / 18, calcSize; nCurrentCalculatedChains < nRainbowChainCount; )
+       {               
+               fd = (double)nCurrentCalculatedChains / (double)nRainbowChainCount;
+               boinc_fraction_done(fd);
+
+               cuTask.hash = ex.GetHash();
+               cuTask.startIdx = nChainStart + nCurrentCalculatedChains;
+               cuTask.idxCount = std::min<int>(nRainbowChainCount - nCurrentCalculatedChains, maxCalcBuffSize);
+               cuTask.stPlainSize = ex.IndexToStartPlain(0, stPlain);
+               cuTask.stPlain = &stPlain[0];
+               cuTask.dimVec = ex.GetPlainDimVec();
+               cuTask.dimVecSize = ex.GetPlainDimVecSize()/3;
+               cuTask.charSet = ex.GetCharSet();
+               cuTask.charSetSize = ex.GetCharSetSize();
+               cuTask.cpPositions = &vCPPositions[0];
+               cuTask.cpPosSize = vCPPositions.size();
+               cuTask.reduceOffset = ex.GetReduceOffset();
+               cuTask.plainSpaceTotal = ex.GetPlainSpaceTotal();
+               cuTask.rainbowChainLen = nRainbowChainLen;
+               for(int ii = 0; ii < cuTask.idxCount; ii++) {
+                       calcBuff[2*ii] = cuTask.startIdx + ii;
+                       calcBuff[2*ii+1] = 0;
+               }
+
+               tStart = time(NULL);
+
+               calcSize = rcuda::CalcChainsOnCUDA(&cuTask, calcBuff);
+               tEnd = time(NULL);
+               std::cerr << "CUDA time taken: " << tEnd - tStart << std::endl;
+               tStart = time(NULL);
+               if(calcSize > 0) {
+                       nCurrentCalculatedChains += calcSize;
+                       for(ii = 0; ii < cuTask.idxCount; ii++) {
+                               nIndex[0] = cuTask.startIdx + ii;
+                               nReturn = fwrite(nIndex, 1, 8, outfile);
+                               nReturn += fwrite(calcBuff+(2*ii), 1, 8, outfile);
+                               nReturn += fwrite(calcBuff+(2*ii+1), 1, 2, outfile);
+                               if(nReturn != 18) {
+                                       std::cerr << "disk write fail" << std::endl;
+                                       fclose(outfile);
+                                       return 9;
+                               }
+                       }
+               } else {
+                       std::cerr << "Calculations on CUDA failed!" << std::endl;
+                       fclose(outfile);
+                       return 0;
+               }
+       }
+       tEndFinal = time(NULL);
+       std::cerr << "Time taken: " << tEndFinal - tStartFinal << " secs" << std::endl;
+       delete [] calcBuff;
+#ifdef _DEBUG
+       std::cout << "Generation completed" << std::endl;
+#endif
+    fseek(outfile, 0, SEEK_SET);
+       nFileLen = GetFileLen(outfile);
+       nRainbowChainCount = nFileLen / 18;
+
+       RainbowChainCP* pChain = (RainbowChainCP*)new unsigned char[sizeof(RainbowChainCP) * nRainbowChainCount];
+
+       if (pChain != NULL)
+       {
+               // Load file
+#ifdef _DEBUG
+       std::cout << "Sorting file" << std::endl;
+#endif
+               fseek(outfile, 0, SEEK_SET);
+               for(int i = 0; i < nRainbowChainCount; i++)
+               {
+                       if(fread(&pChain[i], 1, 16, outfile) != 16)
+                       {
+                               printf("disk read fail\n");
+                               return 9;
+                       }
+                       if(fread(&pChain[i].nCheckPoint, 1, sizeof(pChain[i].nCheckPoint), outfile) != 2)
+                       {
+                               printf("disk read fail\n");
+                               return 9;
+                       }
+               }
+
+               // Sort file
+               QuickSort(pChain, 0, nRainbowChainCount - 1);
+
+               // Write file
+               fseek(outfile, 0, SEEK_SET);
+               for(int i = 0; i < nRainbowChainCount; i++)
+               {
+                       fwrite(&pChain[i], 1, 16, outfile);
+                       fwrite(&pChain[i].nCheckPoint, 2, 1, outfile);
+               }
+               delete[] pChain;
+       }
+
+       fclose(outfile);
+    
+       // main loop - read characters, convert to UC, write
+    //
+
+    boinc_fraction_done(1);
+    boinc_finish(0);
+}
+
+#ifdef _WIN32
+int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) {
+    LPSTR command_line;
+    char* argv[100];
+    int argc;
+
+    command_line = GetCommandLine();
+    argc = parse_command_line( command_line, argv );
+    return main(argc, argv);
+}
+#endif
+
+const char *BOINC_RCSID_33ac47a071 = "$Id: upper_case.C 12135 2007-02-21 20:04:14Z davea $";
+