Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutliround Feistel network in Java

For some student stuff I need to implement a Feistel network in Java.

I started with 3 manual rounds, like this:

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

If I want to have 10 rounds I would need to copy this stuff 10 times and adjust the variables, is there a better way to do this? Maybe it's too late but I can't think of a solution...

like image 317
fsp Avatar asked May 13 '15 00:05

fsp


People also ask

How many rounds are there in Feistel cipher?

A typical size is 16 rounds."

What is round function in Feistel cipher?

A Feistel network uses a round function, a function which takes two inputs – a data block and a subkey – and returns one output of the same size as the data block. In each round, the round function is run on half of the data to be encrypted, and its output is XORed with the other half of the data.

Are the all rounds in a Feistel network the same?

In real implementation of the Feistel Cipher, such as DES, instead of using the whole encryption key during each round, a round-dependent key (a subkey) is derived from the encryption key. This means that each round uses a different key, although all these subkeys are related to the original key.

Why is AES not Feistel?

AES is not a Feistel cipher because the operations in AES are not invertible.


1 Answers

You can simply swap forward an backwards:

//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

After each round, you swap left and right by doing so at reference level (and use temp) to store reference temporary:

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

Note that you don't copy the values here, you simply swap references, this is thus done in constant time. This can be useful if you want to encrypt/decrypt long messages and don't want to waste time copying again.

So what happens is, you initially have three lists L, R and K

Now in the first round, you simply modify the lift list, element-wise as you have shown in your code:

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

Important is that you don't write keys[i], but use keys[r] (the index being the current round): it implies you have at least 10 keys to do the arithmetic of course.

Note that you can overwrite right[i] because you don't reuse that value later. You can thus do inline modifications.

After the modifications, you swap the buffers. The only aspect you need to take into account is that for the last round, after doing the operation, the buffers will be swapped as well. Thus the last left and right will be swapped as well. You can either (1) do an additional swap after the for loop; or (2) take the swap into account and pretend left is right and vice versa; or (3) use an if-clause to prevent the last swap.

like image 147
Willem Van Onsem Avatar answered Sep 21 '22 18:09

Willem Van Onsem