Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 146 - (show annotations) (download) (as text)
Mon Apr 23 09:42:43 2007 UTC (16 years, 11 months ago) by notanpe
File MIME type: text/x-csrc
File size: 23694 byte(s)
有効キーのチェックを入れてみた。
1 /***********************************************************************
2 *
3 * file: mty.c
4 *
5 * まあ、待て屋。
6 *
7 * $Id$
8 *
9 */
10
11 #include <assert.h>
12 #include <ctype.h>
13 #include <errno.h>
14 #include <malloc.h>
15 #include <limits.h>
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22
23 #if defined(WIN32)
24
25 #include <windows.h>
26 #include <sys/timeb.h>
27
28 #elif defined(__GNUC__)
29
30 #include <sys/time.h>
31
32 #endif
33
34 #include "config.h"
35 #include "cp932.h"
36 #include "crypt64.h"
37 #include "desconst.h"
38 #include "expr_parse.h"
39 #include "scoreboard.h"
40 #include "synth.h"
41 #include "tr64.h"
42 #include "translate.h"
43 #include "wdict.h"
44
45 #if USE_DT
46 #include "dt4.h"
47 #endif
48
49 /* 鍵文字列 */
50 unsigned char key[8 + 8];
51 unsigned char okey[8 + 8];
52
53 /* 鍵クラス */
54 static
55 struct
56 {
57 unsigned cls;
58 unsigned map[256];
59 } kcls[8 + 8];
60
61
62 /* 拡張鍵クラス */
63 #define KCLS_DT0 64
64 #define KCLS_DT1 128
65 #define KCLS_K2 256
66
67 #if USE_DT
68 /* 鍵キメ用辞書インデクス */
69 struct DT *kd[8 + 8];
70
71 /* 辞書インデクス */
72 struct DT *dtidx[0x100 + 1];
73 #endif
74
75 /* 指定されたクラスと入っているキーから、classify を行う */
76 void
77 key_make_map(int n)
78 {
79 int i, j;
80 unsigned c = kcls[n].map[key[n]];
81
82 #if USE_DT
83 if (3 <= n && n < 7 && kd[n - 3])
84 {
85 /* 辞書のケツの文字。後ろにナニヤラキャラクタが来る */
86 c = kd[n - 3]->c[0];
87 if ((0x81 <= c && c <= 0x9F)
88 || (0xE0 <= c && c <= 0xFC))
89 c = KCLS_K2;
90 else
91 c = (cp932[256 * key[n]]
92 | cp932[256 * (key[n] ^ 0x80)]);
93 #if DEBUG>=1
94 printf("*n=%d, key=%02X, cls=%04X\n",
95 n,
96 key[n],
97 c);
98 #endif
99 }
100 else if (2 <= n && n < 6 && kd[n - 2])
101 {
102 return;
103 }
104 else if (1 <= n && n < 5 && kd[n - 1])
105 {
106 return;
107 }
108 else if (1 <= n && n < 5 && !kd[n - 1]
109 //&& (c & KCLS_K2)
110 && (c & KCLS_DT1))
111 {
112 /* 漢字2文字を拾っていきまつ */
113 #if DEBUG>=1
114 printf("(%d)%02X %02X(%02X:%02X:%02X:%02X)\n",
115 n, key[n - 1], key[n],
116 cp932[(256 * key[n - 1] + key[n])],
117 cp932[(256 * key[n - 1] + key[n]) ^ 0x0080],
118 cp932[(256 * key[n - 1] + key[n]) ^ 0x8000],
119 cp932[(256 * key[n - 1] + key[n]) ^ 0x8080]);
120 #endif
121 if (n != 1 && n != 2
122 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x0080] & KCLS_DT1))
123 key[n] ^= 0x80;
124 else if (n != 2 && n != 3
125 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8000] & KCLS_DT1))
126 key[n - 1] ^= 0x80;
127 else if (n > 3 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8080] & KCLS_DT1))
128 key[n - 1] ^= 0x80, key[n] ^= 0x80;
129 if (cp932[256 * key[n - 1] + key[n]] & KCLS_DT1)
130 {
131 for (kd[n - 1] = dtidx[key[n - 1]];
132 kd[n - 1]->c[1] != key[n];
133 kd[n - 1]++)
134 assert(kd[n - 1]->c[0] == key[n - 1]);
135 #if DEBUG>=1
136 printf("(%02X%02X:%02X%02X)%c%c%c%c\n",
137 kd[n - 1]->c[0],
138 kd[n - 1]->c[1],
139 kd[n - 1]->c[2],
140 kd[n - 1]->c[3],
141 kd[n - 1]->c[0],
142 kd[n - 1]->c[1],
143 kd[n - 1]->c[2],
144 kd[n - 1]->c[3]);
145 #endif
146 return;
147 }
148 }
149 else if (n < 4 && (c & KCLS_DT0) && kd[n] == NULL)
150 {
151 /* カタカナ埋め込みいきます */
152 assert(kd[n] == NULL);
153 #if DEBUG>=1
154 printf("n=%d, key=%02X\n", n, key[n]);
155 #endif
156 kd[n] = dtidx[key[n]];
157 if (!kd[n]
158 && !(n == 1 || n == 2)
159 && dtidx[key[n] ^ 0x80])
160 {
161 key[n] ^= 0x80;
162 kd[n] = dtidx[key[n]];
163 }
164 if (kd[n])
165 return;
166 }
167 else
168 {
169 kd[n] = NULL;
170 }
171 #endif
172
173 /* 最後の部分は class map を生成する必要ナシ */
174 if (n >= 6)
175 return;
176
177 for (i = 0; i < 256; i++)
178 {
179 unsigned bm = 0;
180 #if 1
181 if (c & KCLS_K1)
182 {
183 if (cp932[256 * key[n] + i] & KCLS_K1)
184 bm |= KCLS_K2 | (cp932[256 * key[n] + i] & KCLS_DT1);
185 if (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
186 bm |= KCLS_K2 | (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_DT1);
187 #if 0
188 bm |= ((cp932[256 * key[n] + i] & KCLS_K1)
189 || (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
190 ? KCLS_K2 : 0);
191 #endif
192 }
193 if (c & (KCLS_AN | KCLS_KA | KCLS_K2))
194 for (j = 0; j < 256; j++)
195 {
196 bm |= cp932[256 * i + j] & (KCLS_AN | KCLS_KA | KCLS_K1
197 | KCLS_DT0);
198 #if 0
199 if (j >= 127 && !(n == 0 || n == 1))
200 break;
201 #endif
202 }
203 kcls[n + 1].map[i] = bm;
204 #endif
205 if (i >= 128 && !(n == 0 || n == 1))
206 kcls[n + 1].map[i - 128] |= kcls[n + 1].map[i];
207 }
208
209 if (n < 6)
210 kcls[n + 1].map[0x00] = kcls[n + 1].map[0x80] = 0;
211 if (n == 6)
212 kcls[7].map[0x00] |= KCLS_AN;
213 }
214
215 #if USE_DT
216 unsigned
217 dt_get(int kdn,
218 int xn,
219 int n,
220 int ch)
221 {
222 int i;
223 #if DEBUG>=1
224 printf("*dt_get(%d)%c%c%c%c(%02X%02X:%02X%02X)->ch=%d",
225 n,
226 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
227 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
228 ch);
229 #endif
230 /* まずは数える */
231 for (i = 0;
232 kd[kdn][i].c[xn] == kd[kdn]->c[xn];
233 i++)
234 ;
235 assert(i > 0);
236 kd[kdn] += ch % i;
237 #if DEBUG>=1
238 printf("/%d\n dt_get: %c%c%c%c(%02X%02X:%02X%02X)->ch=%d\n",
239 i,
240 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
241 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
242 ch);
243 #endif
244 return kd[kdn]->c[n];
245 }
246 #endif
247
248 /* マップから文字を拾ってセット */
249 unsigned
250 key_set(int n, unsigned ch)
251 {
252 int cnt = 0, i;
253
254 #if USE_DT
255 if (3 <= n && n < 7 && kd[n - 3])
256 {
257 return dt_get(n - 3, 2, 3, ch);
258 return kd[n - 3]->c[3];
259 }
260 else if (2 <= n && n < 6 && kd[n - 2])
261 {
262 return dt_get(n - 2, 1, 2, ch);
263 return kd[n - 2]->c[2];
264 }
265 else if (1 <= n && n < 5 && kd[n - 1])
266 {
267 return dt_get(n - 1, 0, 1, ch);
268 return kd[n - 1]->c[1];
269 }
270 #endif
271
272 #if DEBUG>=3
273 if (cnt == 0)
274 {
275 printf("n=%d, ch=%d, (n-1)=%02X\n", n, ch, key[n - 1]);
276 int j;
277 for (i = 0; i < 16; i++)
278 {
279 printf("map[0x%02X] =", 16 * i);
280 for (j = 0; j < 16; j++)
281 printf(" %03X", kcls[n].map[16 * i + j]);
282 printf("\n");
283 }
284 }
285 #endif
286 for (i = 0; i < 256; i++)
287 {
288 if (kcls[n].map[i])
289 {
290 if (ch-- == 0)
291 return i;
292 cnt++;
293 }
294 if (n != 1 && n != 2 && i >= 127)
295 break;
296 }
297 /* 見つからなかったのでもいっぺん */
298 assert(cnt > 0);
299 ch %= cnt;
300 for (i = 0; i < 256; i++)
301 if (kcls[n].map[i])
302 {
303 if (ch-- == 0)
304 return i;
305 }
306 assert(!"not matched");
307 return 0;
308 }
309
310 /* bitwise key をセット */
311 static
312 void
313 key_set64(struct KEY *key64,
314 int n,
315 unsigned k,
316 unsigned vk,
317 unsigned sk)
318 {
319 int i, j;
320 if (!((vk | sk) & 0x7F))
321 return;
322
323 for (i = 0; i < 7; i++)
324 {
325 if (n == 7 && i < N_STRIDE) continue;
326 if (sk & (1 << i))
327 {
328 /* セット */
329 int o = tr_pc1[n][6 - i] - 1;
330 if (o < 28)
331 {
332 assert(o >= 0);
333 for (j = 0; j < N_ALU; j++)
334 key64->k[0][0][o].a[j]
335 = key64->k[0][1][o].a[j]
336 = -!!(k & (1 << i));
337 }
338 else
339 {
340 assert(o >= 28);
341 assert(o < 56);
342 for (j = 0; j < N_ALU; j++)
343 key64->k[1][0][o - 28].a[j]
344 = key64->k[1][1][o - 28].a[j]
345 = -!!(k & (1 << i));
346 }
347 }
348 else if (vk & (1 << i))
349 {
350 /* 反転 */
351 int o = tr_pc1[n][6 - i] - 1;
352 if (o < 28)
353 {
354 assert(o >= 0);
355 for (j = 0; j < N_ALU; j++)
356 key64->k[0][0][o].a[j]
357 = key64->k[0][1][o].a[j]
358 = ~key64->k[0][0][o].a[j];
359 }
360 else
361 {
362 assert(o >= 28);
363 assert(o < 56);
364 for (j = 0; j < N_ALU; j++)
365 key64->k[1][0][o - 28].a[j]
366 = key64->k[1][1][o - 28].a[j]
367 = ~key64->k[1][0][o - 28].a[j];
368 }
369 }
370 }
371 }
372
373 /* 指定されたクラスの開始値にリセット
374 直前の文字のクラスに縛られる */
375 int
376 key_reset(int n)
377 {
378 if (n >= 8)
379 return 1;
380 if (n == 7)
381 {
382 key[7] = 0;
383 return 1;
384 }
385
386 /* 0-2 文字目はランダムに決める
387 3 文字目以降は初期値に */
388 if (n >= 3)
389 key[n] = key_set(n, 0);
390 else
391 key[n] = key_set(n, rand());
392
393 #if DEBUG>=3
394 printf("key[%d]=%02X ncls=%04X\n", n, key[n], kcls[n].map[key[n]]);
395 #endif
396
397 /* セットされた文字を元に、次キャラの文字クラスを決める */
398 key_make_map(n);
399
400 return key_reset(n + 1);
401 }
402
403 /* 指定された鍵空間の中で、キーをひとつ進める
404 安全にインクリメントできた場合 true を返す */
405 static
406 int
407 key_inc(int n)
408 {
409 if (n >= 8)
410 return 0;
411 else if (n == 7)
412 {
413 /* 最後のバイト */
414 key[7] = (key[7] + (1 << N_STRIDE)) & 0x7F;
415 if (key[7]) return 1;
416 else return 0;
417 }
418 else if (key_inc(n + 1)
419 /*
420 && key_inc(n + 1)
421 && key_inc(n + 1)
422 && key_inc(n + 1)*/
423 )
424 return 1;
425
426 /* Salt はインクリメントしない約束にする */
427 if (n == 1 || n == 2)
428 return 1;
429
430 #if DEBUG>=3
431 printf("key_inc(n=%d,ck=%02X)\n", n, key[n]);
432 #endif
433
434 #if USE_DT
435 /* 辞書語はインクリメントしていい約束にする */
436 if (3 <= n && n < 7 && kd[n - 3])
437 {
438 if ((key[n - 3] & 0x7F) == ((kd[n - 3] + 1)->c[0] & 0x7F)
439 && (key[n - 2] & 0x7F) == ((kd[n - 3] + 1)->c[1] & 0x7F)
440 && (key[n - 1] & 0x7F) == ((kd[n - 3] + 1)->c[2] & 0x7F))
441 {
442 memcpy(&key[n - 3], &(++kd[n - 3])->c[0], 4);
443 #if DEBUG>=2
444 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
445 kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3],
446 kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3]);
447 #endif
448 return 1;
449 }
450 else
451 {
452 return 0;
453 }
454 }
455 else if (2 <= n && n < 6 && kd[n - 2])
456 {
457 if ((key[n - 2] & 0x7F) == ((kd[n - 2] + 1)->c[0] & 0x7F)
458 && (key[n - 1] & 0x7F) == ((kd[n - 2] + 1)->c[1] & 0x7F))
459 {
460 memcpy(&key[n - 2], &(++kd[n - 2])->c[0], 4);
461 #if DEBUG>=2
462 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
463 kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3],
464 kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3]);
465 #endif
466 return 1;
467 }
468 else
469 {
470 return 0;
471 }
472 if (kd[n - 2]->c[0] == key[n - 2])
473 return 1;
474 else
475 return 0;
476 }
477 else if (1 <= n && n < 5 && kd[n - 1])
478 {
479 unsigned c2 = kd[n - 1]->c[0];
480 if ((0x81 <= c2 && c2 <= 0x9F)
481 || (0xE0 <= c2 && c2 <= 0xFC))
482 {
483 kd[n - 1] = NULL;
484 #if 0
485 if (!(n == 1 && n == 2))
486 key[n] &= 0x7F;
487 if (!(n == 2 && n == 3))
488 key[n - 1] &= 0x7F;
489 #endif
490 key_make_map(n - 1);
491 }
492 else if ((key[n - 1] & 0x7F) == ((kd[n - 1] + 1)->c[0] & 0x7F))
493 {
494 memcpy(&key[n - 1], &(++kd[n - 1])->c[0], 4);
495 #if DEBUG>=2
496 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
497 kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3],
498 kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3]);
499 #endif
500 return 1;
501 }
502 else
503 {
504 return 0;
505 }
506 #if 0
507 if (kd[n - 1]->c[0] == key[n - 1])
508 return 1;
509 else
510 return 0;
511 #endif
512 }
513 else if (n < 4 && kd[n])
514 {
515 if (0 && kd[n]->c[0] == key[n])
516 return 1;
517 kd[n] = NULL;
518 #if 0
519 if (!(n == 1 || n == 2))
520 key[n] &= 0x7F;
521 #endif
522 }
523 #endif
524
525 /* 実際に増やしてみる */
526 assert(n >= 3);
527 for (;;)
528 {
529 if (n <= 3
530 && !(key[n] & 0x80)
531 && kcls[n].map[key[n] ^ 0x80] & (KCLS_DT0))
532 {
533 /* 半角カタカナの1バイト目 */
534 key[n] ^= 0x80;
535 }
536 else
537 {
538 key[n] = (key[n] & 0x7F) + 1;
539 if (key[n] >= 0x80)
540 return 0;
541 }
542
543 if (kcls[n].map[key[n]])
544 {
545 key_make_map(n);
546 key_reset(n + 1);
547 return 1;
548 }
549 }
550 while (++key[n] < 0x80)
551 {
552 if (kcls[n].map[key[n]])
553 {
554 key_make_map(n);
555 key_reset(n + 1);
556 return 1;
557 }
558 }
559 return 0;
560 }
561
562 /* 鍵を完全にリセットする
563 Saltもセットし直す */
564 static
565 void
566 key_init()
567 {
568 int i, j;
569
570 #if USE_DT
571 /* 辞書を、インデクスを作りながらマップにはめこんで逝く
572 辞書はコード順昇順に並んでるものとする */
573 for (i = 0; i < dtcnt; i++)
574 {
575 unsigned c = dt[i].c[0];
576
577 assert(dt[i].c[0]
578 && dt[i].c[1]
579 && dt[i].c[2]
580 && dt[i].c[3]);
581
582 /* BSD 鯖でしにそうな文字は残念ながら除外 */
583 assert((dt[i].c[0] & 0x7F)
584 && (dt[i].c[1] & 0x7F)
585 && (dt[i].c[2] & 0x7F)
586 && (dt[i].c[3] & 0x7F));
587
588 /* インデクス */
589 if (!dtidx[c])
590 dtidx[c] = &dt[i];
591
592 if ((0x81 <= c && c <= 0x9F)
593 || (0xE0 <= c && c <= 0xFC))
594 {
595 /* 全角なので、2バイトきまった時点で立てる */
596 cp932[256 * c + dt[i].c[1]] |= KCLS_DT1;
597 }
598 else if (0xA1 <= c && c <= 0xDF)
599 {
600 /* 半角カナ */
601 for (j = 0; j < 256; j++)
602 cp932[256 * c + j] |= KCLS_DT0;
603 }
604 }
605 /* ケツ、ちうか番人 */
606 dtidx[0x100] = &dt[i];
607 #endif
608
609 key[8] = 0;
610
611 /* 初期マップを組む */
612 for (i = 0; i < 256; i++)
613 {
614 unsigned bm = 0;
615 kcls[0].map[i] = 0;
616 for (j = 0; j < 256; j++)
617 bm |= cp932[256 * i + j];
618 kcls[0].map[i] = bm & (KCLS_AN | KCLS_KA | KCLS_K1
619 | KCLS_DT0
620 );
621 if (i >= 128)
622 kcls[0].map[i - 128] |= kcls[0].map[i];
623 }
624
625 key_reset(0);
626 }
627
628 /***************************************************************
629 *
630 * 固定キーの生成
631 *
632 * 一見 Big Endian に非対応のように見えるだろうが
633 * 随所でに散らばっている kludge により
634 * ALU_T が 64 ビットである限り、これで問題なく動く。
635 *
636 */
637
638 static
639 void
640 key_init_sk(struct KEY *key)
641 {
642 int i, j;
643 int o;
644 uint64_t m;
645
646 for (i = 5, m = 0xFFFFFFFF00000000ULL;
647 i >= 0;
648 m ^= (m >> (1 << --i)))
649 {
650 o = tr_pc1[7][6 - i] - 1;
651 #if DEBUG>=2
652 printf("%d:%d->%2d: %08X%08X\n",
653 N_Q, i, o,
654 (unsigned)(m >> 32),
655 (unsigned)m);
656 #endif
657 for (j = 0; j < N_Q; j++)
658 if (o < 28)
659 key->k[0][0][o ].q[j] = key->k[0][1][o ].q[j] = m;
660 else
661 key->k[1][0][o - 28].q[j] = key->k[1][1][o - 28].q[j] = m;
662 }
663 #if N_STRIDE==7
664 /* bit 6 は Little Endian として扱う */
665 o = 0;
666 assert(tr_pc1[7][0] - 1 == o);
667 assert(N_Q == 2);
668 key->k[0][0][o].q[0] = key->k[0][1][o].q[0] = 0x0000000000000000ULL;
669 key->k[0][0][o].q[1] = key->k[0][1][o].q[1] = 0xFFFFFFFFFFFFFFFFULL;
670 #endif
671 }
672
673 /***************************************************************
674 *
675 * Salt のセット
676 * オペランドのオフセットを書き換えて回ってるので注意
677 *
678 */
679
680 #if N_STRIDE == 6
681 #define C(c,i,j,o) (*(int8_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
682 #elif N_STRIDE == 7
683 #define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
684 #endif
685
686 void
687 set_salt(signed char *code,
688 unsigned char const *k)
689 {
690 int i, j;
691
692 for (i = 0; i < 2; i++)
693 {
694 unsigned s = k[1 + i] & 255;
695 if (s > 'z')
696 s = 0;
697 else if (s >= 'a')
698 s = s - 'a' + 2 + 10 + 26;
699 else if (s >= 'A')
700 s = s - 'A' + 2 + 10;
701 else if (s >= '.')
702 s = s - '.';
703 else
704 s = 0;
705
706 #if DEBUG>=1
707 printf("Salt %d:%3o\n", i, s & 63);
708 #endif
709 for (j = 0; j < 6; j++)
710 {
711 #if DEBUG>=2
712 //printf("Salt %d:%d %+3d:%+3d",
713 printf("Salt %d:%d %08lX:%08lX",
714 i, j,
715 C(code, i, j, 0),
716 C(code, i, j, 24));
717 #endif
718 if (s & (1 << j))
719 {
720 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
721 C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
722 }
723 else
724 {
725 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
726 C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
727 }
728 C(code, i, j, 12) = sizeof(WS_T) * (((4 * i + j + 7) & 31) - 16);
729 C(code, i, j, 36) = sizeof(WS_T) * (((4 * i + j + 23) & 31) - 16);
730 #if DEBUG>=2
731 //printf(" => %+3d:%+3d\n",
732 printf(" => %08lX:%08lX\n",
733 C(code, i, j, 0),
734 C(code, i, j, 24));
735 #endif
736 }
737 }
738 }
739
740 static
741 uint32_t
742 usec()
743 {
744 static uint32_t epoch = 0;
745 uint32_t sec, msec;
746
747 #if !defined(WIN32)
748 struct timeval tv;
749 gettimeofday(&tv, NULL);
750 sec = tv.tv_sec;
751 msec = tv.tv_usec / 10000;
752 #else
753 struct timeb tm;
754 ftime(&tm);
755 sec = tm.time;
756 msec = tm.millitm / 10;
757 #endif
758
759 if ( epoch == 0 ) {
760 epoch = sec;
761 }
762
763 return ((sec - epoch) * 100 + msec);
764 }
765
766 static
767 int
768 log_printf(FILE *ofp, char const *fmt, ...)
769 {
770 int r;
771 va_list ap;
772 va_start(ap, fmt);
773 vfprintf(stdout, fmt, ap);
774 r = vfprintf(ofp, fmt, ap);
775 va_end(ap);
776 if (r > 0)
777 return r;
778 perror("log_printf");
779 exit(errno);
780 }
781
782 /***************************************************************
783 *
784 * メインループとか
785 *
786 */
787
788 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
789 ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
790
791 int
792 main(int argc, char *argv[])
793 {
794 int i;
795 int mincnt;
796 int nblk_hit, nblk_total;
797 int nap_hit, nap_total;
798 signed char *code = NULL;
799 FILE *ofp;
800 FILE *sfp; /* scoreboard */
801 struct ITREE *root_expr;
802 int cr;
803 #ifdef KEYCHECK
804 unsigned int ok, ng;
805 #endif
806
807 int xhash_loaded;
808
809 #define LOOP_FACTOR 128000 /* こんなもんでいいか */
810 #define UPDATE_INTERVAL 8 /* 速度表示の間隔 秒 */
811 #define AVG_SPD 480000 /* 平均速度の初期値 trips/s */
812 struct status {
813 uint32_t startTime; /* 開始時刻 ミリ秒 */
814 uint32_t lastTime; /* 最後に表示した時刻 ミリ秒 */
815 uint32_t loop; /* 総検索個数 % LOOP_FACTOR */
816 uint32_t mloop; /* 総検索個数 / LOOP_FACTOR */
817 uint32_t lastloop; /* 最後に表示した時の loop */
818 } status;
819 uint32_t upd_int = AVG_SPD * UPDATE_INTERVAL;
820 /*
821 平均速度 (trips/s) * UPDATE_INTERVAL が UINT32_MAX を超えると発狂する。
822 UINT32_MAX = 4294967295, 平均速度 = 100Mtrips/s なら、
823 4294967295 / (100 * 1000 * 1000) = 42.949 秒まで。(和良
824 LOOP_FACTOR が平均速度より十分小さければ、ほぼ指定間隔になる。
825 LOOP_FACTOR * UINT32_MAX + LOOP_FACOTR 個検索するとオーバーフローする。w
826 */
827
828 #if 0
829 if (argc < 2)
830 {
831 fprintf(stderr, "式きぼんぬ\n");
832 return 1;
833 }
834 #endif
835
836 /* 魔改造 いきなり優先度下げ */
837 #if defined(WIN32)
838 SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
839 #endif
840
841 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
842
843 /* t[16] は、内部演算で使用する、all 1 が入っている */
844 for (i = 0; i < N_ALU; i++)
845 param64.t[T_INV].a[i] = -1;
846
847 /* 固定キーの生成 */
848 key_init_sk(&key64);
849
850 /* キースケジュールをここに押し込めておく
851 従来は crypt64.S 内で完結するように引いていた */
852 for (i = 0; i < 28; i++)
853 key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];
854
855 /* タゲ読み込み */
856 root_expr = expr_parse("target.txt");
857
858 /* コードを生成・展開 */
859 sfp = scoreboard_open();
860 fwrite(crypt64_sta, 1, crypt64_end - crypt64_sta, sfp); /* prologue */
861 synth_synthesize(sfp, root_expr);
862 fwrite(crypt64_ep, 1, crypt64_ep_end - crypt64_ep, sfp); /* epilogue */
863
864 /* コードをメモリに貼り付ける */
865 code = scoreboard_map(sfp);
866
867 /* キーの初期化 */
868 srand(time(NULL));
869 key_init();
870 set_salt(code, key);
871 for (i = 0; i < 8; i++)
872 key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
873
874 #if DEBUG>=1
875 printf("key=%p param=%p\n", &key64, &param64);
876 #endif
877 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
878 assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
879
880 if ((ofp = fopen("log.txt", "at")) == NULL)
881 {
882 perror("log.txt");
883 return errno;
884 }
885
886 setvbuf(ofp, NULL, _IONBF, BUFSIZ); /* XXX MSVCRT では _IOLBF が期待通りに動作しない */
887
888 mincnt = 0x7FFFFFFF;
889 nblk_hit = nblk_total = 0;
890 nap_hit = nap_total = 0;
891 cr = 0;
892 memset( &status, 0, sizeof( struct status ) );
893 status.startTime = status.lastTime = usec();
894 #ifdef KEYCHECK
895 ok = ng = 0;
896 #endif
897 /* 探索ループだぞっと */
898 for (;;)
899 {
900 uint64_t cnt;
901 int cnt1, cnt2;
902 int k, kk;
903
904 /* 鍵のセット */
905 for (i = 0; i < 8; i++)
906 {
907 key_set64(&key64, i, key[i], key[i] ^ okey[i], 0);
908 okey[i] = key[i];
909 }
910
911 /* 呼ぶ!
912 LR 初期化は、サブモジュール内で行うべし
913 FASTCALL に準じた呼び出しのため、
914 ホントはいろいろレジスタが破壊されるハズ…なんだが。 */
915 cnt = CALL_CRYPT64(code, key64.k, param64.lr);
916
917 #if DEBUG>=1
918 cnt2 = (int32_t)(cnt >> 32);
919 cnt1 = (int32_t)cnt;
920 if (mincnt > cnt1 && cnt1 > 0)
921 {
922 mincnt = cnt1;
923 if (cr)
924 fprintf(stderr, "\n");
925 cr = 0;
926 fprintf(stderr, "cycle=%6d/%6d\n", cnt1, cnt2);
927 }
928 #endif
929
930 /* ヒットしたときの処理 */
931 xhash_loaded = 0;
932 for (kk = 0; kk < N_ALU; kk++)
933 {
934 ALU_T t;
935 if (!(kk & (N_ALU / N_Q - 1)))
936 nblk_total++, xhash_loaded = 0;
937
938 t = param64.t[HIT_ANY].a[kk];
939 #ifndef KEYCHECK
940 if (!t)
941 continue;
942 #endif
943
944 nap_total += ALU_BITS;
945
946 for (k = 0; k < ALU_BITS; k++)
947 {
948 static uint64_t xhash[64];
949 char hash[16];
950 unsigned char buf[32];
951 time_t tloc;
952
953 #ifndef KEYCHECK
954 if (!(t & ((ALU_T)1 << k)))
955 continue;
956 #endif
957
958 nap_hit++;
959
960 /* 転置 */
961 if (!xhash_loaded)
962 {
963 nblk_hit++;
964 CALL_TR64(&param64.lr[0][0].q[kk / (N_ALU / N_Q)], xhash);
965 xhash_loaded = 1;
966 }
967
968 #ifndef KEYCHECK
969 /* 辞書を調べる */
970 if (!((param64.t[HIT_BOOL].a[kk] & ((ALU_T)1 << k))
971 || wdict_ishit(param64.t,
972 kk, k,
973 xhash[(ALU_BITS * kk + k) & 0x3F])))
974 continue;
975 #endif
976
977 for (i = 1; i < 11; i++)
978 {
979 unsigned c = 0;
980 c = (xhash[(ALU_BITS * kk + k) & 63] >> (6 * (i - 1))) & 0x3F; /* XXX */
981 hash[i - 1] = C64[c];
982 }
983 hash[10] = 0;
984
985 memcpy(buf, key, 32);
986 buf[8] = buf[9] = 0;
987 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
988 time( &tloc );
989 if (translate(buf, 0, 1))
990 {
991 #ifdef KEYCHECK
992 ok++;
993 if ( ok + ng >= 100000000 ) {
994 printf( "\nok = %lu, ng = %lu\n", ok, ng );
995 exit( 1 );
996 }
997 #endif
998 if (cr)
999 fprintf(stderr, "\n");
1000 cr = 0;
1001 /* 魔改造 ヒットした日時を表示 */
1002 log_printf(ofp,
1003 "◆%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X) %s",
1004 hash,
1005 buf,
1006 buf[0], buf[1], buf[2], buf[3],
1007 buf[4], buf[5], buf[6], buf[7],
1008 buf[8], ctime(&tloc) );
1009 }
1010 else
1011 {
1012 #ifdef KEYCHECK
1013 ng++;
1014 if ( ok + ng >= 100000000 ) {
1015 printf( "\nok = %lu, ng = %lu\n", ok, ng );
1016 exit( 1 );
1017 }
1018 #endif
1019 /* 魔改造 failed も表示する */
1020 if (cr)
1021 fprintf(stderr, "\n");
1022 cr = 0;
1023 log_printf(ofp,
1024 "◆%s (%02X %02X %02X %02X %02X %02X %02X %02X ) %s",
1025 hash,
1026 buf[0], buf[1], buf[2], buf[3],
1027 buf[4], buf[5], buf[6], buf[7], ctime(&tloc) );
1028 }
1029 printf( "ok = %lu, ng = %lu\n", ok, ng );
1030 }
1031 }
1032
1033 status.loop += N_ALU * ALU_BITS;
1034 if ( status.loop >= upd_int )
1035 {
1036 /*
1037 ここで更新間隔のチェックをすれば、高速マシンで誤差の大きい速度表示が
1038 出るのを防げる。
1039 だがそれをすると普通のマシンでムダな usec() 呼び出しをすることになる。
1040 だからやらない。決して手抜きではない。
1041 */
1042 uint32_t curTime, diffTime;
1043 int a, b, c;
1044
1045 #ifdef SPDEBUG
1046 putchar( '\n' );
1047 printf( "mloop = %d, loop = %d\n", status.mloop, status.loop );
1048 #endif
1049 curTime = usec();
1050 diffTime = curTime - status.lastTime;
1051 b = (status.loop - status.lastloop) * 100 / diffTime;
1052 status.mloop += ( status.loop / LOOP_FACTOR );
1053 status.loop %= LOOP_FACTOR;
1054 diffTime = curTime - status.startTime;
1055 if ( diffTime >= 1000000000 ) {
1056 c = 1000000;
1057 } else if ( diffTime >= 100000000 ) {
1058 c = 100000;
1059 } else if ( diffTime >= 10000000 ) {
1060 c = 10000;
1061 } else if ( diffTime >= 1000000 ) {
1062 c = 1000;
1063 } else if ( diffTime >= 100000 ) {
1064 c = 100;
1065 } else if ( diffTime >= 10000 ) {
1066 c = 10;
1067 } else {
1068 c = 1;
1069 }
1070 a = status.mloop * (LOOP_FACTOR / (10 * c)) / (diffTime / c);
1071 upd_int = b * UPDATE_INTERVAL;
1072 upd_int = upd_int / LOOP_FACTOR * LOOP_FACTOR;
1073 #ifdef SPDEBUG
1074 {
1075 #ifndef USE_MMX
1076 double d;
1077 d = ((double)status.mloop * LOOP_FACTOR / 1000.0) / ((double)diffTime / 100.0);
1078 printf( "d = %f\n", d );
1079 #endif
1080 printf( "mloop = %d, loop = %d\n", status.mloop, status.loop );
1081 printf( "%d - %d = %d\n", curTime, status.startTime, curTime - status.startTime );
1082 printf( "%d - %d = %d\n", curTime, status.lastTime, curTime - status.lastTime );
1083 printf( "c = %d\n", c );
1084 printf( "upd_int = %d\n", upd_int );
1085 }
1086 #endif
1087 status.lastTime = curTime;
1088 status.lastloop = status.loop;
1089 #if DEBUG>=1
1090 fprintf(stderr,
1091 "%5d/%5d(%3d%%)",
1092 nblk_hit, nblk_total, 100 * nblk_hit / nblk_total);
1093 nblk_hit = nblk_total = 0;
1094 if (nap_total)
1095 fprintf(stderr,
1096 " %5d/%5d(%3d%%)",
1097 nap_hit, nap_total, 100 * nap_hit / nap_total);
1098 else
1099 fprintf(stderr,
1100 " -----/-----(---%%)");
1101 nap_hit = nap_total = 0;
1102 #endif
1103 fprintf( stderr,
1104 "%6dktrips/s [%6d.%03dktrips/s]\r",
1105 a, b / 1000, b % 1000 );
1106 /* 魔改造 速度表示は残さない */
1107 cr = 0;
1108 }
1109 #if 1
1110 if (!key_inc(3))
1111 {
1112 #if DEBUG>=2
1113 printf("********************************\n");
1114 #endif
1115 key_reset(0);
1116 set_salt(code, key);
1117 for (i = 0; i < 8; i++)
1118 key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
1119 }
1120 #endif
1121 }
1122
1123 return 0;
1124 }
1125
1126 /*
1127 * Local Variables:
1128 * tab-width: 4
1129 * End:
1130 *
1131 * 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