trunk/src/mame/machine/315-5881_crypt.c
| r243026 | r243027 | |
| 134 | 134 | given plaintext word, and the remaining 2 to the next plaintext word. |
| 135 | 135 | |
| 136 | 136 | The underlying block cipher consists of two 4-round Feistel Networks (FN): the first one takes the counter (16 bits), |
| 137 | | the game-key (>=29 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key |
| 137 | the game-key (>=27 bits) and the sequence-key (16 bits) and output a middle result (16 bits) which will act as another key |
| 138 | 138 | for the second one. The second FN will take the encrypted word (16 bits), the game-key, the sequence-key and the result |
| 139 | 139 | from the first FN and will output the decrypted word (16 bits). |
| 140 | 140 | |
| r243026 | r243027 | |
| 470 | 470 | }, |
| 471 | 471 | }; |
| 472 | 472 | |
| 473 | | const int sega_315_5881_crypt_device::fn1_game_key_scheduling[FN1GK][2] = { |
| 474 | | {1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11}, |
| 475 | | {6,51}, {7,92}, {8,89}, {9,9}, {9,39}, {9,41}, {9,58}, {9,86}, |
| 476 | | {10,90}, {11,6}, {12,64}, {13,49}, {14,44}, {15,40}, {16,69}, {17,15}, |
| 477 | | {18,23}, {18,43}, {19,82}, {20,81}, {21,32}, {22,5}, {23,66}, {24,13}, |
| 478 | | {24,45}, {25,12}, {25,35}, {26,61}, {27,10}, {27,59}, {28,25} |
| 473 | const int sega_315_5881_crypt_device::fn1_game_key_scheduling[38][2] = { |
| 474 | {1,29}, {1,71}, {2,4}, {2,54}, {3,8}, {4,56}, {4,73}, {5,11}, |
| 475 | {6,51}, {7,92}, {8,89}, {9,9}, {9,10}, {9,39}, {9,41}, {9,58}, |
| 476 | {9,59}, {9,86}, {10,90}, {11,6}, {12,64}, {13,49}, {14,44}, {15,40}, |
| 477 | {16,69}, {17,15}, {18,23}, {18,43}, {19,82}, {20,81}, {21,32}, {22,5}, |
| 478 | {23,66}, {24,13}, {24,45}, {25,12}, {25,35}, {26,61}, |
| 479 | 479 | }; |
| 480 | 480 | |
| 481 | | const int sega_315_5881_crypt_device::fn2_game_key_scheduling[FN2GK][2] = { |
| 482 | | {0,0}, {1,3}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29}, {7,38}, |
| 483 | | {8,39}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50}, {10,53}, {11,57}, |
| 484 | | {12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72}, {17,83}, {18,88}, |
| 485 | | {19,94}, {20,35}, {21,17}, {22,6}, {22,11}, {23,85}, {24,16}, {25,25}, |
| 486 | | {26,92}, {27,47}, {28,28} |
| 481 | const int sega_315_5881_crypt_device::fn2_game_key_scheduling[34][2] = { |
| 482 | {0,0}, {1,3}, {2,11}, {3,20}, {4,22}, {5,23}, {6,29}, {7,38}, |
| 483 | {8,39}, {9,47}, {9,55}, {9,86}, {9,87}, {9,90}, {10,50}, {10,53}, |
| 484 | {11,57}, {12,59}, {13,61}, {13,64}, {14,63}, {15,67}, {16,72}, {17,83}, |
| 485 | {18,88}, {19,94}, {20,35}, {21,17}, {22,6}, {22,11}, {23,85}, {24,16}, |
| 486 | {25,25}, {26,92} |
| 487 | 487 | }; |
| 488 | 488 | |
| 489 | 489 | const int sega_315_5881_crypt_device::fn1_sequence_key_scheduling[20][2] = { |
| r243026 | r243027 | |
| 539 | 539 | memset(fn1_subkeys, 0, sizeof(UINT32) * 4); |
| 540 | 540 | memset(fn2_subkeys, 0, sizeof(UINT32) * 4); |
| 541 | 541 | |
| 542 | | for (j = 0; j < FN1GK; ++j) { |
| 542 | for (j = 0; j < 38; ++j) { |
| 543 | 543 | if (BIT(game_key, fn1_game_key_scheduling[j][0]) != 0) { |
| 544 | 544 | aux = fn1_game_key_scheduling[j][1] % 24; |
| 545 | 545 | aux2 = fn1_game_key_scheduling[j][1] / 24; |
| r243026 | r243027 | |
| 547 | 547 | } |
| 548 | 548 | } |
| 549 | 549 | |
| 550 | | for (j = 0; j < FN2GK; ++j) { |
| 550 | for (j = 0; j < 34; ++j) { |
| 551 | 551 | if (BIT(game_key, fn2_game_key_scheduling[j][0]) != 0) { |
| 552 | 552 | aux = fn2_game_key_scheduling[j][1] % 24; |
| 553 | 553 | aux2 = fn2_game_key_scheduling[j][1] / 24; |
| r243026 | r243027 | |
| 587 | 587 | A = (aux & 0xff) ^ feistel_function(B, fn1_sboxes[0], fn1_subkeys[0]); |
| 588 | 588 | |
| 589 | 589 | // 2nd round |
| 590 | | B ^= feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]); |
| 590 | B = B ^ feistel_function(A, fn1_sboxes[1], fn1_subkeys[1]); |
| 591 | 591 | |
| 592 | 592 | // 3rd round |
| 593 | | A ^= feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]); |
| 593 | A = A ^ feistel_function(B, fn1_sboxes[2], fn1_subkeys[2]); |
| 594 | 594 | |
| 595 | 595 | // 4th round |
| 596 | | B ^= feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]); |
| 596 | B = B ^ feistel_function(A, fn1_sboxes[3], fn1_subkeys[3]); |
| 597 | 597 | |
| 598 | 598 | middle_result = (B << 8) | A; |
| 599 | 599 | |
| r243026 | r243027 | |
| 617 | 617 | A = (aux & 0xff) ^ feistel_function(B, fn2_sboxes[0], fn2_subkeys[0]); |
| 618 | 618 | |
| 619 | 619 | // 2nd round |
| 620 | | B ^= feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]); |
| 620 | B = B ^ feistel_function(A, fn2_sboxes[1], fn2_subkeys[1]); |
| 621 | 621 | |
| 622 | 622 | // 3rd round |
| 623 | | A ^= feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]); |
| 623 | A = A ^ feistel_function(B, fn2_sboxes[2], fn2_subkeys[2]); |
| 624 | 624 | |
| 625 | 625 | // 4th round |
| 626 | | B ^= feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]); |
| 626 | B = B ^ feistel_function(A, fn2_sboxes[3], fn2_subkeys[3]); |
| 627 | 627 | |
| 628 | 628 | aux = (B << 8) | A; |
| 629 | 629 | |