Skip to article frontmatterSkip to article content

扩张域上的求逆计算

对于一个 Base Field Fp\mathbb{F}_p 上的扩张域 Fpn\mathbb{F}_{p^n}。如果直接采用 Extended Euclidean Algorithm 或者 Fermat Little Theorem 来计算逆元,需要多次在 Fpn\mathbb{F}_{p^n} 上进行乘法运算。这个开销较大。一种优化的思路是将 Extension Field 上的求逆运算转换为 Base Field 或者 Subfield 上的求逆运算。转换过程引入少量的额外乘法运算,但整体上计算量会降低。

二次扩张

我们先考虑一个简单的情况,假设 Base Field 为 Fp\mathbb{F}_p,Extension Field 为 Fp2\mathbb{F}_{p^2}

我们指定一个不可约多项式 f(X)Fp[X]f(X)\in\mathbb{F}_p[X],然后构造 Extension Field Fp2\mathbb{F}_{p^2}Fp[X]/(f(X))\mathbb{F}_p[X]/(f(X))

f(X)=X2c0f(X) = X^2 - c_0

那么

Fp2=Fp[X]/(X2c0)\mathbb{F}_{p^2} = \mathbb{F}_{p}[X]/(X^2 - c_0)

我们假设 α\alphaX2c0X^2-c_0Fp2\mathbb{F}_{p^2} 上的一个根。那么 Fp2\mathbb{F}_{p^2} 可以写成 Fp[α]\mathbb{F}_{p}[\alpha]

根据有限域理论,Fp2\mathbb{F}_{p^2} 上的元素可以表示为 a0+a1αa_0 + a_1 \alpha,其中 a0,a1Fpa_0, a_1 \in \mathbb{F}_{p}

Fp2={a0+a1αa0,a1Fp}\mathbb{F}_{p^2} = \{a_0 + a_1 \alpha \mid a_0, a_1 \in \mathbb{F}_{p}\}

如果我们要求解 a=a0+a1αa=a_0 + a_1 \alpha 的逆元,记为 a1a^{-1},我们可以将其转换为 Fp\mathbb{F}_{p} 上的元素。 令 a1=b0+b1αa^{-1} = b_0 + b_1 \alpha,那么我们有

(a0+a1α)(b0+b1α)=1(a_0 + a_1 \alpha)(b_0 + b_1 \alpha) = 1

化简上面等式的左边,并且利用 α2=c0\alpha^2 = c_0,我们可以得到下面的等式:

(a0b0+c0a1b1)+(a0b1+a1b0)α=1(a_0b_0 + c_0\cdot a_1b_1) + (a_0b_1 + a_1b_0)\alpha = 1

由于等式右边没有 uu 项,我们可得 a0b1+a1b0=0a_0b_1 + a_1b_0 = 0,并且 a0b0+c0a1b1=1a_0b_0 + c_0\cdot a_1b_1 = 1。然后上面这个等式也可以用下面的矩阵形式表示:

[a0c0a1a1a0][b0b1]=[10]\begin{bmatrix} a_0 & c_0\cdot a_1 \\ a_1 & a_0 \end{bmatrix} \begin{bmatrix} b_0 \\ b_1 \\ \end{bmatrix} = \begin{bmatrix} 1 \\ 0 \end{bmatrix}

将左边的矩阵求逆之后,我们可以得到 b0b_0b1b_1 的计算矩阵:

[b0b1]=[a0c0a1a1a0]1[10]=(a02c0a12)1[a0c0a1a1a0][10]\begin{bmatrix} b_0 \\ b_1 \\ \end{bmatrix} = \begin{bmatrix} a_0 & c_0\cdot a_1 \\ a_1 & a_0 \end{bmatrix}^{-1} \begin{bmatrix} 1 \\ 0 \\ \end{bmatrix} = (a_0^2 - c_0\cdot a_1^2)^{-1} \begin{bmatrix} a_0 & - c_0\cdot a_1 \\ -a_1 & a_0 \end{bmatrix} \begin{bmatrix} 1 \\ 0 \\ \end{bmatrix}

