Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Fix the functions in the file modes.c so that the output is the desired output:

ID: 3698385 • Letter: F

Question

Fix the functions in the file modes.c so that the output is the desired output:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "hex.h"
#include <assert.h>

/*The block cipher*/
char cipher(unsigned char block, char key)
{ //this is an affine cipher where "a" is fixed at 11 and b=key
return (key+11*block)%256;
}

/*The inverse of the block cipher*/
char inv_cipher(unsigned char block, char key)
{ // 163 is the inverse of 11 mod 256
return (163*(block-key+256))%256;
}


void ofb(char* pt, char key, char iv, int len)
{
/*fix me*/
}

void ecb(char* pt, char key, char iv, int len)
{
/*fix me*/
}

void ecb_dec(char* ct, char key, char iv, int len)
{
/*fix me*/
}

void cfb(char* pt, char key, char iv, int len)
{
/*fix me*/
}

void cfb_dec(char* ct, char key, char iv, int len)
{
/*fix me*/
}

void cbc(char* pt, char key, char iv, int len)
{
/*fix me*/
}

void cbc_dec(char* ct, char key, char iv, int len)
{
/*fix me*/
}

void ctr(char* pt, char key, char iv, int len)
{
iv &= 0xF8; //use only left 5 bits
int i =0, ctr=0;
for(i=0; i < len;i++)
{
ctr &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | ctr), key);
ctr++;
}
}

void print_ct(char* ct,int len)
{
printf("ciphertext: 0x%s ",bin2hex(ct,len));
}


/*Desired output:

plaintext: mother
ciphertext: 0x2D2422090905
plaintext: soldier
ciphertext: 0xF9CDAC548B5FEE
plaintext: risk
ciphertext: 0x24FD940F
plaintext: endless
ciphertext: 0xEDA9D7110425BA
plaintext: hair
ciphertext: 0x3EDB6F38

*/


int main()
{
char key = 8;
char iv = 0xaa;
int len;
int a = 1;
char ct[1000] = {0};
char pt[12][100] = {"wife", "mother", "soldier", "risk", "endless", "hair", "vote", "outside", "plate", "estate", "slow", "baby"};
char ct_ark[12][100] = {{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}};

len = strlen(pt[a]);
strncpy(ct,pt[a],len);
printf("plaintext: %s ",pt[a]);
ctr(ct,key,iv,len);
print_ct(ct,len);
strncpy(ct_ark[a],ct,len);
ctr(ct,key,iv,len);
assert((strncmp(ct,pt[a],len)==0));

a++;
len = strlen(pt[a]);
strncpy(ct,pt[a],len);
printf("plaintext: %s ",pt[a]);
ecb(ct,key,iv,len);
print_ct(ct,len);
strncpy(ct_ark[a],ct,len);
ecb_dec(ct,key,iv,len);
assert((strncmp(ct,pt[a],len)==0));


a++;
len = strlen(pt[a]);
strncpy(ct,pt[a],len);
printf("plaintext: %s ",pt[a]);
cfb(ct,key,iv,len);
print_ct(ct,len);
strncpy(ct_ark[a],ct,len);
cfb_dec(ct,key,iv,len);
assert((strncmp(ct,pt[a],len)==0));

a++;
len = strlen(pt[a]);
strncpy(ct,pt[a],len);
printf("plaintext: %s ",pt[a]);
cbc(ct,key,iv,len);
print_ct(ct,len);
strncpy(ct_ark[a],ct,len);
cbc_dec(ct,key,iv,len);
assert((strncmp(ct,pt[a],len)==0));

a++;
len = strlen(pt[a]);
strncpy(ct,pt[a],len);
printf("plaintext: %s ",pt[a]);
ofb(ct,key,iv,len);
print_ct(ct,len);
strncpy(ct_ark[a],ct,len);
ofb(ct,key,iv,len);
assert((strncmp(ct,pt[a],len)==0));
}

Explanation / Answer

/*The block cipher*/
char cipher(unsigned char block, char key)
{

    //this is an affine cipher where "a" is fixed at 11 and b=key

   b = key;

   a = 11;

   for (int i = 0; i < block.length(); i++)

    {

       if(block[i]!=' ')

            cipher = cipher + (char) ( (b+11*block[i])% 256 );

        else

            cipher += block[i];

    }

   return cipher;
}

/*The inverse of the block cipher*/


char inv_cipher(unsigned char block, char key)
{

   int a_inv = 0;

    int flag = 0;

for (int i = 0; i < 26; i++)

   {

        flag = (a * i) % 256;

       if (flag == 1)

       {

            a_inv = i;

        }

    }

    for (int i = 0; i < cipher.length(); i++)

    {

        if(cipher[i]!=' ')    (163*(block-key+256))%256;

       msg = msg + (char) (163*(cipher[i]-key+256)%256);

        else

            msg += cipher[i];

    }

return msg;
}

void ofb(char* pt, char key, char iv, int len)
{
     iv &= 0xF8; //use only left 5 bits
int i =0, of=0;
for(i=0; i < len;i++)
{
ec &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | of), key);
of++;
}
}

void ecb(char* pt, char key, char iv, int len)
{
   iv &= 0xF8; //use only left 5 bits
int i =0, ec=0;
for(i=0; i < len;i++)
{
ec &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | ec), key);
ec++;
}
}

void ecb_dec(char* ct, char key, char iv, int len)
{
    iv &= 0xF8; //use only left 5 bits
int i =0, ctr=0;
for(i=0; i < len;i++)
{
ecdc &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | ecdc), key);
ecdc++;
}
}

void cfb(char* pt, char key, char iv, int len)
{

    iv &= 0xF8; //use only left 5 bits
int i =0, cfb=0;
for(i=0; i < len;i++)
{
cfb &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | cfb), key);
cfb++;
}  
}

void cfb_dec(char* ct, char key, char iv, int len)
{

    iv &= 0xF8; //use only left 5 bits
int i =0, cfbdc=0;
for(i=0; i < len;i++)
{
  cfbdc &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | cfbdc), key);
cfbdc++;
}
}

void cbc(char* pt, char key, char iv, int len)
{

    iv &= 0xF8; //use only left 5 bits
int i =0, cbc=0;
for(i=0; i < len;i++)
{
  cbc&= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | cbc), key);
cbc++;
}
}

void cbc_dec(char* ct, char key, char iv, int len)
{
  
    iv &= 0xF8; //use only left 5 bits
int i =0, cbcdc=0;
for(i=0; i < len;i++)
{
  cbcdc &= 0x7; //use only right 3 bits
pt[i] ^= cipher((unsigned char) (iv | cbcdc), key);
cbcdc++;
}
}