DES Algorithm - Illustrated with Java Programs
Part:
1
2
3
4
5
6
(Continued from previous part...)
private static byte[] substitution6x4(byte[] in) {
in = splitBytes(in,6); // Splitting byte[] into 6-bit blocks
// printBytes(in,"R: After splitting");
byte[] out = new byte[in.length/2];
int lhByte = 0;
for (int b=0; b<in.length; b++) { // Should be sub-blocks
byte valByte = in[b];
int r = 2*(valByte>>7&0x0001)+(valByte>>2&0x0001); // 1 and 6
int c = valByte>>3&0x000F; // Middle 4 bits
int hByte = S[64*b+16*r+c]; // 4 bits (half byte) output
if (b%2==0) lhByte = hByte; // Left half byte
else out[b/2] = (byte) (16*lhByte + hByte);
}
return out;
}
private static byte[] splitBytes(byte[] in, int len) {
int numOfBytes = (8*in.length-1)/len + 1;
byte[] out = new byte[numOfBytes];
for (int i=0; i<numOfBytes; i++) {
for (int j=0; j<len; j++) {
int val = getBit(in, len*i+j);
setBit(out,8*i+j,val);
}
}
return out;
}
private static byte[] concatenateBits(byte[] a, int aLen, byte[] b,
int bLen) {
int numOfBytes = (aLen+bLen-1)/8 + 1;
byte[] out = new byte[numOfBytes];
int j = 0;
for (int i=0; i<aLen; i++) {
int val = getBit(a,i);
setBit(out,j,val);
j++;
}
for (int i=0; i<bLen; i++) {
int val = getBit(b,i);
setBit(out,j,val);
j++;
}
return out;
}
private static byte[] selectBits(byte[] in, int pos, int len) {
int numOfBytes = (len-1)/8 + 1;
byte[] out = new byte[numOfBytes];
for (int i=0; i<len; i++) {
int val = getBit(in,pos+i);
setBit(out,i,val);
}
return out;
}
private static byte[] selectBits(byte[] in, int[] map) {
int numOfBytes = (map.length-1)/8 + 1;
byte[] out = new byte[numOfBytes];
for (int i=0; i<map.length; i++) {
int val = getBit(in,map[i]-1);
setBit(out,i,val);
// System.out.println("i="+i+", pos="+(map[i]-1)+", val="+val);
}
return out;
}
private static int getBit(byte[] data, int pos) {
int posByte = pos/8;
int posBit = pos%8;
byte valByte = data[posByte];
int valInt = valByte>>(8-(posBit+1)) & 0x0001;
return valInt;
}
private static void setBit(byte[] data, int pos, int val) {
int posByte = pos/8;
int posBit = pos%8;
byte oldByte = data[posByte];
oldByte = (byte) (((0xFF7F>>posBit) & oldByte) & 0x00FF);
byte newByte = (byte) ((val<<(8-(posBit+1))) | oldByte);
data[posByte] = newByte;
}
private static void printBytes(byte[] data, String name) {
System.out.println("");
System.out.println(name+":");
for (int i=0; i<data.length; i++) {
System.out.print(byteToBits(data[i])+" ");
}
System.out.println();
}
private static String byteToBits(byte b) {
StringBuffer buf = new StringBuffer();
for (int i=0; i<8; i++)
buf.append((int)(b>>(8-(i+1)) & 0x0001));
return buf.toString();
}
private static byte[][] getTestSubkeys() {
String[] strKeys = {
" 00011011 00000010 11101111 11111100 01110000 01110010",//1
" 01111001 10101110 11011001 11011011 11001001 11100101",//2
" 01010101 11111100 10001010 01000010 11001111 10011001",//3
" 01110010 10101101 11010110 11011011 00110101 00011101",//4
" 01111100 11101100 00000111 11101011 01010011 10101000",//5
" 01100011 10100101 00111110 01010000 01111011 00101111",//6
" 11101100 10000100 10110111 11110110 00011000 10111100",//7
" 11110111 10001010 00111010 11000001 00111011 11111011",//8
" 11100000 11011011 11101011 11101101 11100111 10000001",//9
" 10110001 11110011 01000111 10111010 01000110 01001111",//0
" 00100001 01011111 11010011 11011110 11010011 10000110",//1
" 01110101 01110001 11110101 10010100 01100111 11101001",//2
" 10010111 11000101 11010001 11111010 10111010 01000001",//3
" 01011111 01000011 10110111 11110010 11100111 00111010",//4
" 10111111 10010001 10001101 00111101 00111111 00001010",//5
" 11001011 00111101 10001011 00001110 00010111 11110101"};
byte[][] subKeys = new byte[16][];
for (int k=0; k<16; k++) {
byte[] theKey = new byte[6];
for (int i=0; i<6; i++) {
String strByte = strKeys[k].substring(9*i+1,9*i+1+8);
theKey[i] = (byte) Integer.parseInt(strByte,2);
}
subKeys[k] = theKey;
}
return subKeys;
}
private static byte[] getTestMsg() {
String strMsg = " 00000001 00100011 01000101 01100111"
+" 10001001 10101011 11001101 11101111";
byte[] theMsg = new byte[8];
for (int i=0; i<8; i++) {
String strByte = strMsg.substring(9*i+1,9*i+1+8);
theMsg[i] = (byte) Integer.parseInt(strByte,2);
}
return theMsg;
}
private static boolean validateCipher(byte[] cipher ) {
String strCipher = " 10000101 11101000 00010011 01010100"
+" 00001111 00001010 10110100 00000101";
boolean ok = true;
for (int i=0; i<8; i++) {
String strByte = strCipher.substring(9*i+1,9*i+1+8);
byte cipherByte = (byte) Integer.parseInt(strByte,2);
if (cipherByte!=cipher[i]) ok = false;
}
return ok;
}
}
(Continued on next part...)
Part:
1
2
3
4
5
6
|