尋找有限域同構映射


一、有限域簡介

有限域亦稱伽羅瓦域(Galois Fields),是伽羅瓦於 18 世紀 30 年代研究代數方程根式求解問題時引出的概念。有限域在密碼學、近代編碼、計算機理論、組合數學等方面有着廣泛的應用

在抽象代數中,域是一個對加法和乘法封閉的集合,其中要求每個元素都有加法逆元,每個非零元素都有乘法逆元。若域 \(F\) 只包含有限個元素,則稱為有限域,有限域中元素的個數稱為有限域的階。可以證明,有限域的階必為素數的冪,即有限域的階可表示為 \(p^n\)\(p\) 是素數,\(n\) 是正整數)。有限域通常記為 \(GF(p^n)\)

二、有限域同構

因為網上似乎都沒有如何尋找有限域同構映射的資料,而正好我上課學到了相關的內容,在此結合自己的理解作簡單的介紹。因為不是數學系相關的學生,而且對有限域的理解僅處於皮毛,有很多定理沒辦法給出詳細的證明,在邏輯上或許會多有漏洞,如果讀者發現我的漏洞希望能夠指出。
(雖然指出了我也不一定能聽懂,但還是希望能夠指出)

另外,有限域的相關知識(例如有限域的性質,有限域的構造等)將默認讀者已經了解,在閱讀后續內容前先保證對上述知識有所了解

關於復合域強烈建議參考這篇博客: AES 和 SM4 S 盒復合域實現方法,本文提到的內容參考了論文《適合SMS4算法硬件實現的S盒構造新方法》中給出的求解同構映射的方法 (--- 2022.04.28 更新 ---)

上面的鏈接好像打不開了,不過我在github上好像找到了對應的作者,SM4-with-AESENCLAST 這個鏈接是對應的資料。
很多尋找有限域同構的方法采用的都是正規基之類的,但我這塊不是很了解,可能沒法給各位滿意的答復。我這里提到的方法是《適合 SMS4 算法硬件實現的 S 盒構造新方法》(徐艷華、白雪飛、郭立)這篇論文中的采用的方法,但論文里邊原理部分感覺不是很清楚。這篇博客是我根據上課學到的內容結合自己的理解寫的,原理上應該會有紕漏 (--- 2022.12.27 更新 ---)

關於復合域優化SM4算法強烈建議參考下方論文: (--- 2023.05.27 更新 ---)
[1] 陳晨,郭華,王闖等.一種基於復合域的國密SM4算法快速軟件實現方法[J].密碼學報,2023,10(02):289-305.

2.1 尋找同構映射思路

首先,任意相同階數的有限域都同構。假設 \(p(x)\)\(q(x)\) 都是域 \(F_p\) 上的 \(n\) 階不可約多項式,那么有限域 \(F_1 = F_p[x] / p(x)\)\(F_2 = F_p[x] / q(x)\) 都是 \(p^n\) 階有限域。

有下面兩條重要定理:

  • 如果假設 \(\alpha\) 是多項式 \(p(x)\) 的一個根,那么有限域 \(F_1\) 可以表示成 \(F_p[\alpha]\)
  • 如果假設 \(\beta\) 是多項式 \(q(x)\) 的一個根,那么有限域 \(F_2\) 可以表示成 \(F_p[\beta]\)

現在需要找到一個兩者的同構映射 \(\phi\)
首先,根 \(\alpha\)\(\beta\) 滿足 \(p(\alpha)=0\)\(q(\beta)=0\)
直接將 \(\alpha\) 映射到 \(\beta\) 是不可行的,因為線性關系無法保證,即無法保證 \(p(\beta)=0\)
那么如果找到 \(\beta ' \in F_p[\beta]\) 使得 \(p(\beta')=0\) 成立,這樣就可以構造 \(\alpha \to \beta '\) 的映射

2.2 尋找同構映射例子

求有限域 \(Z_3[x] / (x^2 + 1)\)\(Z_3[x] / (x^2 + x +2)\) 之間的同構映射

\(p(x) = x^2 + 1\)\(q(x) = x^2 + x + 2\)
且有 \(\alpha = \overline{x} \; mod \; p(x)\)\(p(x)\) 的一個根
且有 \(\beta = \overline{x} \; mod \; q(x)\)\(q(x)\) 的一個根

尋找得到 \(\beta' = \beta + 2\) ,使得 \(p(\beta') = (\beta + 2)^2 + 1 = \beta^2 + \beta + 2 = 0\)
那么對應的映射為 \(\alpha \to \beta + 2\)

