Skip to content

Instantly share code, notes, and snippets.

@RahulSD
Created June 9, 2012 16:45
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save RahulSD/2901719 to your computer and use it in GitHub Desktop.
Save RahulSD/2901719 to your computer and use it in GitHub Desktop.
Simple Implementation of SDES Algorithm in Java
/**
SDES Algorithm
By: Rahul S Dambre
*/
package RahulDambre.SDES;
import java.util.*;
/** This class Generated two 8-bit subkeys from 10-bit input key **/
class KeyGeneration
{
private int[] key = new int[10];
private int[] k1 = new int[8];
private int[] k2 = new int[8];
private boolean flag = false;
KeyGeneration()
{
}
void GenerateKeys(String inputkey )
{
int[] key = new int[10];
/*
int temp;
for(int i=9;i>=0;i--)
{
temp = inputkey % 10;
key[i] = temp;
if(temp != 0 && temp != 1)
{
System.out.println("-- Error Occured : Invalid Key ");
System.exit(0);
return;
}
inputkey = inputkey/10;
}
*/
char c1;
String ts ;
try
{
for(int i=0;i<10;i++)
{
c1 = inputkey.charAt(i);
ts = Character.toString(c1);
key[i] = Integer.parseInt(ts);
if(key[i] !=0 && key[i]!=1)
{
Print.msg("\n .. Invalid Key ..");
System.exit(0);
return ;
}
}
}
catch(Exception e)
{
Print.msg("\n .. Invalid Key .. ");
System.exit(0);
return ;
}
this.key = key;
Print.msg("Input Key : ");
Print.array(this.key,10);
Print.msg("\n");
permutationP10();
Print.msg("After Permutation(P10) Key : ");
Print.array(this.key,10);
Print.msg("\n");
leftshiftLS1();
Print.msg("After LeftShift LS-1 Key : ");
Print.array(this.key,10);
Print.msg("\n");
this.k1 = permutationP8();
Print.msg("Subkey K1 Generated : ");
Print.array(this.k1,8);
Print.msg("\n");
leftshiftLS2();
Print.msg("After LeftShift LS-2 Key : ");
Print.array(this.key,10);
Print.msg("\n");
this.k2 = permutationP8();
Print.msg("Subkey K2 Generated : ");
Print.array(this.k2,8);
Print.msg("\n");
flag = true;
}
/** Perform permutation P10 on 10-bit key
P10(k1, k2, k3, k4, k5, k6, k7, k8, k9, k10) = (k3, k5, k2, k7, k4, k10, k1, k9, k8, k6)
**/
private void permutationP10()
{
int[] temp = new int[10];
temp[0] = key[2];
temp[1] = key[4];
temp[2] = key[1];
temp[3] = key[6];
temp[4] = key[3];
temp[5] = key[9];
temp[6] = key[0];
temp[7] = key[8];
temp[8] = key[7];
temp[9] = key[5];
key = temp;
}
/** Performs a circular left shift (LS-1), or rotation, separately on the first
five bits and the second five bits. **/
private void leftshiftLS1()
{
int[] temp = new int[10];
temp[0] = key[1];
temp[1] = key[2];
temp[2] = key[3];
temp[3] = key[4];
temp[4] = key[0];
temp[5] = key[6];
temp[6] = key[7];
temp[7] = key[8];
temp[8] = key[9];
temp[9] = key[5];
key = temp;
}
/** apply Permutaion P8, which picks out and permutes 8 of the 10 bits according to the following
rule: P8[ 6 3 7 4 8 5 10 9 ] , 8-bit subkey is returned **/
private int[] permutationP8()
{
int[] temp = new int[8];
temp[0] = key[5];
temp[1] = key[2];
temp[2] = key[6];
temp[3] = key[3];
temp[4] = key[7];
temp[5] = key[4];
temp[6] = key[9];
temp[7] = key[8];
return temp;
}
private void leftshiftLS2()
{
int[] temp = new int[10];
temp[0] = key[2];
temp[1] = key[3];
temp[2] = key[4];
temp[3] = key[0];
temp[4] = key[1];
temp[5] = key[7];
temp[6] = key[8];
temp[7] = key[9];
temp[8] = key[5];
temp[9] = key[6];
key = temp;
}
public int[] getK1()
{
if(!flag)
{
Print.msg("\nError Occured: Keys are not generated yet ");
return null;
}
return k1;
}
public int[] getK2()
{
if(!flag)
{
Print.msg("\nError Occured: Keys are not generated yet ");
return null;
}
return k2;
}
}
class Encryption
{
private int[] K1 = new int[8];
private int[] K2 = new int[8];
private int[] pt = new int[8];
void SaveParameters(String plaintext , int[] k1, int[] k2)
{
int[] pt = new int[8];
/*
int temp;
for(int i=7;i>=0;i--)
{
temp = plaintext % 10;
pt[i] = temp;
if(temp != 0 && temp != 1)
{
System.out.println("-- Error Occured : please enter valid 8-bit plaintext ");
System.exit(0);
return;
}
plaintext = plaintext/10;
}
*/
char c1;
String ts ;
try
{
for(int i=0;i<8;i++)
{
c1 = plaintext.charAt(i);
ts = Character.toString(c1);
pt[i] = Integer.parseInt(ts);
if(pt[i] !=0 && pt[i]!=1)
{
Print.msg("\n .. Invalid Plaintext ..");
System.exit(0);
return ;
}
}
}
catch(Exception e)
{
Print.msg("\n .. Invalid Plaintext .. ");
System.exit(0);
return ;
}
this.pt = pt;
Print.msg("Plaintext array : ");
Print.array(this.pt,8);
Print.msg("\n");
this.K1 = k1;
this.K2 = k2;
//Print.array(K1,8);
//Print.msg("\n");
//Print.array(K2,8);
}
/** perform Initial Permutation in following manner [2 6 3 1 4 8 5 7] **/
void InitialPermutation()
{
int[] temp = new int[8];
temp[0] = pt[1];
temp[1] = pt[5];
temp[2] = pt[2];
temp[3] = pt[0];
temp[4] = pt[3];
temp[5] = pt[7];
temp[6] = pt[4];
temp[7] = pt[6];
pt = temp;
Print.msg("Initial Permutaion(IP) : ");
Print.array(this.pt,8);
Print.msg("\n");
}
void InverseInitialPermutation()
{
int[] temp = new int[8];
temp[0] = pt[3];
temp[1] = pt[0];
temp[2] = pt[2];
temp[3] = pt[4];
temp[4] = pt[6];
temp[5] = pt[1];
temp[6] = pt[7];
temp[7] = pt[5];
pt = temp;
}
/** mappingF . arguments 4-bit right-half of plaintext & 8-bit subkey **/
int[] mappingF(int[] R, int[] SK)
{
int[] temp = new int[8];
// EXPANSION/PERMUTATION [4 1 2 3 2 3 4 1]
temp[0] = R[3];
temp[1] = R[0];
temp[2] = R[1];
temp[3] = R[2];
temp[4] = R[1];
temp[5] = R[2];
temp[6] = R[3];
temp[7] = R[0];
Print.msg("EXPANSION/PERMUTATION on RH : ");
Print.array(temp,8);
Print.msg("\n");
// Bit by bit XOR with sub-key
temp[0] = temp[0] ^ SK[0];
temp[1] = temp[1] ^ SK[1];
temp[2] = temp[2] ^ SK[2];
temp[3] = temp[3] ^ SK[3];
temp[4] = temp[4] ^ SK[4];
temp[5] = temp[5] ^ SK[5];
temp[6] = temp[6] ^ SK[6];
temp[7] = temp[7] ^ SK[7];
Print.msg("XOR With Key : ");
Print.array(temp,8);
Print.msg("\n");
// S-Boxes
final int[][] S0 = { {1,0,3,2} , {3,2,1,0} , {0,2,1,3} , {3,1,3,2} } ;
final int[][] S1 = { {0,1,2,3}, {2,0,1,3}, {3,0,1,0}, {2,1,0,3}} ;
int d11 = temp[0]; // first bit of first half
int d14 = temp[3]; // fourth bit of first half
int row1 = BinaryOp.BinToDec(d11,d14); // for input in s-box S0
int d12 = temp[1]; // second bit of first half
int d13 = temp[2]; // third bit of first half
int col1 = BinaryOp.BinToDec(d12,d13); // for input in s-box S0
int o1 = S0[row1][col1];
int[] out1 = BinaryOp.DecToBinArr(o1);
Print.msg("S-Box S0: ");
Print.array(out1,2);
Print.msg("\n");
int d21 = temp[4]; // first bit of second half
int d24 = temp[7]; // fourth bit of second half
int row2 = BinaryOp.BinToDec(d21,d24);
int d22 = temp[5]; // second bit of second half
int d23 = temp[6]; // third bit of second half
int col2 = BinaryOp.BinToDec(d22,d23);
int o2 = S1[row2][col2];
int[] out2 = BinaryOp.DecToBinArr(o2);
Print.msg("S-Box S1: ");
Print.array(out2,2);
Print.msg("\n");
//4 output bits from 2 s-boxes
int[] out = new int[4];
out[0] = out1[0];
out[1] = out1[1];
out[2] = out2[0];
out[3] = out2[1];
//permutation P4 [2 4 3 1]
int [] O_Per = new int[4];
O_Per[0] = out[1];
O_Per[1] = out[3];
O_Per[2] = out[2];
O_Per[3] = out[0];
Print.msg("Output of mappingF : ");
Print.array(O_Per,4);
Print.msg("\n");
return O_Per;
}
/** fK(L, R, SK) = (L (XOR) mappingF(R, SK), R) .. returns 8-bit output**/
int[] functionFk(int[] L, int[] R,int[] SK)
{
int[] temp = new int[4];
int[] out = new int[8];
temp = mappingF(R,SK);
//XOR left half with output of mappingF
out[0] = L[0] ^ temp[0];
out[1] = L[1] ^ temp[1];
out[2] = L[2] ^ temp[2];
out[3] = L[3] ^ temp[3];
out[4] = R[0];
out[5] = R[1];
out[6] = R[2];
out[7] = R[3];
return out;
}
/** switch function (SW) interchanges the left and right 4 bits **/
int[] switchSW(int[] in)
{
int[] temp = new int[8];
temp[0] = in[4];
temp[1] = in[5];
temp[2] = in[6];
temp[3] = in[7];
temp[4] = in[0];
temp[5] = in[1];
temp[6] = in[2];
temp[7] = in[3];
return temp;
}
int[] encrypt(String plaintext , int[] LK, int[] RK)
{
SaveParameters(plaintext,LK,RK);
Print.msg("\n---------------------------------------\n");
InitialPermutation();
Print.msg("\n---------------------------------------\n");
//saperate left half & right half from 8-bit pt
int[] LH = new int[4];
int[] RH = new int[4];
LH[0] = pt[0];
LH[1] = pt[1];
LH[2] = pt[2];
LH[3] = pt[3];
RH[0] = pt[4];
RH[1] = pt[5];
RH[2] = pt[6];
RH[3] = pt[7];
Print.msg("First Round LH : ");
Print.array(LH,4);
Print.msg("\n");
Print.msg("First Round RH: ");
Print.array(RH,4);
Print.msg("\n");
//first round with sub-key K1
int[] r1 = new int[8];
r1 = functionFk(LH,RH,K1);
Print.msg("After First Round : ");
Print.array(r1,8);
Print.msg("\n");
Print.msg("\n---------------------------------------\n");
//Switch the left half & right half of about output
int[] temp = new int[8];
temp = switchSW(r1);
Print.msg("After Switch Function : ");
Print.array(temp,8);
Print.msg("\n");
Print.msg("\n---------------------------------------\n");
// again saperate left half & right half for second round
LH[0] = temp[0];
LH[1] = temp[1];
LH[2] = temp[2];
LH[3] = temp[3];
RH[0] = temp[4];
RH[1] = temp[5];
RH[2] = temp[6];
RH[3] = temp[7];
Print.msg("Second Round LH : ");
Print.array(LH,4);
Print.msg("\n");
Print.msg("Second Round RH: ");
Print.array(RH,4);
Print.msg("\n");
//second round with sub-key K2
int[] r2 = new int[8];
r2 = functionFk(LH,RH,K2);
pt = r2;
Print.msg("After Second Round : ");
Print.array(this.pt,8);
Print.msg("\n");
Print.msg("\n---------------------------------------\n");
InverseInitialPermutation();
Print.msg("After Inverse IP (Result) : ");
Print.array(this.pt,8);
Print.msg("\n");
//Encryption done... return 8-bit output .
return pt;
}
}
public class SDES
{
public static void main(String[] args)
{
KeyGeneration KG = new KeyGeneration();
Encryption enc = new Encryption();
Scanner sc = new Scanner(System.in);
String pt ;
String key;
int[] ct = new int[8];
try
{
//Ex Input : 10101010
System.out.print("Enter 8-bit Plaintext : ");
pt = sc.next();
System.out.println(" \n ");
//Ex Input : 1010000010
System.out.print("Enter 10-bit Key : ");
key = sc.next();
System.out.println(" \n ");
Print.msg("\n Key Generation ...\n");
Print.msg("\n---------------------------------------\n");
KG.GenerateKeys(key);
Print.msg("\n---------------------------------------\n");
ct = enc.encrypt( pt ,KG.getK1(),KG.getK2());
Print.msg("\n---------------------------------------\n");
System.out.println(" \n Decryption ");
//Ex Input : 10001101
System.out.print("Enter 8-bit Ciphertext : ");
pt = sc.next();
System.out.println(" \n ");
//Ex Input : 1010000010
System.out.print("Enter 10-bit Key : ");
key = sc.next();
System.out.println(" \n ");
Print.msg("\n Key Generation ...\n");
Print.msg("\n---------------------------------------\n");
Print.msg("\n For decryption Two Sub-keys will be used in reverse order \n");
Print.msg("\n---------------------------------------\n\n");
KG.GenerateKeys(key);
Print.msg("\n---------------------------------------\n");
ct = enc.encrypt( pt ,KG.getK2(),KG.getK1());
Print.msg("\n---------------------------------------\n");
}
catch(InputMismatchException e)
{
System.out.println("-- Error Occured : Invalid Input ");
}
catch(Exception e)
{
System.out.println("-- Error Occured : "+e);
}
}
}
/** Class to print Strings & arrays shortly **/
class Print
{
/** Prints array to console **/
static void array(int[] arr,int len)
{
System.out.print(" - ");
for(int i=0;i<len;i++)
{
System.out.print(arr[i] + " ");
}
}
static void msg(String msg)
{
System.out.print(msg);
}
}
class BinaryOp
{
/** Gets binary digits as arguments & returns decimal number
for example input args [1,0,0] will return 4 **/
static int BinToDec(int...bits)
{
int temp=0;
int base = 1;
for(int i=bits.length-1 ; i>=0;i--)
{
temp = temp + (bits[i]*base);
base = base * 2 ;
}
return temp;
}
/** gets decimal number as argument and returns array of binary bits
for example input arg [10] will return [1,0,1,0]**/
static int[] DecToBinArr(int no)
{
// 13 1
// 6 0
// 3 1
// 1 1
// 0
if(no==0)
{
int[] zero = new int[2];
zero[0] = 0;
zero[1] = 0;
return zero;
}
int[] temp = new int[10] ;
int count = 0 ;
for(int i= 0 ; no!= 0 ; i++)
{
temp[i] = no % 2;
no = no/2;
count++;
}
int[] temp2 = new int[count];
for(int i=count-1, j=0;i>=0 && j<count;i--,j++)
{
temp2[j] = temp[i];
}
//because we requires 2-bits as output .. so for adding leading 0
if(count<2)
{
temp = new int[2];
temp[0] = 0;
temp[1] = temp2[0];
return temp;
}
return temp2;
}
}
@ProjectDeveloper323
Copy link

Thank you

@EgzonAliu30
Copy link

Can you please help me to do this in CTR Mode ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment