Write a Feistal structure in C++
Program should read the number of rounds and key from command line.
Convert all input to upper case and remove non-text characters and spaces.
If the length of plaintext is not an even number, pad the text with binary zeros.
Use a 32-bit block size
Use the CBC mode for messages larger than the cipher block size.
Basic algorithm is:
The input to each round is split into two blocks of bits.
The round function for this round is applied to the right half.
The result from the round function is XORed with the left half.
The left and right half of the input is swapped and then the right half is replaced with the result of the previous step.
Expert Answer
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
using namespace std;
uint32_t ff(uint32_t block, uint32_t key);
uint64_t encrypt(uint32_t left, uint32_t right, int rounds, uint32_t keys[]);
void encryptCBC(FILE *input_file, FILE *output_file, int rounds, uint32_t keys[]);
void usage(void);
int main(int argc, char *argv[]) {
uint32_t keys[ROUNDS] = { 0xDEADBEEF, 0xFEEDFACE, 0xBAADAC1D, 0xCAFEBABE, 0xDEADBABE, 0xBAADF00D, 0xD15EA5E, 0xDECEA5ED };
FILE *input_file, *output_file;
string fileName,outputFileName;
cout<<“Enter file Name: “;
cin>>fileName;
cout<<“Enter output file name: “;
cin>>outputFileName;
int rounds;
cout<<“Enter total rounds: “;
cin>>rounds;
input_file = fopen(fileName,”r”);
if(!input_file) {
perror(“fopen”);
return EXIT_FAILURE;
}
output_file = fopen(outputFileName,”w”);
if(!output_file) {
perror(“fopen”);
return EXIT_FAILURE;
}
encryptCBC(input_file,output_file,rounds,keys);
/* Close files */
fclose(input_file);
fclose(output_file);
return 0;
}
uint32_t ff(uint32_t _block, uint32_t _key) {
return _block ^ _key;
}
uint64_t encrypt(uint32_t left, uint32_t right, int rounds, uint32_t keys[]) {
uint32_t i, left1, right1;
for(i = 0;i < rounds;i++) {
left1 = ff(left,keys[i]) ^ right;
right1 = left;
if(i == (rounds-1)) {
left = right1;
right = left1;
} else {
left = left1;
right = right1;
}
}
return (uint64_t)left<<32 | right;
}
void encryptCBC(FILE *input_file, FILE *output_file, int rounds, uint32_t keys[]) {
uint32_t left, right;
size_t _ret;
uint64_t sideBlock, sblock_prev = 0xFEEDFACE;
while(!feof(input_file)) {
memset(&sideBlock,0,sizeof(sideBlock));
_ret = fread(&sideBlock,1,sizeof(sideBlock),input_file);
if(!_ret) break;
/******************** CBC *******************************/
sideBlock ^= sblock_prev;
left = (sideBlock>>32) & 0xFFFFFFFF;
right = sideBlock & 0xFFFFFFFF;
sideBlock = encrypt(left,right,ROUNDS,keys);
sblock_prev = sideBlock;
fwrite(&sideBlock,1,sizeof(sideBlock),output_file);
}
}