C/C++ Program for Implementation MD5 Hashing Technique
#include<iostream.h>
#include<conio.h>
#include<math.h>
int input[2000],pointer;
int carry;
class Block
{
public:
int word[32];
Block()
{
word[32]=0;
}
Block operator +(Block);
void operator =(Block);
Block operator &(Block);
Block operator |(Block);
Block operator ^(Block);
Block operator !();
void operator <<(int shift_bits);
}X[16],T[64],a,b,c,d,result,temp;
Block Block::operator +(Block t)
{
int x,y,ans;
for(int i=31;i>=0;i--)
{
x=word[i];
y=t.word[i];
switch(carry)
{
case 0: if(((x==0)&&(y==0))||((x==1)&&(y==1)))
{
ans=0;
carry=x;
}
if(((x==0)&&(y==1))||((x==1)&&(y==0)))
{
ans=1;
carry=0;
}
break;
case 1: if(((x==0)&&(y==0))||((x==1)&&(y==1)))
{
ans=1;
carry=x;
}
if(((x==0)&&(y==1))||((x==1)&&(y==0)))
{
ans=0;
carry=1;
}
break;
}
result.word[i]=ans;
}
return(result);
}
Block Block::operator &(Block t)
{
for(int i=0;i<32;i++)
result.word[i]=word[i] & t.word[i];
return(result);
}
Block Block::operator |(Block t)
{
for(int i=0;i<32;i++)
result.word[i]=word[i] | t.word[i];
return(result);
}
Block Block::operator ^(Block t)
{
for(int i=0;i<32;i++)
result.word[i]=word[i] ^ t.word[i];
return(result);
}
Block Block::operator !()
{
for(int i=0;i<32;i++)
result.word[i]=!word[i];
return(result);
}
void Block::operator=(Block t)
{
for(int i=0;i<32;i++)
word[i]=t.word[i];
}
//Circular left shift
int get_shift_bits(int round,int step)
{
int bits;
int p[17]={0,7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22};
int q[17]={0,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20};
int r[17]={0,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23};
int s[17]={0,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21};
switch(round)
{
case 1: bits=p[step];
break;
case 2: bits=q[step];
break;
case 3: bits=r[step];
break;
case 4: bits=s[step];
break;
}
return(bits);
}
void Block::operator <<(int shift_bits)
{
int i,p,j=0;
p=32-shift_bits;
for(i=shift_bits;i<p;i++)
{
temp.word[j]=word[i];
j++;
}
for(i=0;i<shift_bits;i++)
{
temp.word[j]=result.word[i];
j++;
}
}
void convert(char msg[])
{
int charvalue,i,j;
for(i=0;msg[i]!='\0';i++)
{
int temp[8]={0};
charvalue=(int)msg[i];
j=0;
while(charvalue!=0)
{
temp[j]=charvalue%2;
charvalue=charvalue/2;
j++;
}
for(j=7;j>=0;j--)
{
input[pointer]=temp[j];
pointer++;
}
}
cout<<"\n length of orignal msg before padding: " <<pointer;
}
void padding()
{
int r,p,i,padding_bits;
r=pointer+64;
i=1;
p=512*i;
while(r>=p)
{
i++;
p=512*i;
}
padding_bits=p-r;
cout<<"\n\npadding bits:"<<padding_bits;
input[pointer]=1;
pointer++;
for(i=1;i<padding_bits;i++)
{
input[pointer]=0;
pointer++;
}
cout<<"\n\nlength of message after padding: "<<pointer;
}
void append_length()
{
int i,t;
i=pointer+64;
t=pointer;
pointer=i;
while(t!=0)
{
input[i]=t%2;
t=t/2;
i--;
}
cout<<"\n \n message after padding:\n";
for(i=0;i<pointer;i++)
cout<<" "<<input[i];
}
void display(Block t)
{
cout<<"\n";
for(int i=0;i<32;i++)
cout<<t.word[i]<<" ";
}
void div_into_sblk(int round)
{
int ptr=0,i,j,counter=0,x;
cout<<"\n\n";
for(i=0;i<16;i++)
{
switch(round)
{
case 1:
ptr=0+ptr;
break;
case 2:
x=1+(5*i);
ptr=x%16;
break;
case 3:
x=5+(3*i);
ptr=x%16;
break;
case 4:
x=7*i;
ptr=x%16;
break;
}
cout<<"\nsubblock"<<i+1<<" :";
for(j=0;j<32;j++)
{
X[ptr].word[j]=input[counter];
cout<<X[i].word[j]<<" ";
counter++;
}
ptr++;
}
}
void cal_table()
{
int i,radian_i,abs_i,power_i,ans;
for(i=1;i<=64;i++)
{
radian_i=(3.14/180)*i;
abs_i=abs(sin(radian_i));
power_i=pow(2,32);
ans=power_i *abs_i;
int index=31;
while(ans!=0)
{
T[i].word[index]=ans%2;
ans=ans/2;
}
}
}
void init_registers()
{
int i;
int p[32]={0,1,1,0,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1};
int q[32]={1,1,1,0,1,1,1,1,1,1,0,0,1,1,0,1,1,0,1,0,1,0,1,1,1,0,0,0,1,0,0,1};
int r[32]={1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1,1,1,1,1,1,1,0};
int s[32]={0,1,1,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,1,0,0,0,0,1,0,0,0,0};
for(i=0;i<32;i++)
{
a.word[i]=p[i];
b.word[i]=q[i];
c.word[i]=r[i];
d.word[i]=s[i];
}
}
void rounds()
{
int round,k,cntr=0;
getch();
for(round=1;round<=4;round++)
{
for(k=0;k<16;k++)
{
switch(round)
{
case 1:
result=(b&c|(!b)&d);
break;
case 2:
result=(b&d)|(c&(!d));
break;
case 3:
result=b^c^c;
break;
case 4:
result=c^(b|(!d));
break;
}
result=result+a+X[k]+T[cntr];
int shift_bits=get_shift_bits(round,k+1);
result<<shift_bits;
a=d;d=c;c=b;
b=b+result;
cntr++;
}
cout<<"\n result after round"<<round<<" :";
display(a);
display(b);
display(c);
display(d);
}
cout<<"\n\nmessage digest:\n";
display(a);
display(b);
display(c);
display(d);
}
void MD5_algorithm()
{
char message[100];
cout<<"\n enter input message:";
cin>>message;
convert(message);
padding();
append_length();
div_into_sblk(1);
init_registers();
rounds();
}
void main()
{
clrscr();
MD5_algorithm();
getch();
}