| 1 |
#ifndef CRYPT64_H__ |
| 2 |
#define CRYPT64_H__ |
| 3 |
|
| 4 |
#include "config.h" |
| 5 |
|
| 6 |
#define N_I (sizeof(WS_T) / sizeof(uint32_t)) |
| 7 |
#define N_Q (sizeof(WS_T) / sizeof(uint64_t)) |
| 8 |
#define N_ALU (sizeof(WS_T) / sizeof(ALU_T)) |
| 9 |
|
| 10 |
/* 1ビット分 */ |
| 11 |
typedef union SLICE |
| 12 |
{ |
| 13 |
uint32_t i[N_I]; /* 32-bit initializer */ |
| 14 |
ALU_T a[N_ALU]; /* C で扱いやすいサイズ */ |
| 15 |
uint64_t q[N_Q]; /* 64-bit for transpose */ |
| 16 |
WS_T w; /* エンコードで扱うサイズ */ |
| 17 |
} SLICE; |
| 18 |
|
| 19 |
/* crypt64() が喰うパラメータ */ |
| 20 |
struct PARAM |
| 21 |
{ |
| 22 |
SLICE lr[2][32]; |
| 23 |
SLICE t[32]; |
| 24 |
SLICE hit[19]; /* パケットバンダリをキレイにするためのマジックナンバー */ |
| 25 |
}; |
| 26 |
|
| 27 |
/* 全ビット1 */ |
| 28 |
#define T_INV 16 |
| 29 |
|
| 30 |
/* 鍵はLR と、そのコピーが必要 |
| 31 |
KEY::k[0] LR |
| 32 |
KEY::k[1] LRのコピー(剰余を省くため) |
| 33 |
KEY::k[2][0][i].a[0] 次鍵への増分 */ |
| 34 |
struct KEY |
| 35 |
{ |
| 36 |
SLICE k[2][2][28]; |
| 37 |
SLICE ks[28]; |
| 38 |
}; |
| 39 |
|
| 40 |
/* バッチ処理用パケット */ |
| 41 |
struct PACKET_CRYPT64 |
| 42 |
{ |
| 43 |
union |
| 44 |
{ |
| 45 |
uint8_t key[8]; /* 最後にセットしたキー */ |
| 46 |
SLICE pad; |
| 47 |
} uk; |
| 48 |
struct KEY key64; |
| 49 |
struct PARAM param64; /* 最後尾の要素では、PARAM::hit[]が可変長 */ |
| 50 |
}; |
| 51 |
|
| 52 |
/* CRYPT64 コア記述子 */ |
| 53 |
struct CRYPT64_DESC |
| 54 |
{ |
| 55 |
CODE_T const *pro; /* 手続き入り口 */ |
| 56 |
CODE_T const *crypt; /* CRYPTコアループ */ |
| 57 |
CODE_T const *cmp_pro; /* 比較部セットアップ */ |
| 58 |
CODE_T const *cmp_ep; /* 比較部あとしまつ(計時程度?) */ |
| 59 |
CODE_T const *ep; /* 手続き出口 */ |
| 60 |
CODE_T const *ep_end; /* しんがり */ |
| 61 |
uint8_t n_units; /* 計算単位 */ |
| 62 |
uint8_t ofsw; /* オフセットの大きさ(2 .. int16_t) */ |
| 63 |
uint16_t n_ofs; /* オフセット組数 */ |
| 64 |
int16_t ofs[1][48]; /* Saltオフセット表(crypt基準) */ |
| 65 |
}; |
| 66 |
|
| 67 |
/* 実装によってはこれ以外にも記述子が存在している */ |
| 68 |
extern struct CRYPT64_DESC const crypt64_desc; |
| 69 |
|
| 70 |
/* CODE基準のSalt左辺値 */ |
| 71 |
#define LSALT(d,c,n,i,j,o) (*(SALTOFS_T *)((c) + ((d)->crypt - (d)->pro) + (d)->ofs[n][6 * (i) + (j) + (o)])) |
| 72 |
|
| 73 |
/* 戻り値は 64bit にパックされている。 |
| 74 |
下位32ビットにコアループ tick |
| 75 |
上位32ビットに比較器 tick */ |
| 76 |
|
| 77 |
#ifdef USE_REGPARM |
| 78 |
|
| 79 |
/* REGPARM は、A, D, C の順である |
| 80 |
呼ばれ側は MSFASTCALL(C, D) 前提なので、A にはダミー値を。 */ |
| 81 |
/* crypt(key, lr) */ |
| 82 |
typedef uint64_t |
| 83 |
(*CRYPT64_PP_T)(void *a, struct PARAM *lr, struct KEY const *k) __attribute__((regparm(3))); |
| 84 |
#define CALL_CRYPT64(code,k,lr) (*(CRYPT64_PP_T)(code))(code, lr, k) |
| 85 |
|
| 86 |
/* cmp(hit, lr) */ |
| 87 |
typedef uint32_t |
| 88 |
(*CMP64_PP_T)(void *a, SLICE (*lr)[32], SLICE *hit) __attribute__((regparm(3))); |
| 89 |
#define CALL_CMP64(code,hit,lr) (*(CMP64_PP_T)(code))(code, lr, hit) |
| 90 |
|
| 91 |
#elif defined(__GNUC__) |
| 92 |
|
| 93 |
#define CALL_CRYPT64(code,k,lr) \ |
| 94 |
({uint32_t a, c, d; \ |
| 95 |
asm volatile("call *%3" \ |
| 96 |
: "=a"(a), "=c"(c), "=d"(d) \ |
| 97 |
: "r"(code), "1"(k), "2"(lr) \ |
| 98 |
: "memory"); \ |
| 99 |
((uint64_t)d << 32) | a;}) |
| 100 |
|
| 101 |
#define CALL_CMP64(code,hit,lr) \ |
| 102 |
({uint32_t cnt, c, d; \ |
| 103 |
asm volatile("call *%3" \ |
| 104 |
: "=a"(cnt), "=c"(c), "=d"(d) \ |
| 105 |
: "r"(code), "1"(hit), "2"(lr) \ |
| 106 |
: "memory"); \ |
| 107 |
cnt;}) |
| 108 |
|
| 109 |
#else /* __fastcall 前提 */ |
| 110 |
|
| 111 |
/* crypt(key, lr) */ |
| 112 |
typedef uint64_t (__fastcall *CRYPT64_PP_T)(struct KEY const *k, struct PARAM *lr); |
| 113 |
#define CALL_CRYPT64(code,k,lr) (*(CRYPT64_PP_T)(code))(k, lr) |
| 114 |
|
| 115 |
/* cmp(hit, lr) */ |
| 116 |
typedef uint32_t (__fastcall *CMP64_PP_T)(SLICE *hit, SLICE (*lr)[32]); |
| 117 |
#define CALL_CMP64(code,hit,lr) (*(CMP64_PP_T)(code))(hit, lr) |
| 118 |
|
| 119 |
#endif |
| 120 |
|
| 121 |
#endif /* CRYPT64_H__ */ |
| 122 |
|
| 123 |
/* |
| 124 |
* Local Variables: |
| 125 |
* tab-width: 4 |
| 126 |
* End: |
| 127 |
* |
| 128 |
* EOF */ |