Click here to Skip to main content
15,886,362 members

Please, I need help with this SDES encrypting and deencrypting scheme.

Gbenbam asked:

Open original thread
I got this encryption code from the net. Since I generally use unicode, i wish to re-write it for 16 bit character. I just don't understand how the values of variables P10[10] and P8[8] where gotten. Do they follow a particular sequence or they are randomly generated.

The above question has been answered . I used the code it worked fine but soon exhausted the heap because a lot of pointers were dynamically allocated without being release.
I tried to write a destructor for it. but was unsuccessful.I also tried other points for releasing the allOcated memory but keep getting exception thrown by the compiler. Please can any body help me with THE RELEASING OF ALL DYNAMICALLY ALLOCATED MEMORY?




What do I do to make it work for wide char type?
C++
#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&lt;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//How were this numbers generated
    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//How were this numbers generated
    char *P10LEFT,*pl,*pl1,*P10RIGHT,*pr,*pr1,*plpr;
    int i;
    /*P10 operation is done on main key*/
    for (i=0;i&lt;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&lt;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&lt;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&lt;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&lt;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&lt;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&lt;n;j++)&gt;
    {
        firstbit=char_ptr[0];
        for (i=0;i&lt;length-1;i++)&gt;
        {
            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&gt;=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&lt;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&lt;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&lt;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&lt;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&lt;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&lt;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&lt;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    {
        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&lt;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&lt;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&lt;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&lt;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&lt;strlen(ep);i++)&gt;
    {
        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&lt;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&lt;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&lt;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&lt;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)&gt;8)
    {
        printf("\nWRONG LENGTH STRING");
        exit(0);
    }
    for (i=0;i&lt;8;i++)
    {
        if (bs[i]=='1')
        {
            in=1;
            for (j=1;j&lt;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&lt;n;i++)&gt;
        {
            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);
}
Tags: C++, Windows

Plain Text
ASM
ASP
ASP.NET
BASIC
BAT
C#
C++
COBOL
CoffeeScript
CSS
Dart
dbase
F#
FORTRAN
HTML
Java
Javascript
Kotlin
Lua
MIDL
MSIL
ObjectiveC
Pascal
PERL
PHP
PowerShell
Python
Razor
Ruby
Scala
Shell
SLN
SQL
Swift
T4
Terminal
TypeScript
VB
VBScript
XML
YAML

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the http://www.codeproject.com/info/cpol10.aspx.



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900