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

Properties

Name Value
svn:eol-style native

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