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 15 - (hide annotations) (download) (as text)
Fri Mar 9 11:18:28 2007 UTC (17 years, 1 month ago) by chapuni
Original Path: mty/mty.c
File MIME type: text/x-csrc
File size: 32713 byte(s)
* 鍵シフトスケジュール(ksd)を、 crypt64.S から mty.c へ移動。この改造は元々200509版にて行われていた。
ks_ls[]の内容を、key64.ks[] に移動しているので注意。

* 比較器生成部で、param.hit[]へのポインタをTに割り振っていたが、LRを指しているDIのみを使用するように変更。

* 呼び出し規約のレジスタ破壊を記述するためのマクロ CRYPT64_CLOBBER を定義。

* crypt64.S 中、CNT, KSI はそれぞれ幅の狭いレジスタを採用。姑息な最適化のため。KSIはもはやインクリメントカウンタになった。
また、レジスタ待避の都合上、DX(破壊)とBX(待避)を入れ替えた。

* 初期LRクリアの際、ゼロレジスタとしてR(0)を用いていたが、AMD64ALUだと予約レジスタとかぶってしまいかねないため、R(7)に変更。
1 chapuni 1 /***********************************************************************
2     *
3     * file: mty.cpp
4     *
5 chapuni 2 * ‚Ü‚ A‘Ň‚Ä‰ŽB
6 chapuni 1 *
7     * $Id$
8     *
9     */
10    
11     #define DEBUG 0
12     #define USE_DT 1
13    
14     #ifndef DEBUG
15     #define NDEBUG
16     #endif
17    
18     #include <assert.h>
19     #include <ctype.h>
20 chapuni 13 #include <malloc.h>
21 chapuni 9 #include <limits.h>
22 chapuni 1 #include <stdio.h>
23     #include <stdlib.h>
24     #include <string.h>
25     #include <time.h>
26 chapuni 10
27     #ifdef __GNUC__
28    
29     #include <stdint.h>
30     #define ALIGN_PREFIX(n)
31     #define ALIGN_SUFFIX(n) __attribute__ ((aligned(n)))
32     #ifdef __SSE__
33     typedef unsigned DQWORD_T __attribute__ ((mode(V4SI)));
34     #endif
35    
36     #else
37    
38     #include <xmmintrin.h>
39     #define ALIGN_PREFIX(n) __declspec(align(16))
40     #define ALIGN_SUFFIX(n)
41    
42     /* inttypes.h */
43 chapuni 13 typedef __int8 int8_t;
44 chapuni 10 typedef __int32 int32_t;
45     typedef unsigned __int32 uint32_t;
46     typedef unsigned __int64 uint64_t;
47    
48     typedef __m128 DQWORD_T;
49    
50     #endif
51    
52     #if defined(WIN32)
53    
54     #include <windows.h>
55     #include <sys/timeb.h>
56    
57     #elif defined(__GNUC__)
58    
59     #include <sys/mman.h>
60     #include <sys/time.h>
61    
62     #endif
63    
64 chapuni 1 #include "crypt64.h"
65     #include "dt4.h"
66    
67 chapuni 9 #if defined(USE_MMX)
68 chapuni 6
69     #define N_STRIDE 6
70     typedef uint64_t WS_T;
71     typedef uint32_t ALU_T;
72    
73 chapuni 15 #define CRYPT64_CLOBBER /* "%ecx", "%edx", */
74    
75 chapuni 14 #elif defined(USE_64) /* 64-bit ALU */
76    
77     #define N_STRIDE 6
78     typedef uint64_t WS_T;
79     typedef uint64_t ALU_T;
80    
81 chapuni 9 #elif defined(USE_64_XMM)
82 chapuni 6
83     #define N_STRIDE 7
84 chapuni 10 typedef DQWORD_T WS_T;
85 chapuni 9 typedef uint64_t ALU_T;
86    
87 chapuni 15 #define CRYPT64_CLOBBER /* "%rcx", "%rdx",*/
88    
89 chapuni 9 #else /* XMM */
90    
91     #define N_STRIDE 7
92 chapuni 10 typedef DQWORD_T WS_T;
93 chapuni 6 typedef uint32_t ALU_T;
94    
95 chapuni 15 #define CRYPT64_CLOBBER /* "%ecx", "%edx", */
96    
97 chapuni 6 #endif
98    
99 chapuni 9 #define N_I (sizeof(WS_T) / sizeof(uint32_t))
100 chapuni 6 #define N_ALU (sizeof(WS_T) / sizeof(ALU_T))
101 chapuni 9 #define ALU_BITS (CHAR_BIT * sizeof(ALU_T))
102 chapuni 6
103 chapuni 1 /* ŒŽ“]’u PC1 */
104     static int const tr_pc1[8][7] =
105     {
106     { 8, 16, 24, 56, 52, 44, 36},
107     { 7, 15, 23, 55, 51, 43, 35},
108     { 6, 14, 22, 54, 50, 42, 34},
109     { 5, 13, 21, 53, 49, 41, 33},
110     { 4, 12, 20, 28, 48, 40, 32},
111     { 3, 11, 19, 27, 47, 39, 31},
112     { 2, 10, 18, 26, 46, 38, 30},
113     { 1, 9, 17, 25, 45, 37, 29},
114     };
115    
116     /* LRĹI“]’u */
117     static int const tr_fp[64 + 2] =
118     {
119     39, 7, 47, 15, 55, 23, 63, 31,
120     38, 6, 46, 14, 54, 22, 62, 30,
121     37, 5, 45, 13, 53, 21, 61, 29,
122     36, 4, 44, 12, 52, 20, 60, 28,
123     35, 3, 43, 11, 51, 19, 59, 27,
124     34, 2, 42, 10, 50, 18, 58, 26,
125     33, 1, 41, 9, 49, 17, 57, 25,
126     32, 0, 40, 8, 48, 16, 56, 24,
127     64, 64,
128     };
129    
130 chapuni 15 /* ŒŽƒVƒtƒgƒXƒPƒWƒ…[ƒ‹
131     KEY::k[2] ‚đćґň‚É—p‚˘‚ÄŽć‚čo‚ľ‚ĚŠČ‘f‰ť‚đ}‚é */
132     static int ks_ls[] =
133     {
134     1, 1, 2, -1,
135     2, -1, 2, -1,
136     2, -1, 2, -1,
137     2, -1, 1, 2,
138     -1, 2, -1, 2,
139     -1, 2, -1, 2,
140     -1, 2, -1, 1 - 28,
141     };
142    
143 chapuni 1 /* 1ƒrƒbƒg•Ş */
144 chapuni 6 typedef union SLICE
145 chapuni 1 {
146 chapuni 9 uint32_t i[N_I]; /* 32-bit initializer */
147 chapuni 6 ALU_T a[N_ALU]; /* C ‚Ĺˆľ‚˘‚₡‚˘ƒTƒCƒY */
148     WS_T w; /* ƒGƒ“ƒR[ƒh‚Ĺˆľ‚¤ƒTƒCƒY */
149     } SLICE;
150 chapuni 1
151     /* crypt64() ‚Ş‹ň‚¤ƒpƒ‰ƒ[ƒ^ */
152     struct PARAM
153     {
154 chapuni 6 SLICE lr[2][32];
155     SLICE t[32];
156     SLICE hit[10][64];
157     SLICE hiti[10][26];
158 chapuni 1 };
159    
160 chapuni 15 /* ŒŽ‚ÍLR ‚ƁA‚ť‚ĚƒRƒs[‚Ş•K—v
161     KEY::k[0] LR
162     KEY::k[1] LR‚ĚƒRƒs[(č—]‚đČ‚­‚˝‚ß)
163     KEY::k[2][0][i].a[0] ŽŸŒŽ‚Ö‚Ě‘•Ş */
164 chapuni 1 struct KEY
165     {
166 chapuni 6 SLICE k[2][2][28];
167 chapuni 15 SLICE ks[28];
168 chapuni 1 };
169    
170     /* ŠżŽšƒNƒ‰ƒX•\ */
171     unsigned char cp932[0x10000] = {
172     #include "cp932.inc"
173     };
174    
175     /* ŒŽ•śŽš—ń */
176     unsigned char key[8 + 8];
177     unsigned char okey[8 + 8];
178    
179     /* ŒŽƒNƒ‰ƒX */
180     struct
181     {
182     unsigned cls;
183     unsigned map[256];
184     } kcls[8 + 8];
185    
186     #define KCLS_AN 1
187     #define KCLS_KA 2
188     #define KCLS_K1 4
189     #define KCLS_DT0 64
190     #define KCLS_DT1 128
191     #define KCLS_K2 256
192    
193     #if USE_DT
194     /* ŒŽƒLƒ—pŽŤ‘ƒCƒ“ƒfƒNƒX */
195     struct DT *kd[8 + 8];
196    
197     /* ŽŤ‘ƒCƒ“ƒfƒNƒX */
198     struct DT *dtidx[0x100 + 1];
199     #endif
200    
201     /* Žw’肳‚ę‚˝ƒNƒ‰ƒX‚Ć“ü‚Á‚Ä‚˘‚éƒL[‚Š‚çAclassify ‚đs‚¤ */
202     void
203     key_make_map(int n)
204     {
205     int i, j;
206     unsigned c = kcls[n].map[key[n]];
207    
208     if (3 <= n && n < 7 && kd[n - 3])
209     {
210     /* ŽŤ‘‚ĚƒPƒc‚Ě•śŽšBŒă‚ë‚Ƀiƒjƒ„ƒ‰ƒLƒƒƒ‰ƒNƒ^‚Ş—ˆ‚é */
211     c = kd[n - 3]->c[0];
212     if ((0x81 <= c && c <= 0x9F)
213     || (0xE0 <= c && c <= 0xFC))
214     c = KCLS_K2;
215     else
216     c = (cp932[256 * key[n]]
217     | cp932[256 * (key[n] ^ 0x80)]);
218     #if DEBUG>=1
219     printf("*n=%d, key=%02X, cls=%04X\n",
220     n,
221     key[n],
222     c);
223     #endif
224     }
225     else if (2 <= n && n < 6 && kd[n - 2])
226     {
227     return;
228     }
229     else if (1 <= n && n < 5 && kd[n - 1])
230     {
231     return;
232     }
233     else if (1 <= n && n < 5 && !kd[n - 1]
234     //&& (c & KCLS_K2)
235     && (c & KCLS_DT1))
236     {
237     /* ŠżŽš2•śŽš‚đE‚Á‚Ä‚˘‚Ť‚܂ */
238     #if DEBUG>=1
239     printf("(%d)%02X %02X(%02X:%02X:%02X:%02X)\n",
240     n, key[n - 1], key[n],
241     cp932[(256 * key[n - 1] + key[n])],
242     cp932[(256 * key[n - 1] + key[n]) ^ 0x0080],
243     cp932[(256 * key[n - 1] + key[n]) ^ 0x8000],
244     cp932[(256 * key[n - 1] + key[n]) ^ 0x8080]);
245     #endif
246     if (n != 1 && n != 2
247     && (cp932[(256 * key[n - 1] + key[n]) ^ 0x0080] & KCLS_DT1))
248     key[n] ^= 0x80;
249     else if (n != 2 && n != 3
250     && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8000] & KCLS_DT1))
251     key[n - 1] ^= 0x80;
252     else if (n > 3 && (cp932[(256 * key[n - 1] + key[n]) ^ 0x8080] & KCLS_DT1))
253     key[n - 1] ^= 0x80, key[n] ^= 0x80;
254     if (cp932[256 * key[n - 1] + key[n]] & KCLS_DT1)
255     {
256     for (kd[n - 1] = dtidx[key[n - 1]];
257     kd[n - 1]->c[1] != key[n];
258     kd[n - 1]++)
259     assert(kd[n - 1]->c[0] == key[n - 1]);
260     #if DEBUG>=1
261     printf("(%02X%02X:%02X%02X)%c%c%c%c\n",
262     kd[n - 1]->c[0],
263     kd[n - 1]->c[1],
264     kd[n - 1]->c[2],
265     kd[n - 1]->c[3],
266     kd[n - 1]->c[0],
267     kd[n - 1]->c[1],
268     kd[n - 1]->c[2],
269     kd[n - 1]->c[3]);
270     #endif
271     return;
272     }
273     }
274     else if (n < 4 && (c & KCLS_DT0) && kd[n] == NULL)
275     {
276     /* ƒJƒ^ƒJƒi–„‚ߍž‚Ý‚˘‚Ť‚Ü‚ˇ */
277     assert(kd[n] == NULL);
278     #if DEBUG>=1
279     printf("n=%d, key=%02X\n", n, key[n]);
280     #endif
281     kd[n] = dtidx[key[n]];
282     if (!kd[n]
283     && !(n == 1 || n == 2)
284     && dtidx[key[n] ^ 0x80])
285     {
286     key[n] ^= 0x80;
287     kd[n] = dtidx[key[n]];
288     }
289     if (kd[n])
290     return;
291     }
292     else
293     {
294     kd[n] = NULL;
295     }
296    
297     /* ĹŒă‚Ě•”•Ş‚Í class map ‚đśŹ‚ˇ‚é•K—vƒiƒV */
298     if (n >= 6)
299     return;
300    
301     for (i = 0; i < 256; i++)
302     {
303     unsigned bs = 0, bm = 0;
304     #if 1
305     if (c & KCLS_K1)
306     {
307     if (cp932[256 * key[n] + i] & KCLS_K1)
308     bm |= KCLS_K2 | (cp932[256 * key[n] + i] & KCLS_DT1);
309     if (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
310     bm |= KCLS_K2 | (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_DT1);
311     #if 0
312     bm |= ((cp932[256 * key[n] + i] & KCLS_K1)
313     || (cp932[256 * (key[n] ^ 0x80) + i] & KCLS_K1)
314     ? KCLS_K2 : 0);
315     #endif
316     }
317     if (c & (KCLS_AN | KCLS_KA | KCLS_K2))
318     for (j = 0; j < 256; j++)
319     {
320     bm |= cp932[256 * i + j] & (KCLS_AN | KCLS_KA | KCLS_K1
321     | KCLS_DT0);
322     #if 0
323     if (j >= 127 && !(n == 0 || n == 1))
324     break;
325     #endif
326     }
327     kcls[n + 1].map[i] = bm;
328     #endif
329     if (i >= 128 && !(n == 0 || n == 1))
330     kcls[n + 1].map[i - 128] |= kcls[n + 1].map[i];
331     }
332    
333     if (n < 6)
334     kcls[n + 1].map[0x00] = kcls[n + 1].map[0x80] = 0;
335     if (n == 6)
336     kcls[7].map[0x00] |= KCLS_AN;
337     }
338    
339     unsigned
340     dt_get(int kdn,
341     int xn,
342     int n,
343     int ch)
344     {
345     int i;
346     #if DEBUG>=1
347     printf("*dt_get(%d)%c%c%c%c(%02X%02X:%02X%02X)->ch=%d",
348     n,
349     kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
350     kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
351     ch);
352     #endif
353     /* ‚Ü‚¸‚͐”‚Ś‚é */
354     for (i = 0;
355     kd[kdn][i].c[xn] == kd[kdn]->c[xn];
356     i++)
357     ;
358     assert(i > 0);
359     kd[kdn] += ch % i;
360     #if DEBUG>=1
361     printf("/%d\n dt_get: %c%c%c%c(%02X%02X:%02X%02X)->ch=%d\n",
362     i,
363     kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
364     kd[kdn]->c[0], kd[kdn]->c[1], kd[kdn]->c[2], kd[kdn]->c[3],
365     ch);
366     #endif
367     return kd[kdn]->c[n];
368     }
369    
370     /* ƒ}ƒbƒv‚Š‚ç•śŽš‚đE‚Á‚ăZƒbƒg */
371     unsigned
372     key_set(int n, unsigned ch)
373     {
374     int cnt = 0, i;
375    
376     if (3 <= n && n < 7 && kd[n - 3])
377     {
378     return dt_get(n - 3, 2, 3, ch);
379     return kd[n - 3]->c[3];
380     }
381     else if (2 <= n && n < 6 && kd[n - 2])
382     {
383     return dt_get(n - 2, 1, 2, ch);
384     return kd[n - 2]->c[2];
385     }
386     else if (1 <= n && n < 5 && kd[n - 1])
387     {
388     return dt_get(n - 1, 0, 1, ch);
389     return kd[n - 1]->c[1];
390     }
391    
392     #if DEBUG>=3
393     if (cnt == 0)
394     {
395     printf("n=%d, ch=%d, (n-1)=%02X\n", n, ch, key[n - 1]);
396     int j;
397     for (i = 0; i < 16; i++)
398     {
399     printf("map[0x%02X] =", 16 * i);
400     for (j = 0; j < 16; j++)
401     printf(" %03X", kcls[n].map[16 * i + j]);
402     printf("\n");
403     }
404     }
405     #endif
406     for (i = 0; i < 256; i++)
407     {
408     if (kcls[n].map[i])
409     {
410     if (ch-- == 0)
411     return i;
412     cnt++;
413     }
414     if (n != 1 && n != 2 && i >= 127)
415     break;
416     }
417     /* ŒŠ‚Â‚Š‚ç‚ȂЂÁ‚˝‚Ě‚Ĺ‚ŕ‚˘‚Á‚Ř‚ń */
418     assert(cnt > 0);
419     ch %= cnt;
420     for (i = 0; i < 256; i++)
421     if (kcls[n].map[i])
422     {
423     if (ch-- == 0)
424     return i;
425     }
426     assert(!"not matched");
427     return 0;
428     }
429    
430     /* bitwise key ‚đƒZƒbƒg */
431     static
432     void
433     key_set64(struct KEY *key64,
434     int n,
435     unsigned k,
436     unsigned vk,
437     unsigned sk)
438     {
439 chapuni 6 int i, j;
440 chapuni 1 if (!((vk | sk) & 0x7F))
441     return;
442    
443     for (i = 0; i < 7; i++)
444     {
445 chapuni 6 if (n == 7 && i < N_STRIDE) continue;
446 chapuni 1 if (sk & (1 << i))
447     {
448     /* ƒZƒbƒg */
449     int o = tr_pc1[n][6 - i] - 1;
450     if (o < 28)
451     {
452     assert(o >= 0);
453 chapuni 6 for (j = 0; j < N_ALU; j++)
454     key64->k[0][0][o].a[j]
455     = key64->k[0][1][o].a[j]
456     = -!!(k & (1 << i));
457 chapuni 1 }
458     else
459     {
460     assert(o >= 28);
461     assert(o < 56);
462 chapuni 6 for (j = 0; j < N_ALU; j++)
463     key64->k[1][0][o - 28].a[j]
464     = key64->k[1][1][o - 28].a[j]
465     = -!!(k & (1 << i));
466 chapuni 1 }
467     }
468     else if (vk & (1 << i))
469     {
470     /* ”˝“] */
471     int o = tr_pc1[n][6 - i] - 1;
472     if (o < 28)
473     {
474     assert(o >= 0);
475 chapuni 10 for (j = 0; j < N_ALU; j++)
476     key64->k[0][0][o].a[j]
477     = key64->k[0][1][o].a[j]
478     = ~key64->k[0][0][o].a[j];
479 chapuni 1 }
480     else
481     {
482     assert(o >= 28);
483     assert(o < 56);
484 chapuni 10 for (j = 0; j < N_ALU; j++)
485     key64->k[1][0][o - 28].a[j]
486     = key64->k[1][1][o - 28].a[j]
487     = ~key64->k[1][0][o - 28].a[j];
488 chapuni 1 }
489     }
490     }
491     }
492    
493     /* Žw’肳‚ę‚˝ƒNƒ‰ƒX‚ĚŠJŽn’l‚ÉƒŠƒZƒbƒg
494     ’ź‘O‚Ě•śŽš‚ĚƒNƒ‰ƒX‚É”›‚ç‚ę‚é */
495     int
496     key_reset(int n)
497     {
498     if (n >= 8)
499     return 1;
500     if (n == 7)
501     {
502     key[7] = 0;
503     return 1;
504     }
505    
506     /* 0-2 •śŽš–ڂ̓‰ƒ“ƒ_ƒ€‚ÉŒˆ‚ß‚é
507     3 •śŽš–ÚˆČ~‚͏‰Šú’l‚É */
508     if (n >= 3)
509     key[n] = key_set(n, 0);
510     else
511     key[n] = key_set(n, rand());
512    
513     #if DEBUG>=3
514     printf("key[%d]=%02X ncls=%04X\n", n, key[n], kcls[n].map[key[n]]);
515     #endif
516    
517     /* ƒZƒbƒg‚ł‚ę‚˝•śŽš‚đŒł‚ÉAŽŸƒLƒƒƒ‰‚Ě•śŽšƒNƒ‰ƒX‚đŒˆ‚ß‚é */
518     key_make_map(n);
519    
520     return key_reset(n + 1);
521     }
522    
523     /* Žw’肳‚ę‚˝ŒŽ‹óŠÔ‚Ě’†‚ŁAƒL[‚đ‚ЂƂi‚ß‚é
524     ˆŔ‘S‚ɃCƒ“ƒNƒŠƒƒ“ƒg‚Ĺ‚Ť‚˝ę‡ true ‚đ•Ô‚ˇ */
525     static
526     int
527     key_inc(int n)
528     {
529     if (n >= 8)
530     return 0;
531     else if (n == 7)
532     {
533 chapuni 6 /* ĹŒă‚ĚƒoƒCƒg */
534     if (N_STRIDE == 7)
535     return 0;
536    
537 chapuni 1 key[7] = (key[7] + 64) & 127;
538     if (key[7]) return 1;
539     else return 0;
540     }
541     else if (key_inc(n + 1)
542     /*
543     && key_inc(n + 1)
544     && key_inc(n + 1)
545     && key_inc(n + 1)*/
546     )
547     return 1;
548    
549     /* Salt ‚̓Cƒ“ƒNƒŠƒƒ“ƒg‚ľ‚Č‚˘–ń‘Ђɂˇ‚é */
550     if (n == 1 || n == 2)
551     return 1;
552    
553     #if DEBUG>=3
554     printf("key_inc(n=%d,ck=%02X)\n", n, key[n]);
555     #endif
556    
557     /* ŽŤ‘Œę‚̓Cƒ“ƒNƒŠƒƒ“ƒg‚ľ‚Ä‚˘‚˘–ń‘Ђɂˇ‚é */
558     if (3 <= n && n < 7 && kd[n - 3])
559     {
560     if ((key[n - 3] & 0x7F) == ((kd[n - 3] + 1)->c[0] & 0x7F)
561     && (key[n - 2] & 0x7F) == ((kd[n - 3] + 1)->c[1] & 0x7F)
562     && (key[n - 1] & 0x7F) == ((kd[n - 3] + 1)->c[2] & 0x7F))
563     {
564     memcpy(&key[n - 3], &(++kd[n - 3])->c[0], 4);
565     #if DEBUG>=2
566     printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
567     kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3],
568     kd[n - 3]->c[0], kd[n - 3]->c[1], kd[n - 3]->c[2], kd[n - 3]->c[3]);
569     #endif
570     return 1;
571     }
572     else
573     {
574     return 0;
575     }
576     }
577     else if (2 <= n && n < 6 && kd[n - 2])
578     {
579     if ((key[n - 2] & 0x7F) == ((kd[n - 2] + 1)->c[0] & 0x7F)
580     && (key[n - 1] & 0x7F) == ((kd[n - 2] + 1)->c[1] & 0x7F))
581     {
582     memcpy(&key[n - 2], &(++kd[n - 2])->c[0], 4);
583     #if DEBUG>=2
584     printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
585     kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3],
586     kd[n - 2]->c[0], kd[n - 2]->c[1], kd[n - 2]->c[2], kd[n - 2]->c[3]);
587     #endif
588     return 1;
589     }
590     else
591     {
592     return 0;
593     }
594     if (kd[n - 2]->c[0] == key[n - 2])
595     return 1;
596     else
597     return 0;
598     }
599     else if (1 <= n && n < 5 && kd[n - 1])
600     {
601     unsigned c2 = kd[n - 1]->c[0];
602     if ((0x81 <= c2 && c2 <= 0x9F)
603     || (0xE0 <= c2 && c2 <= 0xFC))
604     {
605     kd[n - 1] = NULL;
606     #if 0
607     if (!(n == 1 && n == 2))
608     key[n] &= 0x7F;
609     if (!(n == 2 && n == 3))
610     key[n - 1] &= 0x7F;
611     #endif
612     key_make_map(n - 1);
613     }
614     else if ((key[n - 1] & 0x7F) == ((kd[n - 1] + 1)->c[0] & 0x7F))
615     {
616     memcpy(&key[n - 1], &(++kd[n - 1])->c[0], 4);
617     #if DEBUG>=2
618     printf(">dt_get:%c%c%c%c(%02X%02X:%02X%02X)\n",
619     kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3],
620     kd[n - 1]->c[0], kd[n - 1]->c[1], kd[n - 1]->c[2], kd[n - 1]->c[3]);
621     #endif
622     return 1;
623     }
624     else
625     {
626     return 0;
627     }
628     #if 0
629     if (kd[n - 1]->c[0] == key[n - 1])
630     return 1;
631     else
632     return 0;
633     #endif
634     }
635     else if (n < 4 && kd[n])
636     {
637     if (0 && kd[n]->c[0] == key[n])
638     return 1;
639     kd[n] = NULL;
640     #if 0
641     if (!(n == 1 || n == 2))
642     key[n] &= 0x7F;
643     #endif
644     }
645    
646     /* ŽŔŰ‚É‘‚₾‚Ă݂é */
647     assert(n >= 3);
648     for (;;)
649     {
650     if (n <= 3
651     && !(key[n] & 0x80)
652     && kcls[n].map[key[n] ^ 0x80] & (KCLS_DT0))
653     {
654     /* ”źŠpƒJƒ^ƒJƒi‚Ě1ƒoƒCƒg–Ú */
655     key[n] ^= 0x80;
656     }
657     else
658     {
659     key[n] = (key[n] & 0x7F) + 1;
660     if (key[n] >= 0x80)
661     return 0;
662     }
663    
664     if (kcls[n].map[key[n]])
665     {
666     key_make_map(n);
667     key_reset(n + 1);
668     return 1;
669     }
670     }
671     while (++key[n] < 0x80)
672     {
673     if (kcls[n].map[key[n]])
674     {
675     key_make_map(n);
676     key_reset(n + 1);
677     return 1;
678     }
679     }
680     return 0;
681     }
682    
683     /* ŒŽ‚đŠŽ‘S‚ÉƒŠƒZƒbƒg‚ˇ‚é
684     Salt‚ŕƒZƒbƒg‚ľ’ꂎ */
685     static
686     void
687     key_init()
688     {
689     int i, j;
690    
691     #if USE_DT
692     /* ŽŤ‘‚đAƒCƒ“ƒfƒNƒX‚đě‚č‚Č‚Ş‚çƒ}ƒbƒv‚ɂ͂߂ą‚ń‚ŐŔ‚­
693     ŽŤ‘‚̓R[ƒh‡¸‡‚É•Ŕ‚ń‚Ĺ‚é‚ŕ‚̂Ƃˇ‚é */
694     for (i = 0; i < dtcnt; i++)
695     {
696     unsigned c = dt[i].c[0];
697    
698     assert(dt[i].c[0]
699     && dt[i].c[1]
700     && dt[i].c[2]
701     && dt[i].c[3]);
702    
703     /* BSD ŽI‚Ĺ‚ľ‚É‚ť‚¤‚Č•śŽš‚ÍŽc”O‚Č‚Ş‚çœŠO */
704     assert((dt[i].c[0] & 0x7F)
705     && (dt[i].c[1] & 0x7F)
706     && (dt[i].c[2] & 0x7F)
707     && (dt[i].c[3] & 0x7F));
708    
709     /* ƒCƒ“ƒfƒNƒX */
710     if (!dtidx[c])
711     dtidx[c] = &dt[i];
712    
713     if ((0x81 <= c && c <= 0x9F)
714     || (0xE0 <= c && c <= 0xFC))
715     {
716     /* ‘SŠp‚Ȃ̂ŁA2ƒoƒCƒg‚Ť‚Ü‚Á‚˝Žž“_‚Ĺ—§‚Ä‚é */
717     cp932[256 * c + dt[i].c[1]] |= KCLS_DT1;
718     }
719     else if (0xA1 <= c && c <= 0xDF)
720     {
721     /* ”źŠpƒJƒi */
722     for (j = 0; j < 256; j++)
723     cp932[256 * c + j] |= KCLS_DT0;
724     }
725     }
726     /* ƒPƒcA‚ż‚¤‚Š”Ôl */
727     dtidx[0x100] = &dt[i];
728     #endif
729    
730     key[8] = 0;
731    
732     /* ‰Šúƒ}ƒbƒv‚đ‘g‚Ţ */
733     for (i = 0; i < 256; i++)
734     {
735     unsigned bm = 0;
736     kcls[0].map[i] = 0;
737     for (j = 0; j < 256; j++)
738     bm |= cp932[256 * i + j];
739     kcls[0].map[i] = bm & (KCLS_AN | KCLS_KA | KCLS_K1
740     | KCLS_DT0
741     );
742     if (i >= 128)
743     kcls[0].map[i - 128] |= kcls[0].map[i];
744     }
745    
746     key_reset(0);
747     }
748    
749     /***************************************************************
750     *
751     * ‰ÂŽ‹•śŽš—ń‚ɕϊˇ
752     * n = 0, flag !=0 ‚ĹŒÄ‚Ô‚ą‚Ć
753     *
754     * ptr ‚ĹŽw‚ł‚ę‚é•śŽš—ń‚́A•ĎŠˇ‚ÉŹŒ÷‚ľ‚˝‚珑‚ŤŠˇ‚Ś‚ç‚ę‚é
755     *
756     * ŹŒ÷‚ľ‚˝‚ç flg, ޏ”s‚ľ‚˝‚ç 0 ‚đ•Ô‚ˇB
757     *
758     */
759    
760     unsigned
761     translate(unsigned char *ptr,
762     int n,
763     unsigned flag)
764     {
765     int r;
766     unsigned char buf[32];
767     unsigned s0 = (n == 1 || n == 2 ? 0x00 : 0x80);
768     unsigned s1 = (n == 0 || n == 1 ? 0x00 : 0x80);
769     unsigned c0 = ptr[n] << 8;
770     unsigned c1 = ptr[n + 1];
771     unsigned cs0 = c0 ^ (s0 << 8);
772     unsigned cs1 = c1 ^ s1;
773    
774     if (n >= 8)
775     return flag;
776    
777     if (n == 7)
778     {
779     int i;
780     /* ĹŒă‚Ě1•śŽš */
781     if (!(ptr[7] & 0x7F))
782     return flag;
783    
784     for (i = 0x00; i <= 0x7E; i++)
785     {
786     if (cp932[c0 | i] & KCLS_K1)
787     {
788     ptr[8] = i;
789     return flag;
790     }
791     if (cp932[c0 | (0x80 + i)] & KCLS_K1)
792     {
793     ptr[8] = 0x80 + i;
794     return flag;
795     }
796     }
797    
798     ptr[7] ^= 0x80; c0 = ptr[7] << 8;
799     for (i = 0x00; i <= 0x7E; i++)
800     {
801     if (cp932[c0 | i] & KCLS_K1)
802     {
803     ptr[8] = i;
804     return flag;
805     }
806     if (cp932[c0 | (0x80 + i)] & KCLS_K1)
807     {
808     ptr[8] = 0x80 + i;
809     return flag;
810     }
811     }
812     ptr[7] ^= 0x80; c0 = ptr[7] << 8;
813     }
814    
815     /* K1 */
816     if (cp932[c0 | c1] & KCLS_K1)
817     {
818     r = translate(ptr, n + 2, flag);
819     if (r)
820     return r;
821     }
822     if (s0
823     && cp932[cs0 | c1] & KCLS_K1)
824     {
825     memcpy(buf, ptr, sizeof(buf));
826     buf[n] ^= s0;
827     r = translate(buf, n + 2, flag);
828     if (r)
829     {
830     memcpy(ptr, buf, sizeof(buf));
831     return r;
832     }
833     }
834     if (s1
835     && cp932[c0 | cs1] & KCLS_K1)
836     {
837     memcpy(buf, ptr, sizeof(buf));
838     buf[n + 1] ^= s1;
839     r = translate(buf, n + 2, flag);
840     if (r)
841     {
842     memcpy(ptr, buf, sizeof(buf));
843     return r;
844     }
845     }
846     if (s0 && s1
847     && cp932[cs0 | cs1] & KCLS_K1)
848     {
849     memcpy(buf, ptr, sizeof(buf));
850     buf[n] ^= s0;
851     buf[n + 1] ^= s1;
852     r = translate(buf, n + 2, flag);
853     if (r)
854     {
855     memcpy(ptr, buf, sizeof(buf));
856     return r;
857     }
858     }
859    
860     /* AN */
861     if (cp932[c0] & (KCLS_AN | KCLS_KA))
862     {
863     r = translate(ptr, n + 1, flag);
864     if (r)
865     return r;
866     }
867     if (s0 && cp932[cs0] & (KCLS_AN | KCLS_KA))
868     {
869     memcpy(buf, ptr, sizeof(buf));
870     buf[n] ^= s0;
871     r = translate(buf, n + 1, flag);
872     if (r)
873     {
874     memcpy(ptr, buf, sizeof(buf));
875     return r;
876     }
877     }
878    
879     /* KA */
880     /* KG */
881     /* KD */
882     /* AD */
883    
884     return 0;
885     }
886    
887     /***************************************************************
888     *
889     * Salt ‚ĚƒZƒbƒg
890     * ƒIƒyƒ‰ƒ“ƒh‚ĚƒIƒtƒZƒbƒg‚đ‘‚ŤŠˇ‚ڂĉń‚Á‚Ä‚é‚̂ŒˆÓ
891     *
892     */
893    
894 chapuni 9 #if N_STRIDE == 6
895     #define C(c,i,j,o) (*(int8_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
896     #elif N_STRIDE == 7
897     #define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_sta) + los[6 * (i) + (j) + (o)]))
898 chapuni 6 #endif
899    
900 chapuni 1 void
901     set_salt(signed char *code,
902     unsigned char const *k)
903     {
904     int i, j;
905    
906     for (i = 0; i < 2; i++)
907     {
908     unsigned s = k[1 + i] & 255;
909     if (s > 'z')
910     s = 0;
911     else if (s >= 'a')
912     s = s - 'a' + 2 + 10 + 26;
913     else if (s >= 'A')
914     s = s - 'A' + 2 + 10;
915     else if (s >= '.')
916     s = s - '.';
917     else
918     s = 0;
919    
920     #if DEBUG>=1
921     printf("Salt %d:%3o\n", i, s & 63);
922     #endif
923     for (j = 0; j < 6; j++)
924     {
925     #if DEBUG>=2
926 chapuni 6 //printf("Salt %d:%d %+3d:%+3d",
927     printf("Salt %d:%d %08lX:%08lX",
928 chapuni 1 i, j,
929 chapuni 6 C(code, i, j, 0),
930     C(code, i, j, 24));
931 chapuni 1 #endif
932     if (s & (1 << j))
933     {
934 chapuni 6 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
935     C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
936 chapuni 1 }
937     else
938     {
939 chapuni 6 C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16);
940     C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16);
941 chapuni 1 }
942 chapuni 6 C(code, i, j, 12) = sizeof(WS_T) * (((4 * i + j + 7) & 31) - 16);
943     C(code, i, j, 36) = sizeof(WS_T) * (((4 * i + j + 23) & 31) - 16);
944 chapuni 1 #if DEBUG>=2
945 chapuni 6 //printf(" => %+3d:%+3d\n",
946     printf(" => %08lX:%08lX\n",
947     C(code, i, j, 0),
948     C(code, i, j, 24));
949 chapuni 1 #endif
950     }
951     }
952     }
953    
954     /***************************************************************
955     *
956     * ƒIƒyƒR[ƒh‚đ“WŠJ
957     *
958     * r EAX, ECX, EDX, EBX
959 chapuni 14 * SIB, EBP, ESI, EDI
960 chapuni 1 *
961     */
962    
963 chapuni 14 /* ofs8(i) ‚ŕ‚ľ‚­‚Í ofs32(i) ‚đśŹ */
964 chapuni 1 static
965     signed char *
966 chapuni 14 disp_rm(signed char *pc,
967     unsigned d,
968     unsigned i,
969     long ofs)
970     {
971     assert(i != 4); /* SP ‚ł͂Ȃ­ SIB ‚ɂȂé */
972     if (-128 <= ofs && ofs <= 127)
973     {
974     /* short ofs
975     01 ddd sss [ofs.b] */
976     pc[0] = (0100
977     | ((d << 3) & 0070)
978     | (i & 0007));
979     pc[1] = ofs;
980     return pc + 2;
981     }
982     else
983     {
984     /* long ofs
985     10 ddd sss [ofs.l] */
986     pc[0] = (0200
987     | ((d << 3) & 0070)
988     | (i & 0007));
989     *(long *)&pc[1] = ofs; /* XXX unaligned */
990     return pc + 5;
991     }
992     }
993    
994 chapuni 15 #define PTR_T 7 /* DI(LR+16) */
995     #define OFS_T (64 + 32 - 16)
996 chapuni 14
997     #ifdef USE_64 /* ALU 64 */
998    
999     /*
1000     * 0x49 0xF7 11-010-ddd not
1001     * 0x49 op 11-sss-ddd
1002     *
1003     * 0x4C op rm
1004     * 0x4C 0x8B rm load
1005     * 0x4C 0x89 rm store
1006     *
1007     */
1008    
1009     #define OP_MOV 0x8B
1010     #define OP_STOR 0x89
1011     #define OP_AND 0x23
1012     #define OP_OR 0x0B
1013     #define OP_XOR 0x33
1014    
1015     static
1016     signed char *
1017 chapuni 1 reg_op(signed char *pc,
1018     unsigned op,
1019     unsigned d,
1020     unsigned s)
1021     {
1022 chapuni 14 pc[0] = 0x4D; /* 49 */
1023     pc[1] = op & 0xFD;
1024     /* 11 ddd sss */
1025     pc[2] = (0300
1026     | ((s << 3) & 0070)
1027     | (d & 0007));
1028     return pc + 3;
1029     }
1030    
1031     static
1032     signed char *
1033     reg_mem(signed char *pc,
1034     unsigned op,
1035     unsigned d,
1036     unsigned i,
1037     long ofs)
1038     {
1039     pc[0] = 0x4C;
1040     pc[1] = op;
1041     return disp_rm(pc + 2, d, i, ofs);
1042     }
1043    
1044     #else /* MMX or XMM */
1045    
1046     #define OP_MOV 0x6F
1047     #define OP_STOR 0x7F
1048     #define OP_AND 0xDB
1049     #define OP_ANDN 0xDF
1050     #define OP_OR 0xEB
1051     #define OP_XOR 0xEF
1052    
1053     static
1054     signed char *
1055     reg_op(signed char *pc,
1056     unsigned op,
1057     unsigned d,
1058     unsigned s)
1059     {
1060 chapuni 10 #ifndef USE_MMX
1061 chapuni 6 *pc++ = 0x66;
1062     #endif
1063 chapuni 1 pc[0] = 0x0F;
1064     pc[1] = op;
1065     /* 11 ddd sss */
1066     pc[2] = (0300
1067     | ((d << 3) & 0070)
1068     | (s & 0007));
1069     return pc + 3;
1070     }
1071    
1072     static
1073     signed char *
1074     reg_mem(signed char *pc,
1075     unsigned op,
1076     unsigned d,
1077 chapuni 14 unsigned i,
1078 chapuni 10 int ofs)
1079 chapuni 1 {
1080 chapuni 10 #ifndef USE_MMX
1081 chapuni 6 *pc++ = 0x66;
1082     #endif
1083 chapuni 1 pc[0] = 0x0F;
1084     pc[1] = op;
1085 chapuni 14 return disp_rm(pc + 2, d, i, ofs);
1086 chapuni 1 }
1087    
1088 chapuni 14 #endif
1089    
1090 chapuni 1 /***************************************************************
1091     *
1092     * —^‚Ś‚ç‚ę‚˝ŽŽ‚đ‰đÍE–˝—ߐśŹ
1093     *
1094     * ^ ć“ŞŒĹ’č
1095     * $ ––”öŒĹ’č
1096     * ? ”CˆÓ‚Ě1•śŽš
1097     * * ”CˆÓ‚Ě0•śŽšˆČă
1098     * & ‘召‹ć•ĘƒiƒVAƒOƒ‹[ƒv‚ÉŽg‚í‚ę‚˝ę‡Acapitalize
1099     * () ƒOƒ‹[ƒv‰ť
1100     * \s or
1101     * \1 ˆę’v‚ľ‚˝ƒOƒ‹[ƒv(ŽŔ‘Ě)
1102     * $(fn) ƒeƒLƒXƒg‚đ“WŠJ(ƒOƒ‹[ƒv‚̓Nƒ‰ƒX‚Ć‚ľ‚Ĉľ‚í‚ę‚é)
1103     *
1104     * ˆČ‰şAƒNƒ‰ƒX“WŠJ‚Ěƒƒ^ƒLƒƒƒ‰
1105     * [A-Z] •śŽšƒNƒ‰ƒX’č‹` ^ ‚Í”r‘ź
1106     * {} 0•śŽšˆČă
1107     * {n} n•śŽš
1108     * {n,} n•śŽšˆČă
1109     * {,n} n•śŽšˆČ‰ş
1110     * {m,n} m-n•śŽš
1111     *
1112     */
1113    
1114     static
1115     int
1116     cv64(int c)
1117     {
1118     if ('.' <= c && c <= '/')
1119     return c - '.';
1120     else if ('0' <= c && c <= '9')
1121     return c - '0' + 2;
1122     else if ('A' <= c && c <= 'Z')
1123     return c - 'A' + 2 + 10;
1124     else if ('a' <= c && c <= 'z')
1125     return c - 'a' + 2 + 10 + 26;
1126     else
1127     return -1;
1128     }
1129    
1130     static
1131     int
1132     expr_make(signed char *iptr,
1133     int ofs,
1134     char const *expr,
1135     int len)
1136     {
1137     /* ć“ސ§–ń */
1138     signed char *o_iptr = iptr;
1139 chapuni 14 unsigned op = OP_MOV;
1140 chapuni 1 int i;
1141    
1142     if (expr[0] == '^')
1143     {
1144     if (len == 0 || ofs > 0)
1145     return -1;
1146     expr++;
1147     len--;
1148     }
1149    
1150     /* ˆę•śŽš‚“WŠJ */
1151     for (i = 0; i < len; i++)
1152     {
1153     int c = expr[i];
1154    
1155     if (c == '$')
1156     {
1157 chapuni 14 assert(op != OP_MOV);
1158 chapuni 1 if (ofs < 10)
1159     return 0;
1160     else if (ofs > 10)
1161     return -1;
1162     return iptr - o_iptr;
1163     }
1164    
1165     if (ofs >= 10)
1166     return -1;
1167    
1168     if (c == '[')
1169     {
1170     /* ƒNƒ‰ƒX‚đ‚܂Ƃ߂é */
1171     unsigned oop; /* MOVQ */
1172     int j;
1173     int cs[64];
1174     memset(cs, 0, 64 * sizeof(int));
1175     for (i++; c = expr[i], c != ']'; i++)
1176     {
1177     c = cv64(c);
1178     if (c < 0)
1179     return -1;
1180     if (expr[i + 1] == '-')
1181     {
1182     int ce = cv64(expr[i + 2]);
1183     if (ce < 0)
1184     return -1;
1185     while (c <= ce)
1186     cs[c++]++;
1187     i += 2;
1188     }
1189     else
1190     cs[c]++;
1191     }
1192     assert(c == ']');
1193    
1194     /* ƒ}ƒbƒv‚ł‚ę‚˝ƒ‚ƒm‚Š‚ç–˝—ß‚đśŹ‚ˇ‚é */
1195 chapuni 14 oop = OP_MOV;
1196 chapuni 1 for (j = 0; j < 64; j++)
1197     if (cs[j])
1198     {
1199     if (ofs == 9 && (j & 3))
1200     continue;
1201     iptr = reg_mem(iptr,
1202     oop,
1203 chapuni 14 1, /* MM1/R9 */
1204     PTR_T,
1205 chapuni 15 sizeof(WS_T) * (OFS_T + (64 * ofs + j)));
1206 chapuni 14 oop = OP_OR;
1207 chapuni 1 }
1208 chapuni 14 if (oop != OP_OR)
1209 chapuni 1 {
1210     if (ofs == 9)
1211     return -1;
1212     }
1213     else
1214     {
1215     iptr = reg_op(iptr,
1216     op,
1217 chapuni 14 0, /* MM0/R8 */
1218     1); /* MM1/R9 */
1219     op = OP_AND;
1220 chapuni 1 }
1221     ofs++;
1222     }
1223     else if (c == '?')
1224     {
1225     ofs++;
1226     }
1227     else if ((c = cv64(c)) >= 0)
1228     {
1229     if (ofs == 9 && (c & 3))
1230     return -1;
1231     iptr = reg_mem(iptr,
1232     op,
1233 chapuni 14 0, /* MM0/R8 */
1234     PTR_T,
1235 chapuni 15 sizeof(WS_T) * (OFS_T + (64 * ofs + c)));
1236 chapuni 14 op = OP_AND;
1237 chapuni 1 ofs++;
1238     }
1239     else
1240     return -1;
1241     }
1242    
1243     return iptr - o_iptr;
1244     }
1245     /*
1246     Fighters ^FIGHTERS ^BayStars ^Red[Ss]tar/ ^REDSTAR/ ^Parsifal ^VALKYRIE ^Valkyrie
1247     ^Dr.Death ^IamCHONO ^RAGNAROK ^MARAOH.. ^MARAOH// ......... God[Ff]ather GODFATHER
1248     ^maraGULO[./] BLACKJACK ^[Bb]lackjack ^BlackJack [Pp]atagonia PATAGONIA ^JC.PENNEY
1249     ^JC.Penney ^syombolic ROCKNROLL stammerB4U Ms.Erie.W. MARA.w/w/w R3[0-4]SKYLINE
1250     100000[Gg]et. 100000GET.
1251     */
1252     signed char *
1253     expr_parse(signed char *iptr,
1254     int codesiz_limit,
1255     char const *expr)
1256     {
1257     char expr_buf[65536 + 1];
1258     FILE *fp;
1259     size_t sz;
1260    
1261     /* ƒtƒ@ƒCƒ‹‚đ“ǂݍž‚Ţ
1262     ‚ą‚̔łł͎蔲‚Ť‚Ĺ 64K §ŒŔ */
1263     #define TARGET_SIZ 65536
1264     fp = fopen("target.txt", "rb");
1265     memset(expr_buf, 0, TARGET_SIZ + 1);
1266     sz = fread(expr_buf, sizeof(char), TARGET_SIZ, fp);
1267     fclose(fp);
1268    
1269     /* XXX ƒ^[ƒQƒbƒg‚ĚƒTƒCƒY‚đƒ`ƒFƒbƒN */
1270     if (sz == TARGET_SIZ)
1271     {
1272     /* ƒg[ƒNƒ“‚Ěƒgƒ‰ƒo[ƒX */
1273     char *ds, *pe, *ps;
1274     for (ds = &expr_buf[TARGET_SIZ - 1];
1275     !isspace(*ds);
1276     ds--)
1277     assert(ds >= expr_buf);
1278     for (pe = ds++; isspace(*pe); pe--)
1279     assert(pe >= expr_buf);
1280     for (ps = pe++; !isspace(*ps); ps--)
1281     assert(ps >= expr_buf);
1282     fprintf(stderr, "WARNING: <");
1283     ps++;
1284     while (ps < pe)
1285     fputc(*ps++, stderr);
1286     fprintf(stderr, ">‚ć‚čŒă‚ë‚Ěƒ^[ƒQƒbƒg<%s(ry>‚̓I‡hƒ‹\n",
1287     ds);
1288     *pe = 0;
1289     }
1290    
1291 chapuni 14 /* MM7 ‚Ƀ^[ƒQƒbƒg–ˆ‚É”äŠrŒ‹‰Ę‚đ OR ‚ľ‚Ä‚˘‚­‚˝‚ß
1292     ‚Ü‚¸‚̓[ƒƒNƒŠƒA */
1293     iptr = reg_op(iptr, OP_XOR, 7, 7); /* MM7/R15 := 0 */
1294 chapuni 1
1295     /* ‡ŒJ‚č‚É parse */
1296     expr = expr_buf;
1297     while (expr[0])
1298     {
1299     char const *p;
1300     int i;
1301    
1302     /* “Ş‚Ě Whitespace ‚đ“ǂݔň‚΂ˇ */
1303     while (isspace(expr[0]))
1304     expr++;
1305    
1306     if (!expr[0])
1307     break;
1308    
1309     /* ƒg[ƒNƒ“‚đŘ‚čo‚ˇ */
1310     for (p = expr; expr[0] && !isspace(expr[0]); expr++)
1311     ;
1312    
1313     /* “WŠJ‚ˇ‚é */
1314     for (i = 0; i < 10; i++)
1315     {
1316     int n = expr_make(iptr, i, p, expr - p);
1317     if (n < 0)
1318     break;
1319     #if DEBUG>=1
1320     if (n > 0)
1321     {
1322     int j;
1323     for (j = 0; &p[j] < expr; j++)
1324     putchar(p[j]);
1325     printf(": of=%d len=%d\n", i, expr - p);
1326     }
1327     #endif
1328 chapuni 14 /* 1ƒ^[ƒQƒbƒg•Ş‚Ě”äŠrŒ‹‰Ę‚đ MM7 ‚ɒljÁ */
1329 chapuni 1 if (n > 0)
1330     iptr = reg_op(iptr + n,
1331 chapuni 14 OP_OR,
1332     7, /* MM7/R15 */
1333     0); /* MM0/R8 */
1334 chapuni 1 }
1335     }
1336    
1337 chapuni 14 /* MM7 ‚ɐśŹ‚ł‚ę‚˝Œ‹‰Ę‚đ t[31] ‚ÉŠi”[ */
1338 chapuni 1 return reg_mem(iptr,
1339 chapuni 14 OP_STOR,
1340     7, /* MM7/R15 */
1341     PTR_T,
1342 chapuni 15 sizeof(WS_T) * (64 + 31 - 16));
1343 chapuni 1 }
1344    
1345     static
1346 chapuni 10 unsigned
1347 chapuni 1 usec()
1348     {
1349 chapuni 10 #if !defined(WIN32)
1350 chapuni 1 struct timeval tv;
1351     gettimeofday(&tv, NULL);
1352     return 100 * tv.tv_sec + (tv.tv_usec / 10000);
1353     #else
1354     struct timeb tm;
1355     ftime(&tm);
1356     return 100 * tm.time + tm.millitm / 10;
1357     #endif
1358     }
1359    
1360     /***************************************************************
1361     *
1362     * ƒƒCƒ“ƒ‹[ƒv‚Ć‚Š
1363     *
1364     */
1365    
1366     /* ’萔€ */
1367 chapuni 6 #if N_STRIDE == 7
1368     static SLICE const sk6[N_STRIDE] =
1369 chapuni 1 {
1370 chapuni 6 {0xAAAAAAAAUL, 0xAAAAAAAAUL, 0xAAAAAAAAUL, 0xAAAAAAAAUL},
1371     {0xCCCCCCCCUL, 0xCCCCCCCCUL, 0xCCCCCCCCUL, 0xCCCCCCCCUL},
1372     {0xF0F0F0F0UL, 0xF0F0F0F0UL, 0xF0F0F0F0UL, 0xF0F0F0F0UL},
1373     {0xFF00FF00UL, 0xFF00FF00UL, 0xFF00FF00UL, 0xFF00FF00UL},
1374     {0xFFFF0000UL, 0xFFFF0000UL, 0xFFFF0000UL, 0xFFFF0000UL},
1375     {0x00000000UL, 0xFFFFFFFFUL, 0x00000000UL, 0xFFFFFFFFUL},
1376     {0x00000000UL, 0x00000000UL, 0xFFFFFFFFUL, 0xFFFFFFFFUL},
1377     };
1378     #elif N_STRIDE == 6
1379     static SLICE const sk6[N_STRIDE] =
1380     {
1381 chapuni 1 {0xAAAAAAAAUL, 0xAAAAAAAAUL},
1382     {0xCCCCCCCCUL, 0xCCCCCCCCUL},
1383     {0xF0F0F0F0UL, 0xF0F0F0F0UL},
1384     {0xFF00FF00UL, 0xFF00FF00UL},
1385     {0xFFFF0000UL, 0xFFFF0000UL},
1386     {0x00000000UL, 0xFFFFFFFFUL},
1387     };
1388 chapuni 6 #endif
1389 chapuni 1
1390 chapuni 10 #ifdef WIN32
1391     typedef int (__fastcall *CRYPT64_PP)(ALU_T const *k, ALU_T *lr);
1392 chapuni 1 #endif
1393    
1394 chapuni 10 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
1395     ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
1396 chapuni 1
1397     int
1398     main(int argc, char *argv[])
1399     {
1400     int i, j;
1401     int mincnt;
1402 chapuni 2 signed char *code = NULL;
1403 chapuni 1 FILE *ofp;
1404     int n_iter;
1405     int cr;
1406    
1407     #define N_TS 4
1408     struct
1409     {
1410     unsigned t;
1411     int c;
1412     } ts[N_TS];
1413    
1414 chapuni 10 #ifdef WIN32
1415     HANDLE h;
1416     #endif
1417    
1418 chapuni 1 #ifndef __GNUC__
1419     CRYPT64_PP d_crypt64;
1420     #endif
1421    
1422     #if 0
1423     if (argc < 2)
1424     {
1425     fprintf(stderr, "ŽŽ‚Ť‚Ú‚ń‚Ę\n");
1426     return 1;
1427     }
1428     #endif
1429    
1430 chapuni 10 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
1431    
1432 chapuni 1 /* t[16] ‚́A“ŕ•”‰‰ŽZ‚ĹŽg—p‚ˇ‚éAall 1 ‚Ş“ü‚Á‚Ä‚˘‚é */
1433 chapuni 6 for (i = 0; i < N_ALU; i++)
1434     param64.t[16].a[i] = -1;
1435 chapuni 1
1436     /* ŒĹ’čƒL[‚ĚƒRƒs[ */
1437 chapuni 6 for (i = 0; i < N_STRIDE; i++)
1438 chapuni 1 {
1439     int o = tr_pc1[7][6 - i] - 1;
1440     if (o < 28)
1441     {
1442     key64.k[0][0][o] = key64.k[0][1][o] = sk6[i];
1443     }
1444     else
1445     {
1446     o -= 28;
1447     key64.k[1][0][o] = key64.k[1][1][o] = sk6[i];
1448     }
1449     }
1450    
1451 chapuni 15 /* ƒL[ƒXƒPƒWƒ…[ƒ‹‚đ‚ą‚ą‚ɉŸ‚ľž‚߂è‚­
1452     ]—ˆ‚Í crypt64.S “ŕ‚ĹŠŽŒ‹‚ˇ‚é‚悤‚Ɉř‚˘‚Ä‚˘‚˝ */
1453     for (i = 0; i < 28; i++)
1454     key64.ks[i].a[0] = sizeof(WS_T) * ks_ls[i];
1455    
1456 chapuni 1 /* Salt‚đ‰Á–Ą‚ľ‚Č‚˘ę‡‚́AƒR[ƒh—Ěˆć‚đ
1457     writable —Ěˆć‚É“WŠJ‚ľ‚Č‚­‚Ä‚ŕ‚悢B
1458     [XXX] OS‚É‚ć‚Á‚ẮA‘ž&ŽŔs‰Â”\—Ěˆć‚đę—p‚ĚƒT[ƒ”ƒBƒX‚Ĺ
1459     Žć“ž‚ľ‚Ȃ݂ę‚΂Ȃç‚Č‚˘‚ŕ‚Ě‚ŕ‚ ‚邊‚ŕ‚ľ‚ę‚Č‚˘‚̂ŁA’ˆÓ */
1460 chapuni 10 #ifdef WIN32
1461     h = CreateFileMapping(INVALID_HANDLE_VALUE,
1462     NULL,
1463     PAGE_EXECUTE_READWRITE,
1464     0, 0x20000000,
1465     NULL);
1466     #ifndef FILE_MAP_EXECUTE
1467     #define FILE_MAP_EXECUTE SECTION_MAP_EXECUTE /* XXX cygwin */
1468     #endif
1469 chapuni 2 if (SUCCEEDED(h))
1470     code = (signed char *)MapViewOfFile(h,
1471 chapuni 10 FILE_MAP_EXECUTE | FILE_MAP_WRITE,
1472 chapuni 2 0, 0x10000000,
1473     0);
1474 chapuni 1 #else
1475     code = (signed char *)mmap(NULL,
1476     0x10000000,
1477     PROT_EXEC | PROT_READ | PROT_WRITE,
1478     MAP_PRIVATE | MAP_ANONYMOUS,
1479     1, /* fd */
1480     0);
1481 chapuni 2 if ((void *)code == MAP_FAILED)
1482     code =NULL;
1483 chapuni 1 #endif
1484 chapuni 2
1485     /* ƒƒ‚ƒŠ‚ŞŠm•ۂłŤ‚Ä‚˘‚Č‚˘ę‡‚Ě‚˘‚ń‚ż‚Ť‘΍ô */
1486     if (code == NULL)
1487     code = (signed char *)malloc(crypt64_end - crypt64_sta + 1024 * 1024);
1488     assert(code != NULL);
1489    
1490     /* Prologue ‚đ“WŠJ */
1491 chapuni 1 memcpy(code, crypt64_sta, crypt64_end - crypt64_sta);
1492     #ifndef __GNUC__
1493     d_crypt64 = (CRYPT64_PP)code;
1494     #endif
1495     memcpy(expr_parse(code + (crypt64_end - crypt64_sta),
1496     1024 * 1024 - (crypt64_ep_end - crypt64_ep),
1497     argv[1]),
1498     crypt64_ep,
1499     crypt64_ep_end - crypt64_ep);
1500    
1501     /* ƒL[‚̏‰Šú‰ť */
1502     srand(time(NULL));
1503     key_init();
1504     set_salt(code, key);
1505     for (i = 0; i < 8; i++)
1506     key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
1507    
1508     #if DEBUG>=1
1509     printf("key=%p param=%p\n", &key64, &param64);
1510     #endif
1511 chapuni 10 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
1512     assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
1513 chapuni 1
1514     if ((ofp = fopen("log.txt", "at")) != NULL)
1515     setvbuf(ofp, NULL, _IOLBF, BUFSIZ);
1516    
1517     for (i = 0; i < N_TS; i++)
1518     ts[i].t = ts[i].c = 0;
1519    
1520     mincnt = 0x7FFFFFFF;
1521     n_iter = 0;
1522     cr = 0;
1523     /* ’Tőƒ‹[ƒv‚ž‚ź‚Á‚Ć */
1524     for (;;)
1525     {
1526 chapuni 9 int32_t cnt;
1527 chapuni 1 int k, kk;
1528    
1529     /* ŒŽ‚ĚƒZƒbƒg */
1530     for (i = 0; i < 8; i++)
1531     {
1532     key_set64(&key64, i, key[i], key[i] ^ okey[i], 0);
1533     okey[i] = key[i];
1534     }
1535    
1536 chapuni 14 /* ŒÄ‚Ô!
1537     LR ‰Šú‰ť‚́AƒTƒuƒ‚ƒWƒ…[ƒ‹“ŕ‚ōs‚¤‚ׂľ
1538     FASTCALL ‚ɏ€‚ś‚˝ŒÄ‚яo‚ľ‚Ě‚˝‚߁A
1539     ƒzƒ“ƒg‚Í‚˘‚낢‚냌ƒWƒXƒ^‚Ş”j‰ó‚ł‚ę‚éƒnƒYc‚Č‚ń‚ž‚ށB */
1540 chapuni 1 #ifdef __GNUC__
1541     asm volatile("call *%3"
1542     : "=a"(cnt)
1543 chapuni 14 : "c"(key64.k), "d"(param64.lr),
1544     "m"(code)
1545     //"m"(crypt64_sta)
1546 chapuni 15 : CRYPT64_CLOBBER "memory");
1547 chapuni 1 #else
1548     cnt = (*d_crypt64)(key64.k[0][0][0].a, param64.lr[0][0].a);
1549     #endif
1550     if (mincnt > cnt && cnt > 0)
1551     {
1552     mincnt = cnt;
1553     if (cr)
1554     fprintf(stderr, "\n");
1555     cr = 0;
1556 chapuni 9 fprintf(stderr, "cycle=%d\n", (int)cnt);
1557 chapuni 1 }
1558    
1559     /* ƒqƒbƒg‚ľ‚˝‚Ć‚Ť‚̏ˆ— */
1560 chapuni 6 for (kk = 0; kk < N_ALU; kk++)
1561 chapuni 1 {
1562 chapuni 6 ALU_T t;
1563 chapuni 9
1564 chapuni 1 t = param64.t[31].a[kk];
1565     if (!t)
1566     continue;
1567 chapuni 9
1568 chapuni 6 for (k = 0; k < ALU_BITS; k++)
1569 chapuni 1 {
1570     char hash[16];
1571     unsigned char buf[32];
1572 chapuni 9
1573     if (!(t & ((ALU_T)1 << k)))
1574 chapuni 1 continue;
1575 chapuni 9
1576 chapuni 14 /* XXX Žč”˛‚Ť‚Ě‚˝‚߁Aƒ[ƒN‚ɂ͂ݏo‚Ä‚˘‚é 2 ƒrƒbƒg‚đ‚ą‚ą‚Ĺ—Ž‚Ć‚ˇ
1577     ƒqƒbƒg‚ˇ‚é‚˝‚Ń‚Éç’ˇ‚ɍs‚í‚ę‚邪A‹C‚É‚ľ‚Ă͂˘‚Š‚ń */
1578     for (i = 0; i < N_ALU; i++)
1579     param64.t[0].a[i] = param64.t[1].a[i] = 0;
1580 chapuni 1 for (i = 1; i < 11; i++)
1581     {
1582     unsigned c = 0;
1583     for (j = 0; j < 6; j++)
1584 chapuni 9 c = (c << 1) | !!(param64.lr[0][tr_fp[6 * i + j]].a[kk] & ((ALU_T)1 << k));
1585 chapuni 1 hash[i - 1] = c["./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
1586     }
1587     hash[10] = 0;
1588    
1589     memcpy(buf, key, 32);
1590     buf[8] = buf[9] = 0;
1591 chapuni 10 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
1592 chapuni 1 if (translate(buf, 0, 1))
1593     {
1594     if (cr)
1595     fprintf(stderr, "\n");
1596     cr = 0;
1597     printf("Ÿ%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)\n",
1598     hash,
1599     buf,
1600     buf[0], buf[1], buf[2], buf[3],
1601     buf[4], buf[5], buf[6], buf[7],
1602     buf[8]);
1603     if (ofp)
1604     fprintf(ofp,
1605     "Ÿ%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)\n",
1606     hash,
1607     buf,
1608     buf[0], buf[1], buf[2], buf[3],
1609     buf[4], buf[5], buf[6], buf[7],
1610     buf[8]);
1611     }
1612     else
1613     {
1614     #if DEBUG>=1
1615     if (cr)
1616     fprintf(stderr, "\n");
1617     cr = 0;
1618     printf("Ÿ%s (%02X %02X %02X %02X %02X %02X %02X %02X )\n",
1619     hash,
1620     buf[0], buf[1], buf[2], buf[3],
1621     buf[4], buf[5], buf[6], buf[7]);
1622     if (ofp)
1623     fprintf(ofp,
1624     "Ÿ%s (%02X %02X %02X %02X %02X %02X %02X %02X )\n",
1625     hash,
1626     buf[0], buf[1], buf[2], buf[3],
1627     buf[4], buf[5], buf[6], buf[7]);
1628     #endif
1629     }
1630     }
1631     }
1632    
1633     if (++n_iter - ts[0].c >= 8192)
1634     {
1635     int t = usec();
1636     if (ts[N_TS - 1].c)
1637     {
1638 chapuni 6 int a = (100 << N_STRIDE) * (n_iter - ts[N_TS - 1].c) / (t - ts[N_TS - 1].t);
1639 chapuni 1 fprintf(stderr,
1640     "%8d.%03d(ktrips/sec)\r",
1641     a / 1000,
1642     a % 1000);
1643     cr++;
1644     }
1645     for (i = N_TS - 1; i >= 1; i--)
1646     ts[i] = ts[i - 1];
1647     ts[0].c = n_iter;
1648     ts[0].t = t;
1649     for (i = 1; i < N_TS; i++)
1650     if (ts[i].c)
1651     break;
1652     else
1653     ts[i] = ts[i - 1];
1654     }
1655     #if 1
1656     if (!key_inc(3))
1657     {
1658     #if DEBUG>=2
1659     printf("********************************\n");
1660     #endif
1661     key_reset(0);
1662     set_salt(code, key);
1663     for (i = 0; i < 8; i++)
1664     key_set64(&key64, i, okey[i] = key[i], 0, 0x7F);
1665     }
1666     #endif
1667     }
1668    
1669     return 0;
1670     }
1671    
1672 chapuni 2 /*
1673     * Local Variables:
1674     * tab-width: 4
1675     * End:
1676     *
1677     * EOF */

Properties

Name Value
svn:eol-style native

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