Simple Data Encryption Standard (SDES) Algorithm for Encryption and Decryption.

Luckychap 1 Tallied Votes 13K Views Share

This is a program for Encryption and Decryption
This program uses the Simple Data Encryption Standard (SDES) Algorithm.
This Algo takes 8-bits of plaintext at a time and produces 8-bits of ciphertext.
It uses 10-bits of key for Encryption and Decryption.

/*
  This is a program for Encryption and Decryption
  This program uses the Simple Data Encryption Standard (SDES) Algorithm.
  This Algo takes 8-bits of plaintext at a time and produces 8-bits of ciphertext.
  It uses 10-bits of key for Encryption and Decryption.

  Developed by : Vivek Kumar (vivek_kumar_bt@yahoo.co.in)

   Created on : 31 March 2005
   Last Modified on : 10 April 2005

   Any sort of suggetions/comments are most welcome at vivek_kumar_bt@yahoo.co.in
*/

#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
void mainmenu(int *);
void menuEn();
void menuDe();
int DoEnDe(int);

class SDES
{
private:
    char KEY[11],K1[9],K2[9],IPOutput[9],InvIPOutput[9];
    char F1Output[9],F2Output[9];
    char INPUT_BIT[9],OUTPUT_BIT[9];

public:
    unsigned char INPUT,OUTPUT;

    SDES(char *key);
    ~SDES();
    void GenerateKeys();
    char *Left_Shift(char *,int );
    void conv_to_bits(unsigned char );
    void IP(char *);
    void InvIP(char *);
    void DES_Encryption(unsigned char );
    void DES_Decryption(unsigned char );
    void Function_F(char *,char *,int );
    char *EX_OR(char *,int );
    char *SBOX0(char *);
    char *SBOX1(char *);
    void SDES::GetChar();
};
SDES::SDES(char *key)  //Initializes the object with 10-bits key
{
    int i;
    if (strlen(key)!=10)  //Checks for valid length key
    {
        printf("\nInValid Key-Length %s %d",key,strlen(key));
        getch();
        exit(1);
    }
    for (i=0;i<10;i++)  //Assigning the key privatly
    {
        KEY[i]=key[i];
    }
    KEY[10]='\0';
    GenerateKeys(); //Key Genaration Starts. Output: (K1/K2)

}

void SDES::GenerateKeys()
{
    int P10[10]={3,5,2,7,4,10,1,9,8,6}; 	 //P10 permutation-array
    char P10_OP[11];    		//Output of P10 is to be stored here
    int P8[8]={6,3,7,4,8,5,10,9}; 		//P8 permutation-array
    char *P10LEFT,*pl,*pl1,*P10RIGHT,*pr,*pr1,*plpr;
    int i;

    /*P10 operation is done on main key*/
    for (i=0;i<10;i++)
        P10_OP[i]=KEY[P10[i]-1];

    P10_OP[10]='\0';

    /*Dividing 10-bit output of P10 operation into
      two parts*/
    for (i=0;i<5;i++)
    {
        P10LEFT[i]=P10_OP[i];
        P10RIGHT[i]=P10_OP[i+5];
    }
    P10LEFT[5]='\0';
    P10RIGHT[5]='\0';

    pl=new char[6];
    pr=new char[6];

    /*Perform Left-Circular shift by 1 bit on the
      two parts of P10 output*/
    pl=Left_Shift(P10LEFT,1);
    pr=Left_Shift(P10RIGHT,1);

    /*Combine the above two parts after
      the left-cicular operation into 'plpr' string*/
    for (i=0;i<5;i++)
    {
        plpr[i]=pl[i];
        plpr[i+5]=pr[i];
    }
    plpr[10]='\0';

    /*Performing P8 Operation on plpr and assigning to K1*/
    for (i=0;i<8;i++)
        K1[i]=plpr[P8[i]-1];

    K1[8]='\0'; //This is our first sub-key K1

    /*Again performing Left-Circular-Shift(LCS) by 2 bits on
      the output of previous Left-Cicular-Shift(LCS)*/
    pl1=Left_Shift(pl,2);
    pr1=Left_Shift(pr,2);

    /*Combining the output of above LCS2 into 1 string*/
    for (i=0;i<5;i++)
    {
        plpr[i]=pl1[i];
        plpr[i+5]=pr1[i];
    }
    plpr[10]='\0';

    /*Again performing P8 operation on the above combined
      string*/
    for (i=0;i<8;i++)
    {
        K2[i]=plpr[P8[i]-1];
    }
    K2[8]='\0'; //This is our second sub-key K2

}