上式中的 (a02c0a12)1(a_0^2 - c_0\cdot a_1^2)^{-1}Fp\mathbb{F}_{p} 中的一个元素。因此,求解 a1a^{-1} 的计算被转换到了 Fp\mathbb{F}_{p} 上的求逆运算,额外带上常数次(这里是五次)Fp\mathbb{F}_{p} 上的乘法运算。

def quadratic_inv(t: K, c0: F):
    if t == K(0):
        raise ValueError("t=0")
    g = K.gen()   # root of f(X)=(X^2 - c0)
    [a0, a1] = t.list()
    a0_sq = a0 * a0
    a1_sq = a1 * a1
    
    scalar = a0_sq - c0 * a1_sq
    scalar_inv = scalar.inverse()

    b0 = scalar_inv * a0
    b1 = scalar_inv * (-a1)
    
    return b0 + b1 * g

这个方法不仅限于二项式扩张,对于任意的不可约多项式都适用。比如我们用下面的多项式来产生 Fp2\mathbb{F}_{p^2}

g(X)=X2+c1X+c0g(X) = X^2 + c_1X + c_0

然后我们试探下 Fp2\mathbb{F}_{p^2} 中的两个元素的乘积:

(a0+a1α)(b0+b1α)=a0b0+(a0b1+a1b0)α+a1b1α2=a0b0+(a0b1+a1b0)α+a1b1(c1α+c0)=(a0b0+c0a1b1)+(a0b1+a1b0+c1a1b1)α\begin{aligned} (a_0 + a_1 \alpha)(b_0 + b_1 \alpha) &= a_0b_0 + (a_0b_1 + a_1b_0)\alpha + a_1b_1 \alpha^2 \\ &= a_0b_0 + (a_0b_1 + a_1b_0)\alpha + a_1b_1 (c_1\alpha + c_0) \\ &= (a_0b_0 + c_0a_1b_1) + (a_0b_1 + a_1b_0 + c_1a_1b_1)\alpha \end{aligned}

写成矩阵形式为:

[a0c0a1a1a0+c1a1][b0b1]=[10]\begin{bmatrix} a_0 & c_0\cdot a_1 \\ a_1 & a_0+c_1a_1 \end{bmatrix} \begin{bmatrix} b_0 \\ b_1 \\ \end{bmatrix} = \begin{bmatrix} 1 \\ 0 \end{bmatrix}

左边矩阵求逆之后为:

[a0c0a1a1a0+c1a1]1=(a02a12c0+a0a1c1)1[a0+a1c1a1c0a1a0]\begin{bmatrix} a_0 & c_0\cdot a_1 \\ a_1 & a_0+c_1a_1 \end{bmatrix}^{-1} = (a_0^2 -a_1^2c_0 + a_0a_1c_1)^{-1} \begin{bmatrix} a_0+a_1c_1 & -a_1c_0 \\ -a_1 & a_0 \end{bmatrix}

三次扩张

我们仍然假设 Base Field 为 Fp\mathbb{F}_p,三次的 Extension Field 为 Fp3\mathbb{F}_{p^3}

为了简化起见,我们继续指定一个二项式不可约多项式 f(X)Fp[X]f(X)\in\mathbb{F}_p[X],然后构造 Extension Field Fp3\mathbb{F}_{p^3}Fp[X]/(f(X))\mathbb{F}_p[X]/(f(X))

f(X)=X3c0f(X) = X^3 - c_0

假设 α\alphaX3c0X^3-c_0Fp3\mathbb{F}_{p^3} 上的一个根。那么 Fp3\mathbb{F}_{p^3} 上的元素可以表示为 a0+a1α+a2α2a_0 + a_1 \alpha + a_2 \alpha^2,其中 a0,a1,a2Fpa_0, a_1, a_2 \in \mathbb{F}_{p}

a1=b0+b1α+b2α2a^{-1} = b_0 + b_1 \alpha + b_2 \alpha^2,那么我们有

