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

Properties

Name Value
svn:eol-style native

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