]> git.sesse.net Git - freerainbowtables/blob - BOINC software/BOINC client apps/distrrtgen/distrrtgen.cpp
527151206f67e6bc8e786ad0b4cf941843d4a116
[freerainbowtables] / BOINC software / BOINC client apps / distrrtgen / 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
64
65 using std::string;
66
67 /*
68 bool early_exit = false;
69 bool early_crash = false;
70 bool early_sleep = false;
71 double cpu_time = 20, comp_result;
72 */
73 int QuickSortPartition(RainbowChainCP* pChain, int nLow, int nHigh)
74 {
75         int nRandomIndex = nLow + ((unsigned int)rand() * (RAND_MAX + 1) + (unsigned int)rand()) % (nHigh - nLow + 1);
76         RainbowChainCP TempChain;
77         TempChain = pChain[nLow];
78         pChain[nLow] = pChain[nRandomIndex];
79         pChain[nRandomIndex] = TempChain;
80
81         TempChain = pChain[nLow];
82         uint64 nPivotKey = pChain[nLow].nIndexE;
83         while (nLow < nHigh)
84         {
85                 while (nLow < nHigh && pChain[nHigh].nIndexE >= nPivotKey)
86                         nHigh--;
87                 pChain[nLow] = pChain[nHigh];
88                 while (nLow < nHigh && pChain[nLow].nIndexE <= nPivotKey)
89                         nLow++;
90                 pChain[nHigh] = pChain[nLow];
91         }
92         pChain[nLow] = TempChain;
93         return nLow;
94 }
95
96 void QuickSort(RainbowChainCP* pChain, int nLow, int nHigh)
97 {
98         if (nLow < nHigh)
99         {
100                 int nPivotLoc = QuickSortPartition(pChain, nLow, nHigh);
101                 QuickSort(pChain, nLow, nPivotLoc - 1);
102                 QuickSort(pChain, nPivotLoc + 1, nHigh);
103         }
104 }
105
106 int main(int argc, char **argv) {    
107     int retval;
108     double fd;
109     char output_path[512], chkpt_path[512];
110     FILE* state;        
111     retval = boinc_init();
112     if (retval) {
113         fprintf(stderr, "boinc_init returned %d\n", retval);
114         exit(retval);
115     }
116         
117
118     // get size of input file (used to compute fraction done)
119     //
120     //file_size(input_path, fsize);
121
122     // See if there's a valid checkpoint file.
123     // If so seek input file and truncate output file
124     //
125
126
127         if(argc < 10)
128         {
129                 fprintf(stderr, "Not enough parameters");
130                 return -1;
131         }
132         string sHashRoutineName, sCharsetName, sSalt, sCheckPoints;
133         uint32 nRainbowChainCount, nPlainLenMin, nPlainLenMax, nRainbowTableIndex, nRainbowChainLen;
134         uint64 nChainStart;
135         sHashRoutineName = argv[1];
136         sCharsetName = argv[2];
137         nPlainLenMin = atoi(argv[3]);
138         nPlainLenMax = atoi(argv[4]);
139         nRainbowTableIndex = atoi(argv[5]);
140         nRainbowChainLen = atoi(argv[6]);
141         nRainbowChainCount = atoi(argv[7]);
142 #ifdef _WIN32
143
144         nChainStart = _atoi64(argv[8]);
145
146 #else
147         nChainStart = atoll(argv[8]);
148 #endif
149         sCheckPoints = argv[9];
150         vector<int> vCPPositions;
151         char *cp = strtok((char *)sCheckPoints.c_str(), ",");
152         while(cp != NULL)
153         {
154                 vCPPositions.push_back(atoi(cp));
155                 cp = strtok(NULL, ",");
156         }
157         if(argc == 11)
158         {
159                 sSalt = argv[10];
160         }
161         //std::cout << "Starting ChainGenerator" << std::endl;
162         // Setup CChainWalkContext
163         //std::cout << "ChainGenerator started." << std::endl;
164
165         if (!CChainWalkContext::SetHashRoutine(sHashRoutineName))
166         {
167                 fprintf(stderr, "hash routine %s not supported\n", sHashRoutineName.c_str());
168                 return 1;
169         }
170         //std::cout << "Hash routine validated" << std::endl;
171
172         if (!CChainWalkContext::SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))
173         {       
174                 std::cerr << "charset " << sCharsetName << " not supported" << std::endl;
175                 return 2;
176         }
177         //std::cout << "Plain charset validated" << std::endl;
178
179         if (!CChainWalkContext::SetRainbowTableIndex(nRainbowTableIndex))
180         {
181                 std::cerr << "invalid rainbow table index " << nRainbowTableIndex << std::endl;
182                 return 3;
183         }
184         //std::cout << "Rainbowtable index validated" << std::endl;
185
186         if(sHashRoutineName == "mscache")// || sHashRoutineName == "lmchall" || sHashRoutineName == "halflmchall")
187         {
188                 // Convert username to unicode
189                 const char *szSalt = sSalt.c_str();
190                 int salt_length = strlen(szSalt);
191                 unsigned char cur_salt[256];
192                 for (int i=0; i<salt_length; i++)
193                 {
194                         cur_salt[i*2] = szSalt[i];
195                         cur_salt[i*2+1] = 0x00;
196                 }
197                 CChainWalkContext::SetSalt(cur_salt, salt_length*2);
198         }
199         else if(sHashRoutineName == "halflmchall")
200         { // The salt is hardcoded into the hash routine
201         //      CChainWalkContext::SetSalt((unsigned char*)&salt, 8);
202         }
203         else if(sHashRoutineName == "oracle")
204         {
205                 CChainWalkContext::SetSalt((unsigned char *)sSalt.c_str(), sSalt.length());
206         }
207         //std::cout << "Opening chain file" << std::endl;
208
209         
210         // Open file
211 //      fclose(fopen(sFilename.c_str(), "a"));
212 //      FILE* file = fopen(sFilename.c_str(), "r+b");
213     boinc_resolve_filename("result", output_path, sizeof(output_path));
214         fclose(boinc_fopen(output_path, "a"));
215         FILE *outfile = boinc_fopen(output_path, "r+b");
216         
217         if (outfile == NULL)
218         {
219                 std::cerr << "failed to create " << output_path << std::endl;
220                 return 4;
221         }
222         
223         
224         // Check existing chains
225         unsigned int nDataLen = (unsigned int)GetFileLen(outfile);
226         unsigned int nFileLen;
227         
228         // Round to boundary
229         nDataLen = nDataLen / 18 * 18;
230         if ((int)nDataLen == nRainbowChainCount * 18)
231         {               
232                 std::cerr << "precomputation of this rainbow table already finished" << std::endl;
233                 fclose(outfile);
234                 return 0;
235         }
236         nChainStart += (nDataLen / 18);
237         fseek(outfile, nDataLen, SEEK_SET);
238         size_t nReturn;
239         CChainWalkContext cwc;
240         uint64 nIndex[2];
241         time_t tStart = time(NULL);
242 //      std::cout << "Starting to generate chains" << std::endl;
243         for(int nCurrentCalculatedChains = nDataLen / 18; nCurrentCalculatedChains < nRainbowChainCount; nCurrentCalculatedChains++)
244         {               
245                 int cpcheck = 0;
246                 unsigned short checkpoint = 0;
247                 fd = (double)nCurrentCalculatedChains / (double)nRainbowChainCount;
248                 boinc_fraction_done(fd);
249                 cwc.SetIndex(nChainStart++); // use a given index now!
250                 nIndex[0] = cwc.GetIndex();
251                 
252                 for (int nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
253                 {
254                 //      std::cout << "IndexToPlain()" << std::endl;
255                         cwc.IndexToPlain();
256                 //      std::cout << "PlainToHash()" << std::endl;
257                         cwc.PlainToHash();
258                 //      std::cout << "HashToIndex()" << std::endl;
259                         cwc.HashToIndex(nPos);
260                         if(cpcheck < vCPPositions.size() && nPos == vCPPositions[cpcheck])
261                         {
262                                 
263                                 checkpoint |= (1 << cpcheck) & (unsigned short)cwc.GetIndex() << cpcheck;
264                                 cpcheck++;
265                         }
266                 }
267                 //std::cout << "GetIndex()" << std::endl;
268
269                 nIndex[1] = cwc.GetIndex();
270                 // Write chain to disk
271                 if ((nReturn = fwrite(nIndex, 1, 16, outfile)) != 16)
272                 {
273                         std::cerr << "disk write fail" << std::endl;
274                         fclose(outfile);
275                         return 9;
276                 }
277                 if((nReturn = fwrite(&checkpoint, 1, 2, outfile)) != 2)
278                 {
279                         std::cerr << "disk write fail" << std::endl;
280                         fclose(outfile);
281                         return 9;
282                 }
283 //              fflush(file);
284         }
285         //std::cout << "Generation completed" << std::endl;
286     fseek(outfile, 0, SEEK_SET);
287         nFileLen = GetFileLen(outfile);
288         nRainbowChainCount = nFileLen / 18;
289
290         RainbowChainCP* pChain = (RainbowChainCP*)new unsigned char[sizeof(RainbowChainCP) * nRainbowChainCount];
291
292         if (pChain != NULL)
293         {
294                 // Load file
295                 fseek(outfile, 0, SEEK_SET);
296                 for(int i = 0; i < nRainbowChainCount; i++)
297                 {
298                         if(fread(&pChain[i], 1, 16, outfile) != 16)
299                         {
300                                 printf("disk read fail\n");
301                                 return 9;
302                         }
303                         if(fread(&pChain[i].nCheckPoint, 1, sizeof(pChain[i].nCheckPoint), outfile) != 2)
304                         {
305                                 printf("disk read fail\n");
306                                 return 9;
307                         }
308                 }
309
310                 // Sort file
311                 QuickSort(pChain, 0, nRainbowChainCount - 1);
312
313                 // Write file
314                 fseek(outfile, 0, SEEK_SET);
315                 for(int i = 0; i < nRainbowChainCount; i++)
316                 {
317                         fwrite(&pChain[i], 1, 16, outfile);
318                         fwrite(&pChain[i].nCheckPoint, 2, 1, outfile);
319                 }
320                 delete[] pChain;
321         }
322
323         fclose(outfile);
324     
325         // main loop - read characters, convert to UC, write
326     //
327
328     boinc_fraction_done(1);
329     boinc_finish(0);
330 }
331
332 #ifdef _WIN32
333 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) {
334     LPSTR command_line;
335     char* argv[100];
336     int argc;
337
338     command_line = GetCommandLine();
339     argc = parse_command_line( command_line, argv );
340     return main(argc, argv);
341 }
342 #endif
343
344 const char *BOINC_RCSID_33ac47a071 = "$Id: upper_case.C 12135 2007-02-21 20:04:14Z davea $";
345