| 18 |
#include <stdlib.h> |
#include <stdlib.h> |
| 19 |
#include <string.h> |
#include <string.h> |
| 20 |
#include <time.h> |
#include <time.h> |
| 21 |
|
#include <sys/timeb.h> |
| 22 |
#include <sys/types.h> |
#include <sys/types.h> |
| 23 |
|
|
| 24 |
#if defined(WIN32) |
#if defined(WIN32) |
| 25 |
|
|
| 26 |
#include <windows.h> |
#include <windows.h> |
| 27 |
#include <process.h> |
#include <process.h> |
|
#include <sys/timeb.h> |
|
| 28 |
|
|
| 29 |
#elif defined(__GNUC__) |
#elif defined(__GNUC__) |
| 30 |
|
|
| 48 |
#include "dt4.h" |
#include "dt4.h" |
| 49 |
#endif |
#endif |
| 50 |
|
|
| 51 |
|
/* CRYPT64 記述子 */ |
| 52 |
|
static |
| 53 |
|
struct CRYPT64_DESC const *const crypt64_descs[] = |
| 54 |
|
{ |
| 55 |
|
&crypt64_desc, |
| 56 |
|
}; |
| 57 |
|
|
| 58 |
/* 鍵クラス */ |
/* 鍵クラス */ |
| 59 |
static |
static |
| 60 |
struct |
struct |
| 62 |
unsigned short map[256]; |
unsigned short map[256]; |
| 63 |
} kcls[8 + 8]; |
} kcls[8 + 8]; |
| 64 |
|
|
|
|
|
| 65 |
/* 拡張鍵クラス */ |
/* 拡張鍵クラス */ |
| 66 |
#define KCLS_DT0 64 |
#define KCLS_DT0 64 |
| 67 |
#define KCLS_DT1 128 |
#define KCLS_DT1 128 |
| 677 |
* |
* |
| 678 |
*/ |
*/ |
| 679 |
|
|
|
#if N_STRIDE == 6 |
|
|
#define C(c,i,j,o) (*(int8_t *)((c) + (loo - crypt64_pro) + los[6 * (i) + (j) + (o)])) |
|
|
#elif N_STRIDE == 7 |
|
|
#define C(c,i,j,o) (*(int32_t *)((c) + (loo - crypt64_pro) + los[6 * (i) + (j) + (o)])) |
|
|
#endif |
|
|
|
|
| 680 |
void |
void |
| 681 |
set_salt(CODE_T *code, |
set_salt(CODE_T *code, |
| 682 |
|
struct CRYPT64_DESC const *desc, |
| 683 |
uint8_t const *k) |
uint8_t const *k) |
| 684 |
{ |
{ |
| 685 |
int i, j; |
int i, j; |
| 707 |
//printf("Salt %d:%d %+3d:%+3d", |
//printf("Salt %d:%d %+3d:%+3d", |
| 708 |
printf("Salt %d:%d %08lX:%08lX", |
printf("Salt %d:%d %08lX:%08lX", |
| 709 |
i, j, |
i, j, |
| 710 |
C(code, i, j, 0), |
LSALT(desc, code, 0, i, j, 0), |
| 711 |
C(code, i, j, 24)); |
LSALT(desc, code, 0, i, j, 24)); |
| 712 |
#endif |
#endif |
| 713 |
if (s & (1 << j)) |
if (s & (1 << j)) |
| 714 |
{ |
{ |
| 715 |
C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16); |
LSALT(desc, code, 0, i, j, 0) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16); |
| 716 |
C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16); |
LSALT(desc, code, 0, i, j, 24) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16); |
| 717 |
} |
} |
| 718 |
else |
else |
| 719 |
{ |
{ |
| 720 |
C(code, i, j, 0) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16); |
LSALT(desc, code, 0, i, j, 0) = sizeof(WS_T) * (((4 * i + j - 1) & 31) - 16); |
| 721 |
C(code, i, j, 24) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16); |
LSALT(desc, code, 0, i, j, 24) = sizeof(WS_T) * (((4 * i + j + 15) & 31) - 16); |
| 722 |
} |
} |
| 723 |
C(code, i, j, 12) = sizeof(WS_T) * (((4 * i + j + 7) & 31) - 16); |
LSALT(desc, code, 0, i, j, 12) = sizeof(WS_T) * (((4 * i + j + 7) & 31) - 16); |
| 724 |
C(code, i, j, 36) = sizeof(WS_T) * (((4 * i + j + 23) & 31) - 16); |
LSALT(desc, code, 0, i, j, 36) = sizeof(WS_T) * (((4 * i + j + 23) & 31) - 16); |
| 725 |
#if DEBUG>=2 |
#if DEBUG>=2 |
| 726 |
//printf(" => %+3d:%+3d\n", |
//printf(" => %+3d:%+3d\n", |
| 727 |
printf(" => %08lX:%08lX\n", |
printf(" => %08lX:%08lX\n", |
| 728 |
C(code, i, j, 0), |
LSALT(desc, code, 0, i, j, 0), |
| 729 |
C(code, i, j, 24)); |
LSALT(desc, code, 0, i, j, 24)); |
| 730 |
#endif |
#endif |
| 731 |
} |
} |
| 732 |
} |
} |
| 733 |
} |
} |
| 734 |
|
|
| 735 |
|
#define USEC_SEC 1000 /* 1秒 */ |
| 736 |
|
|
| 737 |
static |
static |
| 738 |
uint32_t |
uint64_t |
| 739 |
usec(void) |
usec(void) |
| 740 |
{ |
{ |
|
static uint32_t epoch = 0; |
|
| 741 |
uint32_t sec, msec; |
uint32_t sec, msec; |
| 742 |
|
|
| 743 |
#if !defined(WIN32) |
#if !defined(WIN32) |
| 744 |
struct timeval tv; |
struct timeval tv; |
| 745 |
gettimeofday(&tv, NULL); |
gettimeofday(&tv, NULL); |
| 746 |
sec = tv.tv_sec; |
sec = tv.tv_sec; |
| 747 |
msec = tv.tv_usec / 10000; |
msec = tv.tv_usec / (1000000 / USEC_SEC); |
| 748 |
#else |
#else |
| 749 |
struct timeb tm; |
struct timeb tm; |
| 750 |
ftime(&tm); |
ftime(&tm); |
| 751 |
sec = tm.time; |
sec = tm.time; |
| 752 |
msec = tm.millitm / 10; |
msec = tm.millitm / (1000 / USEC_SEC); |
| 753 |
#endif |
#endif |
| 754 |
|
|
| 755 |
if ( epoch == 0 ) { |
return (uint64_t)USEC_SEC * sec + msec; |
|
epoch = sec; |
|
|
} |
|
|
|
|
|
return ((sec - epoch) * 100 + msec); |
|
| 756 |
} |
} |
| 757 |
|
|
| 758 |
static |
static |
| 773 |
|
|
| 774 |
/*************************************************************** |
/*************************************************************** |
| 775 |
* |
* |
| 776 |
* バッチ処理用パケット |
* CPU capabilities を取得 |
| 777 |
|
* [XXX] あまりにも古いプロセッサのことは考えない。 |
| 778 |
|
* |
| 779 |
|
* a[4] = {EAX,EBX,ECX,EDX} |
| 780 |
* |
* |
| 781 |
*/ |
*/ |
| 782 |
|
|
| 783 |
struct PACKET_CRYPT64 |
#if defined(__GNUC__) |
| 784 |
|
|
| 785 |
|
#define cpuid(n,a,b,c,d) \ |
| 786 |
|
asm("cpuid" \ |
| 787 |
|
: "=a"(a), "=b"(b), "=c"(c), "=d"(d) \ |
| 788 |
|
: "a"(n)) |
| 789 |
|
|
| 790 |
|
#elif defined(WIN32) |
| 791 |
|
|
| 792 |
|
#define cpuid(n,a,b,c,d) \ |
| 793 |
|
do {int r[4]; __cpuid(r,n); \ |
| 794 |
|
(a) = r[0]; (b) = r[1]; (c) = r[2]; (d) = r[3];} while (0) |
| 795 |
|
|
| 796 |
|
#endif |
| 797 |
|
|
| 798 |
|
static |
| 799 |
|
unsigned |
| 800 |
|
cpuid_getfflags(void) |
| 801 |
|
{ |
| 802 |
|
unsigned a, b, c, d; |
| 803 |
|
cpuid(1, a, b, c, d); |
| 804 |
|
return d; |
| 805 |
|
} |
| 806 |
|
|
| 807 |
|
static |
| 808 |
|
int |
| 809 |
|
cpuid_issupported(void) |
| 810 |
{ |
{ |
| 811 |
union |
unsigned m = REQUIRED_CAPS; |
| 812 |
{ |
return !((cpuid_getfflags() ^ m) & m); |
| 813 |
uint8_t key[8]; /* 最後にセットしたキー */ |
} |
| 814 |
SLICE pad; |
|
| 815 |
} uk; |
/*************************************************************** |
| 816 |
struct KEY key64; |
* |
| 817 |
struct PARAM param64; /* 最後尾の要素では、PARAM::hit[]が可変長 */ |
* バッチ処理用パケット |
| 818 |
}; |
* |
| 819 |
|
*/ |
| 820 |
|
|
| 821 |
static |
static |
| 822 |
struct PACKET_CRYPT64 * |
struct PACKET_CRYPT64 * |
| 827 |
int i; |
int i; |
| 828 |
int siz; |
int siz; |
| 829 |
void *p; |
void *p; |
| 830 |
|
intptr_t a = 128; |
| 831 |
struct PACKET_CRYPT64 *pkts; |
struct PACKET_CRYPT64 *pkts; |
| 832 |
assert(IS_POWER2(sizeof(struct PACKET_CRYPT64))); |
assert(IS_POWER2(sizeof(struct PACKET_CRYPT64))); |
| 833 |
assert(n >= 1); |
assert(n >= 1); |
| 834 |
|
|
| 835 |
siz = (sizeof(WS_T) - 1 |
siz = (a - 1 |
| 836 |
+ (n - 1) * sizeof(struct PACKET_CRYPT64) |
+ (n - 1) * sizeof(struct PACKET_CRYPT64) |
| 837 |
+ offsetof(struct PACKET_CRYPT64, param64.hit[tn])); |
+ offsetof(struct PACKET_CRYPT64, param64.hit[tn])); |
| 838 |
p = calloc(siz, 1); |
p = calloc(siz, 1); |
| 839 |
/* バンダリあわせ */ |
/* バンダリあわせ */ |
| 840 |
pkts = (struct PACKET_CRYPT64 *)(((intptr_t)p |
pkts = (struct PACKET_CRYPT64 *)(((intptr_t)p |
| 841 |
+ sizeof(WS_T) - 1) |
+ a - 1) |
| 842 |
& -sizeof(WS_T)); |
& -a); |
| 843 |
#if DEBUG>=1 |
#if DEBUG>=1 |
| 844 |
fprintf(stderr, |
fprintf(stderr, |
| 845 |
"packet(n=%d,tn=%d) %d allocated; %p aligned to %p\n", |
"packet(n=%d,tn=%d) %d allocated; %p aligned to %p\n", |
| 853 |
どうせ速度も要求されないしベタコード */ |
どうせ速度も要求されないしベタコード */ |
| 854 |
for (i = 0; i < n; i++) |
for (i = 0; i < n; i++) |
| 855 |
{ |
{ |
| 856 |
int j; |
int j, k; |
| 857 |
|
|
| 858 |
/* t[16] は、内部演算で使用する、all 1 が入っている */ |
/* t[16] は、内部演算で使用する、all 1 が入っている */ |
| 859 |
memset(&pkts[i].param64.t[T_INV], -1, sizeof(SLICE)); |
memset(&pkts[i].param64.t[T_INV], -1, sizeof(SLICE)); |
| 864 |
/* キースケジュールをここに押し込めておく |
/* キースケジュールをここに押し込めておく |
| 865 |
従来は crypt64.S 内で完結するように引いていた */ |
従来は crypt64.S 内で完結するように引いていた */ |
| 866 |
for (j = 0; j < 28; j++) |
for (j = 0; j < 28; j++) |
| 867 |
pkts[i].key64.ks[j].a[0] = sizeof(WS_T) * ks_ls[j]; |
for (k = 0; k < N_ALU; k++) |
| 868 |
|
pkts[i].key64.ks[j].a[k] = sizeof(WS_T) * ks_ls[j]; |
| 869 |
|
|
| 870 |
/* 念のため、鍵をここで落ち着けておく(不要?) */ |
/* 念のため、鍵をここで落ち着けておく(不要?) */ |
| 871 |
for (j = 0; j < 8; j++) |
for (j = 0; j < 8; j++) |
| 914 |
: "m"(*(pd)), "r"(s), "0"(r) \ |
: "m"(*(pd)), "r"(s), "0"(r) \ |
| 915 |
: "memory");a;}) |
: "memory");a;}) |
| 916 |
|
|
|
|
|
| 917 |
#elif defined(WIN32) |
#elif defined(WIN32) |
| 918 |
|
|
| 919 |
typedef LONG ATOMWORD_T; |
typedef LONG ATOMWORD_T; |
| 957 |
: r)); |
: r)); |
| 958 |
} |
} |
| 959 |
|
|
| 960 |
#elif defined(_POSIX_SOURCE) || defined(FREEBSD) || defined(SOLARIS) |
#elif defined(_POSIX_SOURCE) |
| 961 |
|
|
| 962 |
#include <pthread.h> |
#include <pthread.h> |
| 963 |
#include <unistd.h> |
#include <unistd.h> |
| 1091 |
{ |
{ |
| 1092 |
/* 以下は共通情報のコピー */ |
/* 以下は共通情報のコピー */ |
| 1093 |
CODE_T *code; |
CODE_T *code; |
| 1094 |
THREAD_EV_T event_ks_activated; |
THREAD_EV_T *p_ev_ks_activated; |
| 1095 |
ATOMWORD_T volatile *p_nidle; /* 待ちに入ったら増加 */ |
ATOMWORD_T volatile *p_nidle; /* 待ちに入ったら増加 */ |
| 1096 |
|
|
| 1097 |
/* 以下はスレッド固有 */ |
/* 以下はスレッド固有 */ |
| 1158 |
m |= 1ULL << i; |
m |= 1ULL << i; |
| 1159 |
|
|
| 1160 |
return m; |
return m; |
|
|
|
|
#elif defined( FREEBSD ) |
|
|
|
|
|
#include <sys/sysctl.h> |
|
|
|
|
|
int i; |
|
|
uint64_t m; |
|
|
int nCPU; |
|
|
int mib[2]; |
|
|
size_t len; |
|
|
|
|
|
mib[0] = CTL_HW; |
|
|
mib[1] = HW_NCPU; |
|
|
len = sizeof( nCPU ); |
|
|
sysctl( mib, 2, &nCPU, &len, NULL, 0 ); |
|
|
m = (1ULL << nCPU) - 1; |
|
|
|
|
|
return m; |
|
|
|
|
|
#elif defined( SOLARIS ) |
|
|
|
|
|
#include <sys/unistd.h> |
|
|
#include <sys/processor.h> |
|
|
|
|
|
uint64_t m; |
|
|
processorid_t i, cpuid_max; |
|
|
|
|
|
m = 0; |
|
|
cpuid_max = sysconf( _SC_CPUID_MAX ); |
|
|
for ( i = 0; i <= cpuid_max; i++ ) { |
|
|
if ( p_online( i, P_STATUS ) == P_ONLINE ) { |
|
|
m |= 1ULL << i; |
|
|
} |
|
|
} |
|
|
|
|
|
return m; |
|
|
|
|
| 1161 |
#else |
#else |
| 1162 |
|
|
| 1163 |
/* XXX プロセッサ数を調べ上げてください */ |
/* XXX プロセッサ数を調べ上げてください */ |
| 1195 |
: 1); |
: 1); |
| 1196 |
int r; |
int r; |
| 1197 |
|
|
| 1198 |
/* 寝た; auto reset */ |
/* 寝た */ |
| 1199 |
if (tmo == THREAD_INFINITE) |
if (tmo == THREAD_INFINITE) |
| 1200 |
{ |
{ |
| 1201 |
LOCK_INC(param->p_nidle); |
LOCK_INC(param->p_nidle); |
| 1202 |
} |
} |
| 1203 |
|
|
| 1204 |
/* 要求待ち */ |
/* 要求待ち */ |
| 1205 |
r = thread_wait_event(param->event_ks_activated, tmo); |
r = thread_wait_event(*param->p_ev_ks_activated, tmo); |
| 1206 |
|
|
| 1207 |
if (tmo == THREAD_INFINITE) |
if (tmo == THREAD_INFINITE) |
| 1208 |
{ |
{ |
| 1285 |
struct ITREE *root_expr; |
struct ITREE *root_expr; |
| 1286 |
uint64_t proc_mask; |
uint64_t proc_mask; |
| 1287 |
int ks_activated; |
int ks_activated; |
| 1288 |
THREAD_EV_T event_ks_activated; |
static THREAD_EV_T event_ks_activated; |
| 1289 |
static ATOMWORD_T volatile nidle; |
static ATOMWORD_T volatile nidle; |
| 1290 |
struct THREAD_PARAM *threads = NULL; |
struct THREAD_PARAM *threads = NULL; |
| 1291 |
int nthreads; |
int nthreads; |
| 1294 |
uint64_t pkts_vacant; |
uint64_t pkts_vacant; |
| 1295 |
int tn; |
int tn; |
| 1296 |
int cr; |
int cr; |
|
#ifdef KEYCHECK |
|
|
#define KCCNT 1000000 |
|
|
unsigned int ok, ng; |
|
|
#endif /* KEYCHECK */ |
|
|
#ifdef SELFS |
|
|
#define TIME_LIMIT 1 * 60 * 60 * 100 /* 一時間 */ |
|
|
#define HIT_LIMIT 10 |
|
|
int hitcnt; |
|
|
#endif /* SELFS */ |
|
| 1297 |
|
|
| 1298 |
/* 鍵文字列 */ |
/* 鍵文字列 */ |
| 1299 |
uint8_t key[8 + 8]; |
uint8_t key[8 + 8]; |
| 1300 |
|
|
| 1301 |
int xhash_loaded; |
int xhash_loaded; |
| 1302 |
|
|
|
#define LOOP_FACTOR 128000 /* こんなもんでいいか */ |
|
| 1303 |
#define UPDATE_INTERVAL 8 /* 速度表示の間隔 秒 */ |
#define UPDATE_INTERVAL 8 /* 速度表示の間隔 秒 */ |
|
#define AVG_SPD 480000 /* 平均速度の初期値 trips/s */ |
|
| 1304 |
struct status { |
struct status { |
| 1305 |
uint32_t startTime; /* 開始時刻 ミリ秒 */ |
uint64_t startTime; /* 開始時刻 ミリ秒 */ |
| 1306 |
uint32_t lastTime; /* 最後に表示した時刻 ミリ秒 */ |
uint64_t lastTime; /* 最後に表示した時刻 ミリ秒 */ |
| 1307 |
uint32_t loop; /* 総検索個数 % LOOP_FACTOR */ |
uint64_t loop; /* 総検索個数 */ |
| 1308 |
uint32_t mloop; /* 総検索個数 / LOOP_FACTOR */ |
uint64_t lastloop; /* 最後に表示した時の loop */ |
|
uint32_t lastloop; /* 最後に表示した時の loop */ |
|
| 1309 |
} status; |
} status; |
| 1310 |
uint32_t upd_int = AVG_SPD * UPDATE_INTERVAL; |
uint64_t curTime; |
| 1311 |
|
uint32_t upd_int = 0; |
| 1312 |
/* |
/* |
| 1313 |
平均速度 (trips/s) * UPDATE_INTERVAL が UINT32_MAX を超えると発狂する。 |
平均速度 (trips/s) * UPDATE_INTERVAL が UINT32_MAX を超えると発狂する。 |
| 1314 |
UINT32_MAX = 4294967295, 平均速度 = 100Mtrips/s なら、 |
UINT32_MAX = 4294967295, 平均速度 = 100Mtrips/s なら、 |
| 1317 |
LOOP_FACTOR * UINT32_MAX + LOOP_FACOTR 個検索するとオーバーフローする。w |
LOOP_FACTOR * UINT32_MAX + LOOP_FACOTR 個検索するとオーバーフローする。w |
| 1318 |
*/ |
*/ |
| 1319 |
|
|
| 1320 |
#if 0 |
if (!cpuid_issupported()) |
|
if (argc < 2) |
|
| 1321 |
{ |
{ |
| 1322 |
fprintf(stderr, "式きぼんぬ\n"); |
fprintf(stderr, "この環境で走らせることが想定されていません。\n"); |
| 1323 |
return 1; |
exit(1); |
| 1324 |
} |
} |
|
#endif |
|
|
|
|
|
/* 魔改造 いきなり優先度下げ */ |
|
|
#if defined(WIN32) |
|
|
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS ); |
|
|
#endif |
|
| 1325 |
|
|
| 1326 |
assert((1 << N_STRIDE) == N_ALU * ALU_BITS); |
assert((1 << N_STRIDE) == N_ALU * ALU_BITS); |
| 1327 |
|
|
| 1332 |
起動予定スレッド数に応じて |
起動予定スレッド数に応じて |
| 1333 |
生成するコードを変える */ |
生成するコードを変える */ |
| 1334 |
sfp = scoreboard_open(); |
sfp = scoreboard_open(); |
| 1335 |
fwrite(crypt64_pro, 1, crypt64_cmp_pro - crypt64_pro, sfp); /* prologue & コアループ */ |
fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->cmp_pro - crypt64_descs[0]->pro, sfp); /* prologue & コアループ */ |
| 1336 |
proc_mask = thread_avail(); |
proc_mask = thread_avail(); |
| 1337 |
if (proc_mask == 1U) |
if (proc_mask == 1U) |
| 1338 |
{ |
{ |
| 1344 |
else |
else |
| 1345 |
{ |
{ |
| 1346 |
/* multi */ |
/* multi */ |
| 1347 |
fwrite(crypt64_ep, 1, crypt64_ep_end - crypt64_ep, sfp); /* epilogue */ |
fwrite(crypt64_descs[0]->ep, 1, crypt64_descs[0]->ep_end - crypt64_descs[0]->ep, sfp); /* epilogue */ |
| 1348 |
|
|
| 1349 |
/* 比較器のみを生成(前半) */ |
/* 比較器のみを生成(前半) */ |
| 1350 |
code_cmp = ftell(sfp); |
code_cmp = ftell(sfp); |
| 1351 |
fseek(sfp, (-code_cmp) & 63, SEEK_CUR); |
fseek(sfp, (-code_cmp) & 63, SEEK_CUR); |
| 1352 |
code_cmp = ftell(sfp); |
code_cmp = ftell(sfp); |
| 1353 |
fwrite(crypt64_pro, 1, crypt64_crypt - crypt64_pro, sfp); /* prologue */ |
fwrite(crypt64_descs[0]->pro, 1, crypt64_descs[0]->crypt - crypt64_descs[0]->pro, sfp); /* prologue */ |
| 1354 |
npkts = 64; |
npkts = 64; |
| 1355 |
pkts_vacant = (uint64_t)-1; /* (1 << 64) - 1 を計算したくない */ |
pkts_vacant = (uint64_t)-1; /* (1 << 64) - 1 を計算したくない */ |
| 1356 |
} |
} |
| 1357 |
|
|
| 1358 |
/* 比較部を生成 */ |
/* 比較部を生成 */ |
| 1359 |
fwrite(crypt64_cmp_pro, 1, crypt64_cmp_ep - crypt64_cmp_pro, sfp); /* 比較器準備 */ |
fwrite(crypt64_descs[0]->cmp_pro, 1, crypt64_descs[0]->cmp_ep - crypt64_descs[0]->cmp_pro, sfp); /* 比較器準備 */ |
| 1360 |
tn = synth_synthesize(sfp, root_expr); |
tn = synth_synthesize(sfp, root_expr); |
| 1361 |
fwrite(crypt64_cmp_ep, 1, crypt64_ep_end - crypt64_cmp_ep, sfp); /* epilogue */ |
fwrite(crypt64_descs[0]->cmp_ep, 1, crypt64_descs[0]->ep_end - crypt64_descs[0]->cmp_ep, sfp); /* epilogue */ |
| 1362 |
|
|
| 1363 |
/* コードをメモリに貼り付ける */ |
/* コードをメモリに貼り付ける */ |
| 1364 |
code = scoreboard_map(sfp); |
code = scoreboard_map(sfp); |
| 1365 |
|
|
| 1366 |
/* キーの初期化 */ |
/* キーの初期化 */ |
| 1367 |
/* 魔改造 起動時刻が同じでも乱数系列が変わるように */ |
srand(time(NULL)); |
|
srand(time(NULL)-getpid()); |
|
| 1368 |
key_init(key); |
key_init(key); |
| 1369 |
set_salt(code, key); |
set_salt(code, crypt64_descs[0], key); |
| 1370 |
|
|
| 1371 |
/* 演算パケットを作成 */ |
/* 演算パケットを作成 */ |
| 1372 |
pkts = packet_create(npkts, tn, key); |
pkts = packet_create(npkts, tn, key); |
| 1395 |
#if defined(thread_set_priority) |
#if defined(thread_set_priority) |
| 1396 |
/* 心の隙間お埋めします */ |
/* 心の隙間お埋めします */ |
| 1397 |
threads[nthreads].code = code; |
threads[nthreads].code = code; |
| 1398 |
threads[nthreads].event_ks_activated = event_ks_activated; |
threads[nthreads].p_ev_ks_activated = &event_ks_activated; |
| 1399 |
threads[nthreads].p_nidle = &nidle; |
threads[nthreads].p_nidle = &nidle; |
| 1400 |
threads[nthreads].pri = THREAD_PRIORITY_IDLE; |
threads[nthreads].pri = THREAD_PRIORITY_IDLE; |
| 1401 |
thread_create(h, thread_crypt64, &threads[nthreads]); |
thread_create(h, thread_crypt64, &threads[nthreads]); |
| 1412 |
{ |
{ |
| 1413 |
/* 他スレッドは、やや低めの優先度で。 */ |
/* 他スレッドは、やや低めの優先度で。 */ |
| 1414 |
threads[nthreads].code = code; |
threads[nthreads].code = code; |
| 1415 |
threads[nthreads].event_ks_activated = event_ks_activated; |
threads[nthreads].p_ev_ks_activated = &event_ks_activated; |
| 1416 |
threads[nthreads].p_nidle = &nidle; |
threads[nthreads].p_nidle = &nidle; |
| 1417 |
#ifdef thread_set_priority |
#ifdef thread_set_priority |
| 1418 |
threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL; |
threads[nthreads].pri = THREAD_PRIORITY_BELOW_NORMAL; |
| 1447 |
cr = 0; |
cr = 0; |
| 1448 |
memset( &status, 0, sizeof( struct status ) ); |
memset( &status, 0, sizeof( struct status ) ); |
| 1449 |
status.startTime = status.lastTime = usec(); |
status.startTime = status.lastTime = usec(); |
|
#ifdef KEYCHECK |
|
|
ok = ng = 0; |
|
|
#endif /* KEYCHECK */ |
|
| 1450 |
/* 探索ループだぞっと */ |
/* 探索ループだぞっと */ |
|
#ifdef SELFS |
|
|
hitcnt = 0; |
|
|
#endif /* SELFS */ |
|
| 1451 |
for (;;) |
for (;;) |
| 1452 |
{ |
{ |
| 1453 |
struct PACKET_CRYPT64 *pkt_c; |
struct PACKET_CRYPT64 *pkt_c; |
| 1458 |
/* 比較器候補(may be NULL) |
/* 比較器候補(may be NULL) |
| 1459 |
先にキューから取り出す */ |
先にキューから取り出す */ |
| 1460 |
pkt_c = q_cmp[WRAP(rp_cmp, NQ_CMP)]; |
pkt_c = q_cmp[WRAP(rp_cmp, NQ_CMP)]; |
| 1461 |
if (pkt_c != NULL) |
if (pkt_c != NULL && WRAP(rp_cmp, NQ_CMP) != WRAP(wp_cmp, NQ_CMP)) |
| 1462 |
{ |
{ |
| 1463 |
pkt_c = LOCK_CASP(&q_cmp[WRAP(rp_cmp, NQ_CMP)], NULL, pkt_c); |
pkt_c = LOCK_CASP(&q_cmp[WRAP(rp_cmp, NQ_CMP)], NULL, pkt_c); |
| 1464 |
assert(pkt_c != NULL); |
assert(pkt_c != NULL); |
| 1471 |
/* Saltチェンジ待ち */ |
/* Saltチェンジ待ち */ |
| 1472 |
if (!ks_activated) |
if (!ks_activated) |
| 1473 |
{ |
{ |
| 1474 |
int tmo = (pkt_c != NULL |
ATOMWORD_T rp; |
| 1475 |
? 0 /* poll */ |
|
| 1476 |
: 1); |
if (pkt_c == NULL) |
| 1477 |
thread_sleep(tmo); |
{ |
| 1478 |
|
if ((rp = rp_crypt, |
| 1479 |
|
WRAP(rp, NQ_CRYPT) != WRAP(wp_crypt, NQ_CRYPT)) |
| 1480 |
|
&& LOCK_CAS(&rp_crypt, rp + 1, rp) == rp) |
| 1481 |
|
{ |
| 1482 |
|
/* !ks_activate 状態では、自らも要求キューをやっつけにいく */ |
| 1483 |
|
rp = WRAP(rp, NQ_CRYPT); |
| 1484 |
|
pkt_c = q_crypt[rp]; |
| 1485 |
|
assert(pkt_c != NULL); |
| 1486 |
|
pkt_c = LOCK_CASP(&q_crypt[rp], NULL, pkt_c); |
| 1487 |
|
assert(pkt_c != NULL); |
| 1488 |
|
assert(pkt_c != pkt_hit); |
| 1489 |
|
CALL_CRYPT64(code, |
| 1490 |
|
&pkt_c->key64, |
| 1491 |
|
&pkt_c->param64); |
| 1492 |
|
|
| 1493 |
|
/* パケットを vacant に回しておく */ |
| 1494 |
|
pkts_vacant |= 1ULL << (pkt_c - pkts); |
| 1495 |
|
} |
| 1496 |
|
else |
| 1497 |
|
{ |
| 1498 |
|
/* やはりすることがないのでまったりと過ごす */ |
| 1499 |
|
if (nidle != nthreads) |
| 1500 |
|
thread_sleep(1); |
| 1501 |
|
} |
| 1502 |
|
} |
| 1503 |
|
|
| 1504 |
if (nidle == nthreads) |
if (nidle == nthreads) |
| 1505 |
{ |
{ |
| 1506 |
assert(WRAP(rp_crypt, NQ_CRYPT) == WRAP(wp_crypt, NQ_CRYPT)); |
assert(WRAP(rp_crypt, NQ_CRYPT) == WRAP(wp_crypt, NQ_CRYPT)); |
| 1507 |
/* Salt チェンジが可能 */ |
/* Salt チェンジが可能 */ |
| 1508 |
set_salt(code, key); |
set_salt(code, crypt64_descs[0], key); |
| 1509 |
if (code_cmp) |
if (nthreads) |
| 1510 |
thread_signal_event(event_ks_activated); |
thread_signal_event(event_ks_activated); |
| 1511 |
ks_activated = 1; |
ks_activated = 1; |
| 1512 |
} |
} |
| 1538 |
continue; |
continue; |
| 1539 |
|
|
| 1540 |
/* queue full の場合は見送る */ |
/* queue full の場合は見送る */ |
| 1541 |
if (WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp_crypt - 1, NQ_CRYPT) |
if (WRAP(wp_crypt, NQ_CRYPT) == WRAP(rp_crypt - 16, NQ_CRYPT) /* XXX 16 はてきとう */ |
| 1542 |
|| q_crypt[WRAP(wp_crypt, NQ_CRYPT)] != NULL) |
|| q_crypt[WRAP(wp_crypt, NQ_CRYPT)] != NULL) |
| 1543 |
break; |
break; |
| 1544 |
} |
} |
| 1588 |
#if DEBUG>=1 |
#if DEBUG>=1 |
| 1589 |
fprintf(stderr, "********************************SHUFFLE!\n"); |
fprintf(stderr, "********************************SHUFFLE!\n"); |
| 1590 |
#endif |
#endif |
| 1591 |
thread_clear_event(event_ks_activated); |
if (nthreads) |
| 1592 |
|
thread_clear_event(event_ks_activated); |
| 1593 |
key_reset(key, 0); |
key_reset(key, 0); |
| 1594 |
|
|
| 1595 |
/* キューの鍵が捌けるまでアイドル状態に */ |
/* キューの鍵が捌けるまでアイドル状態に */ |
| 1622 |
ホントはいろいろレジスタが破壊されるハズ…なんだが。 */ |
ホントはいろいろレジスタが破壊されるハズ…なんだが。 */ |
| 1623 |
if (pkt_c != pkt_hit) |
if (pkt_c != pkt_hit) |
| 1624 |
{ |
{ |
| 1625 |
|
assert(code_cmp != 0); |
| 1626 |
cnt = CALL_CMP64(code + code_cmp, |
cnt = CALL_CMP64(code + code_cmp, |
| 1627 |
pkt_hit->param64.hit, |
pkt_hit->param64.hit, |
| 1628 |
pkt_c->param64.lr); |
pkt_c->param64.lr); |
| 1663 |
nblk_total++, xhash_loaded = 0; |
nblk_total++, xhash_loaded = 0; |
| 1664 |
|
|
| 1665 |
t = pkt_hit->param64.hit[HIT_ANY].a[kk]; |
t = pkt_hit->param64.hit[HIT_ANY].a[kk]; |
|
#ifndef KEYCHECK |
|
| 1666 |
if (!t) |
if (!t) |
| 1667 |
continue; |
continue; |
|
#endif /* KEYCHECK */ |
|
| 1668 |
|
|
| 1669 |
nap_total += ALU_BITS; |
nap_total += ALU_BITS; |
| 1670 |
|
|
| 1673 |
static uint64_t xhash[64]; |
static uint64_t xhash[64]; |
| 1674 |
char hash[16]; |
char hash[16]; |
| 1675 |
uint8_t buf[32]; |
uint8_t buf[32]; |
| 1676 |
time_t tloc; |
struct timeb tb; |
| 1677 |
|
struct tm *plt; |
| 1678 |
|
|
|
#ifndef KEYCHECK |
|
| 1679 |
if (!(t & ((ALU_T)1 << k))) |
if (!(t & ((ALU_T)1 << k))) |
| 1680 |
continue; |
continue; |
|
#endif /* KEYCHECK */ |
|
| 1681 |
|
|
| 1682 |
nap_hit++; |
nap_hit++; |
| 1683 |
|
|
| 1689 |
xhash_loaded = 1; |
xhash_loaded = 1; |
| 1690 |
} |
} |
| 1691 |
|
|
|
#ifndef KEYCHECK |
|
| 1692 |
/* 辞書を調べる */ |
/* 辞書を調べる */ |
| 1693 |
if (!((pkt_hit->param64.hit[HIT_BOOL].a[kk] & ((ALU_T)1 << k)) |
if (!((pkt_hit->param64.hit[HIT_BOOL].a[kk] & ((ALU_T)1 << k)) |
| 1694 |
|| wdict_ishit(pkt_hit->param64.hit, |
|| wdict_ishit(pkt_hit->param64.hit, |
| 1695 |
kk, k, |
kk, k, |
| 1696 |
xhash[(ALU_BITS * kk + k) & 0x3F]))) |
xhash[(ALU_BITS * kk + k) & 0x3F]))) |
| 1697 |
continue; |
continue; |
| 1698 |
#endif /* KEYCHECK */ |
|
| 1699 |
|
/* ヒット時刻; 魔改造とちょっと違う */ |
| 1700 |
|
ftime(&tb); |
| 1701 |
|
plt = localtime(&tb.time); |
| 1702 |
|
|
| 1703 |
for (i = 1; i < 11; i++) |
for (i = 1; i < 11; i++) |
| 1704 |
{ |
{ |
| 1711 |
memcpy(buf, pkt_c->uk.key, 8); |
memcpy(buf, pkt_c->uk.key, 8); |
| 1712 |
buf[8] = buf[9] = 0; |
buf[8] = buf[9] = 0; |
| 1713 |
buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k; |
buf[7] = (buf[7] & -(1 << N_STRIDE) & 0x7F) + ALU_BITS * kk + k; |
|
#ifdef KEYCHECK |
|
|
{ |
|
|
#include <crypt.h> |
|
|
char *res; |
|
|
char salt[3]; |
|
|
static unsigned char saltTable[] = |
|
|
".............................................../0123456789ABCDEF" |
|
|
"GABCDEFGHIJKLMNOPQRSTUVWXYZabcdefabcdefghijklmnopqrstuvwxyz....." |
|
|
"................................................................" |
|
|
"................................................................"; |
|
|
salt[2] = '\0'; |
|
|
salt[0] = saltTable[buf[1]]; |
|
|
salt[1] = saltTable[buf[2]]; |
|
|
res = crypt( buf, salt ); |
|
|
if ( strcmp( res+3, hash ) != 0 ) { |
|
|
printf( "res+3 = <%s>, hash = <%s>\n", res+3, hash ); |
|
|
exit( 0 ); |
|
|
} |
|
|
} |
|
|
#endif /* KEYCHECK */ |
|
|
time( &tloc ); |
|
| 1714 |
if (translate(buf, 0, 1)) |
if (translate(buf, 0, 1)) |
| 1715 |
{ |
{ |
|
#ifdef KEYCHECK |
|
|
ok++; |
|
|
if ( ok + ng >= KCCNT ) { |
|
|
printf( "\nok = %u, ng = %u\n", ok, ng ); |
|
|
exit( 1 ); |
|
|
} |
|
|
#endif /* KEYCHECK */ |
|
|
#ifndef KEYCHECK |
|
| 1716 |
if (cr) |
if (cr) |
| 1717 |
fprintf(stderr, "\n"); |
fprintf(stderr, "\n"); |
| 1718 |
cr = 0; |
cr = 0; |
| 1719 |
#if DEBUG>=1 |
#if DEBUG>=1 |
| 1720 |
fprintf(stderr, "%3d:", pkt_c - pkts); |
fprintf(stderr, "%3d:", pkt_c - pkts); |
| 1721 |
#endif |
#endif |
|
/* 魔改造 ヒットした日時を表示 */ |
|
| 1722 |
log_printf(ofp, |
log_printf(ofp, |
| 1723 |
"◆%s #%-10.10s(%02X %02X %02X %02X %02X %02X %02X %02X/%02X) %s", |
"◆%s #%s" |
| 1724 |
|
"\t%04d/%02d/%02d %02d:%02d:%02d.%03d" |
| 1725 |
|
"\t(%02X %02X %02X %02X %02X %02X %02X %02X/%02X)\n", |
| 1726 |
hash, |
hash, |
| 1727 |
buf, |
buf, |
| 1728 |
|
plt->tm_year + 1900, |
| 1729 |
|
plt->tm_mon + 1, |
| 1730 |
|
plt->tm_mday, |
| 1731 |
|
plt->tm_hour, |
| 1732 |
|
plt->tm_min, |
| 1733 |
|
plt->tm_sec, |
| 1734 |
|
tb.millitm, |
| 1735 |
buf[0], buf[1], buf[2], buf[3], |
buf[0], buf[1], buf[2], buf[3], |
| 1736 |
buf[4], buf[5], buf[6], buf[7], |
buf[4], buf[5], buf[6], buf[7], |
| 1737 |
buf[8], ctime(&tloc) ); |
buf[8]); |
|
#endif /* not KEYCHECK */ |
|
| 1738 |
} |
} |
| 1739 |
else |
else |
| 1740 |
{ |
{ |
| 1741 |
#ifdef KEYCHECK |
#if DEBUG>=1 |
|
ng++; |
|
|
if ( ok + ng >= KCCNT ) { |
|
|
printf( "\nok = %u, ng = %u\n", ok, ng ); |
|
|
exit( 1 ); |
|
|
} |
|
|
#endif /* KEYCHECK */ |
|
|
#ifndef KEYCHECK |
|
|
/* 魔改造 failed も表示する */ |
|
| 1742 |
if (cr) |
if (cr) |
| 1743 |
fprintf(stderr, "\n"); |
fprintf(stderr, "\n"); |
| 1744 |
cr = 0; |
cr = 0; |
|
#if DEBUG>=1 |
|
| 1745 |
fprintf(stderr, "%3d:", pkt_c - pkts); |
fprintf(stderr, "%3d:", pkt_c - pkts); |
|
#endif |
|
| 1746 |
log_printf(ofp, |
log_printf(ofp, |
| 1747 |
"◆%s (%02X %02X %02X %02X %02X %02X %02X %02X ) %s", |
"◆%s (%02X %02X %02X %02X %02X %02X %02X %02X )\n", |
| 1748 |
hash, |
hash, |
| 1749 |
buf[0], buf[1], buf[2], buf[3], |
buf[0], buf[1], buf[2], buf[3], |
| 1750 |
buf[4], buf[5], buf[6], buf[7], ctime(&tloc) ); |
buf[4], buf[5], buf[6], buf[7]); |
| 1751 |
#endif /* not KEYCHECK */ |
#endif |
| 1752 |
} |
} |
|
#ifdef SELFS |
|
|
hitcnt++; |
|
|
if ( hitcnt >= HIT_LIMIT ) { |
|
|
exit( 0 ); |
|
|
} |
|
|
#endif /* SELFS */ |
|
| 1753 |
} |
} |
| 1754 |
} |
} |
| 1755 |
|
|
| 1756 |
|
/* 速度計測 */ |
| 1757 |
status.loop += N_ALU * ALU_BITS; |
status.loop += N_ALU * ALU_BITS; |
| 1758 |
if ( status.loop >= upd_int ) |
if (status.loop>= status.lastloop + upd_int |
| 1759 |
|
&& (curTime = usec()) != status.lastTime) |
| 1760 |
{ |
{ |
| 1761 |
/* |
uint64_t diffTime; |
|
ここで更新間隔のチェックをすれば、高速マシンで誤差の大きい速度表示が |
|
|
出るのを防げる。 |
|
|
だがそれをすると普通のマシンでムダな usec() 呼び出しをすることになる。 |
|
|
だからやらない。決して手抜きではない。 |
|
|
*/ |
|
|
uint32_t curTime, diffTime; |
|
| 1762 |
int a, b, c; |
int a, b, c; |
| 1763 |
|
|
| 1764 |
#ifdef SPDEBUG |
/* 通算(単位 ktrips/sec) */ |
|
putchar( '\n' ); |
|
|
printf( "mloop = %d, loop = %d\n", status.mloop, status.loop ); |
|
|
#endif |
|
|
curTime = usec(); |
|
|
#ifdef SELFS |
|
|
if ( curTime > TIME_LIMIT ) { |
|
|
exit( 0 ); |
|
|
} |
|
|
#endif /* SELFS */ |
|
|
diffTime = curTime - status.lastTime; |
|
|
b = (status.loop - status.lastloop) * 100 / diffTime; |
|
|
status.mloop += ( status.loop / LOOP_FACTOR ); |
|
|
status.loop %= LOOP_FACTOR; |
|
| 1765 |
diffTime = curTime - status.startTime; |
diffTime = curTime - status.startTime; |
| 1766 |
if ( diffTime >= 1000000000 ) { |
a = status.loop / ((1000 / USEC_SEC) * diffTime); |
| 1767 |
c = 1000000; |
|
| 1768 |
} else if ( diffTime >= 100000000 ) { |
/* 区間(単位 trips/sec) */ |
| 1769 |
c = 100000; |
diffTime = curTime - status.lastTime; |
| 1770 |
} else if ( diffTime >= 10000000 ) { |
b = USEC_SEC * (status.loop - status.lastloop) / diffTime; |
| 1771 |
c = 10000; |
|
| 1772 |
} else if ( diffTime >= 1000000 ) { |
/* 予測 */ |
| 1773 |
c = 1000; |
c = UPDATE_INTERVAL * b; |
| 1774 |
} else if ( diffTime >= 100000 ) { |
|
| 1775 |
c = 100; |
/* 立ち上がりなど、誤差があり upd_int が小さすぎたときは |
| 1776 |
} else if ( diffTime >= 10000 ) { |
いきなり全補正せず 1 秒(==b)づつ収斂させる。 */ |
| 1777 |
c = 10; |
upd_int = (upd_int + b < c |
| 1778 |
} else { |
? upd_int + b |
| 1779 |
c = 1; |
: c); |
| 1780 |
} |
|
|
a = status.mloop * (LOOP_FACTOR / (10 * c)) / (diffTime / c); |
|
|
upd_int = b * UPDATE_INTERVAL; |
|
|
upd_int = upd_int / LOOP_FACTOR * LOOP_FACTOR; |
|
|
#ifdef SPDEBUG |
|
|
{ |
|
|
#ifndef USE_MMX |
|
|
double d; |
|
|
d = ((double)status.mloop * LOOP_FACTOR / 1000.0) / ((double)diffTime / 100.0); |
|
|
printf( "d = %f\n", d ); |
|
|
#endif |
|
|
printf( "mloop = %d, loop = %d\n", status.mloop, status.loop ); |
|
|
printf( "%d - %d = %d\n", curTime, status.startTime, curTime - status.startTime ); |
|
|
printf( "%d - %d = %d\n", curTime, status.lastTime, curTime - status.lastTime ); |
|
|
printf( "c = %d\n", c ); |
|
|
printf( "upd_int = %d\n", upd_int ); |
|
|
} |
|
|
#endif |
|
| 1781 |
status.lastTime = curTime; |
status.lastTime = curTime; |
| 1782 |
status.lastloop = status.loop; |
status.lastloop = status.loop; |
| 1783 |
#if DEBUG>=1 |
#if DEBUG>=1 |
| 1797 |
fprintf( stderr, |
fprintf( stderr, |
| 1798 |
"%6dktrips/s [%6d.%03dktrips/s]\r", |
"%6dktrips/s [%6d.%03dktrips/s]\r", |
| 1799 |
a, b / 1000, b % 1000 ); |
a, b / 1000, b % 1000 ); |
| 1800 |
/* 魔改造 速度表示は残さない */ |
cr++; |
|
cr = 0; |
|
| 1801 |
} |
} |
| 1802 |
} |
} |
| 1803 |
|
|