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 46 - (show annotations) (download) (as text)
Wed Mar 28 08:05:12 2007 UTC (17 years ago) by chapuni
Original Path: mty/mty.c
File MIME type: text/x-csrc
File size: 19809 byte(s)
これまで仕込んできたモジュールを晴れて結合できます。ターゲット数制限が変わりました。制限がかかってる場所があるため、無制限ではありません。また、比較器前段を、 cmp.S を用いずに自前で生成するようにしたため、タゲ数が少ないときにやや速度が上がります。
そんなワケで、cmp.S および expr.[ch] は、晴れて用済みになりました。
ついでにもう使うことがないであろう x64-sse.S も、用済み扱いにしました。

Cycle表示は、デバッグ版でないときは殺すようにしました。C2Dなどではどうやら RDTSC 命令がエミュレート実行されているもようです。
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 "translate.h"
42
43 #if USE_DT
44 #include "dt4.h"
45 #endif
46
47 /* 鍵文字列 */
48 unsigned char key[8 + 8];
49 unsigned char okey[8 + 8];
50
51 /* 鍵クラス */
52 static
53 struct
54 {
55 unsigned cls;
56 unsigned map[256];
57 } kcls[8 + 8];
58
59
60 /* 拡張鍵クラス */
61 #define KCLS_DT0 64
62 #define KCLS_DT1 128
63 #define KCLS_K2 256
64
65 #if USE_DT
66 /* 鍵キメ用辞書インデクス */
67 struct DT *kd[8 + 8];
68
69 /* 辞書インデクス */
70 struct DT *dtidx[0x100 + 1];
71 #endif
72
73 /* 指定されたクラスと入っているキーから、classify を行う */
74 void
75 key_make_map(int n)
76 {
77 int i, j;
78 unsigned c = kcls[n].map[key[n]];
79
80 #if USE_DT
81 if (3 <= n && n < 7 && kd[n - 3])
82 {
83 /* 辞書のケツの文字。後ろにナニヤラキャラクタが来る */
84 c = kd[n - 3]->c[0];
85 if ((0x81 <= c && c <= 0x9F)
86 || (0xE0 <= c && c <= 0xFC))
87 c = KCLS_K2;
88 else
89 c = (cp932[256 * key[n]]
90 | cp932[256 * (key[n] ^ 0x80)]);
91 #if DEBUG>=1
92 printf("*n=%d, key=%02X, cls=%04X\n",
93 n,
94 key[n],
95 c);
96 #endif
97 }
98 else if (2 <= n && n < 6 && kd[n - 2])
99 {
100 return;
101 }
102 else if (1 <= n && n < 5 && kd[n - 1])
103 {
104 return;
105 }
106 else if (1 <= n && n < 5 && !kd[n - 1]
107 //&& (c & KCLS_K2)
108 && (c & KCLS_DT1))
109 {
110 /* 漢字2文字を拾っていきまつ */
111 #if DEBUG>=1
112 printf("(%d)%02X %02X(%02X:%02X:%02X:%02X)\n",
113 n, key[n - 1], key[n],
114 cp932[(256 * key[n - 1] + key[n])],
115 cp932[(256 * key[n - 1] + key[n]) ^ 0x0080],
116 cp932[(256 * key[n - 1] + key[n]) ^ 0x8000],
117 cp932[(256 * key[n - 1] + key[n]) ^ 0x8080]);
118 #endif
119 if (n != 1 && n != 2
120 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x0080] & KCLS_DT1))
121 key[n] ^= 0x80;
122 else if (n != 2 && n != 3
123 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8000] & KCLS_DT1))
124 key[n - 1] ^= 0x80;
125 else if (n > 3 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8080] & KCLS_DT1))
126 key[n - 1] ^= 0x80, key[n] ^= 0x80;
127 if (cp932[256 * key[n - 1] + key[n]] & KCLS_DT1)
128 {
129 for (kd[n - 1] = dtidx[key[n - 1]];
130 kd[n - 1]->c[1] != key[n];
131 kd[n - 1]++)
132 assert(kd[n - 1]->c[0] == key[n - 1]);
133 #if DEBUG>=1
134 printf("(%02X%02X:%02X%02X)%c%c%c%c\n",
135 kd[n - 1]->c[0],
136 kd[n - 1]->c[1],
137 kd[n - 1]->c[2],
138 kd[n - 1]->c[3],
139 kd[n - 1]->c[0],
140 kd[n - 1]->c[1],
141 kd[n - 1]->c[2],
142 kd[n - 1]->c[3]);
143 #endif
144 return;
145 }
146 }
147 else if (n < 4 && (c & KCLS_DT0) && kd[n] == NULL)
148 {
149 /* カタカナ埋め込みいきます */
150 assert(kd[n] == NULL);
151 #if DEBUG>=1
152 printf("n=%d, key=%02X\n", n, key[n]);
153 #endif
154 kd[n] = dtidx[key[n]];
155 if (!kd[n]
156 && !(n == 1 || n == 2)
157 && dtidx[key[n] ^ 0x80])
158 {
159 key[n] ^= 0x80;
160 kd[n] = dtidx[key[n]];
161 }
162 if (kd[n])
163 return;
164 }
165 else
166 {
167 kd[n] = NULL;
168 }
169 #endif
170
171 /* 最後の部分は class map を生成する必要ナシ */
172 if (n >= 6)
173 return;
174
175 for (i = 0; i < 256; i++)
176 {
177 unsigned bm = 0;
178 #if 1
179 if (c & KCLS_K1)
180 {
181 if (cp932[256 * key[n] + i] & KCLS_K1)
182 bm |= KCLS_K2 | (cp932[256 * key[n] + i] & KCLS_DT1);
183 if (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
184 bm |= KCLS_K2 | (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_DT1);
185 #if 0
186 bm |= ((cp932[256 * key[n] + i] & KCLS_K1)
187 || (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
188 ? KCLS_K2 : 0);
189 #endif
190 }
191 if (c & (KCLS_AN | KCLS_KA | KCLS_K2))
192 for (j = 0; j < 256; j++)
193 {
194 bm |= cp932[256 * i + j] & (KCLS_AN | KCLS_KA | KCLS_K1
195 | KCLS_DT0);
196 #if 0
197 if (j >= 127 && !(n == 0 || n == 1))
198 break;
199 #endif
200 }
201 kcls[n + 1].map[i] = bm;
202 #endif
203 if (i >= 128 && !(n == 0 || n == 1))
204 kcls[n + 1].map[i - 128] |= kcls[n + 1].map[i];
205 }
206
207 if (n < 6)
208 kcls[n + 1].map[0x00] = kcls[n + 1].map[0x80] = 0;
209 if (n == 6)
210 kcls[7].map[0x00] |= KCLS_AN;
211 }
212
213 #if USE_DT
214 unsigned
215 dt_get(int kdn,
216 int xn,
217 int n,
218 int ch)
219 {
220 int i;
221 #if DEBUG>=1
222 printf("*dt_get(%d)%c%c%c%c(%02X%02X:%02X%02X)->ch=%d",
223 n,
224 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
225 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
226 ch);
227 #endif
228 /* まずは数える */
229 for (i = 0;
230 kd[kdn][i].c[xn] == kd[kdn]->c[xn];
231 i++)
232 ;
233 assert(i > 0);
234 kd[kdn] += ch % i;
235 #if DEBUG>=1
236 printf("/%d\n dt_get: %c%c%c%c(%02X%02X:%02X%02X)->ch=%d\n",
237 i,
238 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
239 kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
240 ch);
241 #endif
242 return kd[kdn]->c[n];
243 }
244 #endif
245
246 /* マップから文字を拾ってセット */
247 unsigned
248 key_set(int n, unsigned ch)
249 {
250 int cnt = 0, i;
251
252 #if USE_DT
253 if (3 <= n && n < 7 && kd[n - 3])
254 {
255 return dt_get(n - 3, 2, 3, ch);
256 return kd[n - 3]->c[3];
257 }
258 else if (2 <= n && n < 6 && kd[n - 2])
259 {
260 return dt_get(n - 2, 1, 2, ch);
261 return kd[n - 2]->c[2];
262 }
263 else if (1 <= n && n < 5 && kd[n - 1])
264 {
265 return dt_get(n - 1, 0, 1, ch);
266 return kd[n - 1]->c[1];
267 }
268 #endif
269
270 #if DEBUG>=3
271 if (cnt == 0)
272 {
273 printf("n=%d, ch=%d, (n-1)=%02X\n", n, ch, key[n - 1]);
274 int j;
275 for (i = 0; i < 16; i++)
276 {
277 printf("map[0x%02X] =", 16 * i);
278 for (j = 0; j < 16; j++)
279 printf(" %03X", kcls[n].map[16 * i + j]);
280 printf("\n");
281 }
282 }
283 #endif
284 for (i = 0; i < 256; i++)
285 {
286 if (kcls[n].map[i])
287 {
288 if (ch-- == 0)
289 return i;
290 cnt++;
291 }
292 if (n != 1 && n != 2 && i >= 127)
293 break;
294 }
295 /* 見つからなかったのでもいっぺん */
296 assert(cnt > 0);
297 ch %= cnt;
298 for (i = 0; i < 256; i++)
299 if (kcls[n].map[i])
300 {
301 if (ch-- == 0)
302 return i;
303 }
304 assert(!"not matched");
305 return 0;
306 }
307
308 /* bitwise key をセット */
309 static
310 void
311 key_set64(struct KEY *key64,
312 int n,
313 unsigned k,
314 unsigned vk,
315 unsigned sk)
316 {
317 int i, j;
318 if (!((vk | sk) & 0x7F))
319 return;
320
321 for (i = 0; i < 7; i++)
322 {
323 if (n == 7 && i < N_STRIDE) continue;
324 if (sk & (1 << i))
325 {
326 /* セット */
327 int o = tr_pc1[n][6 - i] - 1;
328 if (o < 28)
329 {
330 assert(o >= 0);
331 for (j = 0; j < N_ALU; j++)
332 key64->k[0][0][o].a[j]
333 = key64->k[0][1][o].a[j]
334 = -!!(k & (1 << i));
335 }
336 else
337 {
338 assert(o >= 28);
339 assert(o < 56);
340 for (j = 0; j < N_ALU; j++)
341 key64->k[1][0][o - 28].a[j]
342 = key64->k[1][1][o - 28].a[j]
343 = -!!(k & (1 << i));
344 }
345 }
346 else if (vk & (1 << i))
347 {
348 /* 反転 */
349 int o = tr_pc1[n][6 - i] - 1;
350 if (o < 28)
351 {
352 assert(o >= 0);
353 for (j = 0; j < N_ALU; j++)
354 key64->k[0][0][o].a[j]
355 = key64->k[0][1][o].a[j]
356 = ~key64->k[0][0][o].a[j];
357 }
358 else
359 {
360 assert(o >= 28);
361 assert(o < 56);
362 for (j = 0; j < N_ALU; j++)
363 key64->k[1][0][o - 28].a[j]
364 = key64->k[1][1][o - 28].a[j]
365 = ~key64->k[1][0][o - 28].a[j];
366 }
367 }
368 }
369 }
370
371 /* 指定されたクラスの開始値にリセット
372 直前の文字のクラスに縛られる */
373 int
374 key_reset(int n)
375 {
376 if (n >= 8)
377 return 1;
378 if (n == 7)
379 {
380 key[7] = 0;
381 return 1;
382 }
383
384 /* 0-2 文字目はランダムに決める
385 3 文字目以降は初期値に */
386 if (n >= 3)
387 key[n] = key_set(n, 0);
388 else
389 key[n] = key_set(n, rand());
390
391 #if DEBUG>=3
392 printf("key[%d]=%02X ncls=%04X\n", n, key[n], kcls[n].map[key[n]]);
393 #endif
394
395 /* セットされた文字を元に、次キャラの文字クラスを決める */
396 key_make_map(n);
397
398 return key_reset(n + 1);
399 }
400
401 /* 指定された鍵空間の中で、キーをひとつ進める
402 安全にインクリメントできた場合 true を返す */
403 static
404 int
405 key_inc(int n)
406 {
407 if (n >= 8)
408 return 0;
409 else if (n == 7)
410 {
411 /* 最後のバイト */
412 key[7] = (key[7] + (1 << N_STRIDE)) & 0x7F;
413 if (key[7]) return 1;
414 else return 0;
415 }
416 else if (key_inc(n + 1)
417 /*
418 && key_inc(n + 1)
419 && key_inc(n + 1)
420 && key_inc(n + 1)*/
421 )
422 return 1;
423
424 /* Salt はインクリメントしない約束にする */
425 if (n == 1 || n == 2)
426 return 1;
427
428 #if DEBUG>=3
429 printf("key_inc(n=%d,ck=%02X)\n", n, key[n]);
430 #endif
431
432 #if USE_DT
433 /* 辞書語はインクリメントしていい約束にする */
434 if (3 <= n && n < 7 && kd[n - 3])
435 {
436 if ((key[n - 3] & 0x7F) == ((kd[n - 3] + 1)->c[0] & 0x7F)
437 && (key[n - 2] & 0x7F) == ((kd[n - 3] + 1)->c[1] & 0x7F)
438 && (key[n - 1] & 0x7F) == ((kd[n - 3] + 1)->c[2] & 0x7F))
439 {
440 memcpy(&key[n - 3], &(++kd[n - 3])->c[0], 4);
441 #if DEBUG>=2
442 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
443 kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3],
444 kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3]);
445 #endif
446 return 1;
447 }
448 else
449 {
450 return 0;
451 }
452 }
453 else if (2 <= n && n < 6 && kd[n - 2])
454 {
455 if ((key[n - 2] & 0x7F) == ((kd[n - 2] + 1)->c[0] & 0x7F)
456 && (key[n - 1] & 0x7F) == ((kd[n - 2] + 1)->c[1] & 0x7F))
457 {
458 memcpy(&key[n - 2], &(++kd[n - 2])->c[0], 4);
459 #if DEBUG>=2
460 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
461 kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3],
462 kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3]);
463 #endif
464 return 1;
465 }
466 else
467 {
468 return 0;
469 }
470 if (kd[n - 2]->c[0] == key[n - 2])
471 return 1;
472 else
473 return 0;
474 }
475 else if (1 <= n && n < 5 && kd[n - 1])
476 {
477 unsigned c2 = kd[n - 1]->c[0];
478 if ((0x81 <= c2 && c2 <= 0x9F)
479 || (0xE0 <= c2 && c2 <= 0xFC))
480 {
481 kd[n - 1] = NULL;
482 #if 0
483 if (!(n == 1 && n == 2))
484 key[n] &= 0x7F;
485 if (!(n == 2 && n == 3))
486 key[n - 1] &= 0x7F;
487 #endif
488 key_make_map(n - 1);
489 }
490 else if ((key[n - 1] & 0x7F) == ((kd[n - 1] + 1)->c[0] & 0x7F))
491 {
492 memcpy(&key[n - 1], &(++kd[n - 1])->c[0], 4);
493 #if DEBUG>=2
494 printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
495 kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3],
496 kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3]);
497 #endif
498 return 1;
499 }
500 else
501 {
502 return 0;
503 }
504 #if 0
505 if (kd[n - 1]->c[0] == key[n - 1])
506 return 1;
507 else
508 return 0;
509 #endif
510 }
511 else if (n < 4 && kd[n])
512 {
513 if (0 && kd[n]->c[0] == key[n])
514 return 1;
515 kd[n] = NULL;
516 #if 0
517 if (!(n == 1 || n == 2))
518 key[n] &= 0x7F;
519 #endif
520 }
521 #endif
522
523 /* 実際に増やしてみる */
524 assert(n >= 3);
525 for (;;)
526 {
527 if (n <= 3
528 && !(key[n] & 0x80)
529 && kcls[n].map[key[n] ^ 0x80] & (KCLS_DT0))
530 {
531 /* 半角カタカナの1バイト目 */
532 key[n] ^= 0x80;
533 }
534 else
535 {
536 key[n] = (key[n] & 0x7F) + 1;
537 if (key[n] >= 0x80)
538 return 0;
539 }
540
541 if (kcls[n].map[key[n]])
542 {
543 key_make_map(n);
544 key_reset(n + 1);
545 return 1;
546 }
547 }
548 while (++key[n] < 0x80)
549 {
550 if (kcls[n].map[key[n]])
551 {
552 key_make_map(n);
553 key_reset(n + 1);
554 return 1;
555 }
556 }
557 return 0;
558 }
559
560 /* 鍵を完全にリセットする
561 Saltもセットし直す */
562 static
563 void
564 key_init()
565 {
566 int i, j;
567
568 #if USE_DT
569 /* 辞書を、インデクスを作りながらマップにはめこんで逝く
570 辞書はコード順昇順に並んでるものとする */
571 for (i = 0; i < dtcnt; i++)
572 {
573 unsigned c = dt[i].c[0];
574
575 assert(dt[i].c[0]
576 && dt[i].c[1]
577 && dt[i].c[2]
578 && dt[i].c[3]);
579
580 /* BSD 鯖でしにそうな文字は残念ながら除外 */
581 assert((dt[i].c[0] & 0x7F)
582 && (dt[i].c[1] & 0x7F)
583 && (dt[i].c[2] & 0x7F)
584 && (dt[i].c[3] & 0x7F));
585
586 /* インデクス */
587 if (!dtidx[c])
588 dtidx[c] = &dt[i];
589
590 if ((0x81 <= c && c <= 0x9F)
591 || (0xE0 <= c && c <= 0xFC))
592 {
593 /* 全角なので、2バイトきまった時点で立てる */
594 cp932[256 * c + dt[i].c[1]] |= KCLS_DT1;
595 }
596 else if (0xA1 <= c && c <= 0xDF)
597 {
598 /* 半角カナ */
599 for (j = 0; j < 256; j++)
600 cp932[256 * c + j] |= KCLS_DT0;
601 }
602 }
603 /* ケツ、ちうか番人 */
604 dtidx[0x100] = &dt[i];
605 #endif
606
607 key[8] = 0;
608
609 /* 初期マップを組む */
610 for (i = 0; i < 256; i++)
611 {
612 unsigned bm = 0;
613 kcls[0].map[i] = 0;
614 for (j = 0; j < 256; j++)
615 bm |= cp932[256 * i + j];
616 kcls[0].map[i] = bm & (KCLS_AN | KCLS_KA | KCLS_K1
617 | KCLS_DT0
618 );
619 if (i >= 128)
620 kcls[0].map[i - 128] |= kcls[0].map[i];
621 }
622
623 key_reset(0);
624 }
625
626 /***************************************************************
627 *
628 * Salt のセット
629 * オペランドのオフセットを書き換えて回ってるので注意
630 *
631 */
632
633 #if N_STRIDE == 6
634 #define C(c,i,j,o) (*(int8_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
635 #elif N_STRIDE == 7
636 #define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
637 #endif
638
639 void
640 set_salt(signed char *code,
641 unsigned char const *k)
642 {
643 int i, j;
644
645 for (i = 0; i < 2; i++)
646 {
647 unsigned s = k[1 + i] & 255;
648 if (s > 'z')
649 s = 0;
650 else if (s >= 'a')
651 s = s - 'a' + 2 + 10 + 26;
652 else if (s >= 'A')
653 s = s - 'A' + 2 + 10;
654 else if (s >= '.')
655 s = s - '.';
656 else
657 s = 0;
658
659 #if DEBUG>=1
660 printf("Salt %d:%3o\n", i, s & 63);
661 #endif
662 for (j = 0; j < 6; j++)
663 {
664 #if DEBUG>=2
665 //printf("Salt %d:%d %+3d:%+3d",
666 printf("Salt %d:%d %08lX:%08lX",
667 i, j,
668 C(code, i, j, 0),
669 C(code, i, j, 24));
670 #endif
671 if (s & (1 << j))
672 {
673 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
674 C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
675 }
676 else
677 {
678 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
679 C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
680 }
681 C(code, i, j, 12) = sizeof(WS_T) * (((4 * i + j + 7) & 31) - 16);
682 C(code, i, j, 36) = sizeof(WS_T) * (((4 * i + j + 23) & 31) - 16);
683 #if DEBUG>=2
684 //printf(" => %+3d:%+3d\n",
685 printf(" => %08lX:%08lX\n",
686 C(code, i, j, 0),
687 C(code, i, j, 24));
688 #endif
689 }
690 }
691 }
692
693 static
694 unsigned
695 usec()
696 {
697 #if !defined(WIN32)
698 struct timeval tv;
699 gettimeofday(&tv, NULL);
700 return 100 * tv.tv_sec + (tv.tv_usec / 10000);
701 #else
702 struct timeb tm;
703 ftime(&tm);
704 return 100 * tm.time + tm.millitm / 10;
705 #endif
706 }
707
708 static
709 int
710 log_printf(FILE *ofp, char const *fmt, ...)
711 {
712 int r;
713 va_list ap;
714 va_start(ap, fmt);
715 vfprintf(stdout, fmt, ap);
716 r = vfprintf(ofp, fmt, ap);
717 va_end(ap);
718 if (r > 0)
719 return r;
720 perror("log_printf");
721 exit(errno);
722 }
723
724 /***************************************************************
725 *
726 * メインループとか
727 *
728 */
729
730 /* 定数項 */
731 #if N_STRIDE == 7
732 static SLICE const sk6[N_STRIDE] =
733 {
734 {0xAAAAAAAAUL, 0xAAAAAAAAUL, 0xAAAAAAAAUL, 0xAAAAAAAAUL},
735 {0xCCCCCCCCUL, 0xCCCCCCCCUL, 0xCCCCCCCCUL, 0xCCCCCCCCUL},
736 {0xF0F0F0F0UL, 0xF0F0F0F0UL, 0xF0F0F0F0UL, 0xF0F0F0F0UL},
737 {0xFF00FF00UL, 0xFF00FF00UL, 0xFF00FF00UL, 0xFF00FF00UL},
738 {0xFFFF0000UL, 0xFFFF0000UL, 0xFFFF0000UL, 0xFFFF0000UL},
739 {0x00000000UL, 0xFFFFFFFFUL, 0x00000000UL, 0xFFFFFFFFUL},
740 {0x00000000UL, 0x00000000UL, 0xFFFFFFFFUL, 0xFFFFFFFFUL},
741 };
742 #elif N_STRIDE == 6
743 static SLICE const sk6[N_STRIDE] =
744 {
745 {0xAAAAAAAAUL, 0xAAAAAAAAUL},
746 {0xCCCCCCCCUL, 0xCCCCCCCCUL},
747 {0xF0F0F0F0UL, 0xF0F0F0F0UL},
748 {0xFF00FF00UL, 0xFF00FF00UL},
749 {0xFFFF0000UL, 0xFFFF0000UL},
750 {0x00000000UL, 0xFFFFFFFFUL},
751 };
752 #endif
753
754 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
755 ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
756
757 int
758 main(int argc, char *argv[])
759 {
760 int i, j;
761 int mincnt;
762 signed char *code = NULL;
763 FILE *ofp;
764 FILE *sfp; /* scoreboard */
765 struct ITREE *root_expr;
766 int n_iter;
767 int cr;
768
769 #define N_TS 4
770 struct
771 {
772 unsigned t;
773 int c;
774 } ts[N_TS];
775
776 #if 0
777 if (argc < 2)
778 {
779 fprintf(stderr, "式きぼんぬ\n");
780 return 1;
781 }
782 #endif
783
784 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
785
786 /* t[16] は、内部演算で使用する、all 1 が入っている */
787 for (i = 0; i < N_ALU; i++)
788 param64.t[16].a[i] = -1;
789
790 /* 固定キーのコピー */
791 for (i = 0; i < N_STRIDE; i++)
792 {
793 int o = tr_pc1[7][6 - i] - 1;
794 if (o < 28)
795 {
796 key64.k[0][0][o] = key64.k[0][1][o] = sk6[i];
797 }
798 else
799 {
800 o -= 28;
801 key64.k[1][0][o] = key64.k[1][1][o] = sk6[i];
802 }
803 }
804
805 /* キースケジュールをここに押し込めておく
806 従来は crypt64.S 内で完結するように引いていた */
807 for (i = 0; i < 28; i++)
808 key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];
809
810 /* タゲ読み込み */
811 root_expr = expr_parse("target.txt");
812
813 /* コードを生成・展開 */
814 sfp = scoreboard_open();
815 fwrite(crypt64_sta, 1, crypt64_end - crypt64_sta, sfp); /* prologue */
816 synth_synthesize(sfp, root_expr);
817 fwrite(crypt64_ep, 1, crypt64_ep_end - crypt64_ep, sfp); /* epilogue */
818
819 /* コードをメモリに貼り付ける */
820 code = scoreboard_map(sfp);
821
822 /* キーの初期化 */
823 srand(time(NULL));
824 key_init();
825 set_salt(code, key);
826 for (i = 0; i < 8; i++)
827 key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
828
829 #if DEBUG>=1
830 printf("key=%p param=%p\n", &key64, &param64);
831 #endif
832 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
833 assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
834
835 if ((ofp = fopen("log.txt", "at")) == NULL)
836 {
837 perror("log.txt");
838 return errno;
839 }
840
841 setvbuf(ofp, NULL, _IONBF, BUFSIZ); /* XXX MSVCRT では _IOLBF が期待通りに動作しない */
842
843 for (i = 0; i < N_TS; i++)
844 ts[i].t = ts[i].c = 0;
845
846 mincnt = 0x7FFFFFFF;
847 n_iter = 0;
848 cr = 0;
849 /* 探索ループだぞっと */
850 for (;;)
851 {
852 int32_t cnt;
853 int k, kk;
854
855 /* 鍵のセット */
856 for (i = 0; i < 8; i++)
857 {
858 key_set64(&key64, i, key[i], key[i] ^ okey[i], 0);
859 okey[i] = key[i];
860 }
861
862 /* 呼ぶ!
863 LR 初期化は、サブモジュール内で行うべし
864 FASTCALL に準じた呼び出しのため、
865 ホントはいろいろレジスタが破壊されるハズ…なんだが。 */
866 cnt = CALL_CRYPT64(code, key64.k, param64.lr);
867
868 #if DEBUG>=1
869 if (mincnt > cnt && cnt > 0)
870 {
871 mincnt = cnt;
872 if (cr)
873 fprintf(stderr, "\n");
874 cr = 0;
875 fprintf(stderr, "cycle=%d\n", (int)cnt);
876 }
877 #endif
878
879 /* ヒットしたときの処理 */
880 for (kk = 0; kk < N_ALU; kk++)
881 {
882 ALU_T t;
883
884 t = param64.t[31].a[kk];
885 if (!t)
886 continue;
887
888 for (k = 0; k < ALU_BITS; k++)
889 {
890 char hash[16];
891 unsigned char buf[32];
892
893 if (!(t & ((ALU_T)1 << k)))
894 continue;
895
896 /* XXX 手抜きのため、ワークにはみ出ている 2 ビットをここで落とす
897 ヒットするたびに冗長に行われるが、気にしてはいかん */
898 param64.t[0].a[kk] = param64.t[1].a[kk] = 0;
899 for (i = 1; i < 11; i++)
900 {
901 unsigned c = 0;
902 for (j = 0; j < 6; j++)
903 c = (c << 1) | !!(param64.lr[0][tr_fp[6 * i + j]].a[kk] & ((ALU_T)1 << k));
904 hash[i - 1] = c["./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
905 }
906 hash[10] = 0;
907
908 memcpy(buf, key, 32);
909 buf[8] = buf[9] = 0;
910 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
911 if (translate(buf, 0, 1))
912 {
913 if (cr)
914 fprintf(stderr, "\n");
915 cr = 0;
916 log_printf(ofp,
917 "◆%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)\n",
918 hash,
919 buf,
920 buf[0], buf[1], buf[2], buf[3],
921 buf[4], buf[5], buf[6], buf[7],
922 buf[8]);
923 }
924 else
925 {
926 #if DEBUG>=1
927 if (cr)
928 fprintf(stderr, "\n");
929 cr = 0;
930 log_printf(ofp,
931 "◆%s (%02X %02X %02X %02X %02X %02X %02X %02X )\n",
932 hash,
933 buf[0], buf[1], buf[2], buf[3],
934 buf[4], buf[5], buf[6], buf[7]);
935 #endif
936 }
937 }
938 }
939
940 if (++n_iter - ts[0].c >= 8192)
941 {
942 int t = usec();
943 if (ts[N_TS - 1].c)
944 {
945 int a = (100 << N_STRIDE) * (n_iter - ts[N_TS - 1].c) / (t - ts[N_TS - 1].t);
946 fprintf(stderr,
947 "%8d.%03d(ktrips/sec)\r",
948 a / 1000,
949 a % 1000);
950 cr++;
951 }
952 for (i = N_TS - 1; i >= 1; i--)
953 ts[i] = ts[i - 1];
954 ts[0].c = n_iter;
955 ts[0].t = t;
956 for (i = 1; i < N_TS; i++)
957 if (ts[i].c)
958 break;
959 else
960 ts[i] = ts[i - 1];
961 }
962 #if 1
963 if (!key_inc(3))
964 {
965 #if DEBUG>=2
966 printf("********************************\n");
967 #endif
968 key_reset(0);
969 set_salt(code, key);
970 for (i = 0; i < 8; i++)
971 key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
972 }
973 #endif
974 }
975
976 return 0;
977 }
978
979 /*
980 * Local Variables:
981 * tab-width: 4
982 * End:
983 *
984 * EOF */

Properties

Name Value
svn:eol-style native

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26