(a0+a1α+a2α2)(b0+b1α+b2α2)=1(a_0 + a_1 \alpha + a_2 \alpha^2)(b_0 + b_1 \alpha + b_2 \alpha^2) = 1

展开之后,并代入 α3=c\alpha^3 = c,我们可以得到

(a0b0+c0a2b1+c0a1b2)+(a0b1+a1b0+c0a2b2)α+(a0b2+a1b1+a2b0)α2=1(a_0b_0 + c_0\cdot a_2b_1 + c_0\cdot a_1b_2) + (a_0b_1 + a_1b_0 + c_0\cdot a_2b_2) \alpha + (a_0b_2 + a_1b_1 + a_2b_0) \alpha^2 = 1

我们把上面的等式写成矩阵形式:

[a0c0a2c0a1a1a0c0a2a2a1a0][b0b1b2]=[100]\begin{bmatrix} a_0 & c_0\cdot a_2 & c_0\cdot a_1 \\ a_1 & a_0 & c_0\cdot a_2 \\ a_2 & a_1 & a_0 \end{bmatrix} \begin{bmatrix} b_0 \\ b_1 \\ b_2 \\ \end{bmatrix} = \begin{bmatrix} 1 \\ 0 \\ 0 \\ \end{bmatrix}

我们把左边的矩阵求逆:

[a0c0a2c0a1a1a0c0a2a2a1a0]1=(s)1[a02c0a1a2c0a12c0a0a2c02a22c0a0a1c0a22a0a1a02c0a1a2c0a12c0a0a2a12a0a2ca22a0a1ca1a2a02]\begin{bmatrix} a_0 & c_0\cdot a_2 & c_0\cdot a_1 \\ a_1 & a_0 & c_0\cdot a_2 \\ a_2 & a_1 & a_0 \end{bmatrix}^{-1} = (s)^{-1} \begin{bmatrix} a_0^2 - c_0\cdot a_1\cdot a_2 & c_0\cdot a_1^2 - c_0\cdot a_0\cdot a_2 & c_0^2\cdot a_2^2 - c_0\cdot a_0\cdot a_1 \\ c_0\cdot a_2^2 - a_0\cdot a_1 & a_0^2 - c_0\cdot a_1\cdot a_2 & c_0\cdot a_1^2 - c_0\cdot a_0\cdot a_2 \\ a_1^2 - a_0\cdot a_2 & c\cdot a_2^2 - a_0\cdot a_1 & c\cdot a_1\cdot a_2 - a_0^2 \end{bmatrix}

这里 s=a03+c0a13+c02a233c0a0a1a2s=a_0^3 + c_0\cdot a_1^3 + c_0^2\cdot a_2^3 - 3c_0\cdot a_0\cdot a_1\cdot a_2

接下来我们可以将 b0,b1,b2b_0, b_1, b_2 的计算转换为 Fp\mathbb{F}_{p} 上的求逆运算, s1s^{-1} ,并乘以 Base field 上的元素:

[b0b1b2]=s1[a02c0a1a2c0a22a0a1a12a0a2]\begin{bmatrix} b_0 \\ b_1 \\ b_2 \\ \end{bmatrix} = s^{-1} \begin{bmatrix} a_0^2 - c_0\cdot a_1\cdot a_2 \\ c_0\cdot a_2^2 - a_0\cdot a_1 \\ a_1^2 - a_0\cdot a_2 \end{bmatrix}
def cubic_inv(t: K, w: F):
    [a0, a1, a2] = t.list()
    g = K.gen()
    a0_sq = a0 * a0
    a1_sq = a1 * a1
    a2_w = w * a2
    a0_a1 = a0 * a1

    scalar = a0*a0_sq + w*a1*a1_sq + a2_w * a2_w * a2 - F(3) * a2_w * a0_a1
    scalar_inv = scalar.inverse()
    b0 = scalar_inv * (a0_sq - a1 * a2_w)
    b1 = scalar_inv * (a2_w * a2 - a0_a1)
    b2 = scalar_inv * (a1_sq - a0 * a2)
    return b0 + b1 * g + b2 * g^2

