有限域算法


一、有限域介紹

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

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

有限域 GF(pn) 中的元素可以看成有限域 GF(p) 上次數小於 n 的多項式,因此 GF(pn) 構成 GF(p) 上的 n 維線性空間,其中的一組基為 {1, x, x2, ......, xn-1},所以有限域 GF(pn) 中的所有元素可以用基 {1, x, x2, ......, xn-1} 的線性組合來表示,其線性組合的系數在 GF(p) 中,即 GF(pn) = {a0 + a1 x + a2 x2 + ... + an-1 xn-1 | ai ∈ GF(p), i = 0, 1, 2, ..., n-1}。

若將 GF(p) 上的加法單位元記作 0,乘法單位元記作 1,元素 a 的加法逆元記作 -a,非零元素 b 的乘法逆元記作 b-1,則有:a + (-a) = 0 (mod p), b × b-1 = 1 (mod p)。針對 GF(p) 中的元素 a 和非零元素 b,加法是 (a + b) mod p,減法是 (a + (-b)) mod p,乘法是 a × b mod p,除法是 a × b-1 mod p,該算法對多項式運算同樣成立,因此 GF(pn) 上的四則運算可以由 GF(p) 上多項式的四則運算導出。

特別地,當 p=2 時,GF(2n) 中的元素 a0 + a1 x + a2 x2 + ... + an-1 xn-1 可以轉化為二進制數 an-1 ... a2 a1 a0。因為計算機中使用的是二進制數,且 1 字節為 8 位,所以在密碼學中常常用到有限域 GF(28)

二、有限域的四則運算

1. 有限域 GF(2n) 加法

1.1 原理介紹

GF(2n) 上的加法即為 GF(2) 上多項式的加法,具體是將 GF(2) 上多項式的系數分別相加。而對於 GF(2) 上的元素,加法即為異或運算。所以,GF(2n) 上的加法運算即為按位異或運算

1.2 具體實現(python)

def gf2_add(a: int, b: int, poly) -> int:
    """
    :param a: 被加數
    :param b: 加數
    :param poly: 不可約多項式
    :return: 和
    """
    return a ^ b

1.3 測試樣例及結果

# 不可約多項式 poly = 0b100011011

0x89 + 0x4d = 0xc4
0xaf + 0x3b = 0x94
0x35 + 0xc6 = 0xf3

2. 有限域 GF(2n) 減法

2.1 原理介紹

GF(2n) 上的減法即為 GF(2) 上多項式的減法。具體是將 GF(2) 上多項式的系數分別相減。而對於 GF(2) 上的元素,減法即為加法。所以,GF(2n) 上的減法即為 GF(2n) 上的加法

2.2 具體實現(python)

def gf2_sub(a: int, b: int, poly) -> int:
    """
    :param a: 被減數
    :param b: 減數
    :param poly: 不可約多項式
    :return: 差
    """
    return a ^ b

2.3 測試樣例及結果

# 不可約多項式 poly = 0b100011011

0x89 - 0x4d = 0xc4
0xaf - 0x3b = 0x94
0x35 - 0xc6 = 0xf3

3. 有限域 GF(2n) 乘法

3.1 原理介紹

GF(2n) 上的乘法即為 GF(2) 上多項式的乘法,具體是將 GF(2) 上的兩個多項式相乘,但是兩個多項式相乘之后的次數可能大於等於 n,因此在計算兩個多項式的乘積之后,還需要模一個 GF(2) 上的 n 次不可約多項式,來保證得到的多項式次數小於 n

在具體實現中,模 n 次不可約多項式的操作可以分解到每一次乘 x 的運算中,即乘 x 的運算通過左移一位后再根據條件按位異或給定的不可約多項式對應的 n 位二進制數的后 n-1 位實現。乘 x 的更高次冪可以通過重復使用該方法實現,這樣一來,GF(2n) 上的乘法結果可由多個中間結果相加得到。有限域 GF(2n) 上乘法運算的詳細步驟如下:

  1. 輸入 a, b 和不可約多項式 poly,並將 a, b 轉化為二進制數,將乘法結果 ans 初始化為 0
  2. 判斷 b 是否大於 0,若大於 0,則轉第(3)步,否則轉第(6)步
  3. 判斷 b 的最低位是否為 1,若是,將 ans 與 a 進行按位異或運算,再將 a 左移一位,否則直接將 a 左移一位
  4. 判斷 a 的最高位(xn 對應位)是否為 1,若是,則將 a 與 poly 進行按位異或運算
  5. 將 b 右移一位,轉置第(2)步
  6. 輸出 ans

3.2 流程圖

3.3 具體實現(python)

