As in DES, the initial and final permutations, which are fixed and independent of the key, provide no real security benefit, but make the algorithm slow if implemented in software.
The 10-bit key is transformed into two 8-bit sub-keys K1 and K2.
Example:
P10 = { 3, 5, 2, 7, 4, 10, 1, 9, 8, 6}
P8 = { 6, 3, 7, 4, 8, 5, 10, 9}
K = 10100 00010
P10 10000 01100
LS-1 00001 11000 -> P8 -> K1 = 1010 0100
LS-2 00100 00011 -> P8 -> K2 = 0100 0011
In fK the rightmost 4 bits are passed through unchanged, and the leftmost 4 bits are "mangled" by the non-invertible function F:
fK(L,R) = L XOR F(R,Ki), R -- encrypt or decrypt
E/P = { 4, 1, 2, 3, 2, 3, 4, 1}
P4 = { 2, 4, 3, 1}
S0 = 1 0 3 2 S1 = 0 1 2 3
3 2 1 0 2 0 1 3
0 2 1 3 3 0 1 0
3 1 3 2 2 1 0 3
n1n2n3n4 -> Si[n1n4][n2n3]
Example:
R = 1010
E/P 0101 0101
K1 = 1010 0100
XOR 1111 0001
S0[11][11] -> 10 S1[01][00] -> 10
1010
P4 0011
A B A XOR B A' XOR B A' XOR B' (A XOR B)' 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 From the truth-table: A' XOR B == (A XOR B)' A' XOR B' == A XOR B
The second XOR has inputs L' and F, therefore its output is complemented.
If (S)DES had the property Y'=K'{X} then the search space would be reduced by 1/2; you'd compute Z=K{X} and if Z==Y then K is the key, and if Z==Y' then K' is the key.
Example use: Encrypt.java, Decrypt.java
Copy.java shows how to copy stdin to stdout using system calls; it works even for binary files and can easily be adapted to perform file encryption or decryption.
Consider this code:
byte a = 1, b = 2, c;
c = a ^ b; // a XOR b
That will not compile; the javac error message is:
Incompatible type for =. Explicit cast needed to convert int to byte.
c = a ^ b; // a XOR b
^
1 error
To eliminate the error, use a cast:
c = (byte) (a ^ b); // a XOR b
Attribution: http://www.ece.villanova.edu/~perry/ccs/des/all-sdes.html
Rick Perry, Villanova University