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);
}