DES - Перестановка битов и инверсия

В настоящее время я пытаюсь реализовать схему шифрования DES, но на раннем этапе столкнулся с проблемой. Это первый раз, когда я когда-либо выполнял побитовые манипуляции в программе, и я также не очень хорошо разбираюсь в C. Я применяю перестановку и ее инверсию, и результат не совпадает с вводом.

Что я пытаюсь сделать, так это применить начальную перестановку и обратную перестановку к блоку из 64 бит. У меня есть блок из 64 бит, который я хочу зашифровать на входе массива. В соответствии с таблицей перестановок IP я беру первый бит в первом байте и ставлю его как бит 58 в перестановке. Бит 2 отправляется в бит 50 и так далее. После перестановки результат делится пополам и стороны меняются местами. Это позволит вернуть его обратно по тому же алгоритму, но с таблицей IPinverse.

include <stdio.h>
include <stdlib.h>

static unsigned char Positions[8] = {1,2,4,8,16,32,64,128};

int main()
{
  unsigned char input[8] = {'a','b','c','d','e','f','g','h'};
  unsigned char permutation[8];
  unsigned char inverse[8];
  int i;
  for (i = 0; i < 8; i++) {
        permutation[i] = 0;
        inverse[i] = 0;
  }

  int IP[8][8] ={{58,50,42,34,26,18,10,2},
                          {60,52,44,36,28,20,12,4},
                          {62,54,46,38,30,22,14,6},
                          {64,56,48,40,32,24,16,8},
                          {57,49,41,33,25,17, 9, 1},
                          {59,51,43,35,27,19,11,3},
                          {61,53,45,37,29,21,13,5},
                          {63,55,47,39,31,23,15,7}};

  int IPinverse[8][8] ={{40,8,48,16,56,24,64,32},
                                      {39,7,47,15,55,23,63,31},
                                      {38,6,46,14,54,22,62,30},
                                      {37,5,45,13,53,21,61,29},
                                      {36,4,44,12,52,20,60,28},
                                      {35,3,43,11,51,19,59,27},
                                      {34,2,42,10,50,18,58,26},
                                      {33, 1,41, 9,49,17,57,25}};

  printf("\n Before: \n");
  for (i = 0; i < 8; i++) {
        printf(" %c", input[i]);
  }

  // Initial permutation
  int bit, newpos;
  unsigned char desiredbit;
  for (bit = 0; bit < 64; bit++) {
        // Get the location for where the bit will be sent and translate it to array index
        newpos = ((int)IP[bit/8][bit%8])-1;
        // examine the bit we're currently considering
        desiredbit = input[bit/8] & Positions[bit%8];
        // if equal to zero that means no change necessary
        if (desiredbit != 0) {
              // else it was a 1 and we need to set the appropriate bit to 1
              desiredbit = Positions[newpos%8];
              permutation[newpos/8] = desiredbit ^ permutation[newpos/8];
        }
  }

  printf("\n Permutation: \n");
  for (i = 0; i < 8; i++) {
        printf(" %c", permutation[i]);
  }

  // Perform swap
  unsigned char tempcopy[4] = {0,0,0,0};
  int j;
  for (j = 0; j < 4; j++) {
        tempcopy[j] = permutation[j+4];
  }
  for (j = 0; j < 4; j++) {
        permutation[j+4] = permutation[j];
        permutation[j] = tempcopy[j];
  }

  // Reverse Permutation, remember to swap left side with right
  for (bit = 0; bit < 64; bit++) {
        newpos = ((int)IPinverse[bit/8][bit%8])-1;
        desiredbit = permutation[bit/8] & Positions[bit%8];
        if (desiredbit != 0) {
              desiredbit = Positions[newpos%8];
              inverse[newpos/8] = desiredbit ^ inverse[newpos/8];
        }
  }

 printf("\n Reverse Permutation: \n");
  for (i = 0; i < 8; i++) {
        printf(" %c", inverse[i]);
  }

  return 0;

}


person Steinin    schedule 07.02.2012    source источник
comment
Что он делает правильно? Где он начинает терпеть неудачу?   -  person KevinDTimm    schedule 07.02.2012


Ответы (1)


  1. Ваша перестановка содержит индексы от 1 до 64, но то, как вы их используете, должно быть от 0 до 63.
  2. На что обмен? Если вы переставите, поменяете местами, а затем переставите обратно, вы не окажетесь в одном и том же месте.
  3. Вам нужно убедиться, что перестановка и перестановка действительно являются противоположностями. Я точно не буду перебирать все цифры и проверять их.
person ugoren    schedule 07.02.2012
comment
1. Вы можете видеть, что все индексы вычитаются на 1, что превращает их в 0-63. 2. Багом оказался своп. Его следует использовать для окончательной перестановки, когда к начальной перестановке было применено 16 раундов шифрования. Удаление свопа решило проблему. 3. Таблицы правильные. Это точные копии таблиц, используемых в шифровании DES. [ссылка]en.wikipedia.org/wiki/ - person Steinin; 07.02.2012