我们可以合并一些可以复用的 Fp\mathbb{F}_{p} 上的乘法运算,最终得到 14 次 Fp\mathbb{F}_{p} 上的乘法运算加上一次 Fp\mathbb{F}_{p} 上的求逆运算。

四次扩张

对于四次扩张,我们仍然可以采用上面的思路。不过矩阵求逆的复杂度在快速增加。

我们当然可以将四次扩张转换成两步的二次扩张。

Fp4=Fp(α)(β)\mathbb{F}_{p^4} = \mathbb{F}_{p}(\alpha)(\beta)

那么求逆运算的第一步将四次扩张域上的求逆运算转换成二次扩张域上的求逆运算,最后再利用二次扩张的求逆公式,将其求逆运算转换到 Base Field 上的求逆运算。

如果 Fp4\mathbb{F}_{p^4} 是一个直接的四次扩张,但是使用的不可约多项式是一个四次的二项式,那么我们可以有一种更优化的方案(该方案来自 RicsZero 的实现)。

Fp4Fp[X]/(X4c)\mathbb{F}_{p^4}\cong\mathbb{F}_{p}[X]/(X^4-c)

为了计算某个元素 θ\theta 的乘法逆元 θ1\theta^{-1},即

1θ=1a0+a1α+a2α2+a3α3\frac{1}{\theta} = \frac{1}{a_0 + a_1\alpha + a_2\alpha^2 + a_3\alpha^3}

这里 α\alpha 是不可约多项式 X4c=0X^4-c=0 的根,满足 α4c=0\alpha^4-c=0。我们将上面等式的分子分母同时乘上一个辅助元素 ζ\zeta

ζ=a0a1α+a2α2a3α3\zeta = a_0 - a_1\alpha + a_2\alpha^2 - a_3\alpha^3

这样

1θ=ζζθ\frac{1}{\theta} = \frac{\zeta}{\zeta\cdot\theta}

由于 θ\thetaζ\zeta 中有两个系数正负号相反,因此乘积 ζθ\zeta\cdot\theta 中有两个系数(关于 α\alphaα3\alpha^3)将被消掉:

ζθ=(a02+a22c2a1a3c)+(2a0a2a12+a32c)α2\zeta\cdot\theta = (a_0^2 + a_2^2\cdot c - 2a_1a_3\cdot c) + (2a_0a_2 - a_1^2 + a_3^2\cdot c)\cdot \alpha^2

我们令 ζθ=b0+b1α2\zeta\cdot\theta = b_0 + b_1\alpha^2,这里 b0,b1Fpb_0, b_1\in\mathbb{F}_{p},定义如下:

b0=a02+a22c2a1a3cb1=2a0a2a12+a32c\begin{aligned} b_0 &= a_0^2 + a_2^2\cdot c - 2a_1a_3\cdot c \\ b_1 &= 2a_0a_2 - a_1^2 + a_3^2\cdot c \end{aligned}

继续引入一个辅助元素 ξ=b0b1α2\xi=b_0 - b_1\alpha^2,然后再次在 θ1\theta^{-1} 的分子分母上同时乘上 ξ\xi

1θ=ζζθ=ζξζξθ\frac{1}{\theta} = \frac{\zeta}{\zeta\cdot\theta} = \frac{\zeta\cdot\xi}{\zeta\cdot\xi\cdot\theta}

于是分母 ζξθ\zeta\cdot\xi\cdot\theta 将是一个 Fp\mathbb{F}_{p} 上的元素,推导见下:

ζξθ=(b0+b1α2)(b0b1α2)=b02b12α4=b02b12c\zeta\cdot\xi\cdot\theta = (b_0 + b_1\alpha^2)(b_0-b_1\alpha^2) = b_0^2 - b_1^2\alpha^4 = b_0^2 - b_1^2\cdot c