def gf2_mul(a: int, b: int, poly: int) -> int:
    """
    :param a: 被乘數
    :param b: 乘數
    :param poly: 不可約多項式
    :return: 積
    """
    ans = 0
    digit_1 = poly.bit_length() - 1
    while b:
        if b & 1:
            ans = ans ^ a
        a, b = a << 1, b >> 1
        if a >> digit_1:  # 取出 a 的最高位
            a = a ^ poly
    return ans

3.4 測試樣例及結果

# 不可約多項式 poly = 0b100011011

0xce * 0xf1 = 0xef
0x70 * 0x99 = 0xa2
0x00 * 0xa4 = 0x00

4. 有限域 GF(2n) 帶余除法

4.1 原理介紹

GF(2n) 上的除法指 GF(2) 上多項式的帶余除法,具體是將 GF(2) 上的兩個多項式相除,得到商和余數

在具體實現中,令 a 為被除數,b 為除數,q 為商,r 為余數,且均為二進制數形式。將 q 的值初始化為 0,當 a 的比特長度大於等於 b 的比特長度時,b 左移 k 位后與 a 長度相等,此時將 q 與 1 左移 k 位后的值相加,將 a 與 b 左移 k 位后的值相減,再判斷 a 與 b 的大小;若 a 大於等於 b,則重復以上步驟,直至 a 小於 b,此時 a 的值即為 r

有限域上除法運算的詳細步驟如下:

  1. 輸入 a, b,並將 a, b 轉化為二進制數,將商 ans 初始化為 0
  2. 判斷 a 的比特長度是否大於等於 b 的比特長度,若是,則轉第(3)步,否則轉第(6)步
  3. 計算 a 的比特長度與 b 的比特長度之差,並將運算結果賦值給 rec
  4. 將 a 與 b 左移 rec 位后的值進行按位異或運算
  5. 將 ans 與 1 左移 rec 位后的值進行按位或運算,轉第(2)步
  6. 輸出 ans,算法結束

4.2 流程圖

4.3 具體實現(python)

def gf2_divmod(a: int, b: int, poly: int) -> (int, int):
    """
    :param a: 被除數
    :param b: 除數
    :param poly: 不可約多項式
    :return: 商,余數
    """
    if b == 0:  # 除數不能為 0
        raise ZeroDivisionError
    ans = 0
    digit_a, digit_b = a.bit_length(), b.bit_length()
    while not a < b:
        rec = digit_a - digit_b
        a = a ^ (b << rec)
        ans = ans | (1 << rec)
        digit_a = a.bit_length()
    return ans, a

4.4 測試樣例及結果

# 不可約多項式 poly = 0b100011011

0xde / 0xc6 = 0x01 ... 0x18
0x8c / 0x0a = 0x14 ... 0x04
0x3e / 0xa4 = 0x00 ... 0x3e

三、有限域數論算法

有限域的數論算法原理和實數域上的原理相同,此處僅給出代碼,具體原理移步對應鏈接處

1. 有限域 GF(2n) 擴展歐幾里得

https://www.cnblogs.com/kentle/p/14975039.html

1.1 具體實現

def gf2_ex_gcd(a: int, b: int, poly: int) -> (int, int, int):
    """
    :return: gcd x y
    """
    x1, y1, x2, y2 = 1, 0, 0, 1
    while b:
        q, r = gf2_divmod(a, b, poly)
        a, b = b, r
        x1, x2 = x2, x1 ^ gf2_mul(q, x2, poly)
        y1, y2 = y2, y1 ^ gf2_mul(q, y2, poly)
    return a, x1, y1

2. 有限域 GF(2n) 求逆

2.1 具體實現

def gf2_inverse(a: int, poly: int):
    """
    :param a: GF(2^n) 元素
    :param poly: 不可約多項式
    :return: a^(-1)
    """
    x1, x2 = 1, 0
    b = poly
    while b:
        q, r = gf2_divmod(a, b, poly)
        a, b = b, r
        x1, x2 = x2, x1 ^ gf2_mul(q, x2, poly)
    return x1

2.2 測試樣例及結果

# 不可約多項式 poly = 0b100011011
iv(0x8c) = 0xf7 
iv(0xbe) = 0x86
iv(0x01) = 0x01
iv(0x2d) = 0x44

3. 有限域 GF(2n) 快速冪

https://www.cnblogs.com/kentle/p/14975044.html

3.1 具體實現

def gf2_quick_pow_mod(a: int, k: int, poly: int) -> int:
    """
    :return: a^k mod p
    """
    res = 1  # res: 計算結果
    while k:
        if k & 1:  # 如果 n 是奇數
            res = gf2_mul(res, a, poly)
        k = k // 2
        a = gf2_mul(a, a, poly)
    return res

四、用途

有限域 GF(28) 常用於對稱密碼算法的構造,例如 AES 的列混淆和字節代替部分就使用了 GF(28) 的有限域

參考資料:《密碼學實驗教程》


免責聲明!

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



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