Skip to content

离散对数 学习笔记

离散对数的定义方式和对数类似。取有原根的正整数模数 m,设其一个原根为 g. 对满足 (a,m)=1 的整数 a,我们知道必存在唯一的整数 0k<φ(m) 使得

gka(modm)

我们称这个 k 为以 g 为底,模 m 的离散对数,记作 k=indga,在不引起混淆的情况下可记作 inda.

显然 indg1=0indgg=1.

性质

离散对数的性质也和对数有诸多类似之处。

g 是模 m 的原根,(a,m)=(b,m)=1,则:

  1. indg(ab)indga+indgb(modφ(m))

    进而 (nN),  indgannindga(modφ(m))

  2. g1 也是模 m 的原根,则 indgaindg1aindgg1(modφ(m))

  3. ab(modm)indga=indgb

引入

BSGS(baby-step giant-step),即大步小步算法,常用于求解离散对数问题。该算法可以在 O(p) 的时间复杂度内求解

AxB(modp)

方法

我们将求解的答案 x 设为 kmc(c<m) 的形式,即

AkmcB(modp)

也就是

AkmBAc(modp)

于是就可以用 Meet in middle 攻击了

进阶篇

a,bZ+pP,求解

xab(modp)

该问题可以转化为 BSGS 求解的问题。

由于式子中的模数 p 是一个质数,那么 p 一定存在一个原根 g. 因此对于模 p 意义下的任意的数 x (1x<p) 有且仅有一个数 i (0i<p1) 满足 x=gi.

方法一

我们令 x=gcgp 的原根(我们一定可以找到这个 gc问题转化为求解 (gc)ab(modp). 稍加变换,得到

(ga)cb(modp)

于是就转换成了 BSGS 的基本模型了,可以在 O(p) 解出 c,这样可以得到原方程的一个特解 x0gc(modp).

方法二

我们仍令 x=gc,并且设 b=gt,于是我们得到

gacgt(modp)

方程两边同时取离散对数得到

act(modφ(p))

我们可以通过 BSGS 求解 gtb(modp) 得到 t,于是这就转化成了一个线性同余方程的问题。这样也可以解出 c,求出 x 的一个特解 x0gc(modp).

找到所有解

在知道 x0gc(modp) 的情况下,我们想得到原问题的所有解。首先我们知道 gφ(p)1(modp),于是可以得到

 tZ, xagca+tφ(p)b(modp)

于是得到所有解为

 tZ,atφ(p), xgc+tφ(p)a(modp)

对于上面这个式子,显然有 a(a,φ(p))t. 因此我们设 t=a(a,φ(p))i,得到

 iZ,xgc+φ(p)(a,φ(p))i(modp)

这就是原问题的所有解。

扩展篇(扩展 BSGS)

a,b,mZ+,求解

axb(modm)

其中 a,m 不一定互质。

(a,m)=1 时,在模 m 意义下 a 存在逆元,因此可以使用 BSGS 算法求解。于是我们想办法让他们变得互质。

具体地,设 d1=(a,m). 如果 d1b,则原方程无解。否则我们把方程同时除以 d1,得到

ad1ax1bd1(modmd1)

如果 amd1 仍不互质就再除,设 d2=(a,md1). 如果 d2bd1,则方程无解;否则同时除以 d2 得到

a2d1d2ax2bd1d2(modmd1d2)

同理,这样不停的判断下去,直到 amd1d2dk.

D=i=1kdi,于是方程就变成了这样:

akDaxkbD(modmD)

由于 amD,于是推出 akDmD. 这样 akD 就有逆元了,于是把它丢到方程右边,这就是一个普通的 BSGS 问题了,于是求解 xk 后再加上 k 就是原方程的解啦。

注意,不排除解小于等于 k 的情况,所以在消因子之前做一下 Θ(k) 枚举,直接验证 aib(modm),这样就能避免这种情况。

补充:小粉兔的另一种 exBSGS

洛谷 P5345: 【XR-1】快乐肥宅 - 粉兔 - 博客园

主要思想是特判 “尾巴然后将环上的问题转化为朴素 BSGS