Search code examples
cencryptionbit-manipulationbitwise-operatorsbit-shift

C encryption/decryption algorithm - set bit position 2 two bit positions to the left of the current bit position


I'm given a large set of instructions to follow for the algorithm in regards to what functions might be made and such, but I'm very confused with how to (1) and (2) of 1. b) which asks me to set position 2 to the left of the current position by some bits. I don't quite understand if I should be creating new functions to achieve this or if I could use the setBit() function I already made? And if I do need to create new functions, I'm still confused with how to set the bits and what the instructions mean by circling back.

I feel like if I can understand how to do the first set of instructions and get used to figuring out how to set the bit positions, I'll have an easier time doing the rest of the instructions. I understand this is a very loaded question, but I would appreciate any help or hints or a push in the right direction as I'm very lost.

Note: only the main function was given to me. I wrote the getBit, setBit, and clearBit functions but I feel like none of them are applicable to question 1).

Instructions I'm struggling with:

(1) process the counter value, using the key value, as follows:
    (a) make a copy of the counter value into a temp counter
    (b) for every bit position, starting at bit position 7:
        (i) compute two bit positions (position 1 and position 2) that you will use to perform an xor
            between two of the temp counter bits: position 1 is set to the current bit position, and 
            position 2 is computed as follows:
            (1) if the key bit at the current bit position is 1, then position 2 is set to one bit 
                position to the left of the current bit position, assuming we circle back to the 
                least significant bits (for example, we consider bit 0 to be to the left of bit 7)
            (2) if the key bit at the current bit position is 0, then position 2 is set to two bit 
                positions to the left of the current bit position, assuming we circle back
        (ii) xor the two temp counter bits found at positions 1 and 2

main.c

int main()
{
  char str[8];
  int  choice;

  printf("\nYou may:\n");
  printf("  (1) Encrypt a message \n");
  printf("  (2) Decrypt a message \n");
  printf("\n  what is your selection: ");
  fgets(str, sizeof(str), stdin);
  sscanf(str, "%d", &choice);

  switch (choice) {
    case 1:
      break;
    case 2:
      break;
    default:
      break;
  }
  return 0;
}

unsigned char swapBitsOne(unsigned char counter, int bitOne, int bitTwo){

/* if the key bit at the current bit position is 1, then position 2 is set to one bit position to
the left of the current bit position, assuming we circle back to the least significant bits (for
example, we consider bit 0 to be to the left of bit 7)
*/

}

unsigned char swapBitsTwo(unsigned char counter, int bitOne, int bitTwo){
/* 
if the key bit at the current bit position is 0, then position 2 is set to two bit positions to
the left of the current bit position, assuming we circle back
*/  

}

unsigned char processCounter(unsigned char key, unsigned char counter){
    unsigned char tempCounter;
    strcpy(counter, tempCounter);
    int i;
    for(i = 7; i >= 0; --i){
        if(key == 1){ // if the key bit at the current bit position is 1
            counter = setBit(i, 1
        }
        if(key == 0){
            counter = swapBitsTwo(); 
        }

    } 
    return tempCounter;
}


unsigned char getBit(unsigned char c, int n){
    return(c & 1 << n) >> n;
}


unsigned char setBit(unsigned char c, int n){ 
    return c | (1 << n);
}


unsigned char clearBit(unsigned char c, int n){ 
    return c & (~(1 << n));
}

Solution

  • You've got a few too many functions, making the solution a bit too complex.

    First, you can't use strcpy on simple char arguments. You need to pass char * arguments. But, just use a simple assignment.

    In processCounter ...

    You need to extract the bit from the key for the given/current bit position (e.g. unsigned char keybit = getBit(key,i);).

    "Position 1" is always the current position (i.e. i). "Position 2" is based on what keybit is.

    You need to get the given bits from c, based on the two values of pos1 and pos2.

    You need to set/clear the result bit in the output based on the value of the XOR of those two bits.


    Anyway, here's some refactored code that does what you need.

    Note that I've reversed the order of the c and key arguments to be more idiomatic (and consistent with the c argument for your other [helper] functions).

    Also, you don't really need to "copy" the argument c, just use a different variable for the return value. That's because all eight bits of the result get replaced.

    unsigned char
    getBit(unsigned char c, int n)
    {
    #if ORIG
        return (c & 1 << n) >> n;
    #else
        return (c >> n) & 1;
    #endif
    }
    
    unsigned char
    setBit(unsigned char c, int n)
    {
        return c | (1 << n);
    }
    
    unsigned char
    clearBit(unsigned char c, int n)
    {
    #if ORIG
        return c & (~(1 << n));
    #else
        return c & ~(1 << n);
    #endif
    }
    
    unsigned char
    processCounter(unsigned char c,unsigned char key)
    {
        int curpos;
        int pos1;
        int pos2;
        unsigned char bit1;
        unsigned char bit2;
        unsigned char xor;
        unsigned char out = 0;
    
        for (curpos = 7;  curpos >= 0;  --curpos) {
            // 1.b.i
            pos1 = curpos;
    
            // 1.b.i.1
            if (getBit(key,curpos))
                pos2 = (curpos + 1) % 8;
    
            // 1.b.i.2
            else
                pos2 = (curpos + 2) % 8;
    
            // 1.b.ii
            bit1 = getBit(c,pos1);
            bit2 = getBit(c,pos2);
            xor = (bit1 ^ bit2) & 1;
    
            if (xor)
                out = setBit(out,curpos);
            else
                out = clearBit(out,curpos);
        }
    
        return out;
    }
    

    Note that you could replace the final if/else with:

    out |= xor << curpos;
    

    And, you could replace the if/else for 1.b.i.1 and 1.b.i.2 with:

    pos2 = ((curpos + 2) - getBit(key,curpos)) % 8;