Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


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