跳转至

离散对数

定义

前置知识:阶与原根

离散对数的定义方式和对数类似。取有原根的正整数模数 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
证明
  1. gindg(ab)abgindgagindgbgindga+indgb(modm)
  2. x=indg1a,则 ag1x(modm). 又令 y=indgg1,则 g1gy(modm).

    agxy(modm),即 indgaxyindg1aindgg1(modφ(m))

  3. 注意到

    indga=indgbindgaindgb(modφ(m))gindgagindgb(modm)ab(modm)

大步小步算法

目前离散对数问题仍不存在多项式时间经典算法(离散对数问题的输入规模是输入数据的位数)。在密码学中,基于这一点人们设计了许多非对称加密算法,如 Ed25519

在算法竞赛中,BSGS(baby-step giant-step,大步小步算法)常用于求解离散对数问题。形式化地说,对 a,b,mZ+,该算法可以在 O(m) 的时间内求解

axb(modm)

其中 am。方程的解 x 满足 0x<m.(注意 m 不一定是素数)

算法描述

x=AmB,其中 0A,Bm,则有 aAmBb(modm),稍加变换,则有 aAmbaB(modm).

我们已知的是 a,b,所以我们可以先算出等式右边的 baB 的所有取值,枚举 B,用 hash/map 存下来,然后逐一计算 aAm,枚举 A,寻找是否有与之相等的 baB,从而我们可以得到所有的 xx=AmB.

注意到 A,B 均小于 m,所以时间复杂度为 Θ(m),用 map 则多一个 log.

为什么要求 am 互质

注意到我们求出的是 A,B,我们需要保证从 aAmbaB(modm) 可以推回 aAmBb(modm),后式是前式左右两边除以 aB 得到,所以必须有 aBmam.

扩展 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),这样就能避免这种情况。

习题

本页面部分内容以及代码译自博文 Дискретное извлечение корня 与其英文翻译版 Discrete Root。其中俄文版版权协议为 Public Domain + Leave a Link;英文版版权协议为 CC-BY-SA 4.0。

参考资料

  1. Discrete logarithm - Wikipedia
  2. 潘承洞,潘承彪。初等数论。
  3. 冯克勤。初等数论及其应用。