a better way to optimize the code is to use multiplication by 2 concept(xtime).
xtime(x) is multiplication by 2 which is left-shift modulo irreducible polynomial ($x^8\oplus x^7\oplus x^6\oplus x\oplus1$ = 0x1C3)
xtime is implemented in c code with irreducible polynomial (0x1c3) as following
#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0xc3))
- = addition modulo 2(xor in code)
The binary representation of your values is as following:
16 : 00010000
32 : 00100000
133: 10000101
148: 10010100
192: 11000000
194: 11000010
251: 11111011
16*x (mul16) is as following
16 is $2^4$ (4 times left shift)-> mul16(x)=xtime(xtime(xtime(xtime(x)))). it can be rewritten as of mul8 as following xtime(mul8(x)). mul8 is defined as nested triple time
32*x (mul32) is as following
32 is $2^5$-> mul32(x)=xtime(xtime(xtime(xtime(xtime (x)))))= xtime(mul16(x)).
133*x = (128+4+1)x = 128*x+ 4*x + x;
= ($2^7 + 2^2 +1$)x = (mul128(x)^xtime(xtime(x))^x) = (mul128(x)^mul4(x))^x)
192= (128+64)x = mul128(x)^mul64(x)
194= (192+2)x = mul192(x)^xtime(x)
I will let you do the 148 and 251 multiplication, you can use the following code for assistance:
#include <stdio.h>
#include <stdint.h>
#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0xc3)) //P: x8⊕x7⊕x6⊕x⊕1
#define mul4(x) (xtime(xtime(x)))
#define mul8(x) (xtime(mul4(x)))
#define mul16(x) (xtime(mul8(x)))
#define mul32(x) (xtime(mul16(x)))
#define mul64(x) (xtime(mul32(x)))
#define mul128(x) (xtime(mul64(x)))&0xFF
#define mul133(x) (mul128(x)^xtime(xtime(x))^x)&0xFF
#define mul192(x) mul128(x)^mul64(x)&0xFF
#define mul194(x) mul192(x)^xtime(x)&0xFF
uint8_t gmul(uint8_t a, uint8_t b) {
uint8_t p = 0; /* the product of the multiplication */
while (a && b) {
if (b & 1) /* if b is odd, then add the corresponding a to p (final product = sum of all a's corresponding to odd b's) */
p ^= a; /* since we're in GF(2^m), addition is an XOR */
if (a & 0x80) /* GF modulo: if a >= 128, then it will overflow when shifted left, so reduce */
a = (a << 1) ^ 0x1c3; /* XOR with the primitive polynomial x^8 + x^4 + x^3 + x + 1 (0b1_0001_1011) – you can change it but it must be irreducible */
else
a <<= 1; /* equivalent to a*2 */
b >>= 1; /* equivalent to b // 2 */
}
return p;
}
int main(){
// printf("%x\n",mul16(0x06)&0xFF);
// printf("%x\n",mul32(0x06)&0xFF);
// printf("%x\n",mul32(0x22)&0xFF);
// printf("%x\n",gmul(0x22,32)&0xFF);
printf("---------\n");
printf("%x\n",mul128(0xf5)&0xFF);
printf("%x\n",gmul(0xf5,128)&0xFF);
printf("---------\n");
printf("%x\n",mul64(0xf5)&0xFF);
printf("%x\n",gmul(64,0xf5)&0xFF);
printf("---------\n");
printf("%x\n",mul192(0x35)&0xFF);
printf("%x\n",gmul(192,0x35)&0xFF);
printf("---------\n");
printf("%x\n",mul133(0x35)&0xFF);
printf("%x\n",gmul(133,0x35)&0xFF);
printf("---------\n");
printf("%x\n",mul194(0xe5)&0xFF);
printf("%x\n",gmul(194,0xe5)&0xFF);
return 0;
}