Frage Das Netzwerk von Multiplier Feistel in Java


Für einige Studenten muss ich ein Feistel-Netzwerk in Java implementieren.

Ich begann mit 3 manuellen Runden, so:

    // round 1
    int[] left1 = right;
    int[] right1 = new int[right.length];

    for(int i = 0; i < right.length; i++){
        right1[i] = left[i] ^ (right[i] ^ keys[0]);
    }

    // round 2
    int[] left2 = right1;
    int[] right2 = new int[right.length];

    for(int i = 0; i < right.length; i++){
        right2[i] = left1[i] ^ (right1[i] ^ keys[1]);
    }

    // round 3
    int[] left3 = right2;
    int[] right3 = new int[right.length];

    for(int i = 0; i < right.length; i++){
        right3[i] = left2[i] ^ ( right2[i] ^ keys[2]);
    }

Wenn ich 10 Runden haben möchte, müsste ich dieses Zeug 10 Mal kopieren und die Variablen anpassen, gibt es einen besseren Weg, dies zu tun? Vielleicht ist es zu spät, aber ich kann mir keine Lösung vorstellen ...


5
2018-05-13 00:29


Ursprung


Antworten:


Sie können einfach einen Rückwärtswechsel durchführen:

//initialization
int[] left = {};//setup left
int[] right = {};//setup right
//keys
int[] keys = {};//setup keys

for(int r = 0; r < 10; r++) {//the number of rounds
    for(int i = 0; i < right.length; i++){
        right[i] = left[i] ^ (right[i] ^ keys[r]);
    }

    //swap lists to do the next round
    int[] temp = left;
    left = right;
    right = temp;
}
//remark: the result (right) will be stored in left
//use left as resulting right

Nach jeder Runde tauscht man auf Referenzniveau (links und rechts) um temp) um Referenz temporär zu speichern:

int[] temp = left;
left = right;
right = temp;

Beachten Sie, dass Sie nicht Kopieren Die Werte hier, man tauscht einfach Referenzen aus, dies geschieht also in konstanter Zeit. Dies kann nützlich sein, wenn Sie lange Nachrichten verschlüsseln / entschlüsseln wollen und keine Zeit mit dem erneuten Kopieren verschwenden möchten.

Also, was passiert ist, haben Sie zunächst drei Listen L, R und K

In der ersten Runde modifizierst du einfach die Liftliste elementweise, wie du es in deinem Code gezeigt hast:

for(int i = 0; i < right.length; i++){
    right[i] = left[i] ^ (right[i] ^ keys[r]);
}

Wichtig ist, dass Sie nicht schreiben keys[i], aber benutze es keys[r] (Der Index ist die aktuelle Runde): Es bedeutet, dass Sie mindestens haben 10 Schlüssel, um die Arithmetik natürlich zu tun.

Beachten Sie, dass Sie überschreiben können right[i] weil Sie diesen Wert später nicht wiederverwenden. Sie können also Inline-Änderungen vornehmen.

Nach den Änderungen tauschen Sie die Puffer aus. Der einzige Aspekt, den Sie berücksichtigen müssen, ist, dass für die letzte Runde nach der Operation auch die Puffer ausgetauscht werden. Also das Letzte left und right wird auch getauscht werden. Sie können entweder (1) einen zusätzlichen Swap nach der for-Schleife ausführen; oder (2) den Swap berücksichtigen und vorgeben left ist right und umgekehrt; oder (3) benutze ein if-Klausel, um den letzten Austausch zu verhindern.


6
2018-05-13 00:46



Verwenden Sie ein zweidimensionales Array

int rounds = 10 // number of rounds
int leftArray = new int[rounds][right.length];
int rightArray = new int[rounds][right.length];

Dann:

  • leftArray[0][0] ist äquivalent zu left1[0];
  • leftArray[0][1] ist äquivalent zu left1[1];
  • rightArray[0][0] ist äquivalent zu right1[0];
  • rightArray[2][2] ist äquivalent zu right3[2];
  • ...

Verwenden Sie dann eine verschachtelte Schleife, um die Dinge zu wiederholen, die Sie tun müssen

for(int i=0; i<rouds; i++){
  //set your variables
  for(int j=0; j<right.length; j++){
  //do computation here
  }
}

1
2018-05-13 01:55