Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/mty-makai/mty.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 238 - (show annotations) (download) (as text)
Wed Feb 17 09:26:53 2010 UTC (14 years, 1 month ago) by notanpe
File MIME type: text/x-csrc
File size: 51849 byte(s)
キー空間ロギングを target.txt のオプションにした
1 /***********************************************************************
2 *
3 * file: mty.c
4 *
5 * ‚Ü‚ A‘Ň‚Ä‰ŽB
6 *
7 * $Id$
8 *
9 */
10
11 #include <assert.h>
12 #include <ctype.h>
13 #include <errno.h>
14 #include <limits.h>
15 #include <stdarg.h>
16 #include <stddef.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <time.h>
21 #include <sys/timeb.h>
22 #include <sys/types.h>
23
24 #include <unistd.h>
25 #include <libgen.h>
26 #include <limits.h>
27 #ifdef REON
28 #ifdef ONI
29 #include <onigposix.h>
30 #else /* ONI */
31 /* #include <rxposix.h> */
32 #include <regex.h>
33 #endif /* ONI */
34 #endif /* REON */
35
36 #if defined(WIN32)
37
38 #include <windows.h>
39 #include <process.h>
40
41 #elif defined(__GNUC__)
42
43 #include <sys/time.h>
44
45 #endif
46
47 #include "config.h"
48 #include "cp932.h"
49 #include "crypt64.h"
50 #include "desconst.h"
51 #include "expr_parse.h"
52 #include "scoreboard.h"
53 #include "synth.h"
54 #include "tr64.h"
55 #include "translate.h"
56 #include "util.h"
57 #include "wdict.h"
58
59 #define TRIP_LEN 10
60
61 #define MAKAI_TRUE 1
62 #define MAKAI_FALSE 0
63
64 #define MIN_THREAD 1
65 #define MAX_THREAD 32
66 int nThread = 0;
67 uint64_t pmask = 0;
68
69 #define MIN_UME 3
70 #define MAX_UME 6
71 unsigned char umeStr[10];
72 int umeLen;
73
74 FILE *nfp; /* ‘S” */
75 FILE *cfp; /* ‚ż */
76 FILE *tfp; /* ŞˆČŠO‚Ě“ÁŽęŒŸő */
77 #ifdef REON
78 FILE *rfp; /* ł‹K•\Œť */
79 #endif /* REON */
80
81 /*
82 Cygwin 32bit
83 time_t = long = int
84 INT_MIN -2147483648
85 INT_MAX 2147483647
86 (2009 - 1970) * 365 * 24 * 60 * 60 = 1229904000
87 2147483647 - 1229904000 = 917579647
88 10y * 365 * 24 * 60 * 60 = 315360000
89
90 perl -e 'use POSIX;printf(strftime("%Y/%m/%d %T\n",localtime (1234567890)));'
91 */
92 #define MIN_SOFF -1229904000
93 #define MAX_SOFF 315360000
94 unsigned int seed;
95 int seedOffset;
96 int verbose;
97
98 #define MAX_GEAR 10
99 #define MIN_GEAR 1
100 #define DEF_GEAR 10
101 int gear;
102
103 #ifdef KEYLOG
104 #define KEY_LOG_FILE "keylog.txt"
105 int keyLog = MAKAI_FALSE;
106 #endif /* KEYLOG */
107
108 #ifdef SELF
109 #define SELF_LIM_CNT 50
110 #define SELF_LIM_SEC 60 * 60 * 1000 /* 1h */
111 #endif /* SELF */
112
113 unsigned char saltChar[2];
114
115 #ifdef ALLKEY
116 unsigned char fixedSaltChar[2];
117 #endif /* ALLKEY */
118
119 /* CRYPT64 ‹LqŽq */
120 static
121 struct CRYPT64_DESC const *const crypt64_descs[] =
122 {
123 &crypt64_desc,
124 };
125
126 /* ŒŽƒNƒ‰ƒX */
127 static
128 struct
129 {
130 unsigned short map[256];
131 } kcls[8 + 8];
132
133 /* Šg’ŁŒŽƒNƒ‰ƒX */
134 #define KCLS_DT0 64
135 #define KCLS_DT1 128
136 #define KCLS_K2 256
137
138 int special = 0;
139 #define ST_ALLN 1 /* ‘S” */
140 #define ST_NIKO 1<<0x1 /* “ń\ */
141 #define ST_BUOO 1<<0x8 /* ‚Ô‚¨ */
142 #define ST_DOSU 1<<0x9 /* “{” */
143 #define ST_CHIN 1<<0xb /* ‚ż‚ń Uni ‚ł͊´’Q—p‚Ěƒtƒ‰ƒO */
144 #define ST_EROI 1<<0xc /* ƒGƒ Uni ‚ł͊g”ň‚Ěƒtƒ‰ƒO */
145 #define ST_HREN 1<<0xd /* ”ň˜A */
146 #define ST_YAKU 1<<0xe /* ”މ_ */
147
148 #ifdef REON
149 #define REGEXPLEN 1024
150 char regExpStr[REGEXPLEN];
151 regex_t regExp;
152 #endif /* REON */
153
154 void
155 comment( str )
156 char *str;
157 {
158 if ( strlen( str ) >= 4 ) {
159 if ( str[1] == '[' && str[3] == ']' ) {
160 switch ( str[2] ) {
161 case '0': special |= ST_ALLN; break;
162 case '1': special |= ST_NIKO; break;
163 case '8': special |= ST_BUOO; break;
164 case '9': special |= (ST_DOSU | ST_ALLN); break;
165 case 'd': special |= ST_HREN; break;
166 case 'e': special |= ST_YAKU; break;
167 case 'Y': special |= ST_CHIN; break;
168 case 'Z': special |= ST_EROI; break;
169 #ifdef KEYLOG
170 case 'K': keyLog = MAKAI_TRUE; break;
171 #endif /* KEYLOG */
172 case 'S':
173 seedOffset = atoi( str + 4 );
174 if ( seedOffset < MIN_SOFF || seedOffset > MAX_SOFF ) {
175 fprintf( stderr, "—”‚ĚŽí‚ĚƒIƒtƒZƒbƒg‚́A%d ˆČă %d ˆČ‰ş‚ĹŽw’肾‚ĂˁB\n", MIN_SOFF, MAX_SOFF );
176 fprintf( stderr, "%d ‚͔͈͊O‚Ȃ̂ŖłŽ‹‚ľ‚Ü‚ˇB\n", seedOffset );
177 seedOffset = 0;
178 }
179 break;
180 case 'R':
181 #ifdef REON
182 if ( strlen( str ) >= REGEXPLEN ) {
183 fprintf( stderr, "ł‹K•\Œť (%s) ‚Ş’ˇ‚ˇ‚Ź", str );
184 exit( 1 );
185 }
186 strcpy( regExpStr, str + 4 );
187 if ( regcomp( &regExp, regExpStr, REG_NOSUB|REG_EXTENDED ) != 0 ) {
188 fprintf( stderr, "ł‹K•\Œť (%s) ‚Ş‚¨‚Š‚ľ‚˘H\n", str );
189 exit( 1 );
190 }
191 #else /* REON */
192 fprintf( stderr, "‚ą‚ĚƒoƒCƒiƒŠ‚́Ał‹K•\Œť‚đƒTƒ|[ƒg‚ľ‚Ä‚˘‚Ü‚š‚ńB\n" );
193 fprintf( stderr, "%s ‚Í–łŽ‹‚ľ‚Ü‚ˇB\n", str );
194 #endif /* REON */
195 break;
196 }
197 }
198 }
199 }
200
201 #ifndef ALLKEY
202 /* Žw’肳‚ę‚˝ƒNƒ‰ƒX‚Ć“ü‚Á‚Ä‚˘‚éƒL[‚Š‚çAclassify ‚đs‚¤ */
203 void
204 key_make_map(uint8_t *key, int n)
205 {
206 int i, j;
207 unsigned c = kcls[n].map[key[n]];
208
209 /* ĹŒă‚Ě•”•Ş‚Í class map ‚đśŹ‚ˇ‚é•K—vƒiƒV */
210 /* MAKAI memo
211 6byte –„‚ß‚˝Žž‚Ě‹““Ž
212 ‰ş‚Ě•ű‚Ě if (n == 6) ‚Ć–ľ‚
213 */
214 if ( n >= 6 ) return;
215
216 for ( i = 0; i < 256; i++ ) {
217 unsigned bm = 0;
218 if ( c & KCLS_K1 ) {
219 if ( cp932[256 * key[n] + i] & KCLS_K1 ) {
220 bm |= KCLS_K2 | (cp932[256 * key[n] + i] & KCLS_DT1);
221 }
222 if ( cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1 ) {
223 bm |= KCLS_K2 | (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_DT1);
224 }
225 }
226 if ( c & (KCLS_AN | KCLS_KA | KCLS_K2) ) {
227 for ( j = 0; j < 256; j++ ) {
228 bm |= cp932[256 * i + j] & (KCLS_AN | KCLS_KA | KCLS_K1 | KCLS_DT0);
229 }
230 }
231 kcls[n + 1].map[i] = bm;
232 if ( i >= 128 && !(n == 0 || n == 1) ) {
233 kcls[n + 1].map[i - 128] |= kcls[n + 1].map[i];
234 }
235 }
236
237 if ( n < 6 ) kcls[n + 1].map[0x00] = kcls[n + 1].map[0x80] = 0;
238 #if 0
239 if ( n == 6 ) kcls[7].map[0x00] |= KCLS_AN;
240 #endif /* 0 */
241 }
242 #endif /* not ALLKEY */
243
244 /* ƒ}ƒbƒv‚Š‚ç•śŽš‚đE‚Á‚ăZƒbƒg */
245 unsigned
246 key_set(int n, unsigned ch)
247 {
248 int cnt = 0, i;
249
250 #ifdef NOMORE
251 ch %= 256;
252 #endif /* NOMORE */
253
254 for ( i = 0; i < 256; i++ ) {
255 if ( kcls[n].map[i] ) {
256 if ( ch-- == 0 ) return i;
257 cnt++;
258 }
259 if ( n != 1 && n != 2 && i >= 127 ) break;
260 }
261 /* ŒŠ‚Â‚Š‚ç‚ȂЂÁ‚˝‚Ě‚Ĺ‚ŕ‚˘‚Á‚Ř‚ń */
262 assert( cnt > 0 );
263 ch %= cnt;
264 for ( i = 0; i < 256; i++ ) {
265 if ( kcls[n].map[i] ) {
266 if ( ch-- == 0 ) return i;
267 }
268 }
269 assert( !"not matched" );
270 return 0;
271 }
272
273 /* bitwise key ‚đƒZƒbƒg */
274 static
275 void
276 key_set64(struct KEY *key64,
277 int n,
278 unsigned k,
279 unsigned vk,
280 unsigned sk)
281 {
282 int i, j;
283 if (!((vk | sk) & 0x7F))
284 return;
285
286 for (i = 0; i < 7; i++)
287 {
288 if (n == 7 && i < N_STRIDE) continue;
289 if (sk & (1 << i))
290 {
291 /* ƒZƒbƒg */
292 int o = tr_pc1[n][6 - i] - 1;
293 if (o < 28)
294 {
295 assert(o >= 0);
296 for (j = 0; j < N_ALU; j++)
297 key64->k[0][0][o].a[j]
298 = key64->k[0][1][o].a[j]
299 = -!!(k & (1 << i));
300 }
301 else
302 {
303 assert(o >= 28);
304 assert(o < 56);
305 for (j = 0; j < N_ALU; j++)
306 key64->k[1][0][o - 28].a[j]
307 = key64->k[1][1][o - 28].a[j]
308 = -!!(k & (1 << i));
309 }
310 }
311 else if (vk & (1 << i))
312 {
313 /* ”˝“] */
314 int o = tr_pc1[n][6 - i] - 1;
315 if (o < 28)
316 {
317 assert(o >= 0);
318 for (j = 0; j < N_ALU; j++)
319 key64->k[0][0][o].a[j]
320 = key64->k[0][1][o].a[j]
321 = ~key64->k[0][0][o].a[j];
322 }
323 else
324 {
325 assert(o >= 28);
326 assert(o < 56);
327 for (j = 0; j < N_ALU; j++)
328 key64->k[1][0][o - 28].a[j]
329 = key64->k[1][1][o - 28].a[j]
330 = ~key64->k[1][0][o - 28].a[j];
331 }
332 }
333 }
334 }
335
336 /* Žw’肳‚ę‚˝ƒNƒ‰ƒX‚ĚŠJŽn’l‚ÉƒŠƒZƒbƒg
337 ’ź‘O‚Ě•śŽš‚ĚƒNƒ‰ƒX‚É”›‚ç‚ę‚é */
338 int
339 key_reset(uint8_t *key, int n)
340 {
341 static char firstCall = 1;
342
343 if ( firstCall ) {
344 firstCall = 0;
345 } else {
346 if ( umeStr[0] != '\0' && n == 0 ) {
347 exit( 0 );
348 }
349 }
350
351 if (n >= 8)
352 return 1;
353 if (n == 7)
354 {
355 key[7] = 0;
356 return 1;
357 }
358
359 if ( n >= umeLen ) {
360 #ifdef ALLKEY
361 for ( ; n < 7; n++ ) {
362 key[n] = 1;
363 }
364 key[7] = 0;
365 return 1;
366 #else /* ALLKEY */
367 key[n] = key_set(n, 0);
368 #endif /* ALLKEY */
369 } else {
370 if ( umeStr[0] == '\0' ) {
371 #ifdef ALLKEY
372 key[n] = rand() % 0x7f + 1;
373 #else /* ALLKEY */
374 key[n] = key_set(n, rand());
375 #endif /* ALLKEY */
376 } else {
377 key[n] = umeStr[n];
378 }
379 #ifdef KEYLOG
380 /* ŒŸő‹óŠÔ‚Ě‹L˜^ */
381 if ( keyLog && (n == umeLen - 1) ) {
382 FILE *fp;
383 int i;
384 struct timeb tb;
385 struct tm *plt;
386
387 ftime( &tb );
388 plt = localtime( &tb.time );
389
390 #ifdef OLDDEBUG
391 printf( "\n‚ť‚§[‚é‚Ć‚ż‚Ľ[‚ń‚śI\n" );
392 #endif /* DEBUG */
393 if ( (fp = fopen( KEY_LOG_FILE, "at" )) == NULL ) {
394 perror( KEY_LOG_FILE );
395 exit( 1 );
396 }
397 for ( i = 0; i < umeLen; i++ ) {
398 fprintf( fp, "%02x", key[i] );
399 }
400 fprintf( fp, "\t%04d/%02d/%02d %02d:%02d:%02d.%03d\n",
401 plt->tm_year + 1900, plt->tm_mon + 1, plt->tm_mday,
402 plt->tm_hour, plt->tm_min, plt->tm_sec, tb.millitm );
403 fclose( fp );
404 }
405 #endif /* KEYLOG */
406 }
407
408 #if DEBUG>=3
409 printf("key[%d]=%02X ncls=%04X\n", n, key[n], kcls[n].map[key[n]]);
410 #endif
411
412 #ifndef ALLKEY
413 /* ƒZƒbƒg‚ł‚ę‚˝•śŽš‚đŒł‚ÉAŽŸƒLƒƒƒ‰‚Ě•śŽšƒNƒ‰ƒX‚đŒˆ‚ß‚é */
414 key_make_map(key, n);
415 #endif /* not ALLKEY */
416
417 return key_reset(key, n + 1);
418 }
419
420 /* Žw’肳‚ę‚˝ŒŽ‹óŠÔ‚Ě’†‚ŁAƒL[‚đ‚ЂƂi‚ß‚é
421 ˆŔ‘S‚ɃCƒ“ƒNƒŠƒƒ“ƒg‚Ĺ‚Ť‚˝ę‡ true ‚đ•Ô‚ˇ */
422 static
423 int
424 key_inc(uint8_t *key, int n)
425 {
426 #if 0
427 if ( n != 7 ) {
428 printf( "%d : %02x %02x %02x %02x %02x %02x %02x %02x\n",
429 n, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7] );
430 }
431 #endif /* 0 */
432
433 if ( n >= 8 ) {
434 return 0;
435 } else if ( n == 7 ) {
436 /* MAKAI memo
437 2^N_STRIDE ‚Ş‚˘‚Á‚Ř‚ń‚ÉŒvŽZ‚ˇ‚éŒÂ”
438 MMX 6 : 64 ŒÂ
439 SSE2 7 : 128 ŒÂ
440 ‚ą‚Ě‚˝‚ßĹŒă‚ĚƒoƒCƒg‚̐i‚ß•ű‚Ş•Ď‚í‚é
441 */
442 uint8_t o_k = (key[7] + (1 << N_STRIDE)) & 0x7F;
443 if ( !o_k ) {
444 return 0; /* ƒCƒ“ƒNƒŠƒƒ“ƒg‚Ĺ‚Ť‚ȂЂÁ‚˝‚Ć‚Ť‚ÍŽŸ‚֐i‚ß‚¸‘҂ */
445 } else {
446 key[7] = o_k;
447 return 1;
448 }
449 } else if ( key_inc( key, n+1 ) ) {
450 return 1;
451 }
452
453 /* Salt ‚̓Cƒ“ƒNƒŠƒƒ“ƒg‚ľ‚Č‚˘–ń‘Ђɂˇ‚é */
454 if ( n == 1 || n == 2 ) {
455 return 1;
456 }
457
458 #ifdef ALLKEY
459 key[n] = ( key[n] & 0x7F ) + 1;
460 if ( key[n] >= 0x80 ) {
461 key[n] = 0xFF; /* ŽŸ‚ɓ˓ü‚ł‚š‚Č‚˘‚˝‚ß */
462 return 0;
463 }
464 key_reset( key, n + 1 );
465 return 1;
466 #endif /* ALLKEY */
467
468 /* ŽŔŰ‚É‘‚₾‚Ă݂é */
469 assert( n >= 3 );
470 for ( ;; ) {
471 if (n <= 3
472 && !(key[n] & 0x80)
473 && kcls[n].map[key[n] ^ 0x80] & (KCLS_DT0))
474 {
475 /* ”źŠpƒJƒ^ƒJƒi‚Ě1ƒoƒCƒg–Ú */
476 key[n] ^= 0x80;
477 }
478 else
479 {
480 key[n] = (key[n] & 0x7F) + 1;
481 if (key[n] >= 0x80)
482 {
483 key[n] = 0xFF; /* ŽŸ‚ɓ˓ü‚ł‚š‚Č‚˘‚˝‚ß */
484 return 0;
485 }
486 }
487
488 if (kcls[n].map[key[n]])
489 {
490 #ifndef ALLKEY
491 key_make_map(key, n);
492 #endif /* not ALLKEY */
493 key_reset(key, n + 1);
494 return 1;
495 }
496 }
497 }
498
499 /* ŒŽ‚đŠŽ‘S‚ÉƒŠƒZƒbƒg‚ˇ‚é
500 Salt‚ŕƒZƒbƒg‚ľ’ꂎ */
501 static
502 void
503 key_init(uint8_t *key)
504 {
505 int i, j;
506
507 key[8] = 0;
508
509 #ifndef ALLKEY
510 /* ‰Šúƒ}ƒbƒv‚đ‘g‚Ţ */
511 for ( i = 0; i < 256; i++ ) {
512 unsigned bm = 0;
513
514 for ( j = 0; j < 256; j++ ) {
515 bm |= cp932[256 * i + j];
516 }
517 kcls[0].map[i] = bm & (KCLS_AN | KCLS_KA | KCLS_K1);
518 if ( i >= 128 ) {
519 kcls[0].map[i - 128] |= kcls[0].map[i];
520 }
521 }
522 #endif /* not ALLKEY */
523
524 key_reset(key, 0);
525 }
526
527 /***************************************************************
528 *
529 * ŒĹ’čƒL[‚̐śŹ
530 *
531 * ˆęŒŠ Big Endian ‚É”ń‘Ήž‚̂悤‚ÉŒŠ‚Ś‚é‚ž‚낤‚Ş
532 * Š‚łɎU‚ç‚΂Á‚Ä‚˘‚é kludge ‚É‚ć‚č
533 * ALU_T ‚Ş 64 ƒrƒbƒg‚Ĺ‚ ‚éŒŔ‚čA‚ą‚ę‚Ĺ–â‘č‚Č‚­“Ž‚­B
534 *
535 */
536
537 static
538 void
539 key_init_sk(struct KEY *key)
540 {
541 int i, j;
542 int o;
543 uint64_t m;
544
545 for (i = 5, m = 0xFFFFFFFF00000000ULL;
546 i >= 0;
547 m ^= (m >> (1 << --i)))
548 {
549 o = tr_pc1[7][6 - i] - 1;
550 #if DEBUG>=2
551 printf("%d:%d->%2d: %08X%08X\n",
552 N_Q, i, o,
553 (unsigned)(m >> 32),
554 (unsigned)m);
555 #endif
556 for (j = 0; j < N_Q; j++)
557 if (o < 28)
558 key->k[0][0][o ].q[j] = key->k[0][1][o ].q[j] = m;
559 else
560 key->k[1][0][o - 28].q[j] = key->k[1][1][o - 28].q[j] = m;
561 }
562 #if N_STRIDE==7
563 /* bit 6 ‚Í Little Endian ‚Ć‚ľ‚Ĉľ‚¤ */
564 o = 0;
565 assert(tr_pc1[7][0] - 1 == o);
566 assert(N_Q == 2);
567 key->k[0][0][o].q[0] = key->k[0][1][o].q[0] = 0x0000000000000000ULL;
568 key->k[0][0][o].q[1] = key->k[0][1][o].q[1] = 0xFFFFFFFFFFFFFFFFULL;
569 #endif
570 }
571
572 /***************************************************************
573 *
574 * Salt ‚ĚƒZƒbƒg
575 * ƒIƒyƒ‰ƒ“ƒh‚ĚƒIƒtƒZƒbƒg‚đ‘‚ŤŠˇ‚ڂĉń‚Á‚Ä‚é‚̂ŒˆÓ
576 *
577 */
578
579 void
580 set_salt(CODE_T *code,
581 struct CRYPT64_DESC const *desc,
582 uint8_t const *k)
583 {
584 int i, j;
585
586 static unsigned char *s2c = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
587
588 for ( i = 0; i < 2; i++ ) {
589 unsigned s;
590 #ifdef ALLKEY
591 if ( fixedSaltChar[0] != '\0' ) {
592 saltChar[i] = fixedSaltChar[i];
593 for ( s = 0; s2c[s] != '\0' && s2c[s] != saltChar[i]; s++ )
594 ;
595 assert( s2c[s] != '\0' );
596 } else {
597 s = rand() % 64;
598 saltChar[i] = s2c[s];
599 }
600 #else /* ALLKEY */
601 s = k[1 + i] & 255;
602 if (s > 'z')
603 s = 0;
604 else if (s >= 'a')
605 s = s - 'a' + 2 + 10 + 26;
606 else if (s >= 'A')
607 s = s - 'A' + 2 + 10;
608 else if (s >= '.')
609 s = s - '.';
610 else
611 s = 0;
612 #ifdef OTAKU
613 {
614 unsigned s2;
615 do {
616 s2 = rand() % 64;
617 } while ( s == s2 );
618 s = s2;
619 }
620 #endif /* OTAKU */
621 saltChar[i] = s2c[s];
622 #endif /* ALLKEY */
623
624 for ( j = 0; j < 6; j++ ) {
625 if ( s & (1 << j) ) {
626 LSALT( desc, code, 0, i, j, 0 ) = sizeof(WS_T) * (((4*i+j+15) & 31) - 16);
627 LSALT( desc, code, 0, i, j, 24 ) = sizeof(WS_T) * (((4*i+j- 1) & 31) - 16);
628 } else {
629 LSALT( desc, code, 0, i, j, 0 ) = sizeof(WS_T) * (((4*i+j- 1) & 31) - 16);
630 LSALT( desc, code, 0, i, j, 24 ) = sizeof(WS_T) * (((4*i+j+15) & 31) - 16);
631 }
632 LSALT( desc, code, 0, i, j, 12 ) = sizeof(WS_T) * (((4*i+j+ 7) & 31) - 16);
633 LSALT( desc, code, 0, i, j, 36 ) = sizeof(WS_T) * (((4*i+j+23) & 31) - 16);
634 }
635 }
636 }
637
638 #define USEC_SEC 1000 /* 1•b */
639
640 static
641 uint64_t
642 usec(void)
643 {
644 uint32_t sec, msec;
645
646 #if !defined(WIN32)
647 struct timeval tv;
648 gettimeofday(&tv, NULL);
649 sec = tv.tv_sec;
650 msec = tv.tv_usec / (1000000 / USEC_SEC);
651 #else
652 struct timeb tm;
653 ftime(&tm);
654 sec = tm.time;
655 msec = tm.millitm / (1000 / USEC_SEC);
656 #endif
657
658 return (uint64_t)USEC_SEC * sec + msec;
659 }
660
661 static
662 int
663 log_printf(FILE *ofp, char const *fmt, ...)
664 {
665 int r;
666 va_list ap;
667 va_start(ap, fmt);
668
669 if ( ofp != nfp ) {
670 vfprintf(stdout, fmt, ap);
671 }
672
673 r = vfprintf(ofp, fmt, ap);
674 va_end(ap);
675 #ifdef HITEXIT
676 exit( 0 );
677 #endif /* HITEXIT */
678 if (r > 0)
679 return r;
680 perror("log_printf");
681 exit(errno);
682 }
683
684 static
685 void
686 hit( fp, hash, key, kk, k, kind, dotrans )
687 FILE *fp;
688 char *hash;
689 uint8_t *key;
690 int kk;
691 int k;
692 unsigned char *kind;
693 int dotrans;
694 {
695 struct timeb tb;
696 struct tm *plt;
697 int namaKey;
698 uint8_t buf[32];
699
700 ftime( &tb );
701 plt = localtime( &tb.time );
702
703 memcpy( buf, key, 8 );
704 buf[8] = buf[9] = 0;
705 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
706
707 namaKey = MAKAI_TRUE;
708 #ifndef NAMA
709 if ( dotrans ) {
710 if ( translate( buf, 0, 1 ) ) {
711 namaKey = MAKAI_FALSE;
712 }
713 }
714 #endif /* NAMA */
715
716 if ( namaKey ) {
717 log_printf( fp, "Ÿ%s ##%02x%02x%02x%02x%02x%02x%02x%02x%c%c"
718 "\t%04d/%02d/%02d %02d:%02d:%02d.%03d"
719 " %s ś\n",
720 hash,
721 buf[0], buf[1], buf[2], buf[3],
722 buf[4], buf[5], buf[6], buf[7],
723 saltChar[0], saltChar[1],
724 plt->tm_year + 1900, plt->tm_mon + 1, plt->tm_mday,
725 plt->tm_hour, plt->tm_min, plt->tm_sec, tb.millitm,
726 kind );
727 } else {
728 log_printf( fp, "Ÿ%s #%s"
729 "\t%04d/%02d/%02d %02d:%02d:%02d.%03d"
730 "\t(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)"
731 " %s\n",
732 hash,
733 buf,
734 plt->tm_year + 1900, plt->tm_mon + 1, plt->tm_mday,
735 plt->tm_hour, plt->tm_min, plt->tm_sec, tb.millitm,
736 buf[0], buf[1], buf[2], buf[3], buf[4],
737 buf[5], buf[6], buf[7], buf[8],
738 kind );
739 }
740 }
741
742 /***************************************************************
743 *
744 * CPU capabilities ‚đŽć“ž
745 * [XXX] ‚ ‚Ü‚č‚É‚ŕŒĂ‚˘ƒvƒƒZƒbƒT‚Ě‚ą‚Ć‚Íl‚ڂȂ˘B
746 *
747 * a[4] = {EAX,EBX,ECX,EDX}
748 *
749 */
750
751 #if defined(__GNUC__)
752
753 #define cpuid(n,a,b,c,d) \
754 asm("cpuid" \
755 : "=a"(a), "=b"(b), "=c"(c), "=d"(d) \
756 : "a"(n))
757
758 #elif defined(WIN32)
759
760 #define cpuid(n,a,b,c,d) \
761 do {int r[4]; __cpuid(r,n); \
762 (a) = r[0]; (b) = r[1]; (c) = r[2]; (d) = r[3];} while (0)
763
764 #endif
765
766 static
767 unsigned
768 cpuid_getfflags(void)
769 {
770 unsigned a, b, c, d;
771 cpuid(1, a, b, c, d);
772 return d;
773 }
774
775 static
776 int
777 cpuid_issupported(void)
778 {
779 unsigned m = REQUIRED_CAPS;
780 return !((cpuid_getfflags() ^ m) & m);
781 }
782
783 /***************************************************************
784 *
785 * ƒoƒbƒ`ˆ——pƒpƒPƒbƒg
786 *
787 */
788
789 static
790 struct PACKET_CRYPT64 *
791 packet_create(int n, /* ƒpƒPƒbƒg” */
792 int tn, /* ––”ö—v‘f‚ɂĕK—v‚Čƒ[ƒN” */
793 uint8_t const *ini_key)
794 {
795 int i;
796 int siz;
797 void *p;
798 intptr_t a = 128;
799 struct PACKET_CRYPT64 *pkts;
800 assert(IS_POWER2(sizeof(struct PACKET_CRYPT64)));
801 assert(n >= 1);
802
803 siz = (a - 1
804 + (n - 1) * sizeof(struct PACKET_CRYPT64)
805 + offsetof(struct PACKET_CRYPT64, param64.hit[tn]));
806 p = calloc(siz, 1);
807 /* ƒoƒ“ƒ_ƒŠ‚ ‚킚 */
808 pkts = (struct PACKET_CRYPT64 *)(((intptr_t)p
809 + a - 1)
810 & -a);
811 #if DEBUG>=1
812 fprintf(stderr,
813 "packet(n=%d,tn=%d) %d allocated; %p aligned to %p\n",
814 n, tn,
815 siz, p, pkts);
816 #endif
817
818 /* “ŕ•”‚̏‰Šú‰ť
819 ƒRƒs[‚ľ‚ĉń‚é‚̂́AŒľ–§‚É‚Í
820 ĹI—v‘f‚ĚƒPƒc‚đ”j‚Á‚Ä‚ľ‚Ü‚¤‚ą‚ƂɂȂé‚Ě‚Ĺ
821 ‚Ç‚¤‚š‘Ź“x‚ŕ—v‹‚ł‚ę‚Č‚˘‚ľƒxƒ^ƒR[ƒh */
822 for (i = 0; i < n; i++)
823 {
824 int j, k;
825
826 /* t[16] ‚́A“ŕ•”‰‰ŽZ‚ĹŽg—p‚ˇ‚éAall 1 ‚Ş“ü‚Á‚Ä‚˘‚é */
827 memset(&pkts[i].param64.t[T_INV], -1, sizeof(SLICE));
828
829 /* ŒĹ’čƒL[‚̐śŹ */
830 key_init_sk(&pkts[i].key64);
831
832 /* ƒL[ƒXƒPƒWƒ…[ƒ‹‚đ‚ą‚ą‚ɉŸ‚ľž‚߂è‚­
833 ]—ˆ‚Í crypt64.S “ŕ‚ĹŠŽŒ‹‚ˇ‚é‚悤‚Ɉř‚˘‚Ä‚˘‚˝ */
834 for (j = 0; j < 28; j++)
835 for (k = 0; k < N_ALU; k++)
836 pkts[i].key64.ks[j].a[k] = sizeof(WS_T) * ks_ls[j];
837
838 /* ”O‚Ě‚˝‚߁AŒŽ‚đ‚ą‚ą‚Ĺ—Ž‚ż’…‚݂è‚­(•s—v?) */
839 for (j = 0; j < 8; j++)
840 key_set64(&pkts[i].key64, j, pkts[i].uk.key[j] = ini_key[j], 0, 0x7F);
841 }
842
843 return pkts;
844 }
845
846 /***************************************************************
847 *
848 * thread
849 *
850 */
851
852 #define NQ_CRYPT 64
853 #define NQ_CMP 32
854
855 #if defined(__GNUC__)
856
857 typedef int32_t ATOMWORD_T;
858
859 #define LOCK_INC(p) \
860 asm volatile ("lock incl %0" \
861 : "=m"(*(p)) \
862 : /*nil*/ \
863 : "memory")
864
865 #define LOCK_DEC(p) \
866 asm volatile ("lock decl %0" \
867 : "=m"(*(p)) \
868 : /*nil*/ \
869 : "memory")
870
871 #define LOCK_CAS(pd,s,r) \
872 ({ ATOMWORD_T a; \
873 asm volatile ("lock cmpxchg %2,%1" \
874 : "=a"(a) \
875 : "m"(*(pd)), "r"(s), "0"(r) \
876 : "memory");a;})
877
878 #define LOCK_CASP(pd,s,r) \
879 ({ void *a; \
880 asm volatile ("lock cmpxchg %2,%1" \
881 : "=a"(a) \
882 : "m"(*(pd)), "r"(s), "0"(r) \
883 : "memory");a;})
884
885 #elif defined(WIN32)
886
887 typedef LONG ATOMWORD_T;
888
889 #define LOCK_INC(p) InterlockedIncrement((LONG *)(p))
890 #define LOCK_DEC(p) InterlockedDecrement((LONG *)(p))
891 #define LOCK_CAS(pd,s,r) InterlockedCompareExchange((LONG *)(pd), s, r)
892 #define LOCK_CASP(pd,s,r) InterlockedCompareExchangePointer((PVOID *)(pd), (PVOID)(s), (PVOID)r)
893
894 #else
895 #error "configuration not implemented"
896 #endif
897
898 #if defined(WIN32)
899
900 typedef DWORD THREAD_TIMEOUT_T;
901
902 #define THREAD_INFINITE INFINITE
903
904 typedef HANDLE THREAD_TH_T;
905 typedef HANDLE THREAD_EV_T;
906
907 #define thread_sleep(n) Sleep(n)
908 #define thread_create(th, proc, arg) {(th) = (HANDLE)_beginthread(proc, 8192, arg);}
909 #define thread_create_event(ev, f) {(ev) = CreateEvent(NULL, TRUE, f, NULL);}
910 #define thread_signal_event(ev) SetEvent(ev)
911 #define thread_clear_event(ev) ResetEvent(ev)
912 #define thread_get_tid() GetCurrentThread()
913 #define thread_set_priority(tid,n) SetThreadPriority(tid, n)
914 #if 0
915 #undef thread_set_priority
916 #endif
917 #define thread_set_affinity(tid,m) SetThreadAffinityMask(tid, (DWORD_PTR)1 << (m))
918
919 static
920 int
921 thread_wait_event(THREAD_EV_T ev, DWORD tmo)
922 {
923 DWORD r = WaitForSingleObject(ev, tmo);
924 return (r < 0
925 ? r
926 : (r == WAIT_TIMEOUT
927 ? -1
928 : r));
929 }
930
931 #elif defined(_POSIX_SOURCE) || defined(__FreeBSD__)
932
933 #include <pthread.h>
934 #include <unistd.h>
935
936 typedef int THREAD_TIMEOUT_T;
937
938 #define THREAD_INFINITE INT_MAX
939
940 #if defined(THREAD_PRIORITY_BELOW_NOROMAL) || defined(THREAD_PRIORITY_IDLE)
941 #error "unsupported implementation"
942 #endif
943
944 #define THREAD_PRIORITY_NORMAL 14
945 #define THREAD_PRIORITY_BELOW_NORMAL 15
946 #define THREAD_PRIORITY_IDLE 16
947
948 typedef pthread_t THREAD_TH_T;
949 typedef struct
950 {
951 pthread_mutex_t m;
952 pthread_cond_t c;
953 int volatile f;
954 } THREAD_EV_T;
955
956 #define thread_sleep(n) (usleep(1000 * (n)) != EINVAL || sleep((n) / 1000))
957 #define thread_create(th, proc, arg) thread_create_p(&(th), proc, arg)
958 #define thread_create_event(ev, f) thread_create_event_p(&(ev), f)
959 #define thread_signal_event(ev) thread_set_event_p(&(ev), 1)
960 #define thread_clear_event(ev) thread_set_event_p(&(ev), 0)
961 #define thread_wait_event(ev,tmo) thread_wait_event_p(&(ev), tmo)
962
963 static
964 void
965 thread_create_p(pthread_t *th, NORETURN (*proc)(void *), void *param)
966 {
967 pthread_create(th, NULL, (void *(*)(void *))proc, param);
968 }
969
970 static
971 void
972 thread_create_event_p(THREAD_EV_T *ev, int f)
973 {
974 ev->f = f;
975 pthread_cond_init(&ev->c, NULL);
976 pthread_mutex_init(&ev->m, NULL);
977 }
978
979 static
980 void
981 thread_set_event_p(THREAD_EV_T *ev, int f)
982 {
983 pthread_mutex_lock(&ev->m);
984 if (ev->f != f)
985 {
986 ev->f = f;
987 pthread_cond_broadcast(&ev->c);
988 }
989 pthread_mutex_unlock(&ev->m);
990 }
991
992 static
993 int
994 thread_wait_event_p(THREAD_EV_T *ev, int a_tmo)
995 {
996 int timeout = a_tmo;
997 struct timeval now;
998 struct timespec tmo;
999 int r;
1000
1001 pthread_mutex_lock(&ev->m);
1002
1003 /* ŒťÝŽž‚Š‚çƒ^ƒCƒ€ƒAƒEƒgŽž‚đ‹‚ß‚é
1004 ‚ß‚ń‚Ç‚­‚š[ */
1005 gettimeofday(&now, NULL);
1006 tmo.tv_sec = now.tv_sec + (timeout / 1000);
1007 timeout %= 1000;
1008 timeout *= 1000;
1009 if (now.tv_usec >= 1000000 - timeout)
1010 {
1011 timeout -= 1000000;
1012 tmo.tv_sec++;
1013 }
1014 tmo.tv_nsec = 1000 * (now.tv_usec + timeout);
1015 r = 0;
1016 while (!ev->f)
1017 {
1018 r = pthread_cond_timedwait(&ev->c, &ev->m, &tmo);
1019 if (r == ETIMEDOUT
1020 && a_tmo < THREAD_INFINITE)
1021 break;
1022 }
1023
1024 pthread_mutex_unlock(&ev->m);
1025
1026 return (r == ETIMEDOUT
1027 ? (ETIMEDOUT < 0 ? ETIMEDOUT : -1)
1028 : 0);
1029 }
1030
1031 #if defined(__linux__)
1032
1033 /* ƒfƒtƒHƒ‹ƒgƒXƒPƒWƒ…[ƒŠƒ“ƒOƒ|ƒŠƒV[‚Ĺ‚Í
1034 —Dć“xÝ’肾‚˝‚čƒAƒCƒhƒ‹ƒXƒŒƒbƒh‹N‚ą‚ľ‚Ä‚ŕ
1035 ‚¨‚ŕ‚ľ‚ë‚­‚Č‚˘‚̂ŁA‚ť‚̂ւń‚͍ĄŒă‚ĚŒ¤‹†‰Ű‘čB */
1036
1037 #include <linux/unistd.h>
1038 _syscall0(pid_t,gettid)
1039
1040 #define thread_get_tid() gettid()
1041
1042 static
1043 int thread_set_affinity(pid_t tid, int i)
1044 {
1045 cpu_set_t m;
1046 CPU_ZERO(&m);
1047 CPU_SET(i, &m);
1048 return sched_setaffinity(tid, sizeof(m), &m);
1049 }
1050
1051 #else
1052
1053 /* POSIX ‚ł́AƒXƒŒƒbƒh’PˆĘ‚ĚƒXƒPƒWƒ…[ƒŠƒ“ƒO‚ɉî“ü‚Ĺ‚Ť‚Č‚˘B */
1054
1055 #endif
1056
1057 #else
1058 #error "configuration not supported"
1059 #endif
1060
1061 struct THREAD_PARAM
1062 {
1063 /* ˆČ‰ş‚Í‹¤’ʏî•ń‚ĚƒRƒs[ */
1064 CODE_T *code;
1065 THREAD_EV_T *p_ev_ks_activated;
1066 ATOMWORD_T volatile *p_nidle; /* ‘Ň‚ż‚É“ü‚Á‚˝‚瑝‰Á */
1067
1068 /* ˆČ‰ş‚̓XƒŒƒbƒhŒĹ—L */
1069 #ifdef thread_set_priority
1070 THREAD_TH_T th;
1071 int pri;
1072 #endif
1073 };
1074
1075 static
1076 volatile ATOMWORD_T wp_crypt, rp_crypt;
1077 static
1078 struct PACKET_CRYPT64 *volatile q_crypt[NQ_CRYPT];
1079
1080 static
1081 volatile ATOMWORD_T wp_cmp, rp_cmp;
1082 static
1083 struct PACKET_CRYPT64 *volatile q_cmp[NQ_CMP];
1084
1085 static
1086 uint64_t
1087 thread_avail(void)
1088 {
1089 #if !USE_MT
1090
1091 return 0x1U;
1092
1093 #elif defined(WIN32) /* Win32 API */
1094 DWORD_PTR mask, mask_s;
1095 if (!GetProcessAffinityMask(GetCurrentProcess(),
1096 &mask,
1097 &mask_s)
1098 || !mask
1099 || !mask_s)
1100 return 0x1U;
1101 #if DEBUG>=1
1102 fprintf(stderr,
1103 "m=%08X s=%08X\n",
1104 (unsigned)mask,
1105 (unsigned)mask_s);
1106 #endif
1107 /* todo WIN32 ‚łȂ˘‚Ć‚Ť‚Ě n ”{•\ŽŚ */
1108 if (popcnt64(mask_s) == 1)
1109 /* ‰˝‚ŕŒž‚¤‚Ü‚˘ */;
1110 else if (mask == mask_s)
1111 fprintf(stderr,
1112 "’ʏí‚Ě%d”{‚Ƃ͂悭Œž‚Á‚˝‚ŕ‚̂łˇB\n",
1113 popcnt64(mask));
1114 else
1115 fprintf(stderr,
1116 "Ĺ‚‘Ź—Í‚Ě%g”{‚̗͂łĂŤ‚Ć‚¤‚ɂނń‚΂é‚ćB\n",
1117 (double)popcnt64(mask) / popcnt64(mask_s));
1118 return mask;
1119
1120 #elif defined(__linux__) /* sched.h Šg’Ł */
1121
1122 int i;
1123 uint64_t m = 0;
1124 cpu_set_t am;
1125 if (sched_getaffinity(getpid(), sizeof(am), &am) < 0)
1126 return 0x1U;
1127
1128 for (i = 0; i < 64 && i < CPU_SETSIZE; i++)
1129 if (CPU_ISSET(i, &am))
1130 m |= 1ULL << i;
1131
1132 return m;
1133
1134 #elif defined( __FreeBSD__ )
1135
1136 #include <sys/sysctl.h>
1137
1138 int i;
1139 uint64_t m;
1140 int nCPU;
1141 int mib[2];
1142 size_t len;
1143
1144 mib[0] = CTL_HW;
1145 mib[1] = HW_NCPU;
1146 len = sizeof( nCPU );
1147 sysctl( mib, 2, &nCPU, &len, NULL, 0 );
1148 m = (1ULL << nCPU) - 1;
1149
1150 return m;
1151
1152 #elif defined( __sun__ )
1153
1154 #include <sys/unistd.h>
1155 #include <sys/processor.h>
1156
1157 uint64_t m;
1158 processorid_t i, cpuid_max;
1159
1160 m = 0;
1161 cpuid_max = sysconf( _SC_CPUID_MAX );
1162 for ( i = 0; i <= cpuid_max; i++ ) {
1163 if ( p_online( i, P_STATUS ) == P_ONLINE ) {
1164 m |= 1ULL << i;
1165 }
1166 }
1167
1168 return m;
1169
1170 #else
1171
1172 /* XXX ƒvƒƒZƒbƒT”‚đ’˛‚×ă‚°‚Ä‚­‚ž‚ł‚˘ */
1173 return 0x01U;
1174
1175 #endif
1176 }
1177
1178 static
1179 NORETURN
1180 thread_crypt64(void *a_param)
1181 {
1182 struct THREAD_PARAM *param = a_param;
1183 CODE_T *code = param->code;
1184 struct PACKET_CRYPT64 *pkt;
1185 #ifdef thread_set_priority
1186 THREAD_TH_T th = thread_get_tid();
1187 thread_set_priority(th, param->pri);
1188 #endif
1189
1190 for(;;)
1191 {
1192 ATOMWORD_T rp;
1193 ATOMWORD_T wp;
1194
1195 /* ƒLƒ…[‚Š‚ç—v‹‚đŽć‚čo‚ˇ */
1196 for (;;)
1197 {
1198 while ((rp = rp_crypt,
1199 WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp, NQ_CRYPT)
1200 /*|| q_crypt[WRAP(rp, NQ_CRYPT)] == NULL*/))
1201 {
1202 THREAD_TIMEOUT_T tmo = (WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp, NQ_CRYPT)
1203 ? THREAD_INFINITE
1204 : 1);
1205 int r;
1206
1207 /* Q‚˝ */
1208 if (tmo == THREAD_INFINITE)
1209 {
1210 LOCK_INC(param->p_nidle);
1211 }
1212
1213 /* —v‹‘Ň‚ż */
1214 r = thread_wait_event(*param->p_ev_ks_activated, tmo);
1215
1216 if (tmo == THREAD_INFINITE)
1217 {
1218 /* ‹N‚ą‚ł‚ę‚˝ */
1219 LOCK_DEC(param->p_nidle);
1220 }
1221 else if (r >= 0)
1222 {
1223 /* ‚ŕ‚¤‚ż‚ĺ‚Á‚ƐQ‚Ă݂é */
1224 thread_sleep(tmo);
1225 }
1226
1227 /* ŽŠ‚ç‚Ě—Dć“x‚đ–ß‚ˇ
1228 (ŠO‚Š‚çƒu[ƒXƒg‚ł‚ę‚Ă邊‚ŕ) */
1229 #ifdef thread_set_priority
1230 if (r >= 0)
1231 thread_set_priority(th, param->pri);
1232 #endif
1233 }
1234
1235 if (LOCK_CAS(&rp_crypt, rp + 1, rp) != rp)
1236 continue;
1237 rp = WRAP(rp, NQ_CRYPT);
1238 break;
1239 }
1240
1241 pkt = q_crypt[rp];
1242 assert(pkt != NULL);
1243 pkt = LOCK_CASP(&q_crypt[rp], NULL, pkt);
1244 assert(pkt != NULL);
1245
1246 /* ŽŔs‚ľ‚Ă݂é */
1247 CALL_CRYPT64(code, &pkt->key64, &pkt->param64);
1248
1249 /* Œ‹‰Ę‚đƒLƒ…[‚É‚˝‚˝‚Ťž‚Ţ */
1250 for (;;)
1251 {
1252 while ((wp = wp_cmp,
1253 WRAP(rp_cmp - 1, NQ_CMP) == WRAP(wp, NQ_CMP))
1254 || q_cmp[WRAP(wp, NQ_CMP)] != NULL)
1255 {
1256 #if DEBUG>=1
1257 fprintf(stderr,
1258 "q_cmp stalled(%d,%d) %p\n",
1259 (unsigned)WRAP(wp, NQ_CMP),
1260 (unsigned)WRAP(rp_cmp - 1, NQ_CMP),
1261 q_cmp[WRAP(wp, NQ_CMP)]);
1262 #endif
1263 thread_sleep(1);
1264 }
1265
1266 if (LOCK_CAS(&wp_cmp, wp + 1, wp) != wp)
1267 continue;
1268 wp = WRAP(wp, NQ_CMP);
1269 break;
1270 }
1271
1272 pkt = LOCK_CASP(&q_cmp[wp], pkt, NULL);
1273 assert(pkt == NULL);
1274 }
1275 }
1276
1277 void
1278 usage( path )
1279 char *path;
1280 {
1281 char *myName, *chPtr;
1282
1283 myName = basename( path );
1284 for ( chPtr = myName; *chPtr != '\0'; chPtr++ ) {
1285 if ( *chPtr == '.' ) {
1286 *chPtr = '\0';
1287 break;
1288 }
1289 }
1290 #ifdef ALLKEY
1291 printf( "%s [-t num] [-m mask] [-s num] [-g num] [-k salt] [-v] [\"str\"]\n", myName );
1292 #else /* ALLKEY */
1293 printf( "%s [-t num] [-m mask] [-s num] [-g num] [-v] [\"str\"]\n", myName );
1294 #endif /* ALLKEY */
1295 printf( " -t num : ŒŸőƒXƒŒƒbƒh” ( %d … num … %d )\n",
1296 MIN_THREAD, MAX_THREAD );
1297 printf( " -m mask : ŽŔs‚ˇ‚é CPU ‚đŽw’股‚éƒ}ƒXƒN ( 1 ƒrƒbƒg … mask ‚Ěƒrƒbƒg” … %d ƒrƒbƒg )\n",
1298 MAX_THREAD );
1299 printf( " -s num : —”‚ĚŽí ( 1 … num … %u )\n", UINT_MAX );
1300 printf( " -g num : ‚Ş‚ń‚΂肎‚ ‚˘ ( %d (‚â‚é‹C‚Č‚ľ) … num … %d (ƒtƒ‹ƒpƒ[), ƒfƒtƒHƒ‹ƒg‚́A%d )\n", MIN_GEAR, MAX_GEAR, DEF_GEAR );
1301 #ifdef ALLKEY
1302 printf( " -k salt : ‰–‚đŽw’č\n" );
1303 #endif /* ALLKEY */
1304 printf( " -v : ç’ˇƒƒbƒZ[ƒW\n" );
1305 printf( " str : ć“ނɖ„‚ߍž‚Ţ•śŽš—ń ( %d … str ‚ĚƒoƒCƒg” … %d )\n",
1306 MIN_UME, MAX_UME );
1307 }
1308
1309 /* ƒqƒbƒgŽž‚ɂ͏o—̓tƒ@ƒCƒ‹‚Ö‚Ěƒ|ƒCƒ“ƒ^‚đ•Ô‚ˇ */
1310 FILE *
1311 checkSpecial( trip, kind )
1312 char *trip;
1313 unsigned char *kind;
1314 {
1315 if ( special & ST_CHIN ) {
1316 /* ^Chi(r */
1317 if ( trip[0] == 'C' && trip[1] == 'h' && trip[2] == 'i' &&
1318 trip[3] == 'n' && trip[4] == 'k' && trip[5] == 'o' ) {
1319 strcpy( kind, "‚ż" );
1320 return( cfp );
1321 }
1322 }
1323
1324 if ( special & ST_BUOO ) {
1325 /* ‚Ô‚¨ [A-Za-z]aoo[A-Za-z]uoo$ */
1326 if ( trip[3] == 'a' && trip[4] == 'o' && trip[5] == 'o' &&
1327 trip[7] == 'u' && trip[8] == 'o' && trip[9] == 'o' &&
1328 isalpha( trip[2] ) && isalpha( trip[6] ) ) {
1329 strcpy( kind, "‚Ô" );
1330 return( tfp );
1331 }
1332 }
1333
1334 if ( special & ST_EROI ) {
1335 int i;
1336 /* ƒGƒ‚˘lŒ^“ń\ ‚ť‚Ě 1 looooloooo */
1337 if ( trip[0] == trip[5] &&
1338 trip[1] == trip[2] && trip[1] == trip[3] && trip[1] == trip[4] &&
1339 trip[1] == trip[6] && trip[1] == trip[7] && trip[1] == trip[8] &&
1340 trip[1] == trip[9] ) {
1341 strcpy( kind, "ƒG" );
1342 return( tfp );
1343 }
1344 /* ƒGƒ‚˘lŒ^“ń\ ‚ť‚Ě 2 [./] */
1345 for ( i = 0; i < TRIP_LEN; i++ ) {
1346 if ( trip[i] != '.' && trip[i] != '/' ) {
1347 goto NOEROI;
1348 }
1349 }
1350 strcpy( kind, "ƒG" );
1351 return( tfp );
1352 }
1353 NOEROI:
1354
1355 if ( special & ST_NIKO ) {
1356 /* “ń\ */
1357 int i;
1358 char ch1, ch2;
1359 ch1 = trip[0];
1360 for ( i = 1; i < TRIP_LEN; i++ ) {
1361 if ( trip[i] != ch1 ) break;
1362 }
1363 ch2 = trip[i];
1364 for ( ; i < TRIP_LEN; i++ ) {
1365 if ( trip[i] != ch1 && trip[i] != ch2 ) goto NONIKO;
1366 }
1367 strcpy( kind, "“ń" );
1368 return( tfp );
1369 }
1370 NONIKO:
1371
1372 if ( special & ST_YAKU ) {
1373 /* ”މ_ */
1374 if ( trip[0] == trip[1] && trip[0] == trip[2] &&
1375 trip[3] == trip[4] && trip[3] == trip[5] &&
1376 trip[6] == trip[7] && trip[6] == trip[8] && trip[9] == '.' ) {
1377 strcpy( kind, "”Ş" );
1378 return( tfp );
1379 }
1380 }
1381
1382 /* ”ň˜AŠÖ˜A‚ĚƒR[ƒh‚́AžŰŘÝ ŸCeleron/rc ě */
1383 if ( special & ST_HREN ) {
1384 /* ”ň˜A */
1385 int w, x = 0, y = 0;
1386 for ( w = 0; w < TRIP_LEN; w++ ) {
1387 if ( trip[w] == trip[0] ) x += 1;
1388 if ( trip[w] == trip[1] ) y += 1;
1389 if ( x >= 8 || y >= 8 ) {
1390 strcpy( kind, "”ň" );
1391 return( tfp );
1392 }
1393 }
1394 }
1395
1396 if ( special & ST_ALLN ) {
1397 /* ‘S” ‚Š “{” */
1398 if ( isdigit( trip[0] ) && isdigit( trip[1] ) && isdigit( trip[2] ) &&
1399 isdigit( trip[3] ) && isdigit( trip[4] ) && isdigit( trip[5] ) &&
1400 isdigit( trip[6] ) && isdigit( trip[7] ) && isdigit( trip[8] ) &&
1401 isdigit( trip[9] ) ) {
1402 if ( special & ST_DOSU ) {
1403 /* ‘S” & ‰ń•ś */
1404 if ( trip[0] == trip[9] && trip[1] == trip[8] && trip[2] == trip[7] &&
1405 trip[3] == trip[6] && trip[4] == trip[5] ) {
1406 strcpy( kind, "“{" );
1407 return( tfp );
1408 }
1409 /* ‘S” & ‘o˜A */
1410 if ( trip[0] == trip[1] && trip[2] == trip[3] && trip[4] == trip[5] &&
1411 trip[6] == trip[7] && trip[8] == trip[9] ) {
1412 strcpy( kind, "“{" );
1413 return( tfp );
1414 }
1415 /* ‘S” & ŽR•F */
1416 if ( trip[0] == trip[5] && trip[1] == trip[6] && trip[2] == trip[7] &&
1417 trip[3] == trip[8] && trip[4] == trip[9] ) {
1418 strcpy( kind, "“{" );
1419 return( tfp );
1420 }
1421 /* Ĺ‘ĺ‚ĆĹŹ‚ÍAƒ 8 ˜A‚ŏo‚é‚Ě‚Ĺíœ */
1422 } else {
1423 strcpy( kind, "”" );
1424 return( nfp );
1425 }
1426 }
1427 }
1428
1429 return( NULL );
1430 }
1431
1432 /***************************************************************
1433 *
1434 * ƒƒCƒ“ƒ‹[ƒv‚Ć‚Š
1435 *
1436 */
1437
1438 int
1439 main(int argc, char *argv[])
1440 {
1441 int i;
1442 int mincnt;
1443 int nblk_hit, nblk_total;
1444 int nap_hit, nap_total;
1445 CODE_T *code = NULL;
1446 off_t code_cmp;
1447 FILE *ofp;
1448 FILE *sfp; /* scoreboard */
1449 struct ITREE *root_expr;
1450 uint64_t proc_mask;
1451 int ks_activated;
1452 static THREAD_EV_T event_ks_activated;
1453 static ATOMWORD_T volatile nidle;
1454 struct THREAD_PARAM *threads = NULL;
1455 int nthreads;
1456 int npkts;
1457 struct PACKET_CRYPT64 *pkts, *pkt_hit;
1458 uint64_t pkts_vacant;
1459 int tn;
1460 int cr;
1461
1462 /* ŒŽ•śŽš—ń */
1463 uint8_t key[8 + 8];
1464
1465 int xhash_loaded;
1466
1467 #if defined(WIN32)
1468 #define YOUSUMI 6
1469 int maxSpeed; /* ˆę•bŠÔ‚ÉŒŸő‚ľ‚˝ŒÂ”‚ĚĹ‘ĺ’l (YOUSUMI ‰ńŒv‘Ş’†) */
1470 int sCnt; /* ‘Ź“x‚đ•\ŽŚ‚ľ‚˝‰ń” */
1471 int lCntMax; /* Sleep() ‚Ě‚˝‚ß‚Ěƒ‹[ƒvĹ‘ĺ’l */
1472 int lCnt; /* Sleep() ‚Ě‚˝‚ß‚Ěƒ‹[ƒvƒJƒEƒ“ƒ^ */
1473 #endif /* WIN32 */
1474
1475 #define UPDATE_INTERVAL 8 /* ‘Ź“x•\ŽŚ‚ĚŠÔŠu •b */
1476 struct status {
1477 uint64_t startTime; /* ŠJŽnŽž ƒ~ƒŠ•b */
1478 uint64_t lastTime; /* ĹŒă‚É•\ŽŚ‚ľ‚˝Žž ƒ~ƒŠ•b */
1479 uint64_t loop; /* ‘ŒŸőŒÂ” */
1480 uint64_t lastloop; /* ĹŒă‚É•\ŽŚ‚ľ‚˝Žž‚Ě loop */
1481 } status;
1482 uint64_t curTime;
1483 uint32_t upd_int = 0;
1484
1485 #if defined(WIN32)
1486 SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
1487 maxSpeed = 0;
1488 sCnt = 0;
1489 lCntMax = 0;
1490 lCnt = 0;
1491 #endif
1492
1493 {
1494 int optChar;
1495 extern char *optarg;
1496 extern int optind;
1497 char *chPtr;
1498
1499 nThread = 0;
1500 pmask = 0;
1501 seed = 0;
1502 seedOffset = 0; /* ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“ƒIƒvƒVƒ‡ƒ“‚ł͂Ȃ˘‚ށA‚ą‚ą‚ŏ‰Šú‰ť */
1503 verbose = 0;
1504 gear = DEF_GEAR;
1505 #ifdef ALLKEY
1506 fixedSaltChar[0] = '\0';
1507 while ( (optChar = getopt(argc, argv, "t:m:s:g:k:vh")) != EOF ) {
1508 #else /* ALLKEY */
1509 while ( (optChar = getopt(argc, argv, "t:m:s:g:vh")) != EOF ) {
1510 #endif /* ALLKEY */
1511 switch ( optChar ) {
1512 case 't':
1513 nThread = atoi( optarg );
1514 if ( nThread < MIN_THREAD || nThread > MAX_THREAD ) {
1515 usage( argv[0] );
1516 exit( 1 );
1517 }
1518 break;
1519 case 'm':
1520 if ( strlen( optarg ) > MAX_THREAD ) {
1521 usage( argv[0] );
1522 exit( 1 );
1523 }
1524 for ( chPtr = optarg; *chPtr != '\0'; chPtr++ ) {
1525 pmask <<= 1;
1526 switch ( *chPtr ) {
1527 case '0':
1528 /* ‚Č‚É‚ŕ‚ľ‚Č‚˘ */
1529 break;
1530 case '1':
1531 pmask |= 1;
1532 break;
1533 default:
1534 usage( argv[0] );
1535 exit( 1 );
1536 break;
1537 }
1538 }
1539 if ( pmask < MIN_THREAD ) {
1540 usage( argv[0] );
1541 exit( 1 );
1542 }
1543 break;
1544 case 's':
1545 if ( optarg[0] == '-' ) {
1546 usage( argv[0] );
1547 exit( 1 );
1548 }
1549 seed = (unsigned int)atoi( optarg );
1550 if ( seed < 1 || seed > UINT_MAX ) {
1551 usage( argv[0] );
1552 exit( 1 );
1553 }
1554 break;
1555 case 'g':
1556 gear = atoi( optarg );
1557 if ( gear < MIN_GEAR || gear > MAX_GEAR ) {
1558 usage( argv[0] );
1559 exit( 1 );
1560 }
1561 break;
1562 #ifdef ALLKEY
1563 case 'k':
1564 if ( strlen( optarg ) != 2 ) {
1565 usage( argv[0] );
1566 exit( 1 );
1567 }
1568 for ( i = 0; i < 2; i++ ) {
1569 if ( !isdigit( optarg[i] ) && !isalpha( optarg[i] ) &&
1570 optarg[i] != '.' && optarg[i] != '/' ) {
1571 usage( argv[0] );
1572 exit( 1 );
1573 }
1574 fixedSaltChar[i] = optarg[i];
1575 }
1576 break;
1577 #endif /* ALLKEY */
1578 case 'v':
1579 verbose = 1;
1580 break;
1581 case 'h':
1582 usage( argv[0] );
1583 exit( 0 );
1584 break;
1585 default:
1586 usage( argv[0] );
1587 exit( 1 );
1588 }
1589 }
1590
1591 switch ( argc - optind ) {
1592 case 0:
1593 umeStr[0] = '\0';
1594 umeLen = KEY_SHUFFLE_POS;
1595 break;
1596 case 1:
1597 strcpy( umeStr, argv[optind] );
1598 umeLen = strlen( umeStr );
1599 if ( umeLen < MIN_UME || umeLen > MAX_UME ) {
1600 usage( argv[0] );
1601 exit( 1 );
1602 }
1603 break;
1604 default:
1605 usage( argv[0] );
1606 exit( 1 );
1607 }
1608 }
1609 #ifdef REON
1610 regExpStr[0] = '\0';
1611 #endif /* REON */
1612
1613 #ifdef NAMA
1614 fprintf(stderr, "śƒL[ƒo[ƒWƒ‡ƒ“\n");
1615 fprintf(stderr, "–œ‚ވęAƒgƒŠƒbƒv‚މť‚Ż‚˝ę‡A\n");
1616 fprintf(stderr, "http://trip.is-a-geek.net/test/read.cgi/ra8bbs/1217089930/\n");
1617 fprintf(stderr, "‚É•ń‚ˇ‚é‚ĆŽŸ‚Ěƒo[ƒWƒ‡ƒ“‚ʼnü‘P‚ł‚ę‚邊‚ŕB\n\n");
1618 #endif /* NAMA */
1619
1620 #ifdef MAKEY
1621 fprintf(stderr, "–‚ƒL[‹óŠÔƒo[ƒWƒ‡ƒ“‚ɂ‚ŤAƒVƒƒEƒg‚ɂ͂¨‚ˇ‚ˇ‚߂łŤ‚Č‚˘B\n\n");
1622 #endif /* MAKEY */
1623
1624 #ifdef ALLKEY
1625 fprintf(stderr, "^E‘S‹óŠÔƒo[ƒWƒ‡ƒ“‚ɂ‚ŤAƒVƒƒEƒg‚ɂ͂¨‚ˇ‚ˇ‚߂łŤ‚Č‚˘B\n\n");
1626 #endif /* MAKEY */
1627
1628 if ( !cpuid_issupported() ) {
1629 fprintf( stderr, "‚ą‚̊‹Ť‚Ĺ‘–‚炚‚邹‚Ć‚Ş‘z’肳‚ę‚Ä‚˘‚Ü‚š‚ńB\n" );
1630 exit( 1 );
1631 }
1632
1633 assert( (1 << N_STRIDE) == N_ALU * ALU_BITS );
1634
1635 /* ƒ^ƒQ“ǂݍž‚Ý */
1636 root_expr = expr_parse( "target.txt" );
1637
1638 if ( verbose ) {
1639 printf( "“ÁŽęŒŸőƒIƒvƒVƒ‡ƒ“ : " );
1640 if ( special & ST_DOSU ) {
1641 printf( "“{” " );
1642 } else {
1643 if ( special & ST_ALLN ) {
1644 printf( "‘S” " );
1645 }
1646 }
1647 if ( special & ST_EROI ) {
1648 printf( "ƒGƒ " );
1649 }
1650 if ( special & ST_NIKO ) {
1651 printf( "“ń\ " );
1652 }
1653 if ( special & ST_BUOO ) {
1654 printf( "‚Ô‚¨ " );
1655 }
1656 if ( special & ST_CHIN ) {
1657 printf( "‚ż‚ń " );
1658 }
1659 if ( special & ST_HREN ) {
1660 printf( "”ň˜A " );
1661 }
1662 if ( special & ST_YAKU ) {
1663 printf( "”މ_ " );
1664 }
1665 if ( special ) {
1666 printf( "ƒIƒ“I\n" );
1667 } else {
1668 printf( "ƒI[ƒ‹ƒIƒtI\n" );
1669 }
1670 if ( seedOffset != 0 ) {
1671 printf( "—”‚ĚŽí‚ĚƒIƒtƒZƒbƒg = %d\n", seedOffset );
1672 }
1673 #ifdef REON
1674 if ( regExpStr[0] != '\0' ) {
1675 printf( "ł‹K•\Œť : %s\n", regExpStr );
1676 }
1677 #endif /* REON */
1678 if ( gear != DEF_GEAR ) {
1679 printf( "‚Ş‚ń‚΂肎‚ ‚˘ : %d\n", gear );
1680 }
1681 }
1682
1683 /* ƒR[ƒh‚đśŹE“WŠJ
1684 ‹N“Ž—\’čƒXƒŒƒbƒh”‚ɉž‚ś‚Ä
1685 śŹ‚ˇ‚éƒR[ƒh‚đ•Ď‚Ś‚é */
1686 sfp = scoreboard_open();
1687 /* prologue & ƒRƒAƒ‹[ƒv */
1688 fwrite( crypt64_descs[0]->pro, 1,
1689 crypt64_descs[0]->cmp_pro - crypt64_descs[0]->pro, sfp );
1690
1691 /* proc_mask ‚ÉŽg—p‚ˇ‚é CPU ‚Ěƒ}ƒXƒN‚đƒZƒbƒg */
1692 if ( pmask == 0 ) {
1693 /* Žw’肪‚Ȃ݂ę‚΁AŽg‚Ś‚é CPU ‘S•” */
1694 proc_mask = thread_avail();
1695 } else {
1696 /* Žw’肳‚ę‚˝ CPU ‚Ě‘śÝƒ`ƒFƒbƒNB‚ž‚ށAĄ‚Í Win32 ‚ĚƒR[ƒh‚ľ‚ЂȂ˘B */
1697 #ifdef WIN32
1698 DWORD_PTR processMask, systemMask;
1699 if ( GetProcessAffinityMask( GetCurrentProcess(), &processMask, &systemMask )
1700 == 0 ) {
1701 printf( "CPU ‚ĚŠ„‚č“–‚ĂɎ¸”s ‚ť‚Ě 1\n" );
1702 exit( 1 );
1703 }
1704 if ( (processMask & pmask) != pmask ) {
1705 printf( "‚ť‚ń‚Č CPU ‚͂˂ĽI\n" );
1706 exit( 1 );
1707 }
1708 #endif /* WIN32 */
1709
1710 proc_mask = pmask;
1711 printf( "CPU : " );
1712 for ( i = 0; i < MAX_THREAD; i++ ) {
1713 if ( pmask & 1 ) {
1714 printf( "%d ", i );
1715 }
1716 pmask >>= 1;
1717 }
1718 printf( "‚đŽg—p‚ľ‚Ü‚ˇB\n" );
1719
1720 /* CPU ‚ĚŠ„‚č“–‚āB‚ž‚ށAĄ‚Í Wi(r */
1721 #ifdef WIN32
1722 if ( SetProcessAffinityMask( GetCurrentProcess(), proc_mask ) == 0 ) {
1723 printf( "CPU ‚ĚŠ„‚č“–‚ĂɎ¸”s ‚ť‚Ě 2\n" );
1724 exit( 1 );
1725 }
1726 #endif /* WIN32 */
1727 }
1728
1729 /* ƒXƒŒƒbƒh”‚ĚŽw’肪‚Č‚˘ę‡‚́Aproc_mask ‚Š‚çƒQƒbƒc */
1730 if ( nThread == 0 ) {
1731 nThread = popcnt64( proc_mask );
1732 }
1733
1734 fprintf( stderr, "%d ŒÂ‚ĚŒŸőƒXƒŒƒbƒh‚𐜐Ź\n", nThread );
1735
1736 if ( nThread == 1 ) {
1737 npkts = 1;
1738 pkts_vacant = 1;
1739 code_cmp = 0;
1740 } else {
1741 /* epilogue */
1742 fwrite( crypt64_descs[0]->ep, 1,
1743 crypt64_descs[0]->ep_end - crypt64_descs[0]->ep, sfp );
1744 /* ”äŠrŠí‚݂̂𐜐Ź(‘O”ź) */
1745 code_cmp = ftell( sfp );
1746 fseek( sfp, (-code_cmp) & 63, SEEK_CUR );
1747 code_cmp = ftell( sfp );
1748 /* prologue */
1749 fwrite( crypt64_descs[0]->pro, 1,
1750 crypt64_descs[0]->crypt - crypt64_descs[0]->pro, sfp );
1751 npkts = 64;
1752 pkts_vacant = (uint64_t)-1; /* (1 << 64) - 1 ‚đŒvŽZ‚ľ‚˝‚­‚Č‚˘ */
1753 }
1754
1755 /* ”äŠr•”‚đśŹ */
1756 /* ”äŠrŠí€”ő */
1757 fwrite( crypt64_descs[0]->cmp_pro, 1,
1758 crypt64_descs[0]->cmp_ep - crypt64_descs[0]->cmp_pro, sfp );
1759 tn = synth_synthesize( sfp, root_expr );
1760 /* epilogue */
1761 fwrite( crypt64_descs[0]->cmp_ep, 1,
1762 crypt64_descs[0]->ep_end - crypt64_descs[0]->cmp_ep, sfp );
1763 /* ƒR[ƒh‚đƒƒ‚ƒŠ‚É“\‚č•t‚Ż‚é */
1764 code = scoreboard_map( sfp );
1765
1766 /* ƒL[‚̏‰Šú‰ť */
1767 if ( seed == 0 ) {
1768 seed = (unsigned int)time( NULL ) + seedOffset;
1769 }
1770 if ( verbose ) {
1771 printf( "—”‚ĚŽí = %u\n", seed );
1772 }
1773 srand( seed );
1774
1775 #ifdef KEYCHK
1776 {
1777 int i;
1778
1779 for ( i = 0; i < 100000; i++ ) {
1780 printf( "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1781 key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7] );
1782 key_init( key );
1783 }
1784 exit( 0 );
1785 }
1786 #endif /* KEYCHK */
1787
1788 key_init( key );
1789 set_salt( code, crypt64_descs[0], key );
1790
1791 /* ‰‰ŽZƒpƒPƒbƒg‚đěŹ */
1792 pkts = packet_create( npkts, tn, key );
1793 pkt_hit = &pkts[npkts - 1];
1794
1795 /* “­‚­‚¨‚ś‚ł‚ń‚đ—ĘŽY */
1796 thread_create_event( event_ks_activated, 1 );
1797 ks_activated = 1;
1798 nthreads = 0;
1799 if ( code_cmp ) {
1800 THREAD_TH_T h;
1801 int ots = -1;
1802 threads = calloc( 2 * nThread, sizeof(*threads) );
1803 for ( i = 0; i < nThread; i++ ) {
1804 if ( ots < 0 ) {
1805 /* ŽŠ•ŞŽŠg‚ĚƒXƒPƒWƒ…[ƒŠƒ“ƒO
1806 ‚ą[‚ä[Œn‚ĚƒAƒvƒŠ‚Í’á‚߂ɐݒ股‚é‚Ě‚Ş‹g(‚Š‚ŕ) */
1807 #ifdef WIN32
1808 h = GetCurrentProcess();
1809 /* todo Šî–{—Dć“x‚̐ݒ肪“ń‰ÓŠ‚É‚ ‚é */
1810 SetPriorityClass( h, BELOW_NORMAL_PRIORITY_CLASS );
1811 #endif
1812 #if defined( thread_set_priority )
1813 /* S‚ĚŒ„ŠÔ‚¨–„‚ß‚ľ‚Ü‚ˇ */
1814 threads[nthreads].code = code;
1815 threads[nthreads].p_ev_ks_activated = &event_ks_activated;
1816 threads[nthreads].p_nidle = &nidle;
1817 threads[nthreads].pri = THREAD_PRIORITY_IDLE;
1818 thread_create( h, thread_crypt64, &threads[nthreads] );
1819 threads[nthreads].th = h;
1820 nthreads++;
1821 #endif
1822 if ( !code_cmp ) break;
1823 /* ŽŠ•ŞŽŠg‚ĚŽc‚č‚̐ݒč‚đA‚ ‚Ƃłâ‚é */
1824 ots = i;
1825 } else {
1826 /* ‘źƒXƒŒƒbƒh‚́A‚â‚â’á‚߂̗Dć“x‚ŁB */
1827 threads[nthreads].code = code;
1828 threads[nthreads].p_ev_ks_activated = &event_ks_activated;
1829 threads[nthreads].p_nidle = &nidle;
1830 #ifdef thread_set_priority
1831 threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL;
1832 #endif
1833 thread_create( h, thread_crypt64, &threads[nthreads] );
1834 #ifdef thread_set_priority
1835 threads[nthreads].th = h;
1836 #endif
1837 nthreads++;
1838 }
1839 }
1840 }
1841
1842 if ( (ofp = fopen( "log.txt", "at" )) == NULL ) {
1843 perror( "log.txt" );
1844 return errno;
1845 }
1846 setvbuf(ofp, NULL, _IONBF, BUFSIZ);
1847
1848 if ( (tfp = fopen( "logspe.txt", "at" )) == NULL ) {
1849 perror( "logspe.txt" );
1850 return errno;
1851 }
1852 setvbuf( tfp, NULL, _IONBF, BUFSIZ );
1853 if ( (nfp = fopen( "lognum.txt", "at" )) == NULL ) {
1854 perror( "lognum.txt" );
1855 return errno;
1856 }
1857 setvbuf( nfp, NULL, _IONBF, BUFSIZ );
1858 if ( (cfp = fopen( "logchi.txt", "at" )) == NULL ) {
1859 perror( "logchi.txt" );
1860 return errno;
1861 }
1862 setvbuf( cfp, NULL, _IONBF, BUFSIZ );
1863 #ifdef REON
1864 if ( (rfp = fopen( "logreg.txt", "at" )) == NULL ) {
1865 perror( "logreg.txt" );
1866 return errno;
1867 }
1868 setvbuf( rfp, NULL, _IONBF, BUFSIZ );
1869 #endif /* REON */
1870
1871 mincnt = 0x7FFFFFFF;
1872 nblk_hit = nblk_total = 0;
1873 nap_hit = nap_total = 0;
1874 cr = 0;
1875 memset( &status, 0, sizeof( struct status ) );
1876 status.startTime = status.lastTime = usec();
1877
1878 #ifdef MINAST
1879 #undef assert
1880 #define assert(x)
1881 #endif /* MINAST */
1882
1883 #ifdef SCTEST
1884 {
1885 int i;
1886
1887 for ( i = 1; i < SCTEST; i++ ) {
1888 key_reset( key, 0 );
1889 }
1890 exit( 0 );
1891 }
1892 #endif /* SCTEST */
1893
1894 /* ’Tőƒ‹[ƒv‚ž‚ź‚Á‚Ć */
1895 for ( ;; ) {
1896 struct PACKET_CRYPT64 *pkt_c;
1897 uint64_t cnt;
1898 #if DEBUG>=1
1899 int cnt1, cnt2;
1900 #endif
1901 int k, kk;
1902
1903 /* ”äŠrŠíŒó•â(may be NULL)
1904 ć‚ɃLƒ…[‚Š‚çŽć‚čo‚ˇ */
1905 pkt_c = q_cmp[WRAP( rp_cmp, NQ_CMP )];
1906 if ( pkt_c != NULL && WRAP( rp_cmp, NQ_CMP ) != WRAP( wp_cmp, NQ_CMP ) ) {
1907 pkt_c = LOCK_CASP( &q_cmp[WRAP( rp_cmp, NQ_CMP )], NULL, pkt_c );
1908 assert( pkt_c != NULL );
1909 LOCK_INC( &rp_cmp );
1910 /* ƒpƒPƒbƒg‚đ vacant ‚ɉń‚ľ‚Ä‚¨‚­ */
1911 pkts_vacant |= 1ULL << (pkt_c - pkts);
1912 }
1913
1914 /* Saltƒ`ƒFƒ“ƒW‘Ň‚ż */
1915 if ( !ks_activated ) {
1916 ATOMWORD_T rp;
1917 if ( pkt_c == NULL ) {
1918 if ( (rp = rp_crypt, WRAP( rp, NQ_CRYPT ) != WRAP( wp_crypt, NQ_CRYPT ))
1919 && LOCK_CAS( &rp_crypt, rp + 1, rp ) == rp ) {
1920 /* !ks_activate ó‘Ԃł́AŽŠ‚ç‚ŕ—v‹ƒLƒ…[‚đ‚â‚Á‚Â‚Ż‚É‚˘‚­ */
1921 rp = WRAP( rp, NQ_CRYPT );
1922 pkt_c = q_crypt[rp];
1923 assert( pkt_c != NULL );
1924 pkt_c = LOCK_CASP( &q_crypt[rp], NULL, pkt_c );
1925 assert( pkt_c != NULL );
1926 assert( pkt_c != pkt_hit );
1927 CALL_CRYPT64( code, &pkt_c->key64, &pkt_c->param64 );
1928 /* ƒpƒPƒbƒg‚đ vacant ‚ɉń‚ľ‚Ä‚¨‚­ */
1929 pkts_vacant |= 1ULL << (pkt_c - pkts);
1930 } else {
1931 /* ‚â‚͂股‚邹‚Ć‚Ş‚Č‚˘‚̂ł܂Á‚˝‚č‚Ɖ߂˛‚ˇ */
1932 if ( nidle != nthreads ) thread_sleep(1);
1933 }
1934 }
1935 if ( nidle == nthreads ) {
1936 assert( WRAP( rp_crypt, NQ_CRYPT ) == WRAP( wp_crypt, NQ_CRYPT ) );
1937 /* Salt ƒ`ƒFƒ“ƒW‚މ”\ */
1938 set_salt( code, crypt64_descs[0], key );
1939 if ( nthreads ) thread_signal_event( event_ks_activated );
1940 ks_activated = 1;
1941 }
1942 }
1943
1944 /* ŒŽ‚đƒLƒ…[‚É‚˝‚˝‚Ťž‚݂܂­‚é */
1945 if ( !ks_activated ) {
1946 /* ŒŽ‚đ“o˜^‚ľ‚Č‚˘ */
1947 ;
1948 } else {
1949 for ( i = npkts - 1; i >= 0; i-- ) {
1950 if ( pkts_vacant & (1ULL << i) ) {
1951 int j;
1952 if ( i == npkts - 1 ) {
1953 /* ‘O’i‚ŁA“­‚­‚¨‚ś‚ł‚ń‚Š‚çŒ‹‰Ę‚đ‚ŕ‚ç‚Á‚Ä‚˘‚˝‚çA‰˝‚ŕ‚ľ‚Č‚˘ */
1954 if ( pkt_c != NULL ) continue;
1955 } else {
1956 /* ‘O’i‚ĹŽć‚čo‚ľ‚˝‚Î‚Š‚č‚Ě“­‚­‚¨‚ś‚ł‚ń‚́A‘¸d‚ˇ‚é */
1957 if ( &pkts[i] == pkt_c ) continue;
1958 /* queue full ‚Ěę‡‚ÍŒŠ‘—‚é */
1959 /* XXX 16 ‚͂ĂŤ‚Ć‚¤ */
1960 if ( WRAP( wp_crypt, NQ_CRYPT ) == WRAP( rp_crypt - 16, NQ_CRYPT )
1961 || q_crypt[WRAP( wp_crypt, NQ_CRYPT )] != NULL ) break;
1962 }
1963 /* ŒŽ‚ĚƒZƒbƒg */
1964 for ( j = 0; j < 8; j++ ) {
1965 key_set64( &pkts[i].key64, j, key[j], key[j] ^ pkts[i].uk.key[j], 0 );
1966 pkts[i].uk.key[j] = key[j];
1967 }
1968 if ( i == npkts - 1 ) {
1969 /* ŽŸ’i‚Ĺ CRYPT64->CMP */
1970 assert(pkt_c == NULL);
1971 pkt_c = &pkts[i];
1972 assert( pkt_c == pkt_hit );
1973 } else {
1974 /* ƒLƒ…[‚É‚˝‚˝‚Ťž‚Ţ */
1975 while ( LOCK_CASP( &q_crypt[WRAP( wp_crypt, NQ_CRYPT )], &pkts[i], NULL )
1976 != NULL ) {
1977 /* ÝŒvă‚Í‚ą‚ą‚É—ˆ‚Č‚˘ */
1978 fprintf( stderr,
1979 "q_crypt ‚đ‰˜‚ľ‚Ä‚é‚̂͒N‚ž? (rp=%3d, wp=%3d, v=%08X%08X)\n",
1980 (unsigned)WRAP( rp_crypt, NQ_CRYPT ),
1981 (unsigned)WRAP( wp_crypt, NQ_CRYPT ),
1982 (unsigned)( pkts_vacant >> 32 ),
1983 (unsigned)pkts_vacant );
1984 thread_sleep( 1000 );
1985 }
1986 LOCK_INC( &wp_crypt );
1987 pkts_vacant ^= 1ULL << i;
1988 assert( !(pkts_vacant & (1ULL << i)) ); /* í‚ę */
1989 }
1990 /* ŒŽ‘‰Á‚Í‚ą‚ń‚ȂƂą‚ë‚ɈړŽ! */
1991 assert( ks_activated );
1992 if ( !key_inc( key, 6 ) && !key_inc( key, umeLen ) ) {
1993 /* ŒŽ‚ĚƒVƒƒƒbƒtƒ‹ q_crypt ‚ŞŽJ‚Ż‚é‚܂ŁAset_salt() ‚͂łŤ‚Č‚˘ */
1994 #if DEBUG>=1
1995 fprintf( stderr, "********************************SHUFFLE!\n" );
1996 #endif
1997 if ( nthreads ) thread_clear_event( event_ks_activated );
1998 key_reset( key, 0 );
1999 /* ƒLƒ…[‚ĚŒŽ‚ŞŽJ‚Ż‚é‚Ü‚ĹƒAƒCƒhƒ‹ó‘Ô‚É */
2000 ks_activated = 0;
2001 /* ƒXƒŒƒbƒh‚đƒu[ƒXƒg‚ľ‚ĉń‚é */
2002 #ifdef thread_set_priority
2003 for ( j = 0; j < nthreads; j++ ) {
2004 assert( threads != NULL );
2005 thread_set_priority( threads[j].th, THREAD_PRIORITY_NORMAL );
2006 }
2007 #endif
2008 /* ƒ‹[ƒv‘ąs‚Í‚ŕ‚Í‚â•s—v */
2009 break;
2010 }
2011 }
2012 }
2013 }
2014 /* ‚ˇ‚邹‚Ć‚Ş‚Č‚­‚Č‚Á‚Ä‚˘‚éę‡ */
2015 if ( pkt_c == NULL ) {
2016 assert( !ks_activated );
2017 continue;
2018 }
2019 /* ŒÄ‚Ô!
2020 LR ‰Šú‰ť‚́AƒTƒuƒ‚ƒWƒ…[ƒ‹“ŕ‚ōs‚¤‚ׂľ
2021 FASTCALL ‚ɏ€‚ś‚˝ŒÄ‚яo‚ľ‚Ě‚˝‚߁A
2022 ƒzƒ“ƒg‚Í‚˘‚낢‚냌ƒWƒXƒ^‚Ş”j‰ó‚ł‚ę‚éƒnƒYc‚Č‚ń‚ž‚ށB */
2023 if ( pkt_c != pkt_hit ) {
2024 assert( code_cmp != 0 );
2025 cnt = CALL_CMP64( code + code_cmp, pkt_hit->param64.hit,
2026 pkt_c->param64.lr );
2027 } else {
2028 /* ‚悤‚â‚­ŽŠƒXƒŒƒbƒh‚ʼnń‚š‚é */
2029 cnt = CALL_CRYPT64( code, &pkt_c->key64, &pkt_c->param64 );
2030 if ( code_cmp ) {
2031 cnt = CALL_CMP64( code + code_cmp, pkt_c->param64.hit,
2032 pkt_c->param64.lr );
2033 }
2034 }
2035 /* ƒqƒbƒg‚ľ‚˝‚Ć‚Ť‚̏ˆ—
2036 key ‚¨‚ć‚Ń lr ‚Í pkt_c ‚ɍ‡’v”ť’č‚Í pkt_hit ‚É“ü‚Á‚Ä‚˘‚éƒnƒY */
2037 xhash_loaded = 0;
2038 for ( kk = 0; kk < N_ALU; kk++ ) {
2039 ALU_T t;
2040 static uint64_t xhash[64];
2041 if ( special
2042 #ifdef REON
2043 || regExpStr[0] != '\0'
2044 #endif /* REON */
2045 ) {
2046 CALL_TR64( &pkt_c->param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash );
2047 xhash_loaded = 1;
2048 }
2049 if ( !(kk & (N_ALU / N_Q - 1)) ) nblk_total++, xhash_loaded = 0;
2050 if ( special
2051 #ifdef REON
2052 || regExpStr[0] != '\0'
2053 #endif /* REON */
2054 ) {
2055 char hash[16];
2056 FILE *lfp;
2057 unsigned char kind[3];
2058 for ( k = 0; k < ALU_BITS; k++ ) {
2059 for ( i = 1; i < 11; i++ ) {
2060 unsigned c = 0;
2061 c = (xhash[(ALU_BITS * kk + k) & 63] >> (6 * (i - 1))) & 0x3F;
2062 hash[i - 1] = C64[c];
2063 }
2064 hash[10] = 0;
2065 #ifdef REON
2066 if ( regExpStr[0] != '\0' ) {
2067 if ( regexec( &regExp, hash, (size_t)0, NULL, 0 ) == 0 ) {
2068 if ( cr ) fprintf( stderr, "\n" );
2069 cr = 0;
2070 #ifdef NAMA
2071 hit( rfp, hash, pkt_c->uk.key, kk, k, "ł", MAKAI_FALSE );
2072 #else /* NAMA */
2073 hit( rfp, hash, pkt_c->uk.key, kk, k, "ł", MAKAI_TRUE );
2074 #endif /* NAMA */
2075 }
2076 }
2077 #endif /* REON */
2078 if ( special ) {
2079 if ( (lfp = checkSpecial( hash, kind )) != NULL ) {
2080 if ( cr ) fprintf( stderr, "\n" );
2081 cr = 0;
2082 #ifdef NAMA
2083 hit( lfp, hash, pkt_c->uk.key, kk, k, kind, MAKAI_FALSE );
2084 #else /* NAMA */
2085 hit( lfp, hash, pkt_c->uk.key, kk, k, kind, MAKAI_TRUE );
2086 #endif /* NAMA */
2087 }
2088 }
2089 }
2090 }
2091
2092 t = pkt_hit->param64.hit[HIT_ANY].a[kk];
2093 if ( !t ) continue;
2094 nap_total += ALU_BITS;
2095 for ( k = 0; k < ALU_BITS; k++ ) {
2096 char hash[16];
2097 int hitLen;
2098 if ( !(t & ((ALU_T)1 << k)) ) continue;
2099 nap_hit++;
2100 /* “]’u */
2101 if ( !xhash_loaded ) {
2102 nblk_hit++;
2103 CALL_TR64( &pkt_c->param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash );
2104 xhash_loaded = 1;
2105 }
2106 /* ŽŤ‘‚𒲂ׂé */
2107 hitLen = 0;
2108 if ( !((pkt_hit->param64.hit[HIT_BOOL].a[kk] & ((ALU_T)1 << k))
2109 || (hitLen = wdict_ishit( pkt_hit->param64.hit, kk, k,
2110 xhash[(ALU_BITS * kk + k) & 0x3F]))) )
2111 continue;
2112 for ( i = 1; i < 11; i++ ) {
2113 unsigned c;
2114 c = (xhash[(ALU_BITS * kk + k) & 63] >> (6 * (i - 1))) & 0x3F;
2115 hash[i - 1] = C64[c];
2116 }
2117 hash[10] = 0;
2118 if ( cr ) fprintf( stderr, "\n" );
2119 cr = 0;
2120 {
2121 unsigned char len[10];
2122 #ifdef SELF
2123 static hitCount = 0;
2124 #endif /* SELF */
2125
2126 sprintf( len, "%02d", hitLen );
2127 if ( hitLen < 10 ) {
2128 /* ‚˝‚Ü‚˝‚ÜŒă‚ë‚É‹ćŘ‚č•śŽš‚Ş•t‚˘‚˝ę‡AˆęŒ…–Ú‚đ E ‚É‚ˇ‚é */
2129 if ( hash[hitLen] == '.' || hash[hitLen] == '/' ) {
2130 len[0] = 'E';
2131 }
2132 }
2133
2134 #if SEQ > 0 /* ‚ž‚Ş‚ľ‚Š‚ľASEQ == 8 ‚Ěę‡‚ľ‚Šl‚ڂĂȂ˘ */
2135 /* ˜Aƒ‚ƒm‚̏ˆ—•ű–@‚đ‚ż‚á‚ń‚Ć’Ç‚˘‚Ђ݂é‚ׂŤ‚ž‚ށA‚ß‚ń‚Ç‚­‚ł‚˘‚̂łą‚ę‚Ĺ */
2136 if ( hitLen == 0 ) [
2137 char ref;
2138 ref = hash[2];
2139 if ( ref == hash[3] && ref == hash[4] && ref == hash[5] &&
2140 ref == hash[6] && ref == hash[7] ) {
2141 if ( ref == hash[0] && ref == hash[1] ) {
2142 strcpy( len, "Ÿ" );
2143 }
2144 if ( ref == hash[1] && ref == hash[8] ) {
2145 strcpy( len, "Ÿ" );
2146 }
2147 if ( ref == hash[8] && ref == hash[9] ) {
2148 strcpy( len, "Ÿ" );
2149 }
2150 }
2151 }
2152 #endif /* SEQ */
2153
2154 #ifdef NAMA
2155 hit( ofp, hash, pkt_c->uk.key, kk, k, len, MAKAI_FALSE );
2156 #else /* NAMA */
2157 hit( ofp, hash, pkt_c->uk.key, kk, k, len, MAKAI_TRUE );
2158 #endif /* NAMA */
2159
2160 #ifdef SELF
2161 hitCount++;
2162 if ( hitCount >= SELF_LIM_CNT ) {
2163 exit( 0 );
2164 }
2165 #endif /* SELF */
2166 }
2167 }
2168 }
2169
2170 /* ‘Ź“xŒv‘Ş */
2171 status.loop += N_ALU * ALU_BITS;
2172
2173 /* -g ƒIƒvƒVƒ‡ƒ“—p‚ĚƒR[ƒh‚́AWin32 —p‚ľ‚ЂȂ˘ */
2174 /* todo UNIX Œn—pƒR[ƒh‚ŕ—v‚邊‚Č */
2175 #if defined(WIN32)
2176 if ( sCnt >= YOUSUMI ) {
2177 lCnt++;
2178 if ( lCnt > lCntMax ) {
2179 Sleep( (DWORD)10 );
2180 lCnt = 0;
2181 }
2182 }
2183 #endif /* WIN32 */
2184
2185 if ( status.loop >= status.lastloop + upd_int
2186 && (curTime = usec()) != status.lastTime ) {
2187 uint64_t diffTime;
2188 int a, b, c;
2189 /* ’ĘŽZ(’PˆĘ ktrips/sec) */
2190 diffTime = curTime - status.startTime;
2191 #ifdef SELF
2192 if ( diffTime >= SELF_LIM_SEC ) {
2193 exit( 0 );
2194 }
2195 #endif /* SELF */
2196 a = status.loop / ((1000 / USEC_SEC) * diffTime);
2197 #ifdef BENCH
2198 if ( (diffTime / USEC_SEC) > (BENCH * 60) ) {
2199 fprintf( stderr, "\n%6dktrips/s\n", a );
2200 exit( 0 );
2201 }
2202 #endif /* BENCH */
2203 /* ‹ćŠÔ(’PˆĘ trips/sec) */
2204 diffTime = curTime - status.lastTime;
2205 b = USEC_SEC * (status.loop - status.lastloop) / diffTime;
2206 #if defined(WIN32)
2207 if ( gear != DEF_GEAR ) {
2208 if ( sCnt < YOUSUMI ) {
2209 if ( b > maxSpeed ) {
2210 maxSpeed = b;
2211 /* x = l/s * (gear / (10 - gear)) / 100 */
2212 lCntMax = maxSpeed / (N_ALU * ALU_BITS) * (gear * 1000 / (10 - gear)) / 100000;
2213 if ( lCntMax < 1 ) {
2214 lCntMax = 1;
2215 }
2216 }
2217 sCnt++;
2218 }
2219 }
2220 #endif /* WIN32 */
2221 /* —\‘Ş */
2222 c = UPDATE_INTERVAL * b;
2223 /* —§‚żă‚Ş‚č‚ȂǁAŒëˇ‚Ş‚ ‚č upd_int ‚ŞŹ‚ł‚ˇ‚Ź‚˝‚Ć‚Ť‚Í
2224 ‚˘‚Ť‚Č‚č‘S•␳‚š‚¸ 1 •b(==b)‚ŽűĘ‚ł‚š‚éB */
2225 upd_int = ( upd_int + b < c ? upd_int + b : c );
2226 status.lastTime = curTime;
2227 status.lastloop = status.loop;
2228 fprintf( stderr, "%6dktrips/s [%6d.%03dktrips/s]\r",
2229 a, b / 1000, b % 1000 );
2230 cr++;
2231 }
2232 }
2233
2234 return 0;
2235 }
2236
2237 /*
2238 * Local Variables:
2239 * tab-width: 4
2240 * End:
2241 *
2242 * EOF */

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Rev URL

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26