Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (hide 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 chapuni 1 /***********************************************************************
2     *
3 chapuni 26 * file: mty.c
4 chapuni 1 *
5 chapuni 2 * まあ、待て屋。
6 chapuni 1 *
7     * $Id$
8     *
9     */
10    
11     #include <assert.h>
12     #include <ctype.h>
13 chapuni 24 #include <errno.h>
14 chapuni 13 #include <malloc.h>
15 chapuni 9 #include <limits.h>
16 chapuni 24 #include <stdarg.h>
17 chapuni 20 #include <stddef.h>
18 chapuni 1 #include <stdio.h>
19     #include <stdlib.h>
20     #include <string.h>
21     #include <time.h>
22 chapuni 10
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 chapuni 26 #include "config.h"
36 chapuni 39 #include "cp932.h"
37 chapuni 1 #include "crypt64.h"
38 chapuni 41 #include "desconst.h"
39 chapuni 26 #include "expr.h"
40     #include "translate.h"
41 chapuni 1
42 chapuni 39 #if USE_DT
43     #include "dt4.h"
44     #endif
45    
46 chapuni 9 #define N_I (sizeof(WS_T) / sizeof(uint32_t))
47 chapuni 6 #define N_ALU (sizeof(WS_T) / sizeof(ALU_T))
48 chapuni 9 #define ALU_BITS (CHAR_BIT * sizeof(ALU_T))
49 chapuni 6
50 chapuni 1 /* 1ビット分 */
51 chapuni 6 typedef union SLICE
52 chapuni 1 {
53 chapuni 9 uint32_t i[N_I]; /* 32-bit initializer */
54 chapuni 6 ALU_T a[N_ALU]; /* C で扱いやすいサイズ */
55     WS_T w; /* エンコードで扱うサイズ */
56     } SLICE;
57 chapuni 1
58     /* crypt64() が喰うパラメータ */
59     struct PARAM
60     {
61 chapuni 6 SLICE lr[2][32];
62     SLICE t[32];
63     SLICE hit[10][64];
64     SLICE hiti[10][26];
65 chapuni 1 };
66    
67 chapuni 15 /* 鍵はLR と、そのコピーが必要
68     KEY::k[0] LR
69     KEY::k[1] LRのコピー(剰余を省くため)
70     KEY::k[2][0][i].a[0] 次鍵への増分 */
71 chapuni 1 struct KEY
72     {
73 chapuni 6 SLICE k[2][2][28];
74 chapuni 15 SLICE ks[28];
75 chapuni 1 };
76    
77     /* 鍵文字列 */
78     unsigned char key[8 + 8];
79     unsigned char okey[8 + 8];
80    
81     /* 鍵クラス */
82 chapuni 41 static
83 chapuni 1 struct
84     {
85     unsigned cls;
86     unsigned map[256];
87     } kcls[8 + 8];
88    
89 chapuni 26
90     /* 拡張鍵クラス */
91 chapuni 1 #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 chapuni 39 #if USE_DT
111 chapuni 1 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 chapuni 39 #endif
200 chapuni 1
201     /* 最後の部分は class map を生成する必要ナシ */
202     if (n >= 6)
203     return;
204    
205     for (i = 0; i < 256; i++)
206     {
207 chapuni 25 unsigned bm = 0;
208 chapuni 1 #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 chapuni 39 #if USE_DT
244 chapuni 1 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 chapuni 39 #endif
275 chapuni 1
276     /* マップから文字を拾ってセット */
277     unsigned
278     key_set(int n, unsigned ch)
279     {
280     int cnt = 0, i;
281    
282 chapuni 39 #if USE_DT
283 chapuni 1 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 chapuni 39 #endif
299 chapuni 1
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 chapuni 6 int i, j;
348 chapuni 1 if (!((vk | sk) & 0x7F))
349     return;
350    
351     for (i = 0; i < 7; i++)
352     {
353 chapuni 6 if (n == 7 && i < N_STRIDE) continue;
354 chapuni 1 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 chapuni 6 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 chapuni 1 }
366     else
367     {
368     assert(o >= 28);
369     assert(o < 56);
370 chapuni 6 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 chapuni 1 }
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 chapuni 10 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 chapuni 1 }
388     else
389     {
390     assert(o >= 28);
391     assert(o < 56);
392 chapuni 10 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 chapuni 1 }
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 chapuni 6 /* 最後のバイト */
442 chapuni 25 key[7] = (key[7] + (1 << N_STRIDE)) & 0x7F;
443 chapuni 1 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 chapuni 39 #if USE_DT
463 chapuni 1 /* 辞書語はインクリメントしていい約束にする */
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 chapuni 39 #endif
552 chapuni 1
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 chapuni 9 #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 chapuni 6 #endif
668    
669 chapuni 1 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 chapuni 6 //printf("Salt %d:%d %+3d:%+3d",
696     printf("Salt %d:%d %08lX:%08lX",
697 chapuni 1 i, j,
698 chapuni 6 C(code, i, j, 0),
699     C(code, i, j, 24));
700 chapuni 1 #endif
701     if (s & (1 << j))
702     {
703 chapuni 6 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 chapuni 1 }
706     else
707     {
708 chapuni 6 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 chapuni 1 }
711 chapuni 6 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 chapuni 1 #if DEBUG>=2
714 chapuni 6 //printf(" => %+3d:%+3d\n",
715     printf(" => %08lX:%08lX\n",
716     C(code, i, j, 0),
717     C(code, i, j, 24));
718 chapuni 1 #endif
719     }
720     }
721     }
722    
723     static
724 chapuni 10 unsigned
725 chapuni 1 usec()
726     {
727 chapuni 10 #if !defined(WIN32)
728 chapuni 1 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 chapuni 24 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 chapuni 1 /***************************************************************
755     *
756     * メインループとか
757     *
758     */
759    
760     /* 定数項 */
761 chapuni 6 #if N_STRIDE == 7
762     static SLICE const sk6[N_STRIDE] =
763 chapuni 1 {
764 chapuni 6 {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 chapuni 1 {0xAAAAAAAAUL, 0xAAAAAAAAUL},
776     {0xCCCCCCCCUL, 0xCCCCCCCCUL},
777     {0xF0F0F0F0UL, 0xF0F0F0F0UL},
778     {0xFF00FF00UL, 0xFF00FF00UL},
779     {0xFFFF0000UL, 0xFFFF0000UL},
780     {0x00000000UL, 0xFFFFFFFFUL},
781     };
782 chapuni 6 #endif
783 chapuni 1
784 chapuni 10 #ifdef WIN32
785     typedef int (__fastcall *CRYPT64_PP)(ALU_T const *k, ALU_T *lr);
786 chapuni 1 #endif
787    
788 chapuni 10 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
789     ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
790 chapuni 1
791     int
792     main(int argc, char *argv[])
793     {
794     int i, j;
795     int mincnt;
796 chapuni 2 signed char *code = NULL;
797 chapuni 1 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 chapuni 10 #ifdef WIN32
809     HANDLE h;
810     #endif
811    
812 chapuni 1 #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 chapuni 10 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
825    
826 chapuni 1 /* t[16] は、内部演算で使用する、all 1 が入っている */
827 chapuni 6 for (i = 0; i < N_ALU; i++)
828     param64.t[16].a[i] = -1;
829 chapuni 1
830     /* 固定キーのコピー */
831 chapuni 6 for (i = 0; i < N_STRIDE; i++)
832 chapuni 1 {
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 chapuni 15 /* キースケジュールをここに押し込めておく
846     従来は crypt64.S 内で完結するように引いていた */
847     for (i = 0; i < 28; i++)
848     key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];
849    
850 chapuni 1 /* Saltを加味しない場合は、コード領域を
851     writable 領域に展開しなくてもよい。
852     [XXX] OSによっては、書込&実行可能領域を専用のサーヴィスで
853     取得しなければならないものもあるかもしれないので、注意 */
854 chapuni 10 #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 chapuni 2 if (SUCCEEDED(h))
864     code = (signed char *)MapViewOfFile(h,
865 chapuni 10 FILE_MAP_EXECUTE | FILE_MAP_WRITE,
866 chapuni 2 0, 0x10000000,
867     0);
868 chapuni 1 #else
869     code = (signed char *)mmap(NULL,
870     0x10000000,
871     PROT_EXEC | PROT_READ | PROT_WRITE,
872 chapuni 20 MAP_PRIVATE | MAP_ANON,
873 chapuni 1 1, /* fd */
874     0);
875 chapuni 2 if ((void *)code == MAP_FAILED)
876     code =NULL;
877 chapuni 1 #endif
878 chapuni 2
879     /* メモリが確保できていない場合のいんちき対策 */
880     if (code == NULL)
881     code = (signed char *)malloc(crypt64_end - crypt64_sta + 1024 * 1024);
882     assert(code != NULL);
883    
884     /* Prologue を展開 */
885 chapuni 1 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 chapuni 10 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
906     assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
907 chapuni 1
908 chapuni 24 if ((ofp = fopen("log.txt", "at")) == NULL)
909     {
910     perror("log.txt");
911     return errno;
912     }
913 chapuni 1
914 chapuni 24 setvbuf(ofp, NULL, _IONBF, BUFSIZ); /* XXX MSVCRT では _IOLBF が期待通りに動作しない */
915    
916 chapuni 1 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 chapuni 9 int32_t cnt;
926 chapuni 1 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 chapuni 14 /* 呼ぶ!
936     LR 初期化は、サブモジュール内で行うべし
937     FASTCALL に準じた呼び出しのため、
938     ホントはいろいろレジスタが破壊されるハズ…なんだが。 */
939 chapuni 1 #ifdef __GNUC__
940     asm volatile("call *%3"
941     : "=a"(cnt)
942 chapuni 14 : "c"(key64.k), "d"(param64.lr),
943     "m"(code)
944     //"m"(crypt64_sta)
945 chapuni 15 : CRYPT64_CLOBBER "memory");
946 chapuni 1 #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 chapuni 9 fprintf(stderr, "cycle=%d\n", (int)cnt);
956 chapuni 1 }
957    
958     /* ヒットしたときの処理 */
959 chapuni 6 for (kk = 0; kk < N_ALU; kk++)
960 chapuni 1 {
961 chapuni 6 ALU_T t;
962 chapuni 9
963 chapuni 1 t = param64.t[31].a[kk];
964     if (!t)
965     continue;
966 chapuni 9
967 chapuni 6 for (k = 0; k < ALU_BITS; k++)
968 chapuni 1 {
969     char hash[16];
970     unsigned char buf[32];
971 chapuni 9
972     if (!(t & ((ALU_T)1 << k)))
973 chapuni 1 continue;
974 chapuni 9
975 chapuni 14 /* XXX 手抜きのため、ワークにはみ出ている 2 ビットをここで落とす
976     ヒットするたびに冗長に行われるが、気にしてはいかん */
977 chapuni 29 param64.t[0].a[kk] = param64.t[1].a[kk] = 0;
978 chapuni 1 for (i = 1; i < 11; i++)
979     {
980     unsigned c = 0;
981     for (j = 0; j < 6; j++)
982 chapuni 9 c = (c << 1) | !!(param64.lr[0][tr_fp[6 * i + j]].a[kk] & ((ALU_T)1 << k));
983 chapuni 1 hash[i - 1] = c["./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
984     }
985     hash[10] = 0;
986    
987     memcpy(buf, key, 32);
988     buf[8] = buf[9] = 0;
989 chapuni 10 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
990 chapuni 1 if (translate(buf, 0, 1))
991     {
992     if (cr)
993     fprintf(stderr, "\n");
994     cr = 0;
995 chapuni 24 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 chapuni 1 }
1003     else
1004     {
1005     #if DEBUG>=1
1006     if (cr)
1007     fprintf(stderr, "\n");
1008     cr = 0;
1009 chapuni 24 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 chapuni 1 #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 chapuni 6 int a = (100 << N_STRIDE) * (n_iter - ts[N_TS - 1].c) / (t - ts[N_TS - 1].t);
1025 chapuni 1 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 chapuni 2 /*
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