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

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Rev URL

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