2

私は現在、暗号化スキーム 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;

}

4

1 に答える 1

1
  1. 順列には 1 から 64 までのインデックスが含まれていますが、それらを使用する方法では、それらは 0 から 63 である必要があります。
  2. 何のための交換ですか?並べ替え、入れ替え、元に戻すと、同じ場所には到達しません。
  3. 順列と逆が実際に反対であることを確認する必要があります。すべての数字を調べて検証するつもりはありません。
于 2012-02-07T19:05:16.533 に答える