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