Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show 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 /***********************************************************************
2 *
3 * file: mty.cpp
4 *
5 * ‚Ü‚ A‘Ň‚Ä‰ŽB
6 *
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 #include <malloc.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26
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 typedef __int8 int8_t;
44 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 #include "crypt64.h"
65 #include "dt4.h"
66
67 #if defined(USE_MMX)
68
69 #define N_STRIDE 6
70 typedef uint64_t WS_T;
71 typedef uint32_t ALU_T;
72
73 #define CRYPT64_CLOBBER /* "%ecx", "%edx", */
74
75 #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 #elif defined(USE_64_XMM)
82
83 #define N_STRIDE 7
84 typedef DQWORD_T WS_T;
85 typedef uint64_t ALU_T;
86
87 #define CRYPT64_CLOBBER /* "%rcx", "%rdx",*/
88
89 #else /* XMM */
90
91 #define N_STRIDE 7
92 typedef DQWORD_T WS_T;
93 typedef uint32_t ALU_T;
94
95 #define CRYPT64_CLOBBER /* "%ecx", "%edx", */
96
97 #endif
98
99 #define N_I (sizeof(WS_T) / sizeof(uint32_t))
100 #define N_ALU (sizeof(WS_T) / sizeof(ALU_T))
101 #define ALU_BITS (CHAR_BIT * sizeof(ALU_T))
102
103 /* ŒŽ“]’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 /* ŒŽƒ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 /* 1ƒrƒbƒg•Ş */
144 typedef union SLICE
145 {
146 uint32_t i[N_I]; /* 32-bit initializer */
147 ALU_T a[N_ALU]; /* C ‚Ĺˆľ‚˘‚₡‚˘ƒTƒCƒY */
148 WS_T w; /* ƒGƒ“ƒR[ƒh‚Ĺˆľ‚¤ƒTƒCƒY */
149 } SLICE;
150
151 /* crypt64() ‚Ş‹ň‚¤ƒpƒ‰ƒ[ƒ^ */
152 struct PARAM
153 {
154 SLICE lr[2][32];
155 SLICE t[32];
156 SLICE hit[10][64];
157 SLICE hiti[10][26];
158 };
159
160 /* ŒŽ‚Í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 struct KEY
165 {
166 SLICE k[2][2][28];
167 SLICE ks[28];
168 };
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 int i, j;
440 if (!((vk | sk) & 0x7F))
441 return;
442
443 for (i = 0; i < 7; i++)
444 {
445 if (n == 7 && i < N_STRIDE) continue;
446 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 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 }
458 else
459 {
460 assert(o >= 28);
461 assert(o < 56);
462 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 }
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 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 }
480 else
481 {
482 assert(o >= 28);
483 assert(o < 56);
484 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 }
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 /* ĹŒă‚ĚƒoƒCƒg */
534 if (N_STRIDE == 7)
535 return 0;
536
537 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 #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 #endif
899
900 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 //printf("Salt %d:%d %+3d:%+3d",
927 printf("Salt %d:%d %08lX:%08lX",
928 i, j,
929 C(code, i, j, 0),
930 C(code, i, j, 24));
931 #endif
932 if (s & (1 << j))
933 {
934 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 }
937 else
938 {
939 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 }
942 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 #if DEBUG>=2
945 //printf(" => %+3d:%+3d\n",
946 printf(" => %08lX:%08lX\n",
947 C(code, i, j, 0),
948 C(code, i, j, 24));
949 #endif
950 }
951 }
952 }
953
954 /***************************************************************
955 *
956 * ƒIƒyƒR[ƒh‚đ“WŠJ
957 *
958 * r EAX, ECX, EDX, EBX
959 * SIB, EBP, ESI, EDI
960 *
961 */
962
963 /* ofs8(i) ‚ŕ‚ľ‚­‚Í ofs32(i) ‚đśŹ */
964 static
965 signed char *
966 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 #define PTR_T 7 /* DI(LR+16) */
995 #define OFS_T (64 + 32 - 16)
996
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 reg_op(signed char *pc,
1018 unsigned op,
1019 unsigned d,
1020 unsigned s)
1021 {
1022 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 #ifndef USE_MMX
1061 *pc++ = 0x66;
1062 #endif
1063 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 unsigned i,
1078 int ofs)
1079 {
1080 #ifndef USE_MMX
1081 *pc++ = 0x66;
1082 #endif
1083 pc[0] = 0x0F;
1084 pc[1] = op;
1085 return disp_rm(pc + 2, d, i, ofs);
1086 }
1087
1088 #endif
1089
1090 /***************************************************************
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 unsigned op = OP_MOV;
1140 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 assert(op != OP_MOV);
1158 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 oop = OP_MOV;
1196 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 1, /* MM1/R9 */
1204 PTR_T,
1205 sizeof(WS_T) * (OFS_T + (64 * ofs + j)));
1206 oop = OP_OR;
1207 }
1208 if (oop != OP_OR)
1209 {
1210 if (ofs == 9)
1211 return -1;
1212 }
1213 else
1214 {
1215 iptr = reg_op(iptr,
1216 op,
1217 0, /* MM0/R8 */
1218 1); /* MM1/R9 */
1219 op = OP_AND;
1220 }
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 0, /* MM0/R8 */
1234 PTR_T,
1235 sizeof(WS_T) * (OFS_T + (64 * ofs + c)));
1236 op = OP_AND;
1237 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 /* MM7 ‚Ƀ^[ƒQƒbƒg–ˆ‚É”äŠrŒ‹‰Ę‚đ OR ‚ľ‚Ä‚˘‚­‚˝‚ß
1292 ‚Ü‚¸‚̓[ƒƒNƒŠƒA */
1293 iptr = reg_op(iptr, OP_XOR, 7, 7); /* MM7/R15 := 0 */
1294
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 /* 1ƒ^[ƒQƒbƒg•Ş‚Ě”äŠrŒ‹‰Ę‚đ MM7 ‚ɒljÁ */
1329 if (n > 0)
1330 iptr = reg_op(iptr + n,
1331 OP_OR,
1332 7, /* MM7/R15 */
1333 0); /* MM0/R8 */
1334 }
1335 }
1336
1337 /* MM7 ‚ɐśŹ‚ł‚ę‚˝Œ‹‰Ę‚đ t[31] ‚ÉŠi”[ */
1338 return reg_mem(iptr,
1339 OP_STOR,
1340 7, /* MM7/R15 */
1341 PTR_T,
1342 sizeof(WS_T) * (64 + 31 - 16));
1343 }
1344
1345 static
1346 unsigned
1347 usec()
1348 {
1349 #if !defined(WIN32)
1350 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 #if N_STRIDE == 7
1368 static SLICE const sk6[N_STRIDE] =
1369 {
1370 {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 {0xAAAAAAAAUL, 0xAAAAAAAAUL},
1382 {0xCCCCCCCCUL, 0xCCCCCCCCUL},
1383 {0xF0F0F0F0UL, 0xF0F0F0F0UL},
1384 {0xFF00FF00UL, 0xFF00FF00UL},
1385 {0xFFFF0000UL, 0xFFFF0000UL},
1386 {0x00000000UL, 0xFFFFFFFFUL},
1387 };
1388 #endif
1389
1390 #ifdef WIN32
1391 typedef int (__fastcall *CRYPT64_PP)(ALU_T const *k, ALU_T *lr);
1392 #endif
1393
1394 ALIGN_PREFIX(16) struct KEY key64 ALIGN_SUFFIX(16);
1395 ALIGN_PREFIX(16) struct PARAM param64 ALIGN_SUFFIX(16);
1396
1397 int
1398 main(int argc, char *argv[])
1399 {
1400 int i, j;
1401 int mincnt;
1402 signed char *code = NULL;
1403 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 #ifdef WIN32
1415 HANDLE h;
1416 #endif
1417
1418 #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 assert((1 << N_STRIDE) == N_ALU * ALU_BITS);
1431
1432 /* t[16] ‚́A“ŕ•”‰‰ŽZ‚ĹŽg—p‚ˇ‚éAall 1 ‚Ş“ü‚Á‚Ä‚˘‚é */
1433 for (i = 0; i < N_ALU; i++)
1434 param64.t[16].a[i] = -1;
1435
1436 /* ŒĹ’čƒL[‚ĚƒRƒs[ */
1437 for (i = 0; i < N_STRIDE; i++)
1438 {
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 /* ƒ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 /* Salt‚đ‰Á–Ą‚ľ‚Č‚˘ę‡‚́AƒR[ƒh—Ěˆć‚đ
1457 writable —Ěˆć‚É“WŠJ‚ľ‚Č‚­‚Ä‚ŕ‚悢B
1458 [XXX] OS‚É‚ć‚Á‚ẮA‘ž&ŽŔs‰Â”\—Ěˆć‚đę—p‚ĚƒT[ƒ”ƒBƒX‚Ĺ
1459 Žć“ž‚ľ‚Ȃ݂ę‚΂Ȃç‚Č‚˘‚ŕ‚Ě‚ŕ‚ ‚邊‚ŕ‚ľ‚ę‚Č‚˘‚̂ŁA’ˆÓ */
1460 #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 if (SUCCEEDED(h))
1470 code = (signed char *)MapViewOfFile(h,
1471 FILE_MAP_EXECUTE | FILE_MAP_WRITE,
1472 0, 0x10000000,
1473 0);
1474 #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 if ((void *)code == MAP_FAILED)
1482 code =NULL;
1483 #endif
1484
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 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 assert(!((ptrdiff_t)&key64 & (sizeof(WS_T) - 1)));
1512 assert(!((ptrdiff_t)&param64 & (sizeof(WS_T) - 1)));
1513
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 int32_t cnt;
1527 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 /* ŒÄ‚Ô!
1537 LR ‰Šú‰ť‚́AƒTƒuƒ‚ƒWƒ…[ƒ‹“ŕ‚ōs‚¤‚ׂľ
1538 FASTCALL ‚ɏ€‚ś‚˝ŒÄ‚яo‚ľ‚Ě‚˝‚߁A
1539 ƒzƒ“ƒg‚Í‚˘‚낢‚냌ƒWƒXƒ^‚Ş”j‰ó‚ł‚ę‚éƒnƒYc‚Č‚ń‚ž‚ށB */
1540 #ifdef __GNUC__
1541 asm volatile("call *%3"
1542 : "=a"(cnt)
1543 : "c"(key64.k), "d"(param64.lr),
1544 "m"(code)
1545 //"m"(crypt64_sta)
1546 : CRYPT64_CLOBBER "memory");
1547 #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 fprintf(stderr, "cycle=%d\n", (int)cnt);
1557 }
1558
1559 /* ƒqƒbƒg‚ľ‚˝‚Ć‚Ť‚̏ˆ— */
1560 for (kk = 0; kk < N_ALU; kk++)
1561 {
1562 ALU_T t;
1563
1564 t = param64.t[31].a[kk];
1565 if (!t)
1566 continue;
1567
1568 for (k = 0; k < ALU_BITS; k++)
1569 {
1570 char hash[16];
1571 unsigned char buf[32];
1572
1573 if (!(t & ((ALU_T)1 << k)))
1574 continue;
1575
1576 /* 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 for (i = 1; i < 11; i++)
1581 {
1582 unsigned c = 0;
1583 for (j = 0; j < 6; j++)
1584 c = (c << 1) | !!(param64.lr[0][tr_fp[6 * i + j]].a[kk] & ((ALU_T)1 << k));
1585 hash[i - 1] = c["./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"];
1586 }
1587 hash[10] = 0;
1588
1589 memcpy(buf, key, 32);
1590 buf[8] = buf[9] = 0;
1591 buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k;
1592 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 int a = (100 << N_STRIDE) * (n_iter - ts[N_TS - 1].c) / (t - ts[N_TS - 1].t);
1639 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 /*
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