javaencryptionfeistel-cipher

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


Solution

  • 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.