注意到这里因为该方案要求不可约多项式必须为一个二项式,即 X4cX^4-c,所以上面等式中的 α4\alpha^4 项可以被完全替换成 cc,从而确保 ζξθ\zeta\cdot\xi\cdot\theta 是一个 Fp\mathbb{F}_{p} 上的元素。否则如果不可约多项式形如 X4cX+cX^4-c'\cdot X+ c,那么等式右边会引入一个多余的 α\alpha 项,这将难以处理。

最后我们可以得到 θ1\theta^{-1} 的计算公式:

1θ=ζξζξθ=(a0a1α+a2α2a3α3)(b0b1α2)b02b12c\frac{1}{\theta} = \frac{\zeta\cdot\xi}{\zeta\cdot\xi\cdot\theta} = \frac{(a_0 - a_1\alpha + a_2\alpha^2 - a_3\alpha^3) \cdot (b_0 - b_1\alpha^2)}{b_0^2 - b_1^2\cdot c}

显然上面的等式中的分母是一个 Fp\mathbb{F}_{p} 上的元素。而分子关于 α\alpha 的各个系数是若干 Fp\mathbb{F}_{p} 上的元素的乘积。

基于 Frobenius Map 的求逆算法

上面几个算法的核心思想是把 Extension Field 上的求逆运算转换成 Base Field 上的求逆运算。

基于 Frobenius Map,我们也可以将 Extension Field 上的求逆运算转换成 Base Field 上的求逆运算。

对于 n 次扩张域 Fpn\mathbb{F}_{p^n},其 Frobenius Map 为 Frobn:FpnFpnFrob_n: \mathbb{F}_{p^n} \to \mathbb{F}_{p^n},定义为 Frobn(α)=αpFrob_n(\alpha) = \alpha^{p}

对于任何一个 Fpn\mathbb{F}_{p^n} 上的元素 α\alpha,我们可以用过 Frobeinus Map 得到它的全部共轭元素:

α,αp,αp2,,αpn1\alpha, \alpha^p, \alpha^{p^2}, \cdots, \alpha^{p^{n-1}}

这些共轭元素的乘积(被称为 α\alpha 的 Norm)恰好是一个 Fp\mathbb{F}_{p} 上的元素:

ααpαp2αpn1=c\alpha \cdot \alpha^p \cdot \alpha^{p^2} \cdots \alpha^{p^{n-1}} = c

为何?下面简单证明一下。

假设 α\alpha 的特征多项式为 f(X)f(X) ,则

f(X)=(Xα)(Xαp)(Xαp2)(Xαpn1)f(X) = (X-\alpha)(X-\alpha^p)(X-\alpha^{p^2})\cdots(X-\alpha^{p^{n-1}})

其中 f(X)f(X) 的常数项系数恰好为 c=ααpαp2αpn1c=\alpha \cdot \alpha^p \cdot \alpha^{p^2} \cdots \alpha^{p^{n-1}},又因为 f(X)Fp[X]f(X)\in\mathbb{F}_{p}[X],所以 cFpc\in\mathbb{F}_{p}。除此之外,Norm Map 也是一个常用的从 Fpn\mathbb{F}_{p^n}Fp\mathbb{F}_{p} 的同态映射。

那么我们可以利用 Norm Map 的性质来计算任意元素 θFpn\theta\in\mathbb{F}_{p^n} 的乘法逆元 θ1\theta^{-1}

θ1=θrθr1\theta^{-1} = \theta^{-r} \cdot \theta^{r-1}

这里 rr 的计算如下:

r=pn1p1=1+p+p2++pn1r = \frac{p^n-1}{p-1} = 1 + p + p^2 + \cdots + p^{n-1}

那么根据定义, θr\theta^{r} 恰好为 θ\theta 的 Norm:

θr=θθpθp2θpn1=c\theta^{r} = \theta\cdot\theta^p\cdot\theta^{p^2}\cdots\theta^{p^{n-1}} = c