也就是原先 \(Z_3[\alpha]\) 中的元素 \(a_1 \alpha + a_0\) 將被映射成 \(a_1 (\beta + 2) + a_0 = a_1 \beta + (2a_1 + a_0) \in Z_3[\beta]\)
或者說原先 \(Z_3[x] / (x^2 + 1)\) 中的元素 \(a_1 x + a_0\) 將被映射到 \(Z_3[x] / (x^2 + x +2)\) 中的 \(a_1 x + (2a_1 + a_0)\)

2.3 同構映射逆映射

在 2.2 中已經求出了一個同構映射 \(\alpha \to \beta + 2\)
很容易發現 \(q(\alpha - 2) = (\alpha - 2)^2 + (\alpha - 2) + 2 = \alpha^2 + 1 = 0\)

也就是說逆映射為 \(\beta \to \alpha - 2\)

三、復合域與同構

3.1 復合域

接下來介紹一個稍微復雜的有限域——復合域,復合域在密碼學中具有非常大的用途,將一個高階的有限域轉化為兩個或多個低階有限域的復合,便於后續分析

\(p(x) = x^2 + x + 4\)\(F_2[x] / p(x)\)\(2^2\) 階有限域
\(q(x) = x^4 + x^3 + 1\)\(F_2[x] / q(x)\)\(2^4\) 階有限域
那么將兩者復合得到 \(F : b_1 x + b_2 \; mod \; p(x), \; b_i \in F_2[x] / q(x)\) ,為 \((2^4)^2 = 2^8\) 階有限域(復合域)

3.2 復合域同構

通過一個例子來了解求復合域同構的過程

\(F_2[x] / r(x)\)\(2^8\) 階有限域, \(r(x) = x^8 + x^7 + x^6 + x^5 + x^4 + x^2 + 1\)

\(F[x] / (p(x), q(y)) = (a_3 y^3 + a_2 y^2 + a_1 y + a_0) x + (b_3 y^3 + b_2 y^2 + b_1 y + b_0)\) 為上述 3.1 中的 \((2^4)^2\) 階有限域

\(F_2[x] / r(x) \to F[x] / (p(x), q(x))\) 的一個同構映射

