离散对数
定义
前置知识:阶与原根。
离散对数的定义方式和对数类似。取有原根的正整数模数 𝑚 ,设其一个原根为 𝑔
,设其一个原根为 𝑔 . 对满足 (𝑎,𝑚) =1
. 对满足 (𝑎,𝑚) =1 的整数 𝑎
 的整数 𝑎 ,我们知道必存在唯一的整数 0 ≤𝑘 <𝜑(𝑚)
,我们知道必存在唯一的整数 0 ≤𝑘 <𝜑(𝑚) 使得
 使得
𝑔𝑘≡𝑎(mod𝑚)
我们称这个 𝑘 为以 𝑔
 为以 𝑔 为底,模 𝑚
 为底,模 𝑚 的离散对数,记作 𝑘 =ind𝑔𝑎
 的离散对数,记作 𝑘 =ind𝑔𝑎 ,在不引起混淆的情况下可记作 ind𝑎
,在不引起混淆的情况下可记作 ind𝑎 .
.
显然 ind𝑔1 =0 ,ind𝑔𝑔 =1
,ind𝑔𝑔 =1 .
.
性质
离散对数的性质也和对数有诸多类似之处。
性质
 设 𝑔 是模 𝑚
 是模 𝑚 的原根,(𝑎,𝑚) =(𝑏,𝑚) =1
 的原根,(𝑎,𝑚) =(𝑏,𝑚) =1 ,则:
,则:
 - ind𝑔(𝑎𝑏) ≡ind𝑔𝑎 +ind𝑔𝑏(mod𝜑(𝑚)) 
 - 进而 (∀𝑛 ∈𝐍),  ind𝑔𝑎𝑛 ≡𝑛ind𝑔𝑎(mod𝜑(𝑚)) 
 
- 若 𝑔1 也是模 𝑚 也是模 𝑚 的原根,则 ind𝑔𝑎 ≡ind𝑔1𝑎 ⋅ind𝑔𝑔1(mod𝜑(𝑚)) 的原根,则 ind𝑔𝑎 ≡ind𝑔1𝑎 ⋅ind𝑔𝑔1(mod𝜑(𝑚)) 
 
- 𝑎 ≡𝑏(mod𝑚)  ⟺ ind𝑔𝑎 =ind𝑔𝑏 
证明
 - 𝑔ind𝑔(𝑎𝑏) ≡𝑎𝑏 ≡𝑔ind𝑔𝑎𝑔ind𝑔𝑏 ≡𝑔ind𝑔𝑎+ind𝑔𝑏(mod𝑚) 
- 令 𝑥 =ind𝑔1𝑎 ,则 𝑎 ≡𝑔𝑥1(mod𝑚) ,则 𝑎 ≡𝑔𝑥1(mod𝑚) . 又令 𝑦 =ind𝑔𝑔1 . 又令 𝑦 =ind𝑔𝑔1 ,则 𝑔1 ≡𝑔𝑦(mod𝑚) ,则 𝑔1 ≡𝑔𝑦(mod𝑚) . .
 - 故 𝑎 ≡𝑔𝑥𝑦(mod𝑚) ,即 ind𝑔𝑎 ≡𝑥𝑦 ≡ind𝑔1𝑎 ⋅ind𝑔𝑔1(mod𝜑(𝑚)) ,即 ind𝑔𝑎 ≡𝑥𝑦 ≡ind𝑔1𝑎 ⋅ind𝑔𝑔1(mod𝜑(𝑚)) 
 
- 注意到 ind𝑔𝑎=ind𝑔𝑏⟺ind𝑔𝑎≡ind𝑔𝑏(mod𝜑(𝑚))⟺𝑔ind𝑔𝑎≡𝑔ind𝑔𝑏(mod𝑚)⟺𝑎≡𝑏(mod𝑚) 
大步小步算法
目前离散对数问题仍不存在多项式时间经典算法(离散对数问题的输入规模是输入数据的位数)。在密码学中,基于这一点人们设计了许多非对称加密算法,如 Ed25519。
在算法竞赛中,BSGS(baby-step giant-step,大步小步算法)常用于求解离散对数问题。形式化地说,对 𝑎,𝑏,𝑚 ∈𝐙+ ,该算法可以在 𝑂(√𝑚)
,该算法可以在 𝑂(√𝑚) 的时间内求解
 的时间内求解
