Search code examples
java-meaes

Is my implementation of MixColumns correct?


I'm trying to implement AES in J2ME, I've implemented mine based on the C# example on Wikipedia: https://en.wikipedia.org/wiki/Rijndael_MixColumns#Implementation_example My AES implementation is giving incorrect results and this is the code I'm least confident in so I'd like to make sure it's correct:

state is an array of bytes storing the state matrix in column major order.

  public void mix_columns() {
    byte[] new_state = new byte[16];

    for (int i = 0; i < 4; i++) {
      new_state[0|(i<<2)] = (byte)(
        galois_field_multiply((byte)0x02, state[0|(i<<2)]) ^
        galois_field_multiply((byte)0x03, state[1|(i<<2)]) ^
        state[2|(i<<2)] ^
        state[3|(i<<2)]
      );
      new_state[1|(i<<2)] = (byte)(
        state[0|(i<<2)] ^
        galois_field_multiply((byte)0x02, state[1|(i<<2)]) ^
        galois_field_multiply((byte)0x03, state[2|(i<<2)]) ^
        state[3|(i<<2)]
      );
      new_state[2|(i<<2)] = (byte)(
        state[0|(i<<2)] ^
        state[1|(i<<2)] ^
        galois_field_multiply((byte)0x02, state[2|(i<<2)]) ^
        galois_field_multiply((byte)0x03, state[3|(i<<2)])
      );
      new_state[3|(i<<2)] = (byte)(
        galois_field_multiply((byte)0x03, state[0|(i<<2)]) ^
        state[1|(i<<2)] ^
        state[2|(i<<2)] ^
        galois_field_multiply((byte)0x02, state[3|(i<<2)])
      );
    }

    state = new_state;
  }

Solution

  • The implementation is correct, looking on the page there is a section with some test vectors. Each column of the input can be tested individually with one of these test vectors and these provide the correct results. For example, you can provide the following state:

            (byte)0xDB, (byte)0x13, (byte)0x53, (byte)0x45,
            (byte)0xDB, (byte)0x13, (byte)0x53, (byte)0x45,
            (byte)0xDB, (byte)0x13, (byte)0x53, (byte)0x45,
            (byte)0xDB, (byte)0x13, (byte)0x53, (byte)0x45,
    

    and it will provide the value:

            (byte)0x8E, (byte)0x4D, (byte)0xA1, (byte)0xBC,
            (byte)0x8E, (byte)0x4D, (byte)0xA1, (byte)0xBC,
            (byte)0x8E, (byte)0x4D, (byte)0xA1, (byte)0xBC,
            (byte)0x8E, (byte)0x4D, (byte)0xA1, (byte)0xBC,