0

Consider a slightly modified variant of the Gimli SP-box:

function spbox(s) {
    x = s[0];
    y = s[1];
    z = s[2];
    X = x ^ (z << 1) ^ ((x ^ (y | ~z)) << 1);  
    Y = y ^ x ^ ((y ^ (x | z)) << 1);
    Z = z ^ y ^ ((z ^ (x & y)) << 1);
    return [Z, Y, X]
}

Here s is an array of three $32$-bit words, ^ is the bitwise XOR, | is the bitwise OR, & is the bitwise AND, ~ is the bitwise NOT, << is the left non-cyclic shift modulo $2^{32}$:

~11000000000000000000000000000000 = 00111111111111111111111111111111,
11000000000000000000000000000000 << 1 = 10000000000000000000000000000000.

What is the inverse function of spbox (in the C-like pseudocode)?

lyrically wicked
  • 1,379
  • 7
  • 11

1 Answers1

3

First, note that (z << 1) ^ ((x ^ (y | ~z)) << 1) can be simplified to the shorter ~(x ^ (y & z)) << 1.

The trick is to start from the least significant bit. When considering only the least significant bit, we have $$ \begin{align} x_0 &= X_0 \\ y_0 &= Y_0 \oplus x_0 \\ z_0 &= Z_0 \oplus y_0 \end{align} $$ The next bits are also obtainable similarly by using the newly recovered least significant bits: $$ \begin{align} x_i &= X_i \oplus 1 \oplus x_{i-1} \oplus (y_{i-1} \land z_{i-1}) \\ y_i &= Y_i \oplus x_i \oplus y_{i-1} \oplus (x_{i-1} \lor z_{i-1}) \\ z_i &= Z_i \oplus y_i \oplus z_{i-1} \oplus (x_{i-1} \oplus y_{i-1}) \end{align} $$ Putting this together into pseudocode, we get

function ispbox(s) {
    X = s[2];
    Y = s[1];
    Z = s[0];
    x = X & 1;
    y = (Y ^ x) & 1;
    z = (Z ^ y) & 1;
    for(i = 1; i < 32; ++i) {
        x |= (1 << i) & (X ^ ~(x ^ (y & z)) << 1);
        y |= (1 << i) & (Y ^ x ^ (y ^ (x | z)) << 1);
        z |= (1 << i) & (Z ^ y ^ (z ^ (x & y)) << 1);
    }
    return [x,y,z];
}
Samuel Neves
  • 12,960
  • 46
  • 54