/*Method to perform Left-Circular-Shift on bit-string*/
char *SDES::Left_Shift(char *bs,int n)
{
    int length=strlen(bs);
    char *char_ptr,firstbit,*str;

    char_ptr = new char[length +1];
    str=new char[length+1];
    char_ptr=bs;

    int i,j;
    for (j=0;j<n;j++)
    {
        firstbit=char_ptr[0];

        for (i=0;i<length-1;i++)
        {
            str[i]=char_ptr[i+1];
        }
        str[length-1]=firstbit;
        char_ptr[length]='\0';
        char_ptr=str;
    }
    char_ptr[length]='\0';
    return(str);
}

/*Method to convert unsigned char to bit-string
  For Ex. 1="00000001"*/
void SDES::conv_to_bits(unsigned char ch)
{
    int i,bit;
    INPUT_BIT[8]='\0';
    for (i=7;i>=0;i--)
    {
        bit=ch%2;
        ch=ch/2;

        if (bit!=0)
            INPUT_BIT[i]='1';
        else
            INPUT_BIT[i]='0';
    }

}

/*Method to perform Initial-Permutation*/
void SDES::IP(char *input)
{
    int IPArray[8]={2,6,3,1,4,8,5,7};
    int i;
    IPOutput[8]='\0';
    for (i=0;i<8;i++)
    {
        IPOutput[i]=input[IPArray[i]-1];
    }
}

/*Method to perform Inverse of Initial-Permutation*/
void SDES::InvIP(char *input)
{
    int InvIPArray[8]={4,1,3,5,7,2,8,6};
    int i;
    InvIPOutput[8]='\0';
    for (i=0;i<8;i++)
    {
        InvIPOutput[i]=input[InvIPArray[i]-1];
    }
}

/*Method to perform SDES-Encryption on 8-bit 'input'*/
void SDES::DES_Encryption(unsigned char input)
{
    char LIP[5],RIP[5],L1[5],R1[5];
    int i;

    INPUT=input;
    conv_to_bits(INPUT);  //Converts the input to bit-string
    IP(INPUT_BIT);        //Initial-Permutation

    //gotoxy(1,1);
    printf("\nEncrpyting.........");

    /*Dividing the output of IP into 2 parts*/
    for (i=0;i<4;i++)
    {
        LIP[i]=IPOutput[i];
        RIP[i]=IPOutput[i+4];
    }
    LIP[4]='\0';
    RIP[4]='\0';

    /*Sending the above divided parts to Function_F and  sub-key K1*/
    Function_F(LIP,RIP,1);

    /*Dividing the output of the Function_F into 2 parts*/
    for (i=0;i<4;i++)
    {
        L1[i]=F1Output[i];
        R1[i]=F1Output[4+i];
    }
    L1[4]='\0';
    R1[4]='\0';

    /*This time the string-parameters swaped and uses sub-key K2*/
    Function_F(R1,L1,2);

    /*Performing the Inverse IP on the output of the Funtion_F*/
    InvIP(F1Output); //The output of the function will give us
    //Cipher-string

    /*Cipher string is converted back to unsigned char and stored
      in private-variable OUTPUT of this class*/
    GetChar();
}


/*Decryption is just inverse of Encryption
  Here IP, InvIP, E/P, SBOX1 and SBOX2 are same
  But Function_F first operats on sub-key K2 and
  then on sub-key K1*/
void SDES::DES_Decryption(unsigned char input)
{
    char LIP[5],RIP[5],L1[5],R1[5];
    int i;

    INPUT=input;
    conv_to_bits(INPUT);
    IP(INPUT_BIT);        //Initial-Permutation

    //gotoxy(1,1);
    printf("\nDecrpyting.........");

    for (i=0;i<4;i++)
    {
        LIP[i]=IPOutput[i];
        RIP[i]=IPOutput[i+4];
    }
    LIP[4]='\0';
    RIP[4]='\0';

    Function_F(LIP,RIP,2);

    for (i=0;i<4;i++)
    {
        L1[i]=F1Output[i];
        R1[i]=F1Output[4+i];
    }
    L1[4]='\0';
    R1[4]='\0';

    Function_F(R1,L1,1);
    InvIP(F1Output);
    GetChar();
}

