Write a Feistal structure in C++ ****READ BEFORE BLINDLY COPY / PASTING CODE!!!!
ID: 3846040 • Letter: W
Question
Write a Feistal structure in C++
****READ BEFORE BLINDLY COPY / PASTING CODE!!!!*****
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.
Explanation / Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define ROUNDS 8
#define ACTION_ENCRYPT "-e"
#define ACTION_DECRYPT "-d"
#define MODE_ECB "ecb"
#define MODE_CBC "cbc"
enum { ACTION = 1, MODE };
uint32_t f(uint32_t block, uint32_t key);
uint64_t encrypt(uint32_t left, uint32_t right, uint32_t rounds, uint32_t keys[]);
uint64_t decrypt(uint32_t left, uint32_t right, uint32_t rounds, uint32_t keys[]);
void encrypt_ecb(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]);
void decrypt_ecb(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]);
void encrypt_cbc(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]);
void decrypt_cbc(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]);
void usage(void);
int main(int argc, char *argv[]) {
uint32_t keys[ROUNDS] = { 0xDEADBEEF, 0xBAADF00D, 0xFEEDFACE, 0xCAFEBABE, 0xDEADBABE, 0xD15EA5E, 0xDECEA5ED, 0xBAADAC1D };
FILE *infile, *outfile;
/* Check argc */
if(argc < 5) {
fprintf(stderr,"An insufficient amount of arguments supplied ");
return EXIT_FAILURE;
}
/* Open in/out files */
fprintf(stderr,"Trying to open file '%s' as input file ",argv[3]);
infile = fopen(argv[3],"r");
if(!infile) {
perror("fopen");
return EXIT_FAILURE;
}
fprintf(stderr,"Trying to open file '%s' as output file ",argv[4]);
outfile = fopen(argv[4],"w");
if(!outfile) {
perror("fopen");
return EXIT_FAILURE;
}
/* Parse cmdline */
if(!strcmp(argv[ACTION],ACTION_ENCRYPT)) {
if(!strcmp(argv[MODE],MODE_ECB)) {
encrypt_ecb(infile,outfile,ROUNDS,keys);
} else if(!strcmp(argv[MODE],MODE_CBC)) {
encrypt_cbc(infile,outfile,ROUNDS,keys);
} else {
usage();
}
} else if(!strcmp(argv[ACTION],ACTION_DECRYPT)) {
if(!strcmp(argv[MODE],MODE_ECB)) {
fprintf(stderr,"decrypt_ecb() ");
decrypt_ecb(infile,outfile,ROUNDS,keys);
} else if(!strcmp(argv[MODE],MODE_CBC)) {
decrypt_cbc(infile,outfile,ROUNDS,keys);
} else {
usage();
}
} else {
usage();
}
/* Close files */
fclose(infile);
fclose(outfile);
return 0;
}
void usage(void) {
fprintf(stderr,"NOPE. ");
}
uint32_t f(uint32_t block, uint32_t key) {
return block ^ key;
}
uint64_t encrypt(uint32_t left, uint32_t right, uint32_t rounds, uint32_t keys[]) {
uint32_t i, left1, right1;
for(i = 0;i < rounds;i++) {
left1 = f(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;
}
uint64_t decrypt(uint32_t left, uint32_t right, uint32_t rounds, uint32_t keys[]) {
uint32_t i, left1, right1;
for(i = 0;i < rounds;i++) {
left1 = f(left,keys[rounds-i-1]) ^ right;
right1 = left;
if(i == (rounds-1)) {
left = right1;
right = left1;
} else {
left = left1;
right = right1;
}
}
return (uint64_t)left<<32 | right;
}
void encrypt_ecb(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]) {
uint32_t left, right;
size_t ret;
uint64_t sblock;
while(!feof(infile)) {
memset(&sblock,0,sizeof(sblock));
ret = fread(&sblock,1,sizeof(sblock),infile);
if(!ret) break;
left = (sblock>>32) & 0xFFFFFFFF;
right = sblock & 0xFFFFFFFF;
sblock = encrypt(left,right,ROUNDS,keys);
ret = fwrite(&sblock,1,sizeof(sblock),outfile);
}
}
void decrypt_ecb(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]) {
uint32_t left, right;
size_t ret;
uint64_t sblock;
while(!feof(infile)) {
memset(&sblock,0,sizeof(sblock));
ret = fread(&sblock,1,sizeof(sblock),infile);
if(!ret) break;
left = (sblock>>32) & 0xFFFFFFFF;
right = sblock & 0xFFFFFFFF;
sblock = decrypt(left,right,ROUNDS,keys);
ret = fwrite(&sblock,1,sizeof(sblock),outfile);
}
}
void encrypt_cbc(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]) {
uint32_t left, right;
size_t ret;
uint64_t sblock, sblock_prev = 0xFEEDFACE;
while(!feof(infile)) {
memset(&sblock,0,sizeof(sblock));
ret = fread(&sblock,1,sizeof(sblock),infile);
if(!ret) break;
/* CBC */
sblock ^= sblock_prev;
left = (sblock>>32) & 0xFFFFFFFF;
right = sblock & 0xFFFFFFFF;
sblock = encrypt(left,right,ROUNDS,keys);
sblock_prev = sblock;
fwrite(&sblock,1,sizeof(sblock),outfile);
}
}
void decrypt_cbc(FILE *infile, FILE *outfile, uint32_t rounds, uint32_t keys[]) {
int first = 1;
uint32_t left, right;
size_t ret;
uint64_t sblock, sblock_prev, saved;
while(!feof(infile)) {
memset(&sblock,0,sizeof(sblock));
ret = fread(&sblock,1,sizeof(sblock),infile);
if(!ret) break;
saved = sblock;
left = (sblock>>32) & 0xFFFFFFFF;
right = sblock & 0xFFFFFFFF;
sblock = decrypt(left,right,ROUNDS,keys);
if(first) {
sblock ^= 0xFEEDFACE;
first = 0;
} else {
sblock ^= sblock_prev;
}
/* CBC */
sblock_prev = saved;
fwrite(&sblock,1,sizeof(sblock),outfile);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.