Discrete logarithm problem
Discrete logarithm problem
发现自己只是知道离散对数很难求,而且自己拿这玩意也没办法,专门来学一下带老婆问题
基本定义
生成元
在一个群 G 中,如果 g 是 G 的生成元,即所有 G 中的所有元素都可以被表示成 $y = g^x$ ,此时的 x 我们称为 y 在 G 中的对数
阶
设 $m\geq 1$ , $gcd(a,m)=1$ ,使得 $a^d=1\pmod{m}$ 成立的最小正整数 d 称为 a 对模 m 的指数或者阶,我们一般将其记为 $\delta_m(a)$
另:满足 $a^d=1\pmod{m}$ 的d
一定满足 $d\mid\varphi(m)$
原根
当 $\delta_m(a)=\varphi(m)$ 时,称 a 是模 m 的原根,简称 m 的原根
只有 $m=2,4,p^\alpha,2p^\alpha (p为奇素数,\alpha为正整数)$ 时,模 m 的剩余系存在原根(充要条件)
离散对数
暴力枚举
万物皆可暴力
1 | def ForceDLP(A,B,P): |
Baby-step giant-step
又称北上广深算法 带老婆去了北上广深(bushi
已知 $y = g^x$ ,我们不妨假设 $x=i\cdot m+j$ ,$m = \sqrt{x}$ ,这样 $m^2>n$ ,则这时候一定在[0,m]
内存在一组(i,j)
满足 $x=i\cdot m+j$
具体做法就是:因为 $y = g^x=g^{i\cdot m+j}$ , 则 $y\cdot (g^{-m})^i=g^j$ ,所以我们首先枚举所有的j
并存在一个盒子里,接着枚举i
,如果能找到相同的结果,这说明我们得到了(i,j)
据说
- 每一次 j 的增加表示 “baby-step”,一次乘上 $g$
- 每一次 i 的增加表示 “giant-step”,一次乘上 $g^{-m}$
1 | def BSGS(g, y, p): |
Pohlig-Hellman Algorithm
这种方法适用于当p-1
是个光滑数,因为p
是个质数,所以 $\varphi(p)=p-1$ ,根据唯一分解定理,我们可以假设 $p-1 =q_1^{e_1}\cdot q_2^{e_2}\cdot q_3^{e_3}\cdots q_n^{e_n}$ ,我们首先分解 $p-1$ 得到因子列表listq
,接着计算每一个因子对应的 $g^{\frac{p-1}{q^e}}$ 与 $h^{\frac{p-1}{q^e}}$ ,此时我们就可以较轻松地计算出满足 $({g^{\frac{p-1}{q^e}}})^x=h^{\frac{p-1}{q^e}}\pmod{p}$ 的x'
,而此时的x'
也满足 $x’ =x\pmod{p^e}$ ,那么我们可以通过许多的因子来得到许多的x'
,最后通过CRT即可找到我们最终要求的x
1 | from Crypto.Util.number import * |