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 42 - (hide 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 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 1 /* 鍵文字列 */
47     unsigned char key[8 + 8];
48     unsigned char okey[8 + 8];
49    
50     /* 鍵クラス */
51 chapuni 41 static
52 chapuni 1 struct
53     {
54     unsigned cls;
55     unsigned map[256];
56     } kcls[8 + 8];
57    
58 chapuni 26
59     /* 拡張鍵クラス */
60 chapuni 1 #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 chapuni 39 #if USE_DT
80 chapuni 1 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 chapuni 39 #endif
169 chapuni 1
170     /* 最後の部分は class map を生成する必要ナシ */
171     if (n >= 6)
172     return;
173    
174     for (i = 0; i < 256; i++)
175     {
176 chapuni 25 unsigned bm = 0;
177 chapuni 1 #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 chapuni 39 #if USE_DT
213 chapuni 1 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 chapuni 39 #endif
244 chapuni 1
245     /* マップから文字を拾ってセット */
246     unsigned
247     key_set(int n, unsigned ch)
248     {
249     int cnt = 0, i;
250    
251 chapuni 39 #if USE_DT
252 chapuni 1 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 chapuni 39 #endif
268 chapuni 1
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 chapuni 6 int i, j;
317 chapuni 1 if (!((vk | sk) & 0x7F))
318     return;
319    
320     for (i = 0; i < 7; i++)
321     {
322 chapuni 6 if (n == 7 && i < N_STRIDE) continue;
323 chapuni 1 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 chapuni 6 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 chapuni 1 }
335     else
336     {
337     assert(o >= 28);
338     assert(o < 56);
339 chapuni 6 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 chapuni 1 }
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 chapuni 10 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 chapuni 1 }
357     else
358     {
359     assert(o >= 28);
360     assert(o < 56);
361 chapuni 10 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 chapuni 1 }
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 chapuni 6 /* 最後のバイト */
411 chapuni 25 key[7] = (key[7] + (1 << N_STRIDE)) & 0x7F;
412 chapuni 1 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 chapuni 39 #if USE_DT
432 chapuni 1 /* 辞書語はインクリメントしていい約束にする */
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 chapuni 39 #endif
521 chapuni 1
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 chapuni 9 #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 chapuni 6 #endif
637    
638 chapuni 1 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 chapuni 6 //printf("Salt %d:%d %+3d:%+3d",
665     printf("Salt %d:%d %08lX:%08lX",
666 chapuni 1 i, j,
667 chapuni 6 C(code, i, j, 0),
668     C(code, i, j, 24));
669 chapuni 1 #endif
670     if (s & (1 << j))
671     {
672 chapuni 6 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 chapuni 1 }
675     else
676     {
677 chapuni 6 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 chapuni 1 }
680 chapuni 6 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 chapuni 1 #if DEBUG>=2
683 chapuni 6 //printf(" => %+3d:%+3d\n",
684     printf(" => %08lX:%08lX\n",
685     C(code, i, j, 0),
686     C(code, i, j, 24));
687 chapuni 1 #endif
688     }
689     }
690     }
691    
692     static
693 chapuni 10 unsigned
694 chapuni 1 usec()
695     {
696 chapuni 10 #if !defined(WIN32)
697 chapuni 1 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 chapuni 24 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 chapuni 1 /***************************************************************
724     *
725     * メインループとか
726     *
727     */
728    
729     /* 定数項 */
730 chapuni 6 #if N_STRIDE == 7
731     static SLICE const sk6[N_STRIDE] =
732 chapuni 1 {
733 chapuni 6 {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 chapuni 1 {0xAAAAAAAAUL, 0xAAAAAAAAUL},
745     {0xCCCCCCCCUL, 0xCCCCCCCCUL},
746     {0xF0F0F0F0UL, 0xF0F0F0F0UL},
747     {0xFF00FF00UL, 0xFF00FF00UL},
748     {0xFFFF0000UL, 0xFFFF0000UL},
749     {0x00000000UL, 0xFFFFFFFFUL},
750     };
751 chapuni 6 #endif
752 chapuni 1
753 chapuni 10 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
754     ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
755 chapuni 1
756     int
757     main(int argc, char *argv[])
758     {
759     int i, j;
760     int mincnt;
761 chapuni 2 signed char *code = NULL;
762 chapuni 1 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 chapuni 10 #ifdef WIN32
774     HANDLE h;
775     #endif
776    
777 chapuni 1 #if 0
778     if (argc < 2)
779     {
780     fprintf(stderr, "式きぼんぬ\n");
781     return 1;
782     }
783     #endif
784    
785 chapuni 10 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
786    
787 chapuni 1 /* t[16] は、内部演算で使用する、all 1 が入っている */
788 chapuni 6 for (i = 0; i < N_ALU; i++)
789     param64.t[16].a[i] = -1;
790 chapuni 1
791     /* 固定キーのコピー */
792 chapuni 6 for (i = 0; i < N_STRIDE; i++)
793 chapuni 1 {
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 chapuni 15 /* キースケジュールをここに押し込めておく
807     従来は crypt64.S 内で完結するように引いていた */
808     for (i = 0; i < 28; i++)
809     key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];
810    
811 chapuni 1 /* Saltを加味しない場合は、コード領域を
812     writable 領域に展開しなくてもよい。
813     [XXX] OSによっては、書込&実行可能領域を専用のサーヴィスで
814     取得しなければならないものもあるかもしれないので、注意 */
815 chapuni 10 #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 chapuni 2 if (SUCCEEDED(h))
825     code = (signed char *)MapViewOfFile(h,
826 chapuni 10 FILE_MAP_EXECUTE | FILE_MAP_WRITE,
827 chapuni 2 0, 0x10000000,
828     0);
829 chapuni 1 #else
830     code = (signed char *)mmap(NULL,
831     0x10000000,
832     PROT_EXEC | PROT_READ | PROT_WRITE,
833 chapuni 20 MAP_PRIVATE | MAP_ANON,
834 chapuni 1 1, /* fd */
835     0);
836 chapuni 2 if ((void *)code == MAP_FAILED)
837     code =NULL;
838 chapuni 1 #endif
839 chapuni 2
840     /* メモリが確保できていない場合のいんちき対策 */
841     if (code == NULL)
842     code = (signed char *)malloc(crypt64_end - crypt64_sta + 1024 * 1024);
843     assert(code != NULL);
844    
845     /* Prologue を展開 */
846 chapuni 1 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 chapuni 10 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
864     assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
865 chapuni 1
866 chapuni 24 if ((ofp = fopen("log.txt", "at")) == NULL)
867     {
868     perror("log.txt");
869     return errno;
870     }
871 chapuni 1
872 chapuni 24 setvbuf(ofp, NULL, _IONBF, BUFSIZ); /* XXX MSVCRT では _IOLBF が期待通りに動作しない */
873    
874 chapuni 1 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 chapuni 9 int32_t cnt;
884 chapuni 1 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 chapuni 14 /* 呼ぶ!
894     LR 初期化は、サブモジュール内で行うべし
895     FASTCALL に準じた呼び出しのため、
896     ホントはいろいろレジスタが破壊されるハズ…なんだが。 */
897 chapuni 42 cnt = CALL_CRYPT64(code, key64.k, param64.lr);
898    
899 chapuni 1 if (mincnt > cnt && cnt > 0)
900     {
901     mincnt = cnt;
902     if (cr)
903     fprintf(stderr, "\n");
904     cr = 0;
905 chapuni 9 fprintf(stderr, "cycle=%d\n", (int)cnt);
906 chapuni 1 }
907    
908     /* ヒットしたときの処理 */
909 chapuni 6 for (kk = 0; kk < N_ALU; kk++)
910 chapuni 1 {
911 chapuni 6 ALU_T t;
912 chapuni 9
913 chapuni 1 t = param64.t[31].a[kk];
914     if (!t)
915     continue;
916 chapuni 9
917 chapuni 6 for (k = 0; k < ALU_BITS; k++)
918 chapuni 1 {
919     char hash[16];
920     unsigned char buf[32];
921 chapuni 9
922     if (!(t & ((ALU_T)1 << k)))
923 chapuni 1 continue;
924 chapuni 9
925 chapuni 14 /* XXX 手抜きのため、ワークにはみ出ている 2 ビットをここで落とす
926     ヒットするたびに冗長に行われるが、気にしてはいかん */
927 chapuni 29 param64.t[0].a[kk] = param64.t[1].a[kk] = 0;
928 chapuni 1 for (i = 1; i < 11; i++)
929     {
930     unsigned c = 0;
931     for (j = 0; j < 6; j++)
932 chapuni 9 c = (c << 1) | !!(param64.lr[0][tr_fp[6 * i + j]].a[kk] & ((ALU_T)1 << k));
933 chapuni 1 hash[i - 1] = c["./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
934     }
935     hash[10] = 0;
936    
937     memcpy(buf, key, 32);
938     buf[8] = buf[9] = 0;
939 chapuni 10 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
940 chapuni 1 if (translate(buf, 0, 1))
941     {
942     if (cr)
943     fprintf(stderr, "\n");
944     cr = 0;
945 chapuni 24 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 chapuni 1 }
953     else
954     {
955     #if DEBUG>=1
956     if (cr)
957     fprintf(stderr, "\n");
958     cr = 0;
959 chapuni 24 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 chapuni 1 #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 chapuni 6 int a = (100 << N_STRIDE) * (n_iter - ts[N_TS - 1].c) / (t - ts[N_TS - 1].t);
975 chapuni 1 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 chapuni 2 /*
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