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

时间:2019-01-04 13:19:21

标签: python aes finite-field

我正在使用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

这是我的手爱抚的更好形式:

enter image description here

那哪里错了?是我手工解决的吗?还是在pyfinite中?该如何解决?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:0)

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

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

虽然我不知道 pyfinite 的详细信息,但我创建了一个类似的库 galois,它扩展了 NumPy 数组以对 Galois 字段进行操作。它支持任意大小的数组算术、伽罗瓦域矩阵上的线性代数、伽罗瓦域上的多项式等。该库是用 Python 编写的,但使用 Numba 进行 JIT 编译,因此数组算法是 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