1

I'm coding AES Invert mixcolumns operation and I need to multiply numbers by 14 in GF(256). This is what I have come up with (p is the result and q the number to multiply by 14):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
int main()
{
    uint8_t p=1, q=0x02;
    p = (q<<1) ^ (q<<2) ^ (q<<3);//*(x³+x²+x)
    //modulo x⁸+x⁴+x³+x+1
    if((q>>5)<5&&(q>>5)!=0&&(q>>5)!=3)
        p^=0x1B;
    if((q>>5)>1&&(q>>5)<6)
        p^=0x36;
    if((q>>5)>3)
        p^=0x6C;
    printf("\n\n\t%2.2X\n\n",p);
    return 0;
}

It works but I think there is a simpler way to do this but I cannot seem to find it. My main issue here is that I make 6 comparisons.

2A-66-42
  • 554
  • 1
  • 5
  • 18
  • I don't understand the need for comparisons, but is there more to the code than you are asking since it contains the comment `//modulo`? But multiplying by 14 is simple, 14 = 8 + 4 + 2, so `p = (q << 3) + (q << 2) + (q << 1);` – Weather Vane Sep 15 '16 at 17:42
  • No in GF(256) you need to reduce the multiplication modulo an irreducible polynom which is x⁸+x⁴+x³+x+1 as specified by the AES standard. – 2A-66-42 Sep 15 '16 at 18:25

1 Answers1

2

My main issue here is that I make 6 comparisons.

Use look-up table to avoid all compares. q>>5 is only 3 bits.

static const uint8_t Table1B[8] = { 0, 0x1B, 0x1B, 0, 0x1B, 0, 0, 0 };
static const uint8_t Table36[8] = { 0, 0, 0x36, 0x36, 0x36, 0x36, 0, 0 };
static const uint8_t Table6C[8] = { 0, 0, 0, 0, 0x6C, 0x6C, 0x6C, 0x6C };

q >>= 5;
p ^= Table1B[q];
p ^= Table36[q];
p ^= Table6C[q];

Likely could simplify to 1 table: Table[0] = Table1B[0] ^ Table36[0] ^ Table6C[0], etc.

p ^= Table[q >> 5];
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Would that increase the performance? How does xoring 0 works machine code wise? – 2A-66-42 Sep 15 '16 at 18:42
  • @2A-66-42 "Would that increase the performance" Likely. Testing (profiling) would show. To determine, you need to provide platform, compiler, options used and a complete test case code. "How does xoring 0 works machine code wise?" `p ^= some_variable_that_happens_to_be_0` takes as much time as `p ^= any_variable`. `p ^= a_constant_0;` is certainly optimized out to a NOP. – chux - Reinstate Monica Sep 15 '16 at 19:17