I'm coding this program that allows you to encrypt files using vernam cipher in C language. I would be glad if you could inspect my code and tell me if I can make some improvements to it or if there are any error.
The request they gave me is:
The goal is to develop a simple application that allows you to encrypt files using a variant of the Vernam cipher, here called bvernan. The proposed algorithm exploits a simple property of the binary operator XOR: (A XOR B) XOR B = A Given a sequence of k-bytes b0 ... bk-1 (called key), the encoding function of a sequence of bytes d0 ... dN, the encoding / decoding function follows the following simple procedure. The sequence d0 ... dN is first divided into N / k blocks (integer division), D0, ..., D [(N / k) -1] each of which consists of exactly k bytes (apart from the 'last sequence which, obviously, may contain a smaller number of bytes). Subsequently each sequence Dj = dj, 0 ... dj, k-1 is transformed into the sequence D'j = d'j, 0 ... d'j, k-1 such that for each i: d'j, i = b (j + i) mod k XOR dj, i That is, the byte in position i of block j is placed in XOR with the byte (j + i) mod k of the key. The output sequence will then be obtained from the juxtaposition of the sequences D'0, ..., D '[(N / k) -1].
This is the code:
file main.c
#include "encode.h"
int main (int argc ,char** argv){
if(argc!=4){
printf("Usage: bvernan keyfile inputfile outputfile \n");
return 1;
}
Key_t* key=openKey(argv[1]);
Register_t* file=openFile(argv[2],argv[3],key->lenght);
encode(file,key);
closeRegister(file);
freeKey(key);
printf("Success!\n");
}
file encode.c
#include "encode.h"
int encode (Register_t* file, Key_t* key ){
while(readF(file)>0){
encodeDivision(file->buffer,file->bufferLenght,key);
writeF(file);
}
}
void encodeDivision (unsigned char* block,long lenght,Key_t*key){
for(int i=0;i<lenght;i++){
block[i]=block[i]^key->buffer[i];
}
}
file encode.h
#include "key.h"
#include "register.h"
int encode (Register_t* file, Key_t* key );
void encodeDivision (unsigned char* block,long lenght,Key_t*key);
file key.c
#include "key.h"
#include <stdio.h>
#include <stdlib.h>
long keySize (FILE* file){
fseek (file,0,SEEK_END);
long size=ftell(file);
rewind (file);
return size;
}
Key_t* openKey(char* path){
Key_t* kFile= malloc (sizeof(Key_t));
FILE*file= fopen(path,"rb");
kFile->lenght=keySize(file);
kFile->buffer= malloc(kFile->lenght);
fread(kFile->buffer,1,kFile->lenght,file);
fclose(file);
return kFile;
}
void freeKey (Key_t* key ){
free (key->buffer);
free (key);
}
file key.h
typedef struct Key
{
unsigned char* buffer;
long lenght;
} Key_t;
Key_t* openKey(char* path);
void freeKey (Key_t*);
file register.c
#include <stdio.h>
#include <stdlib.h>
#include "register.h"
Register_t* openFile (char* inPath,char* outPath,long bufferLenght){
Register_t* file = malloc (sizeof(Register_t));
file->buffer= malloc(bufferLenght);
file->bufferLenght=bufferLenght;
file->fdIn= fopen(inPath,"rb");
file->fdOut= fopen(outPath,"wb");
if(file->fdOut==NULL || file->fdIn==NULL){
return NULL;
}
return file;
}
int readF (Register_t* file){
int readbyte = fread(file->buffer,1,file->bufferLenght,file->fdIn);
file->bufferLenght=readbyte;
return readbyte;
}
int writeF (Register_t* file){
int writebyte = fwrite(file->buffer,1,file->bufferLenght,file->fdOut);
return writebyte;
}
void closeRegister (Register_t* file){
free(file->buffer);
fclose(file->fdIn);
fclose(file->fdOut);
free(file);
}
file register.h
#include <stdio.h>
#include <stdlib.h>
typedef struct Register
{
unsigned char *buffer;
FILE *fdIn;
FILE *fdOut;
long bufferLenght;
} Register_t;
Register_t *openFile(char *inPath, char *outPath, long bufferLenght);
int readF(Register_t *);
int writeF(Register_t *);
void closeRegister(Register_t *);
file Makefile
all: bvernan
bvernan: encode.o key.o main.o register.o
gcc -o bvernan $^
%.o: %.c
gcc -c $<
clean:
rm *.o bvernan