bit level permutation function

• 07-26-2008
zxcv
bit level permutation function
Im trying to write a bit level permutation function for a block cipher, only the catch is you go from working with 4 bit unsigned integers, to one unsigned 64 bit integer.

So the permutation is you take this one 64 bit integer and for all the bits you apply the rule that bit i goes to 16i mod 63, except for the last bit which is mapped to itself. The inverse appears to be the same, only the rule changes to 4i mod 63.

I've implemented them both but they don't seem to be actual inverses, anyone mind taking a look? I'm not sure where my errors are or if I picked a good way to tackle this.

Thanks
Code:

```unsigned char bitGet(unsigned char x, int bit) {         switch(bit) {                 case 0:                         return (x & 0x1);                 case 1:                         return (x & 0x2);                 case 2:                         return (x & 0x4);                 case 3:                         return (x & 0x8);         }         return (-1); } unsigned char bitSet(unsigned char x, int bit) {         switch(bit) {                 case 0:                         return (x | 0x1);                 case 1:                         return (x | 0x2);                 case 2:                         return (x | 0x4);                 case 3:                         return (x | 0x8);         }         return (-1); } unsigned char bitClear(unsigned char x, int bit) {         switch(bit) {                 case 0:                         return (x & 0xE);                 case 1:                         return (x & 0xD);                 case 2:                         return (x & 0xB);                 case 3:                         return (x & 0x7);         }         return (-1); } void pLayer(unsigned char dst[16]) {         int i, j;         int srcIndex, srcBit;         int dstIndex, dstBit;         unsigned char src[16];                 /* Copy orginal data */         memcpy(dst, src, sizeof(unsigned char[16]));                 /* Start main permutation */         for(i = 0; i < 63; ++i) {                 /* Relative index */                 j = (16*i) % 63;                                 /* Locations */                 srcIndex = i / 4;                 srcBit = i % 4;                 dstIndex = j / 4;                 dstBit = j % 4;                                 /* debug */                 printf("%i(%i.%i)->%i(%i.%i)\n", i, srcIndex, srcBit, j, dstIndex, dstBit);                                 /* Permutate */                 if(bitGet(src[srcIndex], srcBit) > 0)                         dst[dstIndex] = bitSet(dst[dstIndex], dstBit);                 else                         dst[dstIndex] = bitClear(dst[dstIndex], dstBit);         }                 /* Special case - last bit */         if(bitGet(src[15], 3) > 0)                 dst[15] = bitSet(dst[15], 3);         else                 dst[15] = bitClear(dst[15], 3); } void INVpLayer(unsigned char dst[16]) {         int i, j;         int srcIndex, srcBit;         int dstIndex, dstBit;         unsigned char src[16];                 /* Copy orginal data */         memcpy(dst, src, sizeof(unsigned char[16]));                 /* Start main permutation */         for(i = 0; i < 63; ++i) {                 /* Relative index */                 j = (4*i) % 63;                                 /* Locations */                 srcIndex = i / 4;                 srcBit = i % 4;                 dstIndex = j / 4;                 dstBit = j % 4;                                 /* debug */                 printf("%i(%i.%i)->%i(%i.%i)\n", i, srcIndex, srcBit, j, dstIndex, dstBit);                                 /* Permutate */                 if(bitGet(src[srcIndex], srcBit) > 0)                         dst[dstIndex] = bitSet(dst[dstIndex], dstBit);                 else                         dst[dstIndex] = bitClear(dst[dstIndex], dstBit);         }                 /* Special case - last bit */         if(bitGet(src[15], 3) > 0)                 dst[15] = bitSet(dst[15], 3);         else                 dst[15] = bitClear(dst[15], 3); }```
• 07-26-2008
vart
1. you can simplify it using << operator
Code:

``` unsigned char bitGet(unsigned char x, int bit) {     unsigned char mask = 1 << bit;     if(bit >=0 && bit < 4)         return x & mask;     return 0xFF; }```
2. it never returns negative values, so checking return value >0 - you will get true for bit value 1 and for error value as well

if you want to return 0 and 1 in case when parameters as valid - you can use >> operator:

Code:

``` unsigned char bitGet(unsigned char x, int bit) {     if(bit >=0 && bit < 4)         return (x>>bit) & 0x1;     return 0xFF; }```
in this case it will be easier to test the return value
• 07-27-2008
zxcv
Ok, nice idea. Ill have to play with that. I forgot that I could shift so easily.

Anyone happen to see anything else? I still haven't made any progress towards this yet.

Thanks!