𝑎𝑥≡𝑏(mod𝑚)
其中 𝑎 ⟂𝑚 。方程的解 𝑥
。方程的解 𝑥 满足 0 ≤𝑥 <𝑚
 满足 0 ≤𝑥 <𝑚 .(注意 𝑚
.(注意 𝑚 不一定是素数)
 不一定是素数)
算法描述
令 𝑥 =𝐴⌈√𝑚⌉ −𝐵 ,其中 0 ≤𝐴,𝐵 ≤⌈√𝑚⌉
,其中 0 ≤𝐴,𝐵 ≤⌈√𝑚⌉ ,则有 𝑎𝐴⌈√𝑚⌉−𝐵 ≡𝑏(mod𝑚)
,则有 𝑎𝐴⌈√𝑚⌉−𝐵 ≡𝑏(mod𝑚) ,稍加变换,则有 𝑎𝐴⌈√𝑚⌉ ≡𝑏𝑎𝐵(mod𝑚)
,稍加变换,则有 𝑎𝐴⌈√𝑚⌉ ≡𝑏𝑎𝐵(mod𝑚) .
.
我们已知的是 𝑎,𝑏 ,所以我们可以先算出等式右边的 𝑏𝑎𝐵
,所以我们可以先算出等式右边的 𝑏𝑎𝐵 的所有取值,枚举 𝐵
 的所有取值,枚举 𝐵 ,用
,用 hash/map 存下来,然后逐一计算 𝑎𝐴⌈√𝑚⌉ ,枚举 𝐴
,枚举 𝐴 ,寻找是否有与之相等的 𝑏𝑎𝐵
,寻找是否有与之相等的 𝑏𝑎𝐵 ,从而我们可以得到所有的 𝑥
,从而我们可以得到所有的 𝑥 ,𝑥 =𝐴⌈√𝑚⌉ −𝐵
,𝑥 =𝐴⌈√𝑚⌉ −𝐵 .
.
注意到 𝐴,𝐵 均小于 ⌈√𝑚⌉
 均小于 ⌈√𝑚⌉ ,所以时间复杂度为 Θ(√𝑚)
,所以时间复杂度为 Θ(√𝑚) ,用
,用 map 则多一个 log .
.
为什么要求 𝑎 与 𝑚
 与 𝑚 互质
 互质
 注意到我们求出的是 𝐴,𝐵 ,我们需要保证从 𝑎𝐴⌈√𝑚⌉ ≡𝑏𝑎𝐵(mod𝑚)
,我们需要保证从 𝑎𝐴⌈√𝑚⌉ ≡𝑏𝑎𝐵(mod𝑚) 可以推回 𝑎𝐴⌈√𝑚⌉−𝐵 ≡𝑏(mod𝑚)
 可以推回 𝑎𝐴⌈√𝑚⌉−𝐵 ≡𝑏(mod𝑚) ,后式是前式左右两边除以 𝑎𝐵
,后式是前式左右两边除以 𝑎𝐵 得到,所以必须有 𝑎𝐵 ⟂𝑚
 得到,所以必须有 𝑎𝐵 ⟂𝑚 即 𝑎 ⟂𝑚
 即 𝑎 ⟂𝑚 .
.
扩展 BSGS 算法
对 𝑎,𝑏,𝑚 ∈𝐙+ ,求解
,求解
𝑎𝑥≡𝑏(mod𝑚)
其中 𝑎,𝑚 不一定互质。
 不一定互质。
当 (𝑎,𝑚) =1 时,在模 𝑚
 时,在模 𝑚 意义下 𝑎
 意义下 𝑎 存在逆元,因此可以使用 BSGS 算法求解。于是我们想办法让他们变得互质。
 存在逆元,因此可以使用 BSGS 算法求解。于是我们想办法让他们变得互质。
