跳转至

离散对数

定义

前置知识:阶与原根.

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

gk≡a(modm)

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

显然 indg⁡1=0,indg⁡g=1.

性质

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

性质

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

  1. indg⁡(ab)≡indg⁡a+indg⁡b(modφ(m))

    进而 (∀n∈N),  indg⁡an≡nindg⁡a(modφ(m))

  2. 若 g1 也是模 m 的原根,则 indg⁡a≡indg1⁡a⋅indg⁡g1(modφ(m))

  3. a≡b(modm)⟺indg⁡a=indg⁡b
证明
  1. gindg⁡(ab)≡ab≡gindg⁡agindg⁡b≡gindg⁡a+indg⁡b(modm)
  2. 令 x=indg1⁡a,则 a≡g1x(modm). 又令 y=indg⁡g1,则 g1≡gy(modm).

    故 a≡gxy(modm),即 indg⁡a≡xy≡indg1⁡a⋅indg⁡g1(modφ(m))

  3. 注意到

    indg⁡a=indg⁡b⟺indg⁡a≡indg⁡b(modφ(m))⟺gindg⁡a≡gindg⁡b(modm)⟺a≡b(modm)

大步小步算法

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

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

ax≡b(modm)

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

算法描述

令 x=A⌈m⌉−B,其中 0≤A,B≤⌈m⌉,则有 aA⌈m⌉−B≡b(modm),稍加变换,则有 aA⌈m⌉≡baB(modm).

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

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

为什么要求 a 与 m 互质

注意到我们求出的是 A,B,我们需要保证从 aA⌈m⌉≡baB(modm) 可以推回 aA⌈m⌉−B≡b(modm),后式是前式左右两边除以 aB 得到,所以必须有 aB⟂m 即 a⟂m.

扩展 BSGS 算法

对 a,b,m∈Z+,求解

ax≡b(modm)

其中 a,m 不一定互质.

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

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

ad1⋅ax−1≡bd1(modmd1)

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

a2d1d2⋅ax−2≡bd1d2(modmd1d2)

同理,这样不停的判断下去,直到 a⟂md1d2⋯dk.

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

akD⋅ax−k≡bD(modmD)

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

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

习题

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

参考资料

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