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 46 - (hide annotations) (download) (as text)
Wed Mar 28 08:05:12 2007 UTC (17 years ago) by chapuni
Original Path: mty/mty.c
File MIME type: text/x-csrc
File size: 19809 byte(s)
これまで仕込んできたモジュールを晴れて結合できます。ターゲット数制限が変わりました。制限がかかってる場所があるため、無制限ではありません。また、比較器前段を、 cmp.S を用いずに自前で生成するようにしたため、タゲ数が少ないときにやや速度が上がります。
そんなワケで、cmp.S および expr.[ch] は、晴れて用済みになりました。
ついでにもう使うことがないであろう x64-sse.S も、用済み扱いにしました。

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

Properties

Name Value
svn:eol-style native

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