Так как все индексы мы xor'им с одним и тем же числом cryptor то повторы между i и i ^ cryptor будут заключены в равных отрезках, притом размер этого отрезка всегда будет ближайшей от cryptor степенью 2 сверху, а сами повторы будут распределены в разных половинах данных отрезков, длина половинок соответственно ближайшая от cryptor степенью 2 снизу.
Ну и нужно не забывать, что есть крайний случай, когда cryptor равен 0, при котором перестановок вообще не будет
uint8_t main_buffer[512];
uint8_t cryptor;
cryptor = readCryptor();
if(cryptor != 0)
{
// вычислим ближайшую к cryptor степень 2 снизу
uint8_t pow2 = 0x80;
while((pow2 & cryptor) == 0) pow2 >>= 1;
while(readNext512Bytes(main_buffer))
{
// один большой цикл заменим на 2 маленьких
// k будет считать отрезки
// i будет считать позицию внутри отрезка
for(uint16_t k = 0; k < 512; k += pow2 << 1) for(uint8_t i = 0; i < pow2; i++)
{
uint8_t tmp;
tmp = main_buffer[i + k];
main_buffer[i + k] = main_buffer[(i + k) ^ cryptor];
main_buffer[(i + k) ^ cryptor] = tmp;
}
}
}