mirror of
https://github.com/holub/mame
synced 2025-04-30 11:50:30 +03:00
Two new key bits for SEGA's 315-5881 encryption
This commit is contained in:
parent
11fc352eb7
commit
83bde098ff
@ -134,7 +134,7 @@ internal block-cipher. So, at a given step, the internal block cipher will outpu
|
|||||||
given plaintext word, and the remaining 2 to the next plaintext word.
|
given plaintext word, and the remaining 2 to the next plaintext word.
|
||||||
|
|
||||||
The underlying block cipher consists of two 4-round Feistel Networks (FN): the first one takes the counter (16 bits),
|
The underlying block cipher consists of two 4-round Feistel Networks (FN): the first one takes the counter (16 bits),
|
||||||
the game-key (>=27 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key
|
the game-key (>=29 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key
|
||||||
for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key and the result
|
for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key and the result
|
||||||
from the first FN and will output the decrypted word (16 bits).
|
from the first FN and will output the decrypted word (16 bits).
|
||||||
|
|
||||||
@ -470,20 +470,20 @@ const sega_315_5881_crypt_device::sbox sega_315_5881_crypt_device::fn2_sboxes[4]
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const int sega_315_5881_crypt_device::fn1_game_key_scheduling[38][2] = {
|
const int sega_315_5881_crypt_device::fn1_game_key_scheduling[FN1GK][2] = {
|
||||||
{1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11},
|
{1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11},
|
||||||
{6,51}, {7,92}, {8,89}, {9,9}, {9,10}, {9,39}, {9,41}, {9,58},
|
{6,51}, {7,92}, {8,89}, {9,9}, {9,39}, {9,41}, {9,58}, {9,86},
|
||||||
{9,59}, {9,86}, {10,90}, {11,6}, {12,64}, {13,49}, {14,44}, {15,40},
|
{10,90}, {11,6}, {12,64}, {13,49}, {14,44}, {15,40}, {16,69}, {17,15},
|
||||||
{16,69}, {17,15}, {18,23}, {18,43}, {19,82}, {20,81}, {21,32}, {22,5},
|
{18,23}, {18,43}, {19,82}, {20,81}, {21,32}, {22,5}, {23,66}, {24,13},
|
||||||
{23,66}, {24,13}, {24,45}, {25,12}, {25,35}, {26,61},
|
{24,45}, {25,12}, {25,35}, {26,61}, {27,10}, {27,59}, {28,25}
|
||||||
};
|
};
|
||||||
|
|
||||||
const int sega_315_5881_crypt_device::fn2_game_key_scheduling[34][2] = {
|
const int sega_315_5881_crypt_device::fn2_game_key_scheduling[FN2GK][2] = {
|
||||||
{0,0}, {1,3}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29}, {7,38},
|
{0,0}, {1,3}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29}, {7,38},
|
||||||
{8,39}, {9,47}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50}, {10,53},
|
{8,39}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50}, {10,53}, {11,57},
|
||||||
{11,57}, {12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72}, {17,83},
|
{12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72}, {17,83}, {18,88},
|
||||||
{18,88}, {19,94}, {20,35}, {21,17}, {22,6}, {22,11}, {23,85}, {24,16},
|
{19,94}, {20,35}, {21,17}, {22,6}, {22,11}, {23,85}, {24,16}, {25,25},
|
||||||
{25,25}, {26,92}
|
{26,92}, {27,47}, {28,28}
|
||||||
};
|
};
|
||||||
|
|
||||||
const int sega_315_5881_crypt_device::fn1_sequence_key_scheduling[20][2] = {
|
const int sega_315_5881_crypt_device::fn1_sequence_key_scheduling[20][2] = {
|
||||||
@ -539,7 +539,7 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc
|
|||||||
memset(fn1_subkeys, 0, sizeof(UINT32) * 4);
|
memset(fn1_subkeys, 0, sizeof(UINT32) * 4);
|
||||||
memset(fn2_subkeys, 0, sizeof(UINT32) * 4);
|
memset(fn2_subkeys, 0, sizeof(UINT32) * 4);
|
||||||
|
|
||||||
for (j = 0; j < 38; ++j) {
|
for (j = 0; j < FN1GK; ++j) {
|
||||||
if (BIT(game_key, fn1_game_key_scheduling[j][0]) != 0) {
|
if (BIT(game_key, fn1_game_key_scheduling[j][0]) != 0) {
|
||||||
aux = fn1_game_key_scheduling[j][1] % 24;
|
aux = fn1_game_key_scheduling[j][1] % 24;
|
||||||
aux2 = fn1_game_key_scheduling[j][1] / 24;
|
aux2 = fn1_game_key_scheduling[j][1] / 24;
|
||||||
@ -547,7 +547,7 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 34; ++j) {
|
for (j = 0; j < FN2GK; ++j) {
|
||||||
if (BIT(game_key, fn2_game_key_scheduling[j][0]) != 0) {
|
if (BIT(game_key, fn2_game_key_scheduling[j][0]) != 0) {
|
||||||
aux = fn2_game_key_scheduling[j][1] % 24;
|
aux = fn2_game_key_scheduling[j][1] % 24;
|
||||||
aux2 = fn2_game_key_scheduling[j][1] / 24;
|
aux2 = fn2_game_key_scheduling[j][1] / 24;
|
||||||
@ -587,13 +587,13 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc
|
|||||||
A = (aux & 0xff) ^ feistel_function(B, fn1_sboxes[0], fn1_subkeys[0]);
|
A = (aux & 0xff) ^ feistel_function(B, fn1_sboxes[0], fn1_subkeys[0]);
|
||||||
|
|
||||||
// 2nd round
|
// 2nd round
|
||||||
B = B ^ feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]);
|
B ^= feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]);
|
||||||
|
|
||||||
// 3rd round
|
// 3rd round
|
||||||
A = A ^ feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]);
|
A ^= feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]);
|
||||||
|
|
||||||
// 4th round
|
// 4th round
|
||||||
B = B ^ feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]);
|
B ^= feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]);
|
||||||
|
|
||||||
middle_result = (B << 8) | A;
|
middle_result = (B << 8) | A;
|
||||||
|
|
||||||
@ -617,13 +617,13 @@ UINT16 sega_315_5881_crypt_device::block_decrypt(UINT32 game_key, UINT16 sequenc
|
|||||||
A = (aux & 0xff) ^ feistel_function(B, fn2_sboxes[0], fn2_subkeys[0]);
|
A = (aux & 0xff) ^ feistel_function(B, fn2_sboxes[0], fn2_subkeys[0]);
|
||||||
|
|
||||||
// 2nd round
|
// 2nd round
|
||||||
B = B ^ feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]);
|
B ^= feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]);
|
||||||
|
|
||||||
// 3rd round
|
// 3rd round
|
||||||
A = A ^ feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]);
|
A ^= feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]);
|
||||||
|
|
||||||
// 4th round
|
// 4th round
|
||||||
B = B ^ feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]);
|
B ^= feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]);
|
||||||
|
|
||||||
aux = (B << 8) | A;
|
aux = (B << 8) | A;
|
||||||
|
|
||||||
|
@ -66,8 +66,10 @@ private:
|
|||||||
static const sbox fn1_sboxes[4][4];
|
static const sbox fn1_sboxes[4][4];
|
||||||
static const sbox fn2_sboxes[4][4];
|
static const sbox fn2_sboxes[4][4];
|
||||||
|
|
||||||
static const int fn1_game_key_scheduling[38][2];
|
static const int FN1GK = 39;
|
||||||
static const int fn2_game_key_scheduling[34][2];
|
static const int FN2GK = 35;
|
||||||
|
static const int fn1_game_key_scheduling[FN1GK][2];
|
||||||
|
static const int fn2_game_key_scheduling[FN2GK][2];
|
||||||
static const int fn1_sequence_key_scheduling[20][2];
|
static const int fn1_sequence_key_scheduling[20][2];
|
||||||
static const int fn2_sequence_key_scheduling[16];
|
static const int fn2_sequence_key_scheduling[16];
|
||||||
static const int fn2_middle_result_scheduling[16];
|
static const int fn2_middle_result_scheduling[16];
|
||||||
|
Loading…
Reference in New Issue
Block a user