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