为了计算 θ1\theta^{-1},我们还需要计算 θr1\theta^{r-1},但它为 Fpn\mathbb{F}_{p^n} 中的元素。不过经过分析,我们可以采用下面的公式来「递推地」计算 θ1\theta^{-1}

θr1=i=1n1θpi=(((1θ)pθ)pθ)p\begin{aligned} \theta^{r-1} &= \prod_{i=1}^{n-1} \theta^{p^i} \\ &= (((1\cdot \theta)^p \cdot \theta)^p \cdot \cdots \cdot \theta)^p \end{aligned}

写成 Python 代码如下:

def frobenius_map(a: K):
    return a^(K.characteristic())

def frobenius_inv(a: F, degree: int):
    # compute a^{r-1}
    s = F(1)
    for i in range(1, degree):
        s = frobenius_map(s * a)
    t = s * a
    t_inv = t.inverse()

    return s * t_inv

可以看出,这个算法是一个通用的算法,这里并没有对 Extension Field 的结构或者不可约多项式有任何假设。

二项式扩张域 Frobenius Map 的优化

假如我们这里只考虑二项式扩张域,那么我们可以继续优化 Frobenius Map 的计算。

我们假设扩张域定义如下:

Fpn=Fp[X]/(Xne)\mathbb{F}_{p^n} = \mathbb{F}_{p}[X]/(X^n - e)

这里 eeFp\mathbb{F}_{p} 上的元素。另外令 βne=0\beta^n-e=0 ,那么 β\betaFpn\mathbb{F}_{p^n} 上的一个元素,并且满足:

βn=c\beta^n = c

对于任意一个元素 α\alpha ,都可以表示为 β\beta 的幂次 Basis 的系数向量:

α=a0+a1β+a2β2++an1βn1\alpha = a_0 + a_1\beta + a_2 \beta^2 + \cdots + a_{n-1} \beta^{n-1}

那么 α\alpha 的 Frobenius Map 为 αp\alpha^p,可以推导如下:

αp=(a0+a1β+a2β2++an1βn1)p=a0p+a1pβp+a2pβ2p++an1pβp(n1)=a0+a1βp+a2β2p++an1βp(n1)=a0+a1(βp1)β+a2(βp1)2β2++an1(βp1)(n1)βn1\begin{aligned} \alpha^p &= (a_0 + a_1\beta + a_2 \beta^2 + \cdots + a_{n-1} \beta^{n-1})^p \\ &= a_0^p + a_1^p\beta^p + a_2^p\beta^{2p} + \cdots + a_{n-1}^p\beta^{p(n-1)} \\ &= a_0 + a_1\beta^p + a_2\beta^{2p} + \cdots + a_{n-1}\beta^{p(n-1)} \\ &= a_0 + a_1\cdot (\beta^{p-1})\cdot \beta + a_2\cdot (\beta^{p-1})^{2}\cdot \beta^2 + \cdots + a_{n-1}\cdot (\beta^{p-1})^{(n-1)} \cdot \beta^{n-1} \end{aligned}

那么 αp\alpha^p 可以表示为下面向量和 (1,β,β2,,βn1)(1,\beta,\beta^2,\cdots,\beta^{n-1}) 的点积:

(a0,a1(βp1),a2(βp1)2,,an1(βp1)(n1))(a_0, a_1\cdot (\beta^{p-1}), a_2\cdot (\beta^{p-1})^{2}, \cdots, a_{n-1}\cdot (\beta^{p-1})^{(n-1)})

z=βp1z = \beta^{p-1},并且如果 n(p1)n\mid (p-1) ,那么 zFpz\in\mathbb{F}_{p},那么它的计算只涉及 Base Field 上的计算。

z=βp1=cp1nz = \beta^{p-1} = c^{\frac{p-1}{n}}

于是,αp\alpha^p 的系数表示如下:

(a0,a1z,a2z2,,an1zn1)(a_0, a_1\cdot z, a_2\cdot z^2, \cdots, a_{n-1}\cdot z^{n-1})