static unsigned int p_table[CRYPT_GAMEKEY_COUNT][18];
static unsigned int s_table[CRYPT_GAMEKEY_COUNT][1024];
#define ROUND(LL, R, S, P) \
LL = \
(LL) \
^ (P) \
^ ( \
( \
S[(R) >> 24] \
+ S[0x0100 + (((R) >> 16) & 0xff)] \
) ^ S[0x0200 + (((R) >> 8) & 0xff)] \
) + S[0x0300 + ((R) & 0xff)]
bool m_tables_ready = false;
void init_tables()
{
for(int key_index = 0; key_index < CRYPT_GAMEKEY_COUNT; key_index++)
{
int i;
memcpy(p_table[key_index], p_box, sizeof(p_box));
memcpy(s_table[key_index], s_box, sizeof(s_box));
unsigned char * pkey = g_key_table[key_index];
unsigned char * pkey_end = g_key_table[key_index + 1];
for(i = 0; i < 18; i++)
{
unsigned int mask = *pkey++;
if(pkey >= pkey_end)
pkey = g_key_table[key_index];
mask = ( mask << 8) | *pkey++;
if(pkey >= pkey_end)
pkey = g_key_table[key_index];
mask = ( mask << 8) | *pkey++;
if(pkey >= pkey_end)
pkey = g_key_table[key_index];
mask = ( mask << 8) | *pkey++;
if(pkey >= pkey_end)
pkey = g_key_table[key_index];
p_table[key_index][i] ^= mask;
}
unsigned int value[2] = { 0, 0 };
for(i = 0; i < 18; i += 2)
{
raw_encrypt(value, key_index);
p_table[key_index][i] = value[0];
p_table[key_index][i+1] = value[1];
}
for(i = 0; i < 1024; i += 2)
{
raw_encrypt(value, key_index);
s_table[key_index][i] = value[0];
s_table[key_index][i+1] = value[1];
}
}
m_tables_ready = true;
}
void raw_encrypt(unsigned int * values, int table)
{
unsigned int left = values[0];
unsigned int right = values[1];
left ^= p_table[table][0];
ROUND(right, left, s_table[table], p_table[table][1]);
ROUND(left, right, s_table[table], p_table[table][2]);
ROUND(right, left, s_table[table], p_table[table][3]);
ROUND(left, right, s_table[table], p_table[table][4]);
ROUND(right, left, s_table[table], p_table[table][5]);
ROUND(left, right, s_table[table], p_table[table][6]);
ROUND(right, left, s_table[table], p_table[table][7]);
ROUND(left, right, s_table[table], p_table[table][8]);
ROUND(right, left, s_table[table], p_table[table][9]);
ROUND(left, right, s_table[table], p_table[table][10]);
ROUND(right, left, s_table[table], p_table[table][11]);
ROUND(left, right, s_table[table], p_table[table][12]);
ROUND(right, left, s_table[table], p_table[table][13]);
ROUND(left, right, s_table[table], p_table[table][14]);
ROUND(right, left, s_table[table], p_table[table][15]);
ROUND(left, right, s_table[table], p_table[table][16]);
right ^= p_table[table][17];
values[1] = left;
values[0] = right;
}
void encrypt(unsigned char * in, unsigned char * out, int len)
{
while(m_stream_pos + len > CRYPT_GAMETABLE_TRIGGER)
{
int len_remaining = CRYPT_GAMETABLE_TRIGGER - m_stream_pos;
encrypt(in, out, len_remaining);
m_table_index = (m_table_index + CRYPT_GAMETABLE_STEP) %
CRYPT_GAMETABLE_MODULO;
memcpy(m_seed, g_seed_table[1][m_table_index][0],
CRYPT_GAMESEED_LENGTH);
m_stream_pos = 0;
m_block_pos = 0;
in += len_remaining;
out += len_remaining;
len -= len_remaining;
}
for(int i = 0; i < len; i++)
{
if(m_block_pos == 0)
{
unsigned int values[2];
unsigned char * seed = m_seed;
N2L(seed, values[0]);
N2L(seed, values[1]);
raw_encrypt(values, m_table_index);
seed = m_seed;
L2N(values[0], seed);
L2N(values[1], seed);
}
unsigned char c = (*in++) ^ m_seed[m_block_pos];
*out++ = c;
m_seed[m_block_pos] = c;
m_block_pos = (m_block_pos + 1) % 8;
}
m_stream_pos += len;
}
So uh anyone care to port/help port this to java?
What exactly are you stuck on? I can help with bits and pieces, but I'm not going to do all that code :P
Unsure of how to handle the memcpys and then *pkey++ in init_tables
Quote from: Zorm on February 05, 2004, 08:38 PM
Unsure of how to handle the memcpys and then *pkey++ in init_tables
A memcpy can be replaced with a loop iterating over and copying the data.
The *pkey++ should probably be replaced with indexing by an integer variable and increasing that.
char *pkey = "Testing testing";
// code 1:
int i = 0;
while(pkey[i])
pkey[i++] += 1;
// equivalent code 2 (except pkey is moved):
while(*pkey)
*pkey++ += 1;
Quote from: Adron on February 06, 2004, 04:33 AM
Quote from: Zorm on February 05, 2004, 08:38 PM
Unsure of how to handle the memcpys and then *pkey++ in init_tables
A memcpy can be replaced with a loop iterating over and copying the data.
Depending on what's being memcpy'd, you might be able to use clone().
Also consider System.arraycopy()