具体地,设 𝑑1 =(𝑎,𝑚) . 如果 𝑑1 ∤𝑏
. 如果 𝑑1 ∤𝑏 ,则原方程无解。否则我们把方程同时除以 𝑑1
,则原方程无解。否则我们把方程同时除以 𝑑1 ,得到
,得到
𝑎𝑑1⋅𝑎𝑥−1≡𝑏𝑑1(mod𝑚𝑑1)
如果 𝑎 和 𝑚𝑑1
 和 𝑚𝑑1 仍不互质就再除,设 𝑑2 =(𝑎,𝑚𝑑1)
 仍不互质就再除,设 𝑑2 =(𝑎,𝑚𝑑1) . 如果 𝑑2 ∤𝑏𝑑1
. 如果 𝑑2 ∤𝑏𝑑1 ,则方程无解;否则同时除以 𝑑2
,则方程无解;否则同时除以 𝑑2 得到
 得到
𝑎2𝑑1𝑑2⋅𝑎𝑥−2≡𝑏𝑑1𝑑2(mod𝑚𝑑1𝑑2)
同理,这样不停的判断下去,直到 𝑎 ⟂𝑚𝑑1𝑑2⋯𝑑𝑘 .
.
记 𝐷 =∏𝑘𝑖=1𝑑𝑖 ,于是方程就变成了这样:
,于是方程就变成了这样:
𝑎𝑘𝐷⋅𝑎𝑥−𝑘≡𝑏𝐷(mod𝑚𝐷)
由于 𝑎 ⟂𝑚𝐷 ,于是推出 𝑎𝑘𝐷 ⟂𝑚𝐷
,于是推出 𝑎𝑘𝐷 ⟂𝑚𝐷 . 这样 𝑎𝑘𝐷
. 这样 𝑎𝑘𝐷 就有逆元了,于是把它丢到方程右边,这就是一个普通的 BSGS 问题了,于是求解 𝑥 −𝑘
 就有逆元了,于是把它丢到方程右边,这就是一个普通的 BSGS 问题了,于是求解 𝑥 −𝑘 后再加上 𝑘
 后再加上 𝑘 就是原方程的解啦。
 就是原方程的解啦。
注意,不排除解小于等于 𝑘 的情况,所以在消因子之前做一下 Θ(𝑘)
 的情况,所以在消因子之前做一下 Θ(𝑘) 枚举,直接验证 𝑎𝑖 ≡𝑏(mod𝑚)
 枚举,直接验证 𝑎𝑖 ≡𝑏(mod𝑚) ,这样就能避免这种情况。
,这样就能避免这种情况。
习题
本页面部分内容以及代码译自博文 Дискретное извлечение корня 与其英文翻译版 Discrete Root。其中俄文版版权协议为 Public Domain + Leave a Link;英文版版权协议为 CC-BY-SA 4.0。
参考资料
- Discrete logarithm - Wikipedia
- 潘承洞,潘承彪。初等数论。
- 冯克勤。初等数论及其应用。
本页面最近更新:2025/10/29 21:16:33,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:Ir1d, StudyingFather, sshwy, Steaunk, Great-designer, H-J-Granger, Enter-tainer, MegaOwIer, c-forrest, countercurrent-time, Henry-ZHR, Konano, ksyx, NachtgeistW, ouuan, stevebraveman, Tiphereth-A, Xeonacid, Alpha1022, AngelKitty, CCXXXI, Chrogeek, ChungZH, cjsoft, diauweb, Early0v0, ezoixx130, FFjet, GavinZhengOI, GekkaSaori, Gesrua, hly1204, hsfzLZH1, iamtwz, isdanni, Kelatte, kxccc, Lampese, LovelyBuggies, lychees, Makkiy, Marcythm, mgt, minghu6, P-Y-Y, Peanut-Tang, PotassiumWings, purple-vine, SamZhangQingChuan, SukkaW, Suyun514, weiyong1024, xyf007, YOYO-UIAT
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用