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

Properties

Name Value
svn:eol-style native

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