pyfinite 在字段 GF(2^8) 中给出错误的乘法结果

pyfinite gives wrong result for multiplication in field GF(2^8)

我正在使用 pyfinte 来计算 AES 在它使用的字段上的乘法,即 F(2^8) 但是当我执行以下操作时:

from pyfinite import ffield

a = 0xbf
b = 0x03
F = ffield.FField(8)
c = F.Multiply(a, b)
print(hex(c))

实际结果是0xdc,但应该是0xda,我是这样手工解决的:

0xbf*0x03 = 0xbf * 0x02 + 0xbf * 0x01 = 0b10111111 * 0x02 + 0xbf = 0b01111110 + 0x1B + 0xbf = 0b11011010 = 0xda

这是我手牌独奏的更好格式:

所以哪里错了?是我手工解决的吗?或者在 pyfinite 中?如何解决?

我对 AES 不是很熟悉,但是从您提供的 link 来看,该字段的生成多项式似乎是 0x11b。默认情况下,pyfinite 使用不同的生成器,这将产生不同的乘法结果:

>>> f = ffield.FField(8)
>>> hex(f.generator)
'0x11d'

如果您在创建字段对象时指定生成器,您会得到预期的结果:

>>> f = ffield.FField(8, gen=0x11b, useLUT=0)
>>> hex(f.Multiply(0xbf, 0x03))
'0xda'

问题是 AES 对其扩展字段使用不可约但不是原始的多项式。大多数扩展字段使用原始多项式,因此 x 是该字段的原始元素。我想这就是 pyfinite 的默认设置。

相反,AES 使用 x^8 + x^4 + x^3 + x + 1 作为其不可约多项式,并将 x + 1 作为原始元素(或乘法群的生成器)。

虽然我不知道 pyfinite 的细节,但我创建了一个类似的库 galois that extends NumPy arrays to operate over Galois fields. It supports arbitrarily-sized array arithmetic, linear algebra on Galois field matrices, polynomials over Galois field, and more. The library is written in Python but JIT compiled using Numba so the array arithmetic is as fast as native NumPy

这是一个按照您的要求执行的示例。

In [1]: import galois                                                                                                                                                                          

In [2]: GF = galois.GF(2**8, irreducible_poly=0x11b)                                                                                                                                           

In [3]: print(GF.properties)                                                                                                                                                                   
GF(2^8):
  characteristic: 2
  degree: 8
  order: 256
  irreducible_poly: x^8 + x^4 + x^3 + x + 1
  is_primitive_poly: False
  primitive_element: x + 1

In [4]: a = GF(0xbf); a                                                                                                                                                                        
Out[4]: GF(191, order=2^8)

In [5]: b = GF(0x03); b                                                                                                                                                                        
Out[5]: GF(3, order=2^8)

In [6]: a * b                                                                                                                                                                                  
Out[6]: GF(218, order=2^8)

In [7]: 0xda                                                                                                                                                                                   
Out[7]: 218