import SBox;
import Key;
import java.lang.Long;
import java.lang.Integer;
/******************************************************************************
* The DES class below implements an encryptor/decryptor for the DES Algorithm *
******************************************************************************/
public class DES
{
/************************************************************************
* Some handy constants: masks for the high and low words of a long type *
************************************************************************/
public static long HighWordMask = Key.HighWordMask;
public static long LowWordMask = Key.LowWordMask;
/************************************************************************
* private data for this class (there is no public/state data needed) *
************************************************************************/
private Key key;
private int rounds = 16;
private static SBox sboxes[]= { new SBox(0), new SBox(1), new SBox(2), new SBox(3),
new SBox(4), new SBox(5), new SBox(6), new SBox(7)};
/**************************
* Permutation tables *
**************************/
private static byte expansion[] = { 32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1};
private static int cipherPermutation[] = {16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25};
private static int initialPermutation[] = { 58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7};
/***********************************************************************************************************************
* Test data (does not pertain to the actual functionality of the encryption, but is only used for my testing purposes) *
************************************************************************************************************************
* The below data was taken from: *
* *
* "Cryptography: Theory and Practice", by Douglas R. Stinson, CRC Press 1995 *
***********************************************************************************************************************/
private static String StinsonKeyValues[] = {"000110110000001011101111111111000111000001110010", //1
"011110011010111011011001110110111100100111100101", //2
"010101011111110010001010010000101100111110011001", //3
"011100101010110111010110110110110011010100011101", //4
"011111001110110000000111111010110101001110101000", //5
"011000111010010100111110010100000111101100101111", //6
"111011001000010010110111111101100001100010111100", //7
"111101111000101000111010110000010011101111111011", //8
"111000001101101111101011111011011110011110000001", //9
"101100011111001101000111101110100100011001001111", //10
"001000010101111111010011110111101101001110000110", //11
"011101010111000111110101100101000110011111101001", //12
"100101111100010111010001111110101011101001000001", //13
"010111110100001110110111111100101110011100111010", //14
"101111111001000110001101001111010011111100001010", //15
"110010110011110110001011000011100001011111110101" }; //16
private static String StinsonExpansionValues[] = {"011110100001010101010101011110100001010101010101",
"011101011110101001010100001100001010101000001001",
"111001011000000000000010101110101110100001010011",
"010100000100001011111000000001010111111110101001",
"101110101110100100000100000000000000001000001010",
"110001010100001001011111110100001100000110101111",
"111101010010101100001111111001011010101101010011",
"000000001100001001010101010111110100000010100000",
"011010101010101101010010101001010111110010100001",
"000100001000001111111001011000001100001111110100",
"010110101111111010101011111010101111110110100101",
"011000001010101111110000000111111000001111110001",
"001110101011110111111010100011110000001011110000",
"000011110001011000000110100010101010101011110100",
"111000000101010001011001010010101100000001011011",
"001000000110101000000100000110100100000110101000"};
private static String StinsonSBoxValues[] = {"01011100100000101011010110010111", //1
"11111000110100000011101010101100", //2
"00100111000100001110000101101111", //3
"00100001111011011001111100111010", //4
"01010000110010000011000111101011", //5
"01000001111100110100110000111101", //6
"00010000011101010100000010101101", //7
"01101100000110000111110010101110", //8
"00010001000011000101011101110111", //9
"11011010000001000101001001110101", //10
"01110011000001011101000100000001", //11
"01111011100010110010011000110101", //12
"10011010110100011000101101001111", //13
"01100100011110011001101011110001", //14
"10110010111010001000110100111100", //15
"10100111100000110010010000101001"}; //16
private static String StinsonCipherValues[] = {"00100011010010101010100110111011", //1
"00111100101010111000011110100011", //2
"01001101000101100110111010110000", //3
"10111011001000110111011101001100", //4
"00101000000100111010110111000011", //5
"10011110010001011100110100101100", //6
"10001100000001010001110000100111", //7
"00111100000011101000011011111001", //8
"00100010001101100111110001101010", //9
"01100010101111001001110000100010", //10
"11100001000001001111101000000010", //11
"11000010011010001100111111101010", //12
"11011101101110110010100100100010", //13
"10110111001100011000111001010101", //14
"01011011100000010010011101101110", //15
"11001000110000000100111110011000"}; //16
/****************************************************************************************************
* Test routines. Again, not part of the actual algorithm, but compares Stinson's results to my own. *
****************************************************************************************************/
public void testStinson()
{
System.out.println("\n\n\n--------------------------------- Keys --------------------------------------\n");
Key oldk = key;
key = new Key(Long.parseLong("133457799BBCDFF1", 16)); // 0001 0011 0011 0100 0101 0111 0111 1001 1001 1011 1011 1100 1101 1111 1111 0001
key.testStinson();
System.out.println("\n\n\n--------------------------- Cipher Initialisation -----------------------------\n");
System.out.println(" k = "