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