3
$\begingroup$

The Blowfish cipher uses a so called F-function which uses S-Boxes (S[i], i=0,1,2,3) to chiffre an integer x, for which I've seen different versions:

  1. source:

    uint32_t F (uint32_t x) {
        uint32_t h = S[0][x >> 24] + S[1][x >> 16 & 0xff];
        return ( h ^ S[2][x >> 8 & 0xff] ) + S[3][x & 0xff];
    }
    
  2. source:

    uint32_t F (uint32_t x) {
        uint32_t h = S[0][x >> 24] + S[1][x >> 16 & 0xff] % (2**32);
        return ( h ^ S[2][x >> 8 & 0xff] ) + S[3][x & 0xff] % (2**32);
    }
    

F should output a 32 bit value. The second version tries to handle overflows - although I dont see how this works when the values in the S-Boxes itself are 32 bit.

I realize this also depends on the language in which the cipher is implemented.

If we're assuming to implement it in C, the high bytes in case of an overflow in S[0][x >> 24] + S[1][x >> 16 & 0xff] would just be cut off.

Is this just the way it should work for the F-function?

$\endgroup$
  • 1
    $\begingroup$ $\mod {2^{32}}$ should be expected for uint32 values, I don't see any reason why % (2**32) would do anything at all. $\endgroup$ – Maarten Bodewes Jan 3 '16 at 15:39
  • 1
    $\begingroup$ It seems to me that you've misinterpreted the pseudocode here while translating it to C: the code is clearly using x + y mod 2**32 to mean "add x and y modulo 2**32", or, in other words, "add x and y using 32-bit integer arithmetic" -- not "reduce y modulo 2**32 and add the result to x" like your C code reads. $\endgroup$ – Ilmari Karonen Jan 3 '16 at 16:37
  • $\begingroup$ Well, thanks, that explains that part. Overflows in 32-bit integer arithmetic will occur, though - that's just how it works for the blowfish algorithm? $\endgroup$ – John H. K. Jan 3 '16 at 17:10
  • $\begingroup$ To be exact: the expression expr1 + expr2 in C where both expr1 and expr2 are 32-bits is not guaranteed to "cut off ... high bytes"; it's entirely legal (though currently rare) for int to be wider than (and rank above) 32 bits. What is guaranteed is assigning or returning to uint32_t (assuming the standard-specified type not a user-made-up one); those do force modulo for a narrower unsigned integer -- but not signed. This is one of the reasons C is not as good for bitbashing crypto pseudocode as some believe. $\endgroup$ – dave_thompson_085 Jan 3 '16 at 17:15