void SDES::Function_F(char *linput,char *rinput,int key)
{
    int E_P[8]={4,1,2,3,2,3,4,1}; //E/P Operation-Array
    int P4[4]={2,4,3,1};          //P4 Operation-Array
    int i;
    char E_POutput[9],*EXOR_Output,*LEXOR,*REXOR;
    char *SBOX0_Output,*SBOX1_Output;
    char SBOX_Output[5];
    char P4_Output[5];
    char fk_Output[5];
    char Main_Output[9];

    /*E/P Operaion is performed here*/
    for (i=0;i<8;i++)
    {
        E_POutput[i]=rinput[E_P[i]-1];
    }
    E_POutput[8]='\0';

    /*Bitwise-EXOR is done on E/P Output and sub-key(K1/K2)*/
    EXOR_Output=EX_OR(E_POutput,key);

    /*Divide the output of Exor in 2 parts*/
    LEXOR=new char[strlen(EXOR_Output)/2+1];
    REXOR=new char[strlen(EXOR_Output)/2+1];

    for (i=0;i<strlen(EXOR_Output)/2;i++)
    {
        LEXOR[i]=EXOR_Output[i];
        REXOR[i]=EXOR_Output[i+4];
    }
    LEXOR[4]=REXOR[4]='\0';


    /*Peforming SBOX0 Operation on left 4 bits*/
    SBOX0_Output=SBOX0(LEXOR);

    /*Peforming SBOX1 Operation on right 4 bits*/
    SBOX1_Output=SBOX1(REXOR);

    /*Combining the 2-bits output of both SBOXES in one string*/
    for (i=0;i<2;i++)
    {
        SBOX_Output[i]=SBOX0_Output[i];
        SBOX_Output[i+2]=SBOX1_Output[i];
    }
    SBOX_Output[4]='\0';

    /*Performing the P4 operation on SBOX output*/
    for (i=0;i<4;i++)
    {
        P4_Output[i]=SBOX_Output[P4[i]-1];
    }
    P4_Output[4]='\0';

    /*Performing the EXOR operation on 4-bits P4-output
      and 4-bits Leftinput of Funtion_F*/
    for (i=0;i<4;i++)
    {
        if (P4_Output[i]==linput[i])
            fk_Output[i]='0';
        else
            fk_Output[i]='1';
    }
    fk_Output[4]='\0';

    /*Cancating the 4-bits output of above EXOR-operation
      and 4-bits Right-input of Function_F*/
    for (i=0;i<4;i++)
    {
        Main_Output[i]=fk_Output[i];
        Main_Output[i+4]=rinput[i];
    }
    Main_Output[8]='\0';
    /*Assigning this Cucaneted string to Private variable 'F1Output'*/
    strcpy(F1Output,Main_Output);
}

/*This method EXORS the output ofE/P and sub-keys
  depending on the parameter k.
  k=1:subkey K1  k=2:subkey K2*/
char *SDES::EX_OR(char *ep,int k)
{
    char *output,*key;
    int i,klen;

    output=new char[strlen(ep)+1];
    key=new char[strlen(K1)+1];
    if (k==1)
    {
        strcpy(key,K1);
    } else
    {
        if (k==2)
        {
            strcpy(key,K2);
        } else
        {
            printf("\n\nWrong Choice in the key parameter(1/2)");
            getch();
            exit(1);
        }
    }
    klen=strlen(K1);
    if (strlen(ep)!=klen)
    {
        printf("\ninput=%d is not equal to K=%d",strlen(ep),klen);
        printf("\n\nError in the Output of E/P (Length)..Press any key");
        getch();
        exit(1);
    }
    for (i=0;i<strlen(ep);i++)
    {
        if (ep[i]==key[i])
            output[i]='0';
        else
            output[i]='1';
    }
    output[strlen(ep)]='\0';
    return(output);
}

/*SBOX0 Operation is defined here*/
char *SDES::SBOX0(char *l)
{
    int S0[4][4]={1,0,3,2,  //S0 Matrix
        3,2,1,0,
        0,2,1,3,
        3,1,3,2
    };

    char *bits[]={"00","01","10","11"};
    char lrow[3],lcol[3];
    char *SO;
    int i,lr,lc,b;

    SO=new char[3];

    lrow[0]=l[0];
    lrow[1]=l[3];
    lcol[0]=l[1];
    lcol[1]=l[2];

    lrow[2]='\0';
    lcol[2]='\0';


    for (i=0;i<4;i++)
    {
        if (strcmp(lrow,bits[i])==0)
            lr=i;
        if (strcmp(lcol,bits[i])==0)
            lc=i;
    }
    b=S0[lr][lc];
    for (i=0;i<3;i++)
        SO[i]=bits[b][i];
    SO[3]='\0';
    return(SO);
}
/*SBOX1 Operation is defined here*/
char *SDES::SBOX1(char *l)
{
    int S0[4][4]={0,1,2,3,   //S1 Matrix
        2,0,1,3,
        3,0,1,0,
        2,1,0,3
    };

    char *bits[]={"00","01","10","11"};
    char lrow[3],lcol[3];
    char *SO;
    int i,lr,lc,b;

    SO=new char[3];

    lrow[0]=l[0];
    lrow[1]=l[3];
    lcol[0]=l[1];
    lcol[1]=l[2];

    lrow[2]='\0';
    lcol[2]='\0';


    for (i=0;i<4;i++)
    {
        if (strcmp(lrow,bits[i])==0)
            lr=i;
        if (strcmp(lcol,bits[i])==0)
            lc=i;
    }
    b=S0[lr][lc];
    for (i=0;i<3;i++)
        SO[i]=bits[b][i];

    SO[3]='\0';
    return(SO);
}