首先,需要遍歷 \(F[x] / (p(x), q(y))\) 的全部元素,找到其中一個 \(\beta'\) 滿足 \(r(\beta') = 0\) 的元素 \((y^2 + 1)x + (y^3 + y^2 + y)\)
\(\alpha = \overline{x} \; mod \; r(x)\)\(r(x)\) 的根
那么同構映射為 \(\alpha \to \beta'\)

四、映射矩陣

4.1 有限域與矩陣

在密碼學中,常將多項式表示為矩陣的形式,例如在 \(GF(2^8)\) 上的多項式

\[x^7 + x^6 + x + 1 \equiv \begin{bmatrix} 1 & 1 & 0 & 0 & 0 & 0 & 1 & 1 \end{bmatrix}^T \]

假設 \(p(x)\)\(q(x)\) 都是 \(F_2\) 上的 \(8\) 次不可約多項式,那么可以構成 \(2^8\) 階有限域 \(F_2[x]/p(x)\)\(F_2[x]/q(x)\)

假設 \(\alpha\) 是多項式 \(p(x)\) 的一個根,那么有限域 \(F_2[x]/p(x)\) 可以表示成 \(F_2[\alpha]\)
假設 \(\beta\) 是多項式 \(q(x)\) 的一個根,那么有限域 \(F_2[x]/q(x)\) 可以表示成 \(F_2[\beta]\)

且假設 \(c_7 x^7 + c_6 x^6 + c_5 x^5 + \cdots + c_1 x + c_0\)\(F_2[x]/p(x)\) 上的一個多項式,那么該多項式也可以等價於 \(c_7 \alpha^7 + c_6 \alpha^6 + c_5 \alpha^5 \cdots c_1 \alpha + c_0\) ,即

\[\begin{bmatrix} \alpha^7 & \alpha^6 & \alpha^5 & \alpha^4 & \alpha^3 & \alpha^2 & \alpha & 1 \end{bmatrix} \times \begin{bmatrix} c_7 & c_6 & c_5 & c_4 & c_3 & c_2 & c_1 & c_0\end{bmatrix}^T \]

4.2 多項式矩陣

假設 \(\alpha^i = a_{7,i} x^7 + a_{6,i} x^6 + \cdots a_{1,i} x + a_{0,i}\)

那么

\[\begin{bmatrix} \alpha^7 \\ \alpha^6 \\ \alpha^5 \\ \alpha^4 \\ \alpha^3 \\ \alpha^2 \\ \alpha \\ 1 \end{bmatrix}^T \equiv \begin{bmatrix} a_{7,7} & a_{7,6} & a_{7,5} & a_{7,4} & a_{7,3} & a_{7,2} & a_{7,1} & a_{7,0}\\ a_{6,7} & a_{6,6} & a_{6,5} & a_{6,4} & a_{6,3} & a_{6,2} & a_{6,1} & a_{6,0}\\ a_{5,7} & a_{5,6} & a_{5,5} & a_{5,4} & a_{5,3} & a_{5,2} & a_{5,1} & a_{5,0}\\ a_{4,7} & a_{4,6} & a_{4,5} & a_{4,4} & a_{4,3} & a_{4,2} & a_{4,1} & a_{4,0}\\ a_{3,7} & a_{3,6} & a_{3,5} & a_{3,4} & a_{3,3} & a_{3,2} & a_{3,1} & a_{3,0}\\ a_{2,7} & a_{2,6} & a_{2,5} & a_{2,4} & a_{2,3} & a_{2,2} & a_{2,1} & a_{2,0}\\ a_{1,7} & a_{1,6} & a_{1,5} & a_{1,4} & a_{1,3} & a_{1,2} & a_{1,1} & a_{1,0}\\ a_{0,7} & a_{0,6} & a_{0,5} & a_{0,4} & a_{0,3} & a_{0,2} & a_{0,1} & a_{0,0} \end{bmatrix} \]

\(\alpha = \overline{x} \; mod \; p(x)\) 時,上式為單位陣 \(I\)

4.3 同構映射與矩陣

假設 \(c_7 x^7 + c_6 x^6 + c_5 x^5 + \cdots + c_1 x + c_0\)\(F_2[x]/p(x)\) 上的多項式
假設 \(d_7 x^7 + d_6 x^6 + d_5 x^5 + \cdots + d_1 x + d_0\)\(F_2[x]/q(x)\) 上的多項式

記它們兩者的矩陣表示為 \(C\)\(D\)

要找到兩個域的映射關系,將一個多項式映射到另一個多項式
也就是要找到一個映射矩陣 \(T\) ,使得一個多項式的矩陣表示 \(C\) 和另一個多項式的矩陣表示 \(D\) 滿足 \(TC = D\)

上文提到,可以找到一個同構映射 \(\alpha \to \beta'\) ,使得有限域 \(F_2[\alpha]\) 和有限域 \(F_2[\beta]\) 同構

根據同構關系的線性性質,有 \(\alpha^i \to \beta'^i\) ,故映射為

\[c_7 \alpha^7 + c_6 \alpha^6 + c_5 \alpha^5 \cdots c_1 \alpha + c_0 \to c_7 \beta'^7 + c_6 \beta'^6 + c_5 \beta'^5 \cdots c_1 \beta' + c_0 \]

\(\alpha\) 對應的矩陣(如4.2所示)為 \(A\)\(\beta'\) 對應的矩陣為 \(B\)
那么映射矩陣 \(T\) 滿足 \(TAC = BC\) ,即 \(T= B A^{-1}\)

為了計算方便,一般選取的根 \(\alpha = \overline{x} \; mod \; p(x)\)
那么 \(\alpha\) 對應的矩陣 \(A\) 即為單位陣 \(I\)
那么 \(T = B\)

假設 \(\beta'^i = b_{7,i} x^7 + b_{6,i} x^6 + \cdots b_{1,i} x + b_{0,i}\)
那么

\[T = \begin{bmatrix} b_{7,7} & b_{7,6} & b_{7,5} & b_{7,4} & b_{7,3} & b_{7,2} & b_{7,1} & b_{7,0}\\ b_{6,7} & b_{6,6} & b_{6,5} & b_{6,4} & b_{6,3} & b_{6,2} & b_{6,1} & b_{6,0}\\ b_{5,7} & b_{5,6} & b_{5,5} & b_{5,4} & b_{5,3} & b_{5,2} & b_{5,1} & b_{5,0}\\ b_{4,7} & b_{4,6} & b_{4,5} & b_{4,4} & b_{4,3} & b_{4,2} & b_{4,1} & b_{4,0}\\ b_{3,7} & b_{3,6} & b_{3,5} & b_{3,4} & b_{3,3} & b_{3,2} & b_{3,1} & b_{3,0}\\ b_{2,7} & b_{2,6} & b_{2,5} & b_{2,4} & b_{2,3} & b_{2,2} & b_{2,1} & b_{2,0}\\ b_{1,7} & b_{1,6} & b_{1,5} & b_{1,4} & b_{1,3} & b_{1,2} & b_{1,1} & b_{1,0}\\ b_{0,7} & b_{0,6} & b_{0,5} & b_{0,4} & b_{0,3} & b_{0,2} & b_{0,1} & b_{0,0} \end{bmatrix} \]

4.4 一般算法流程

首先,需要找到兩個域 \(F_2[x]/p(x)\)\(F_2[x]/q(x)\) 滿足映射關系的 \(\alpha\)\(\beta'\)
其中 \(\alpha = \overline{x} \; mod \; p(x)\)\(\beta = \overline{x} \; mod \; q(x)\)
\(p(\beta') = 0, \beta' \in F_2[\beta] = F_2[x]/q(x)\)

計算 \(\beta'^i, i = 0, 1, \cdots , 7\) ,並將 \(\beta'^i\) 的系數值置於矩陣 \(T\) 的倒數第 \(i\) 列(從0開始)

五、代碼實現(尋找同構映射)

有限域的四則運算:點擊此處跳轉

假設 \(p(x) = x^8 + x^4 + x^3 + x + 1\)\(q(x) = x^8 + x^7 + x^6 + x^5 + x^4 + x^2 + 1\)
需要求解 \(F_2[x]/p(x)\)\(F_2[x]/q(x)\) 之間的映射關系

5.1 有限域類(GF28)

def gf2_mul(a: int, b: int, poly: int) -> int:
    """有限域乘法"""
    ans = 0
    digit = poly.bit_length() - 1
    while b:
        if b & 1:
            ans = ans ^ a
        a, b = a << 1, b >> 1
        if a >> digit:
            a = a ^ poly
    return ans


class GF256:
    def __init__(self, value, poly):
        self.value = value
        self.poly = poly

    def __add__(self, other):
        """加法"""
        return GF256(self.value ^ other.value, self.poly)

    def __sub__(self, other):
        """減法"""
        return GF256(self.value ^ other.value, self.poly)

    def __mul__(self, other):
        """乘法"""
        return GF256(gf2_mul(self.value, other.value, self.poly), self.poly)

    def __pow__(self, power, modulo=None):
        """冪"""
        res = GF256(1, self.poly)
        for i in range(power):
            res = res * self
        return res

5.2 p(x)和q(x)定義

px = 0b100011011  # x^8 + x^4 + x^3 + x + 1
qx = 0b111110101  # x^8 + x^7 + x^6 + x^5 + x^4 + x^2 + 1
p = lambda x: x ** 8 + x ** 4 + x ** 3 + x + x ** 0
q = lambda x: x ** 8 + x ** 7 + x ** 6 + x ** 5 + x ** 4 + x ** 2 + x ** 0

5.3 遍歷搜索

for i in range(2 ** 8):
    # 遍歷 F_2[x]/q(x) 的元素
    t = GF256(i, qx)
    if p(t).value == 0:  # 滿足p(t)=0
        print(bin(t.value))

得到8個結果

0b100000
0b110011
0b111110
0b1110000
0b10011111
0b10100110
0b10101010
0b11001110

5.4 結果

\(\alpha = \overline{x} \; mod \; p(x)\)\(p(x)\) 的一個根
\(\beta = \overline{x} \; mod \; q(x)\)\(q(x)\) 的一個根

上述結果也就是找到了8個映射關系,分別為

關系
0b100000 \(\alpha \to \beta^5\)
0b110011 \(\alpha \to \beta^5 + \beta^4 + \beta + \beta^0\)
0b111110 \(\alpha \to \beta^5 + \beta^4 + \beta^3 + \beta^2 + \beta^1\)
0b1110000 \(\alpha \to \beta^6 + \beta^5 + \beta^4\)
0b10011111 \(\alpha \to \beta^7 + \beta^4 + \beta^3 + \beta^2 + \beta^1 + \beta^0\)
0b10100110 \(\alpha \to \beta^7 + \beta^5 + \beta^2 + \beta^1\)
0b10101010 \(\alpha \to \beta^7 + \beta^5 + \beta^3 + \beta^1\)
0b11001110 \(\alpha \to \beta^7 + \beta^6 + \beta^3 + \beta^2 + \beta^1\)

六、有限域同構與密碼學

在例如 AES 和 SM4 這類對稱密碼的 S 盒變換的底層,所使用的就是有限域 \(GF(2^8)\) 的求逆變換(除了求逆還涉及一些仿射變換)。

如果采用硬件(例如FPGA)實現密碼算法,可將 \(GF(2^8)\) 的同構於 \(GF((2^4)^2)\) 復合域甚至同構於 \(GF(((2^2)^2)^2)\) 復合域,便於分析有限域的求逆表達式,使用邏輯函數代替原先的查表運算,能夠節省門電路資源

如果使用軟件實現,可以利用有限域同構關系將 SM4 的 S盒 轉化為 AES 的 S盒,利用 AES 指令集完成 SM4 的 S盒 操作

七、求解復合域同構映射的示例代碼

(--- 2023.11.24 更新 ---)

下面給出復合域同構映射的示例python代碼,用於搜索SM4算法對應的復合域,參考論文是陳晨等人的《一種基於復合域的國密SM4算法快速軟件實現方法》。論文里有比本博客更詳細的原理介紹,流程詳見論文中的算法1.

陳晨,郭華,王闖等.一種基於復合域的國密SM4算法快速軟件實現方法[J].密碼學報,2023,10(02):289-305.

python代碼需要提前安裝好一個有關復合域運算的庫 gf2lib,通過指令 pip install gf2lib 即可安裝。下方代碼實現了Gf242復合域類以及Gf28有限域類,使用論文中的搜索算法搜索出復合條件的映射矩陣。代碼的輸出結果和論文中給出的數據完全一致

# -*- coding:utf-8 -*-
"""
需要安裝的包:gf2lib
類:Gf242
    GF(2^4^2)復合域元素,為F[x]/(P(x),Q(y)),P(x) = x^2 + x + 4, Q(y) = y^4 + y^3 + 1
    支持加、減、乘、冪、判等運算
    (1,0)代表單位元e
類:Gf28
    GF(2^8)元素,為F[x]/r(x), r(x) = x^8 + x^7 + x^6 + x^5 + x^4 + x^2 + 1,即SM4復合域
    支持加、減、乘、冪、判等運算
函數:gf28_items
函數:gf242_items
函數:gf242_p
函數:gf28_p
函數:cast_gf28_to_gf242
函數:cast_gf242_to_gf28

功能1:搜索GF(2^4^2)本原元
功能2:搜索指定GF(2^8)和GF(2^4^2)的映射矩陣
"""
from math import gcd
from gf2lib import gf2poly
from gf2lib.gf2matrix import GF2Matrix
from typing import Tuple, List


class Gf28:
    @staticmethod
    def one():
        """單位元"""
        return Gf28(1)

    @staticmethod
    def zero():
        """零元"""
        return Gf28(0)

    def __init__(self, n: int):
        self.n = n

    def __mul__(self, other):
        sm4_poly = 0b111110101  # x^8 + x^7 + x^6 + x^5 + x^4 + x^2 + 1
        return Gf28(gf2poly.mul(self.n, other.n, sm4_poly))

    def __add__(self, other):
        return Gf28(self.n ^ other.n)

    def __pow__(self, power, modulo=None):
        assert not (power == 0 and self.n == 0)
        r = Gf28.one()
        for _ in range(power):
            r = r * self
        return r

    def __eq__(self, other):
        return self.n == other.n

    def __str__(self):
        return str(self.n)


class Gf242:
    def __init__(self, a: Tuple[int, int]):
        self.a = a

    @staticmethod
    def gf24_mul(a: int, b: int) -> int:
        gf24_poly = 0b11001  # y^4+y^3+1
        return gf2poly.mul(a, b, gf24_poly)

    @staticmethod
    def one():
        """單位元"""
        return Gf242((1, 0))

    @staticmethod
    def zero():
        """零元"""
        return Gf242((0, 0))

    def __add__(self, other):
        return Gf242((self.a[0] ^ other.a[0], self.a[1] ^ other.a[1]))

    def __mul__(self, other):
        # P(x) = x^2 + x + 4
        a0, a1 = self.a[0], self.a[1]
        b0, b1 = other.a[0], other.a[1]
        # c2x^2 + c1x + c0
        c0 = Gf242.gf24_mul(a0, b0)
        c1 = Gf242.gf24_mul(a0, b1) ^ Gf242.gf24_mul(a1, b0)
        c2 = Gf242.gf24_mul(a1, b1)
        # c2x^2 = c2x + 4*c2
        r0 = c0 ^ Gf242.gf24_mul(c2, 4)
        r1 = c1 ^ c2
        return Gf242((r0, r1))

    def __pow__(self, power, modulo=None):
        assert not (power == 0 and self == Gf242.zero())
        r = Gf242.one()
        for _ in range(power):
            r = r * self
        return r

    def __eq__(self, other):
        return self.a == other.a

    def __str__(self):
        return str(self.a)


def gf28_items() -> List[Gf28]:
    """返回GF(2^8)所有元素"""
    return [Gf28(a) for a in range(256)]


def gf242_items() -> List[Gf242]:
    """返回GF(2^4^2)中所有元素"""
    return [Gf242((a0, a1)) for a0 in range(16) for a1 in range(16)]


def gf242_p(a: Gf242) -> Gf242:
    """帶入至GF(2^4^2)多項式"""
    return a * a + a + Gf242((4, 0))


def gf28_p(a):
    """帶入至GF(2^8)多項式"""
    # x^8 + x^7 + x^6 + x^5 + x^4 + x^2 + 1
    return a ** 8 + a ** 7 + a ** 6 + a ** 5 + a ** 4 + a ** 2 + a ** 0


def cast_gf28_to_gf242(a: Gf28, T: GF2Matrix) -> Gf242:
    """將GF(2^8)元素映射至GF(2^4^2)

    :param a: GF(2^8)元素
    :param T: 映射矩陣
    :return: T*a
    """
    b = T * GF2Matrix.from_int(a.n, 8)
    b = b.to_int()
    return Gf242((b & 0x0F, b >> 4))


def cast_gf242_to_gf28(a: Gf242, T: GF2Matrix) -> Gf28:
    """將GF(2^4^2)元素映射至GF(2^8)

    :param a: GF(2^4^2)元素
    :param T: 映射矩陣
    :return: T*a
    """
    b = T * GF2Matrix.from_int((a.a[1] << 4) + a.a[0], 8)
    b = b.to_int()
    return Gf28(b)


# 計算GF242本原元,得到(0,1)和(1,1),即x和1+x
print("GF242本原元:")
for g in gf242_items():
    flag = True
    if gf242_p(g) != Gf242.zero():
        flag = False
    t = g
    for i in range(2, 255):
        t = t * g
        if t == Gf242.one():
            flag = False
    if flag:
        print(g)

print("搜索映射矩陣:beta=", (0, 1))
result = []
# step1 選擇本原元 x
beta = Gf242((0, 1))
flag = [1 for _ in range(256)]
t = 1
while t <= 255:
    # step2
    beta_t = beta ** t
    if gf28_p(beta_t) == Gf242.zero():
        result.append(beta_t)
        t = t + 1
    # step3
    else:
        for j in range(8):
            flag[(t * (2 ** j)) % 255] = 0
    # step4,5
    t = t + 1
    while flag[t] == 0 or gcd(t, 255) > 1:
        t = t + 1
        if not t <= 255:
            break

for beta in result:
    # 打印結果
    print("滿足條件的beta^t: ", beta, ", 映射矩陣 col 0-7: ", end='')
    for i in range(7, -1, -1):
        a = beta ** i
        print((a.a[1] << 4) + a.a[0], end=', ')
    print()
    # 計算映射矩陣
    M = GF2Matrix.from_int(0b00000001, 8)  # (0, 0, ..., 1)
    for i in range(1, 8):
        a = beta ** i
        a = (a.a[1] << 4) + a.a[0]
        M = GF2Matrix.from_int(a, 8) | M
    # 計算映射和逆映射矩陣
    T = M
    T_inv = M.inverse()
    # # 測試乘法是否滿足同構,遍歷所有元素
    # for i in range(256):
    #     for j in range(256):
    #         a28, b28 = Gf28(i), Gf28(j)
    #         a242 = cast_gf28_to_gf242(a28, T)
    #         b242 = cast_gf28_to_gf242(b28, T)
    #         assert a28 * b28 == cast_gf242_to_gf28(a242 * b242, T_inv)
    #         assert a28 + b28 == cast_gf242_to_gf28(a242 + b242, T_inv)
    # 打印映射矩陣
    for item in T.transpose().matrix:
        print(item)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM