]> git.sesse.net Git - freerainbowtables/blob - BOINC software/BOINC client apps/distrrtgen_cuda/distrrtgen.cpp
001e54af10768f7f3d3c3bee779d65f26114b83d
[freerainbowtables] / BOINC software / BOINC client apps / distrrtgen_cuda / distrrtgen.cpp
1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 University of California
4 //
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
9 //
10 // BOINC is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17
18 // This program serves as both
19 // - An example BOINC application, illustrating the use of the BOINC API
20 // - A program for testing various features of BOINC
21 //
22 // NOTE: this file exists as both
23 // boinc/apps/upper_case.C
24 // and
25 // boinc_samples/example_app/uc2.C
26 // If you update one, please update the other!
27
28 // The program converts a mixed-case file to upper case:
29 // read "in", convert to upper case, write to "out"
30 //
31 // command line options
32 // -run_slow: sleep 1 second after each character
33 // -cpu_time N: use about N CPU seconds after copying files
34 // -early_exit: exit(10) after 30 chars
35 // -early_crash: crash after 30 chars
36 //
37
38 #ifdef _WIN32
39 #include "boinc_win.h"
40 #else
41 #include "config.h"
42 #include <cstdio>
43 #include <cctype>
44 #include <ctime>
45 #include <cstring>
46 #include <cstdlib>
47 #include <csignal>
48 #include <unistd.h>
49 #endif
50
51 #include <string>
52 #include <fstream>
53 #include <iostream>
54 #include "str_util.h"
55 #include "util.h"
56 #include "filesys.h"
57 #include "boinc_api.h"
58 #include "Public.h"
59 // Rainbowcrack code
60 #include "ChainWalkContext.h"
61 //typedef unsigned int uint32;
62 //typedef unsigned __int64 uint64;
63 #include "rcuda.h"
64 #include "rcuda_ext.h"
65
66
67 using std::string;
68
69 /*
70 bool early_exit = false;
71 bool early_crash = false;
72 bool early_sleep = false;
73 double cpu_time = 20, comp_result;
74 */
75 int QuickSortPartition(RainbowChainCP* pChain, int nLow, int nHigh)
76 {
77         int nRandomIndex = nLow + ((unsigned int)rand() * (RAND_MAX + 1) + (unsigned int)rand()) % (nHigh - nLow + 1);
78         RainbowChainCP TempChain;
79         TempChain = pChain[nLow];
80         pChain[nLow] = pChain[nRandomIndex];
81         pChain[nRandomIndex] = TempChain;
82
83         TempChain = pChain[nLow];
84         uint64 nPivotKey = pChain[nLow].nIndexE;
85         while (nLow < nHigh)
86         {
87                 while (nLow < nHigh && pChain[nHigh].nIndexE >= nPivotKey)
88                         nHigh--;
89                 pChain[nLow] = pChain[nHigh];
90                 while (nLow < nHigh && pChain[nLow].nIndexE <= nPivotKey)
91                         nLow++;
92                 pChain[nHigh] = pChain[nLow];
93         }
94         pChain[nLow] = TempChain;
95         return nLow;
96 }
97
98 void QuickSort(RainbowChainCP* pChain, int nLow, int nHigh)
99 {
100         if (nLow < nHigh)
101         {
102                 int nPivotLoc = QuickSortPartition(pChain, nLow, nHigh);
103                 QuickSort(pChain, nLow, nPivotLoc - 1);
104                 QuickSort(pChain, nPivotLoc + 1, nHigh);
105         }
106 }
107
108 int main(int argc, char **argv) {    
109     int retval;
110     double fd;
111     char output_path[512], chkpt_path[512];
112     FILE* state;        
113     retval = boinc_init();
114     if (retval) {
115         fprintf(stderr, "boinc_init returned %d\n", retval);
116         exit(retval);
117     }
118         
119
120     // get size of input file (used to compute fraction done)
121     //
122     //file_size(input_path, fsize);
123
124     // See if there's a valid checkpoint file.
125     // If so seek input file and truncate output file
126     //
127
128
129         if(argc < 10)
130         {
131                 fprintf(stderr, "Not enough parameters");
132                 return -1;
133         }
134         string sHashRoutineName, sCharsetName, sSalt, sCheckPoints;
135         uint32 nRainbowChainCount, nPlainLenMin, nPlainLenMax, nRainbowTableIndex, nRainbowChainLen;
136         uint64 nChainStart;
137         sHashRoutineName = argv[1];
138         sCharsetName = argv[2];
139         nPlainLenMin = atoi(argv[3]);
140         nPlainLenMax = atoi(argv[4]);
141         nRainbowTableIndex = atoi(argv[5]);
142         nRainbowChainLen = atoi(argv[6]);
143         nRainbowChainCount = atoi(argv[7]);
144 #ifdef _WIN32
145
146         nChainStart = _atoi64(argv[8]);
147
148 #else
149         nChainStart = atoll(argv[8]);
150 #endif
151         sCheckPoints = argv[9];
152         vector<int> vCPPositions;
153         char *cp = strtok((char *)sCheckPoints.c_str(), ",");
154         while(cp != NULL)
155         {
156                 vCPPositions.push_back(atoi(cp));
157                 cp = strtok(NULL, ",");
158         }
159         if(argc == 11)
160         {
161                 sSalt = argv[10];
162         }
163         //std::cout << "Starting ChainGenerator" << std::endl;
164         // Setup CChainWalkContext
165         //std::cout << "ChainGenerator started." << std::endl;
166
167         if (!CChainWalkContext::SetHashRoutine(sHashRoutineName))
168         {
169                 fprintf(stderr, "hash routine %s not supported\n", sHashRoutineName.c_str());
170                 return 1;
171         }
172         //std::cout << "Hash routine validated" << std::endl;
173
174         if (!CChainWalkContext::SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))
175         {       
176                 std::cerr << "charset " << sCharsetName << " not supported" << std::endl;
177                 return 2;
178         }
179         //std::cout << "Plain charset validated" << std::endl;
180
181         if (!CChainWalkContext::SetRainbowTableIndex(nRainbowTableIndex))
182         {
183                 std::cerr << "invalid rainbow table index " << nRainbowTableIndex << std::endl;
184                 return 3;
185         }
186         //std::cout << "Rainbowtable index validated" << std::endl;
187
188         if(sHashRoutineName == "mscache")// || sHashRoutineName == "lmchall" || sHashRoutineName == "halflmchall")
189         {
190                 // Convert username to unicode
191                 const char *szSalt = sSalt.c_str();
192                 int salt_length = strlen(szSalt);
193                 unsigned char cur_salt[256];
194                 for (int i=0; i<salt_length; i++)
195                 {
196                         cur_salt[i*2] = szSalt[i];
197                         cur_salt[i*2+1] = 0x00;
198                 }
199                 CChainWalkContext::SetSalt(cur_salt, salt_length*2);
200         }
201         else if(sHashRoutineName == "halflmchall")
202         { // The salt is hardcoded into the hash routine
203         //      CChainWalkContext::SetSalt((unsigned char*)&salt, 8);
204         }
205         else if(sHashRoutineName == "oracle")
206         {
207                 CChainWalkContext::SetSalt((unsigned char *)sSalt.c_str(), sSalt.length());
208         }
209         //std::cout << "Opening chain file" << std::endl;
210
211         
212         // Open file
213 //      fclose(fopen(sFilename.c_str(), "a"));
214 //      FILE* file = fopen(sFilename.c_str(), "r+b");
215     boinc_resolve_filename("result", output_path, sizeof(output_path));
216         fclose(boinc_fopen(output_path, "a"));
217         FILE *outfile = boinc_fopen(output_path, "r+b");
218         
219         if (outfile == NULL)
220         {
221                 std::cerr << "failed to create " << output_path << std::endl;
222                 return 4;
223         }
224         
225         
226         // Check existing chains
227         unsigned int nDataLen = (unsigned int)GetFileLen(outfile);
228         unsigned int nFileLen;
229         
230         // Round to boundary
231         nDataLen = nDataLen / 18 * 18;
232         if ((int)nDataLen == nRainbowChainCount * 18)
233         {               
234                 std::cerr << "precomputation of this rainbow table already finished" << std::endl;
235                 fclose(outfile);
236                 return 0;
237         }
238
239         fseek(outfile, nDataLen, SEEK_SET);
240         size_t nReturn;
241         CChainWalkContext cwc;
242         uint64 nIndex[2];
243
244 //      std::cout << "Starting to generate chains" << std::endl;
245         int maxCalcBuffSize = rcuda::GetChainsBufferSize(5000);
246         uint64 *calcBuff = new uint64[2*maxCalcBuffSize];
247         int ii;
248
249         CudaCWCExtender ex(&cwc);
250         rcuda::RCudaTask cuTask;
251         std::vector<unsigned char> stPlain;
252         ex.Init();
253 time_t tStart, tStartFinal, tEndFinal;
254 time_t tEnd;
255         tStartFinal = time(NULL);
256         for(int nCurrentCalculatedChains = nDataLen / 18, calcSize; nCurrentCalculatedChains < nRainbowChainCount; )
257         {               
258                 fd = (double)nCurrentCalculatedChains / (double)nRainbowChainCount;
259                 boinc_fraction_done(fd);
260
261                 cuTask.hash = ex.GetHash();
262                 cuTask.startIdx = nChainStart + nCurrentCalculatedChains;
263                 cuTask.idxCount = std::min<int>(nRainbowChainCount - nCurrentCalculatedChains, maxCalcBuffSize);
264                 cuTask.stPlainSize = ex.IndexToStartPlain(0, stPlain);
265                 cuTask.stPlain = &stPlain[0];
266                 cuTask.dimVec = ex.GetPlainDimVec();
267                 cuTask.dimVecSize = ex.GetPlainDimVecSize()/3;
268                 cuTask.charSet = ex.GetCharSet();
269                 cuTask.charSetSize = ex.GetCharSetSize();
270                 cuTask.cpPositions = &vCPPositions[0];
271                 cuTask.cpPosSize = vCPPositions.size();
272                 cuTask.reduceOffset = ex.GetReduceOffset();
273                 cuTask.plainSpaceTotal = ex.GetPlainSpaceTotal();
274                 cuTask.rainbowChainLen = nRainbowChainLen;
275                 for(int ii = 0; ii < cuTask.idxCount; ii++) {
276                         calcBuff[2*ii] = cuTask.startIdx + ii;
277                         calcBuff[2*ii+1] = 0;
278                 }
279
280                 tStart = time(NULL);
281
282                 calcSize = rcuda::CalcChainsOnCUDA(&cuTask, calcBuff);
283                 tEnd = time(NULL);
284                 std::cerr << "CUDA time taken: " << tEnd - tStart << std::endl;
285                 tStart = time(NULL);
286                 if(calcSize > 0) {
287                         nCurrentCalculatedChains += calcSize;
288                         for(ii = 0; ii < cuTask.idxCount; ii++) {
289                                 nIndex[0] = cuTask.startIdx + ii;
290                                 nReturn = fwrite(nIndex, 1, 8, outfile);
291                                 nReturn += fwrite(calcBuff+(2*ii), 1, 8, outfile);
292                                 nReturn += fwrite(calcBuff+(2*ii+1), 1, 2, outfile);
293                                 if(nReturn != 18) {
294                                         std::cerr << "disk write fail" << std::endl;
295                                         fclose(outfile);
296                                         return 9;
297                                 }
298                         }
299                 } else {
300                         std::cerr << "Calculations on CUDA failed!" << std::endl;
301                         fclose(outfile);
302                         return 0;
303                 }
304         }
305         tEndFinal = time(NULL);
306         std::cerr << "Time taken: " << tEndFinal - tStartFinal << " secs" << std::endl;
307         delete [] calcBuff;
308 #ifdef _DEBUG
309         std::cout << "Generation completed" << std::endl;
310 #endif
311     fseek(outfile, 0, SEEK_SET);
312         nFileLen = GetFileLen(outfile);
313         nRainbowChainCount = nFileLen / 18;
314
315         RainbowChainCP* pChain = (RainbowChainCP*)new unsigned char[sizeof(RainbowChainCP) * nRainbowChainCount];
316
317         if (pChain != NULL)
318         {
319                 // Load file
320 #ifdef _DEBUG
321         std::cout << "Sorting file" << std::endl;
322 #endif
323                 fseek(outfile, 0, SEEK_SET);
324                 for(int i = 0; i < nRainbowChainCount; i++)
325                 {
326                         if(fread(&pChain[i], 1, 16, outfile) != 16)
327                         {
328                                 printf("disk read fail\n");
329                                 return 9;
330                         }
331                         if(fread(&pChain[i].nCheckPoint, 1, sizeof(pChain[i].nCheckPoint), outfile) != 2)
332                         {
333                                 printf("disk read fail\n");
334                                 return 9;
335                         }
336                 }
337
338                 // Sort file
339                 QuickSort(pChain, 0, nRainbowChainCount - 1);
340
341                 // Write file
342                 fseek(outfile, 0, SEEK_SET);
343                 for(int i = 0; i < nRainbowChainCount; i++)
344                 {
345                         fwrite(&pChain[i], 1, 16, outfile);
346                         fwrite(&pChain[i].nCheckPoint, 2, 1, outfile);
347                 }
348                 delete[] pChain;
349         }
350
351         fclose(outfile);
352     
353         // main loop - read characters, convert to UC, write
354     //
355
356     boinc_fraction_done(1);
357     boinc_finish(0);
358 }
359
360 #ifdef _WIN32
361 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) {
362     LPSTR command_line;
363     char* argv[100];
364     int argc;
365
366     command_line = GetCommandLine();
367     argc = parse_command_line( command_line, argv );
368     return main(argc, argv);
369 }
370 #endif
371
372 const char *BOINC_RCSID_33ac47a071 = "$Id: upper_case.C 12135 2007-02-21 20:04:14Z davea $";
373