我正在C#中实现AES,并且在某些时候(MixColumns函数),我必须在GF(2 ^ 8)有限字段上乘以两个字节。

因此,我有三个选择:


使用dotNet具有的默认功能(它具有类似的功能吗?)
编写一个自定义函数
使用查询表


对于自定义函数,我找到了一段C代码,我试图用C#重写它,但是它不起作用(我得到错误的结果)。 (*)

这是原始的C代码(source):

/* Multiply two numbers in the GF(2^8) finite field defined
 * by the polynomial x^8 + x^4 + x^3 + x + 1 */
uint8_t gmul(uint8_t a, uint8_t b) {
        uint8_t p = 0;
        uint8_t counter;
        uint8_t hi_bit_set;
        for (counter = 0; counter < 8; counter++) {
                if (b & 1)
                        p ^= a;
                hi_bit_set = (a & 0x80);
                a <<= 1;
                if (hi_bit_set)
                        a ^= 0x1b; /* x^8 + x^4 + x^3 + x + 1 */
                b >>= 1;
        }
        return p;
}


这是我改写的:

public Byte GMul(Byte a, Byte b) { // Galois Field (256) Multiplication
   Byte p = 0;
   Byte counter;
   Byte hi_bit_set;
   for (counter = 0; counter < 8; counter++) {
      if ((b & 1) != 0) {
         p ^= a;
      }
      hi_bit_set = (Byte) (a & 0x80);
      a <<= 1;
      if (hi_bit_set != 0) {
         a ^= 0x1b; /* x^8 + x^4 + x^3 + x + 1 */
      }
      b >>= 1;
   }
   return p;
}


我还找到了一些查找表here,这似乎是一种简单且不错的方法,但是尽管我有预感,但我真的不知道如何使用它们。 (**)

底线:鉴于上面我所写的内容,到目前为止,我应该选择哪个选项,以及如何使它起作用,而且我真的不希望深入了解数学知识。

更新:

*)同时,我意识到我的C#重写代码正在产生正确的答案,这只是我的错,因为我在验证它们时搞砸了。

**)这些表可以用作Byte [256]数组,而x*3的答案是table_3[x]x在用作表数组的索引时将从十六进制转换为DECIMAL。

最佳答案

为了在GF(2)中乘以x * 3,只需访问x = table_3 [x];

可能存在一种使用对数方法的3查找表方法。

就像常规数a * b = 2 ^(log2(a)+ log2(b))一样,GF(2)中也会发生同样的情况,但是没有浮点数或舍入误差。

10-08 01:01