Search code examples
c++11hexcodeblocksmatrix-multiplication

Incorrect hexadecimal matrix multiplication results


matrix 1:

0x02 0x03 0x01 0x01

0x01 0x02 0x03 0x01

0x01 0x01 0x02 0x03

0x03 0x01 0x01 0x02

matrix 2:

0x63 0x53 0xe0 0x8c

0x09 0x60 0xe1 0x04

0xcd 0x70 0xb7 0x51

0xba 0xca 0xd0 0xe7

These two matrices are multipled in this function:

void mul(uint8_t state[4][4])
{
    for(unsigned short i = 0; i < 4; i++)
    {
        state [0][i] = byteProduct(0x02 ,state[0][i]) ^ byteProduct(0x03, state[1][i]) ^ state[2][i] ^ state[3][i];
        state [1][i] = state[0][i] ^ byteProduct(0x02, state[1][i]) ^ byteProduct(0x03, state[2][i]) ^ state[3][i];
        state [2][i] = state[0][i] ^ state[1][i] ^ byteProduct(0x02, state[2][i]) ^ byteProduct(0x03, state[3][i]);
        state [3][i] = byteProduct(0x03, state[0][i]) ^ state[1][i] ^ state[2][i] ^ byteProduct(0x02, state[3][i]);
    }
}

In this function I've taken matrix 2 column by column and individually multiplied with the values of the rows of matrix 1. And the value should be replaced in the state matrix.

ByteProduct is defined as:

uint8_t byteProduct(uint8_t x, uint8_t y)
{
    uint8_t result = 0, temp;

    while(x != 0)
    {
        if((x & 1) != 0)
            result ^= y;

        temp = y & 0x80;
        y <<= 1;

        if(temp != 0)
            y ^= 0x1b;

        x >>= 1;
    }

    return result;
}

The result should be :

0x5f 0x72 0x64 0x15

0x57 0xf5 0xbc 0x92

0xf7 0xbe 0x3b 0x29

0x1d 0xb9 0xf9 0x1a

But the mamtrix resulting from the function is different from this.
Any solutions to this?

Note that these calculations are performed in GF(2^8) field, hence don't try to use + and * operators, rather ^ is used for + operator and byteProduct() functions returns the multiplication of uint8_ts.

I've performed row x column multiplication.


Solution

  • Do not fill values into one of the matrixes you are still using for calculation.
    Make a copy of it first or fill a new matrix.
    Otherwise you will compromise the values you still use for calculation.

    E.g.

        state [0][i] = byteProduct(0x02 ,state[0][i]) ^ byteProduct(0x03, state[1][i]) ^ state[2][i] ^ state[3][i];
        state [1][i] = state[0][i] ^ byteProduct(0x02, state[1][i]) ^ byteProduct(0x03, state[2][i]) ^ state[3][i];
    

    The first line already overwrites the value of state [0][i] and then the second line uses it again to calculate the state [1][i].