1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto.engines;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.BlockCipher;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.CipherParameters;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.DataLengthException;
6a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstromimport org.bouncycastle.crypto.OutputLengthException;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.crypto.params.KeyParameter;
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a class that provides a basic DES engine.
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DESEngine
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    implements BlockCipher
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected static final int  BLOCK_SIZE = 8;
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private int[]               workingKey = null;
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * standard constructor.
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DESEngine()
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * initialise a DES cipher.
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param encrypting whether or not we are for encryption.
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param params the parameters required to set up the cipher.
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the params argument is
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * inappropriate.
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void init(
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean           encrypting,
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        CipherParameters  params)
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (params instanceof KeyParameter)
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (((KeyParameter)params).getKey().length > 8)
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                throw new IllegalArgumentException("DES key too long - should be 8 bytes");
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            workingKey = generateWorkingKey(encrypting,
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                                  ((KeyParameter)params).getKey());
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return;
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getAlgorithmName()
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "DES";
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int getBlockSize()
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return BLOCK_SIZE;
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int processBlock(
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[] in,
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int inOff,
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[] out,
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int outOff)
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (workingKey == null)
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalStateException("DES engine not initialised");
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if ((inOff + BLOCK_SIZE) > in.length)
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new DataLengthException("input buffer too short");
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if ((outOff + BLOCK_SIZE) > out.length)
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
82a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom            throw new OutputLengthException("output buffer too short");
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        desFunc(workingKey, in, inOff, out, outOff);
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return BLOCK_SIZE;
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void reset()
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * what follows is mainly taken from "Applied Cryptography", by
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Bruce Schneier, however it also bears great resemblance to Richard
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Outerbridge's D3DES...
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//    private static final short[]    Df_Key =
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//        {
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//            0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//            0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//            0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom//        };
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final short[]    bytebit =
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0200, 0100, 040, 020, 010, 04, 02, 01
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        };
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[]    bigbyte =
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0x800000, 0x400000, 0x200000, 0x100000,
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0x80000,  0x40000,  0x20000,  0x10000,
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0x8000,      0x4000,   0x2000,   0x1000,
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0x800,    0x400,    0x200,    0x100,
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0x80,      0x40,        0x20,     0x10,
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            0x8,      0x4,      0x2,      0x1
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        };
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /*
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Use the key schedule specified in the Standard (ANSI X3.92-1981).
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final byte[]    pc1 =
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            56, 48, 40, 32, 24, 16,  8,   0, 57, 49, 41, 33, 25, 17,
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam             9,  1, 58, 50, 42, 34, 26,  18, 10,  2, 59, 51, 43, 35,
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            62, 54, 46, 38, 30, 22, 14,   6, 61, 53, 45, 37, 29, 21,
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            13,  5, 60, 52, 44, 36, 28,  20, 12,  4, 27, 19, 11,  3
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        };
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
134c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final byte[] totrot =
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            1, 2, 4, 6, 8, 10, 12, 14,
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            15, 17, 19, 21, 23, 25, 27, 28
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        };
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
140c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final byte[] pc2 =
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        };
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
148c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP1 = {
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01010400, 0x00000000, 0x00010000, 0x01010404,
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01010004, 0x00010404, 0x00000004, 0x00010000,
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000400, 0x01010400, 0x01010404, 0x00000400,
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01000404, 0x01010004, 0x01000000, 0x00000004,
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000404, 0x01000400, 0x01000400, 0x00010400,
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00010400, 0x01010000, 0x01010000, 0x01000404,
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00010004, 0x01000004, 0x01000004, 0x00010004,
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x00000404, 0x00010404, 0x01000000,
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00010000, 0x01010404, 0x00000004, 0x01010000,
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01010400, 0x01000000, 0x01000000, 0x00000400,
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01010004, 0x00010000, 0x00010400, 0x01000004,
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000400, 0x00000004, 0x01000404, 0x00010404,
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01010404, 0x00010004, 0x01010000, 0x01000404,
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x01000004, 0x00000404, 0x00010404, 0x01010400,
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000404, 0x01000400, 0x01000400, 0x00000000,
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00010004, 0x00010400, 0x00000000, 0x01010004
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP2 = {
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80108020, 0x80008000, 0x00008000, 0x00108020,
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00100000, 0x00000020, 0x80100020, 0x80008020,
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80000020, 0x80108020, 0x80108000, 0x80000000,
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80008000, 0x00100000, 0x00000020, 0x80100020,
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00108000, 0x00100020, 0x80008020, 0x00000000,
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80000000, 0x00008000, 0x00108020, 0x80100000,
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00100020, 0x80000020, 0x00000000, 0x00108000,
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00008020, 0x80108000, 0x80100000, 0x00008020,
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x00108020, 0x80100020, 0x00100000,
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80008020, 0x80100000, 0x80108000, 0x00008000,
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80100000, 0x80008000, 0x00000020, 0x80108020,
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00108020, 0x00000020, 0x00008000, 0x80000000,
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00008020, 0x80108000, 0x00100000, 0x80000020,
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00100020, 0x80008020, 0x80000020, 0x00100020,
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00108000, 0x00000000, 0x80008000, 0x00008020,
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x80000000, 0x80100020, 0x80108020, 0x00108000
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
186c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP3 = {
187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000208, 0x08020200, 0x00000000, 0x08020008,
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08000200, 0x00000000, 0x00020208, 0x08000200,
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00020008, 0x08000008, 0x08000008, 0x00020000,
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08020208, 0x00020008, 0x08020000, 0x00000208,
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08000000, 0x00000008, 0x08020200, 0x00000200,
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00020200, 0x08020000, 0x08020008, 0x00020208,
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08000208, 0x00020200, 0x00020000, 0x08000208,
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000008, 0x08020208, 0x00000200, 0x08000000,
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08020200, 0x08000000, 0x00020008, 0x00000208,
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00020000, 0x08020200, 0x08000200, 0x00000000,
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000200, 0x00020008, 0x08020208, 0x08000200,
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08000008, 0x00000200, 0x00000000, 0x08020008,
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08000208, 0x00020000, 0x08000000, 0x08020208,
200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000008, 0x00020208, 0x00020200, 0x08000008,
201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x08020000, 0x08000208, 0x00000208, 0x08020000,
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00020208, 0x00000008, 0x08020008, 0x00020200
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP4 = {
206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00802001, 0x00002081, 0x00002081, 0x00000080,
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00802080, 0x00800081, 0x00800001, 0x00002001,
208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x00802000, 0x00802000, 0x00802081,
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000081, 0x00000000, 0x00800080, 0x00800001,
210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000001, 0x00002000, 0x00800000, 0x00802001,
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000080, 0x00800000, 0x00002001, 0x00002080,
212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00800081, 0x00000001, 0x00002080, 0x00800080,
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00002000, 0x00802080, 0x00802081, 0x00000081,
214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00800080, 0x00800001, 0x00802000, 0x00802081,
215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000081, 0x00000000, 0x00000000, 0x00802000,
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00002080, 0x00800080, 0x00800081, 0x00000001,
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00802001, 0x00002081, 0x00002081, 0x00000080,
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00802081, 0x00000081, 0x00000001, 0x00002000,
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00800001, 0x00002001, 0x00802080, 0x00800081,
220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00002001, 0x00002080, 0x00800000, 0x00802001,
221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000080, 0x00800000, 0x00002000, 0x00802080
222b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
223b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP5 = {
225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000100, 0x02080100, 0x02080000, 0x42000100,
226b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00080000, 0x00000100, 0x40000000, 0x02080000,
227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x40080100, 0x00080000, 0x02000100, 0x40080100,
228b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x42000100, 0x42080000, 0x00080100, 0x40000000,
229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x02000000, 0x40080000, 0x40080000, 0x00000000,
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x40000100, 0x42080100, 0x42080100, 0x02000100,
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x42080000, 0x40000100, 0x00000000, 0x42000000,
232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x02080100, 0x02000000, 0x42000000, 0x00080100,
233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00080000, 0x42000100, 0x00000100, 0x02000000,
234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x40000000, 0x02080000, 0x42000100, 0x40080100,
235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x02000100, 0x40000000, 0x42080000, 0x02080100,
236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x40080100, 0x00000100, 0x02000000, 0x42080000,
237b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x42080100, 0x00080100, 0x42000000, 0x42080100,
238b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x02080000, 0x00000000, 0x40080000, 0x42000000,
239b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00080100, 0x02000100, 0x40000100, 0x00080000,
240b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x40080000, 0x02080100, 0x40000100
241b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
243c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP6 = {
244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20000010, 0x20400000, 0x00004000, 0x20404010,
245b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20400000, 0x00000010, 0x20404010, 0x00400000,
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20004000, 0x00404010, 0x00400000, 0x20000010,
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00400010, 0x20004000, 0x20000000, 0x00004010,
248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x00400010, 0x20004010, 0x00004000,
249b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00404000, 0x20004010, 0x00000010, 0x20400010,
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20400010, 0x00000000, 0x00404010, 0x20404000,
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00004010, 0x00404000, 0x20404000, 0x20000000,
252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20004000, 0x00000010, 0x20400010, 0x00404000,
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20404010, 0x00400000, 0x00004010, 0x20000010,
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00400000, 0x20004000, 0x20000000, 0x00004010,
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20000010, 0x20404010, 0x00404000, 0x20400000,
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00404010, 0x20404000, 0x00000000, 0x20400010,
257b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000010, 0x00004000, 0x20400000, 0x00404010,
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00004000, 0x00400010, 0x20004010, 0x00000000,
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x20404000, 0x20000000, 0x00400010, 0x20004010
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
262c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP7 = {
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00200000, 0x04200002, 0x04000802, 0x00000000,
264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000800, 0x04000802, 0x00200802, 0x04200800,
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04200802, 0x00200000, 0x00000000, 0x04000002,
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000002, 0x04000000, 0x04200002, 0x00000802,
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04000800, 0x00200802, 0x00200002, 0x04000800,
268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04000002, 0x04200000, 0x04200800, 0x00200002,
269b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04200000, 0x00000800, 0x00000802, 0x04200802,
270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00200800, 0x00000002, 0x04000000, 0x00200800,
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04000000, 0x00200800, 0x00200000, 0x04000802,
272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04000802, 0x04200002, 0x04200002, 0x00000002,
273b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00200002, 0x04000000, 0x04000800, 0x00200000,
274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04200800, 0x00000802, 0x00200802, 0x04200800,
275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000802, 0x04000002, 0x04200802, 0x04200000,
276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00200800, 0x00000000, 0x00000002, 0x04200802,
277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x00200802, 0x04200000, 0x00000800,
278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x04000002, 0x04000800, 0x00000800, 0x00200002
279b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
280b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int[] SP8 = {
282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10001040, 0x00001000, 0x00040000, 0x10041040,
283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10000000, 0x10001040, 0x00000040, 0x10000000,
284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00040040, 0x10040000, 0x10041040, 0x00041000,
285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10041000, 0x00041040, 0x00001000, 0x00000040,
286b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10040000, 0x10000040, 0x10001000, 0x00001040,
287b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00041000, 0x00040040, 0x10040040, 0x10041000,
288b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00001040, 0x00000000, 0x00000000, 0x10040040,
289b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10000040, 0x10001000, 0x00041040, 0x00040000,
290b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00041040, 0x00040000, 0x10041000, 0x00001000,
291b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000040, 0x10040040, 0x00001000, 0x00041040,
292b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10001000, 0x00000040, 0x10000040, 0x10040000,
293b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10040040, 0x10000000, 0x00040000, 0x10001040,
294b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00000000, 0x10041040, 0x00040040, 0x10000040,
295b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10040000, 0x10001000, 0x10001040, 0x00000000,
296b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x10041040, 0x00041000, 0x00041000, 0x00001040,
297b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        0x00001040, 0x00040040, 0x10000000, 0x10041000
298b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    };
299b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
300b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
301b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate an integer based working key based on our secret key
302b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * and what we processing we are planning to do.
303b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
304b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Acknowledgements for this routine go to James Gillogly & Phil Karn.
305b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *         (whoever, and wherever they are!).
306b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
307b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected int[] generateWorkingKey(
308b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean encrypting,
309b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  key)
310b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int[]       newKey = new int[32];
312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean[]   pc1m = new boolean[56],
313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    pcr = new boolean[56];
314b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
315b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int j = 0; j < 56; j++)
316b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
317b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            int    l = pc1[j];
318b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
319b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i < 16; i++)
323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            int    l, m, n;
325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (encrypting)
327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                m = i << 1;
329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                m = (15 - i) << 1;
333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            n = m + 1;
336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            newKey[m] = newKey[n] = 0;
337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int j = 0; j < 28; j++)
339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
340b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                l = j + totrot[i];
341b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (l < 28)
342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    pcr[j] = pc1m[l];
344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    pcr[j] = pc1m[l - 28];
348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int j = 28; j < 56; j++)
352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                l = j + totrot[i];
354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (l < 56)
355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    pcr[j] = pc1m[l];
357b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
358b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
359b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
360b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    pcr[j] = pc1m[l - 28];
361b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
362b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
363b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
364b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int j = 0; j < 24; j++)
365b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
366b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (pcr[pc2[j]])
367b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
368b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    newKey[m] |= bigbyte[j];
369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
371b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (pcr[pc2[j + 24]])
372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    newKey[n] |= bigbyte[j];
374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
375b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
376b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
377b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
378b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
379b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // store the processed key
380b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        //
381b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != 32; i += 2)
382b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            int    i1, i2;
384b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
385b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            i1 = newKey[i];
386b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            i2 = newKey[i + 1];
387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
388b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
389b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                                   | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
390b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
391b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
392b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                                   | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
393b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
394b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
395b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return newKey;
396b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
397b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
398b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
399b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * the DES engine.
400b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
401b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected void desFunc(
402b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int[]   wKey,
403b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  in,
404b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     inOff,
405b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  out,
406b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     outOff)
407b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
408b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     work, right, left;
409b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
410b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left     = (in[inOff + 0] & 0xff) << 24;
411b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left    |= (in[inOff + 1] & 0xff) << 16;
412b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left    |= (in[inOff + 2] & 0xff) << 8;
413b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left    |= (in[inOff + 3] & 0xff);
414b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
415b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right     = (in[inOff + 4] & 0xff) << 24;
416b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right    |= (in[inOff + 5] & 0xff) << 16;
417b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right    |= (in[inOff + 6] & 0xff) << 8;
418b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right    |= (in[inOff + 7] & 0xff);
419b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
420b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
421b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= work;
422b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= (work << 4);
423b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((left >>> 16) ^ right) & 0x0000ffff;
424b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= work;
425b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= (work << 16);
426b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((right >>> 2) ^ left) & 0x33333333;
427b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= work;
428b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= (work << 2);
429b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((right >>> 8) ^ left) & 0x00ff00ff;
430b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= work;
431b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= (work << 8);
432b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
433b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = (left ^ right) & 0xaaaaaaaa;
434b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= work;
435b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= work;
436b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
437b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
438b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int round = 0; round < 8; round++)
439b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
440b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            int     fval;
441b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
442b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            work  = (right << 28) | (right >>> 4);
443b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            work ^= wKey[round * 4 + 0];
444b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval  = SP7[ work      & 0x3f];
445b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP5[(work >>>  8) & 0x3f];
446b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP3[(work >>> 16) & 0x3f];
447b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP1[(work >>> 24) & 0x3f];
448b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            work  = right ^ wKey[round * 4 + 1];
449b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP8[ work      & 0x3f];
450b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP6[(work >>>  8) & 0x3f];
451b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP4[(work >>> 16) & 0x3f];
452b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP2[(work >>> 24) & 0x3f];
453b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            left ^= fval;
454b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            work  = (left << 28) | (left >>> 4);
455b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            work ^= wKey[round * 4 + 2];
456b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval  = SP7[ work      & 0x3f];
457b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP5[(work >>>  8) & 0x3f];
458b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP3[(work >>> 16) & 0x3f];
459b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP1[(work >>> 24) & 0x3f];
460b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            work  = left ^ wKey[round * 4 + 3];
461b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP8[ work      & 0x3f];
462b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP6[(work >>>  8) & 0x3f];
463b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP4[(work >>> 16) & 0x3f];
464b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            fval |= SP2[(work >>> 24) & 0x3f];
465b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            right ^= fval;
466b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
467b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
468b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right = (right << 31) | (right >>> 1);
469b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = (left ^ right) & 0xaaaaaaaa;
470b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= work;
471b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= work;
472b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left = (left << 31) | (left >>> 1);
473b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((left >>> 8) ^ right) & 0x00ff00ff;
474b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= work;
475b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= (work << 8);
476b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((left >>> 2) ^ right) & 0x33333333;
477b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= work;
478b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= (work << 2);
479b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((right >>> 16) ^ left) & 0x0000ffff;
480b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= work;
481b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= (work << 16);
482b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
483b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        left ^= work;
484b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        right ^= (work << 4);
485b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
486b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 0] = (byte)((right >>> 24) & 0xff);
487b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 1] = (byte)((right >>> 16) & 0xff);
488b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 2] = (byte)((right >>>  8) & 0xff);
489b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 3] = (byte)(right         & 0xff);
490b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 4] = (byte)((left >>> 24) & 0xff);
491b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 5] = (byte)((left >>> 16) & 0xff);
492b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 6] = (byte)((left >>>  8) & 0xff);
493b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out[outOff + 7] = (byte)(left         & 0xff);
494b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
495b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
496