# PC1 Encryption Algorithm Implementation in C

0
1668

PC1 is a symmetric encryption algorithm which uses variable key lengths (40, 56, 64, 80, 128 or 256 bits). Currently, 256 is the maximum key length used in PC1 encryption as it does not require lengthy keys. We use symmetric algorithms to securely exchange passwords. We can also call this as Pukall cipher as it was developed by Alexander Pukall.

If you are considering the other ciphers which use the same key length, PC1 is a better option in terms of security factors. This encryption algorithm was designed originally with a key length of 80 bits in 1991. But according to the security constraints and challenges with time, the key length was upgraded to 128 bits and later to 256 bits.

Pukall Cipher Implementation in C:

#include<stdio.h>
#include<string.h>
/*Global variable*/
unsigned short ax,bx,cx,dx,si,tmp,x1a2,x1a0,res,i,inter,cfc,cfd,compte;
unsigned char cle;
unsigned char buff;
short c;
int c1,count;
short d,e;
FILE *in,*out;
/*End global variable*/
/*Function def*/
int fin();
int assemble();
int code();

int main(int argc,char *argv[]){
if(!argv || (!strcmp(argv,”-h”)) || !argv){
printf(“NAME :\n”);
printf(” CryptFile – Encrypt and Decrypt File with PC1 Cipher Algorithm\n”);
printf(“SYNOPSIS :\n”);
printf(” -c file_name [outputfile] for encrypt a file\n”);
printf(” -d file_name [outputfile] for decrypt a file\n”);
printf(“Key size : 256 bits\n”);
printf(“Defaut output file name is \”output.bin\”\n”);
return 0;
}
if(!strcmp(argv,”-c”)){
printf(“Encrypt : %s\n”,argv);
strcpy(cle,”abcdefghijklmnopqrstuvwxyz012345″);
printf(“Enter a key : “);
scanf(“%32s”,cle);
if((in = fopen(argv,”rb”)) == NULL){printf(“Error file doesn’t exist\n”);return 1;}
if(!argv){
if((out = fopen(“output.bin”,”wb”)) == NULL){printf(“Error file can’t be create\n”);return 1;}
}else{
if((out = fopen(argv,”wb”)) == NULL){printf(“Error file doesn’t exist\n”);return 1;}
}
while ( (c=fgetc(in)) != EOF){/* c contains the byte read in the file */
assemble();
cfc=inter>>8;
cfd=inter&255; /* cfc^cfd = random byte */

/* K ZONE !!!!!!!!!!!!! */
/* here the mix of c and cle[compte] is before the encryption of c */
for (compte=0;compte> 4); /* we split the ‘c’ crypted byte into two 4 bits parts ‘d’ and ‘e’ */
e=(c & 15);

fputc(0x61+d,out); /*we write the two 4 bits parts as ASCII letters */
fputc(0x61+e,out);
}
fclose(in);fclose(out);fin();
printf(“\nEncryption done !\n”);
return 0;
}
if(!strcmp(argv,”-d”)){
printf(“Decrypt : %s\n”,argv);
strcpy(cle,”abcdefghijklmnopqrstuvwxyz012345″);
printf(“Enter a key : “);
scanf(“%32s”,cle);
if((in = fopen(argv,”rb”)) == NULL){printf(“Error file doesn’t exist\n”);return 1;}
if(!argv){
if((out = fopen(“output.bin”,”wb”)) == NULL){printf(“Error file can’t be create\n”);return 1;}
}else{
if((out = fopen(argv,”wb”)) == NULL){printf(“Error file doesn’t exist\n”);return 1;}
}
while ( (d=fgetc(in)) != EOF){ /* read the first letter in the file */
e=fgetc(in); /* read the second letter in the file */
d=d-0x61; /* retrieve the 4 bits from the first letter */
d=d<>8;
cfd=inter&255; /* cfc^cfd = random byte */

/* K ZONE !!!!!!!!!!!!! */
/* here the mix of c and cle[compte] is after the decryption of c */
c = c ^ (cfc^cfd);

for (compte=0;compte<=31;compte++){
/* we mix the plaintext byte with the key */
cle[compte]=cle[compte]^c;
}
fputc(c,out); /* we write the decrypted byte in the file IN.BIN */
}
fclose(in);fclose(out);fin();
printf(“\nDecryption done !\n”);
return 0;
}
printf(“Enter :\n -h for help\n”);
return 0;
}

int code(){
dx=x1a2+i;
ax=x1a0[i];
cx=0x015a;
bx=0x4e35;

tmp=ax;
ax=si;
si=tmp;

tmp=ax;
ax=dx;
dx=tmp;

if (ax!=0){
ax=ax*bx;
}

tmp=ax;
ax=cx;
cx=tmp;

if (ax!=0){
ax=ax*si;
cx=ax+cx;
}

tmp=ax;
ax=si;
si=tmp;
ax=ax*bx;
dx=cx+dx;

ax=ax+1;

x1a2=dx;
x1a0[i]=ax;

res=ax^dx;
i=i+1;
return 0;
}
int assemble(){

x1a0= ( cle*256 )+ cle;
code();
inter=res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

x1a0= x1a0 ^ ( (cle*256) + cle );
code();
inter=inter^res;

i=0;
return 0;
}
int fin(){
/* erase all variables */
for (compte=0;compte<=31;compte++){
cle[compte]=0;
}
ax=0;
bx=0;
cx=0;
dx=0;
si=0;
tmp=0;
x1a2=0;
x1a0=0;
x1a0=0;
x1a0=0;
x1a0=0;
x1a0=0;
res=0;
i=0;
inter=0;
cfc=0;
cfd=0;
compte=0;
c=0;
return 0;
}

Output:

We are using 256 bits key size here for better security. Copy the above code into a c file and run it. You will get the result as shown in the first section as given below. Create 2 text files e.txt and d.txt. One is to hold the text to be encrypted and the other one is to keep the output text. We use 2 commands:

• ./a.out -c e.txt output.bin
• ./a.out -d output.bin d.txt

The encrypted text is stored in output.bin and is decrypted to the text file d.txt. Open this text file to get the decrypted text.  