[英]Generating reverse element in Galois Field
我有一個伽羅瓦域GF(2^409)
和不可約多項式f(x) = x^409 + x^15 + x^6 + x + 1
,其中系數只能是 1 或 0
如果我有這個字段a(x)
一些元素a(x)
,我怎么能找到反向元素a_1(x)
,這樣
a(x) * a_1(x) = 1 (mod f(x))
使用擴展 Euklid 算法
我正在使用多項式基礎
我知道我可以只使用pow(a(x),2^409 - 2)
找到a_1(x)
,但是我使用的是 Python,並且電源操作需要太多時間
我在定義多項式下的除法運算時遇到了麻煩(沒有它我不能使用擴展 Euklid 算法)
一種常見的方法來表示GF(2 k)的元素將是使用一個大的整數( long
在Python 2, int
在Python 3),並讓每一個比特代表一個系數。 要執行多項式除法,您基本上可以按照長除法的步驟操作,就像用紙筆執行它們一樣。
讓我們舉一些更簡單的例子。 取模數為 x 7 + x + 1 的 GF(2 7 )。讓我們試着找出 x 6 + x 3 + x 的倒數。 所以你必須使用擴展的歐幾里德算法來計算這兩個多項式的 GCD。 第一步是計算一個的商和余數。 即較大度數除以較小度數。
x 6 + x 3 + x 是 1x 6 + 0x 5 + 0x 4 + 1x 3 + 0x 2 + 1x 1 + 0x 0或1 0 0 1 0 1 0
簡而言之。 根據相同的約定,模數為1 0 0 0 0 0 1 1
。 所以你分
1 0 0 0 0 0 1 1 / 1 0 0 1 0 1 0 = 1 0 remainder 1 0 1 1 1
1 0 0 1 0 1 0
1 0 1 1 1
那么我在這里做了什么? 將a除以b我尋找每個這些中的最高設置位,即多項式的次數。 這些度數之間的差異是我想在商中設置的一點。 在這種情況下, a 的階數為 7, b的階數為 6。差為 1,因此商必須具有項 x 1 。 現在我寫下b乘以那個項,在這種情況下,它只是b的二進制表示,左移了度數差)。 然后我從原來的a 中減去那個移位的值,但是我在 𝔽 2 [x] 中做減法,所以它實際上是一個異或運算。 那結果是一個新的號碼,這是我作為一個在未來的迭代中值使用。 我繼續直到度數的差異變為負數,即我將較小度數的多項式除以較大度數之一。 然后我就完成了, a的最后一個值是我的余數。 在上面的划分中,我一步完成。
通過這個執行帶余數除法的操作,您應該能夠找出歐幾里得算法。 擴展版本需要更多的工作,但請嘗試一下。 最后,您應該能夠發現,在上面給出的示例中,逆是 x 3 + x + 1(由 Sage 計算)。 為了進行比較,原始字段 GF(2 409 ) 中 x 6 + x 3 + x 的倒數將是
"+".join("x^{}".format(i) for i in range(409,-1,-1) if (1 << i) & 71418312917235914488287388787154746126088900129923309868417397199063993100653429184865046255190862140902867842544110449930)
我在 Sage 中計算的這個數字:
x = polygen(ZZ)
m = x^ 409 + x^15 + x^6 + x + 1
F409 = GF(2^409, name="z", modulus=p)
z = F409.gen()
(1/(z^6+z^3+z)).polynomial().change_ring(ZZ)(2)
您可以使用 SymPy 和這個很棒的答案來處理有限域。
您在n = 2
的環Z/nZ
,因此您想使用鏈接答案中的GF
類:
>>> %time field = GF(2, 409)
CPU times: user 1min 47s, sys: 6.64 ms, total: 1min 47s
Wall time: 1min 47s
如您所見, GF(2, 409)
的初始化時間很長(~= 1-2 分鍾)...
...但乘法反轉的計算幾乎是即時的:
%%time
import numpy as np
# list of 410 coefficients regarding x^409 (left-most) up to x^0 (right-most)
coeffs = [0] * 410
for idx in [0, 1, 6, 15, 409]: # exponents present in your polynome
coeffs[409 - idx] = 1 # set to 1 to indicate existence
li = []
for i in range(4):
'''
To help SymPy make the polynome `x^409 + x^15 + x^6 + x + 1`,
provide the `GF.inv()` method with its coefficients using `ZZ.map()`
Actually, `inv()` will call `sympy.polys.galoistools.gf_gcdex()`
'''
coeffs = field.inv(ZZ.map(coeffs))
li.append(np.array(coeffs))
CPU times: user 37.3 ms, sys: 2 µs, total: 37.3 ms
Wall time: 36 ms
GF.inv()
返回的結果是反演系數的數組。 請注意,再次重新應用反演將恢復為原始多項式:
>>> print(np.equal(li[0], li[2]).all() and np.equal(li[1], li[3]).all())
True
您還可以驗證p(x) * p(x)^(-1) = 1
:
>>> field.mul(li[0], li[1])
[1] # Ok !
下面是從引用的答案中刪除的代碼,只有你需要的反演:
import itertools
from sympy.polys.domains import ZZ
from sympy.polys.galoistools import (gf_irreducible_p, gf_gcdex)
from sympy.ntheory.primetest import isprime
class GF():
def __init__(self, p, n=1):
p, n = int(p), int(n)
if not isprime(p):
raise ValueError("p must be a prime number, not %s" % p)
if n <= 0:
raise ValueError("n must be a positive integer, not %s" % n)
self.p = p
self.n = n
if n == 1:
self.reducing = [1, 0]
else:
for c in itertools.product(range(p), repeat=n):
poly = (1, *c)
if gf_irreducible_p(poly, p, ZZ):
self.reducing = poly
break
def inv(self, x):
s, t, h = gf_gcdex(x, self.reducing, self.p, ZZ)
return s
GF(2, 409).inv(ZZ.map(coeffs))
我有一個Galois字段GF(2^409)
和不可約多項式f(x) = x^409 + x^15 + x^6 + x + 1
,其系數只能是1或0
如果我有此字段a(x)
某個元素,如何找到反向元素a_1(x)
,使得
a(x) * a_1(x) = 1 (mod f(x))
使用擴展的Euklid算法
我使用多項式基礎
我知道我可以使用pow(a(x),2^409 - 2)
a_1(x)
來找到a_1(x)
,但是我正在使用Python,並且冪運算需要太多時間
我在定義多項式下的除法運算時遇到了麻煩(沒有它,我將無法使用擴展Euklid算法)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.