Click here to Skip to main content
15,894,646 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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);
}
Posted
Updated 2-Oct-12 4:59am
v3

Solution 1: Convert your unicode string to utf8
Solution 2: Cast your buffer to a char* and encode it as binary data no matter what it contains.

Usually you are encoding binary data and not text and characters. Note that a 16 bit widechar (wchar_t) isn't a unicode character! That was tha case with UCS encoding but with the advent of utf-16 this is no longer true! There are around 1million characters in the unicode table and only utf-32 can represent 1 character with 1 (32bit)word used by the encoding. In utf16 the (16bit)words can store at most 2^16 characters so sometimes 2 words are used to describe 1 unicode characters (this utf16 word-pair is called a high and low surrogate pair). So it makes no sense to mess around with (wchar_t) because it isn't unicode at all and all you can achieve with that is making an otherwise scure encryption unsecure! Instead of your original plan just encode your unicode text to whatever format (utf32, utf16, or utf8) or leave it as it is and cast the whole buffer into a byte array and encrypt that. The encryption doesn't care what kind of data you encrypt.

PS: Using unicode and using wchar_t are two totally different things. I usually use utf-8 to store unicode strings and I'm usually using norma char pointers becuase thats much natural for the C/C++ language plus it makes porting my application much easier to unix like systems where utf8 is the native format. String-related efficiency has never been an issue in my apps because of the utf8-utf16 conversion on WinNT (since the native format of WinNT is utf16) but I can image an application where string-operations are frequent and this can could cause performance issues. In that case I would go with a string class with utf16 internal representation, but in practice this never happened to me.
 
Share this answer
 
v2
Given the 10-bit key [k1, k2, k3, k4,k5,k6,k7,k8,k9,k10]

P10:
Input: 1 2 3 4 5 6 7 8 9 10
Output: 3 5 2 7 4 10 1 9 8 6

It is a fixed permutation. It is one of the flaws of S-DES because the output is fixed/predefined.

For example, given the key 1000010110 the P10 is 0000001111

P8:
Input: 1 2 3 4 5 6 7 8 9 10
Output: 6 3 7 4 8 5 10 9

It is a fixed permutation.

You can find the full explanation on the YouTube video: Simplified DES Example
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



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