/*Method to get back unsigned char from bit-string*/
void SDES::GetChar()
{
    int i,j,in;
    unsigned char ch=0;
    char *bs;
    bs=new char[9];
    bs=InvIPOutput;
    if (strlen(bs)>8)
    {
        printf("\nWRONG LENGTH STRING");
        exit(0);
    }
    for (i=0;i<8;i++)
    {
        if (bs[i]=='1')
        {
            in=1;
            for (j=1;j<8-i;j++)
            {
                in=in*2;
            }
            ch=ch+in;
        }
    }
    OUTPUT=ch;
}

/*Destructor*/
SDES::~SDES()
{
}


char *sfname,*tfname;
char *key;//="1010000010";
void main(void)
{
    //clrscr();
    unsigned char ch,ch1;
    int i,n=10,choice;

    while (1)
    {
        key = new char[11];
        sfname = new char[20];
        tfname = new char[20];
        mainmenu(&choice);
        fflush(stdin);
        switch (choice)
        {
        case 1:
            menuEn();
            DoEnDe(choice);
            break;
        case 2:
            menuDe();
            DoEnDe(choice);
            break;
        case 3:
            exit(0);
        default:
            printf("\nWrong Choice Enter again\nPress any key to return to Main Menu..");
            getch();
            break;
        }
    }
}

void mainmenu(int *c)
{
    //clrscr();
    printf("\nWhat do you want to do..");
    printf("\n1. Encryption");
    printf("\n2. Decryption");
    printf("\n3. Exit");
    printf("\n\nEnter the choice? ");
    scanf("%d",c);
}
void menuEn()
{
    //clrscr();
    sfname=new char[20];
    tfname=new char[20];
    key=new char[11];
    printf("\nEncryption Menu\n\n");
    printf("\nEnter the filename to be Encrypted: ");
    gets(sfname);
    printf("\nEnter the Target file name: ");
    gets(tfname);
    printf("\nEnter the 10-bits KEY: ");
    gets(key);
    printf("\n\nNotedown this key, as same key is used for Decryption");
    //getch();
}

void menuDe()
{
    //clrscr();
    sfname=new char[20];
    tfname=new char[20];
    key=new char[11];
    printf("\nDecryption Menu\n\n");
    printf("\nEnter the filename to be Decrypted: ");
    gets(sfname);
    printf("\nEnter the Target file name: ");
    gets(tfname);
    printf("\nEnter the 10-bits KEY: ");
    gets(key);
}

int DoEnDe(int c)
{
    SDES S(key);
    int i,n;
    n=10; //Number of Rounds
    unsigned char ch;
    FILE *fp;
    FILE *ft;
    fp=fopen(tfname,"w");
    ft=fopen(sfname,"r");
    if (fp==NULL)
    {
        printf("\nTarget File not opened SORRY");
        getch();
        fclose(fp);
        return(0);
    }
    if (ft==NULL)
    {
        printf("\nSource File not opened SORRY");
        getch();
        fclose(ft);
        return(0);
    }
    while (fread(&ch,1,1,ft)==1)
    {
        S.OUTPUT=ch;

        for (i=0;i<n;i++)
        {
            if (c==1)
                S.DES_Encryption(S.OUTPUT);
            if (c==2)
                S.DES_Decryption(S.OUTPUT);
        }
        fwrite(&S.OUTPUT,1,1,fp);
    }
    printf("\nCompleted!!!!!");
    getch();
    fclose(fp);
    fclose(ft);
    return(1);
}
tux4life 2,072 Postaholic

Very nice snippet !

Udupa 0 Newbie Poster

sir...Can I get explaination for each line please....

Thank you in advance

Sri_2 0 Newbie Poster

what is this language?

Mocabilly 14 Newbie Poster

@Sri_2

It's C language.
See the fragment with the includes.. typical for C.
Don't know if it's ansi-C or C++ or an other "version" of C...

#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
overwraith 83 Newbie Poster

A cool program for sure, but I always submit to the observation I have read in a practical crypto book, "Don't roll your own encryption" I don't know much about this crypto standard, but when people roll their own encryption they tend to make mistakes regaurdless of how well they try. There shouldy be crypto analysts, and mathemeticians, and whole scores of other people involved in implementing a crypto standard. More eyes take care of the problems. Subtle problems are always the bane of crypto programs.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.