大步小步法解决离散对数问题 by——miskcoo

转自:http://blog.miskcoo.com/2015/05/discrete-logarithm-problem

扩展大步小步法解决离散对数问题

离散对数(Discrete Logarithm)问题是这样一个问题,它是要求解模方程

axb(modm) ax≡b(modm)

这个问题是否存在多项式算法目前还是未知的,这篇文章先从  m m 是质数开始介绍大步小步法(Baby Step Giant Step)来解决它,之后再将其应用到  m m 是任意数的情况。这个算法可以在  O(m) O(m) 的时间内计算出最小的  x x,或者说明不存在这样一个  x x

题目链接:BZOJ-2480SPOJ-MODBZOJ-3239

首先解决  m=p m=p 是质数的情况,我们可以设  x=Ap+B x=A⌈p⌉+B,其中  0B<p 0≤B<⌈p⌉,   0A<p 0≤A<⌈p⌉,这样的话就变成求解  A A 和  B B 了,方程也变成

aAp+Bb(modp) aA⌈p⌉+B≡b(modp)

可以在两边同时乘以  aB aB 的逆元,由于  p p 是质数,这个逆元一定存在,于是方程变成

aApbaB(modp) aA⌈p⌉≡b⋅a−B(modp)

由于  A,B A,B 都是  O(p) O(p) 级别的数,可以先计算出右边这部分的值,存入 Hash 表,然后计算左边的值,在 Hash 表中查找,只要按照从小到大的顺序如果有解就能够找到最小的解,由于两边都只有  O(p) O(p) 个数,因此时间复杂度是  O(p) O(p) 的,这样  m m 是质数的情况就解决了

一个优化:我们可以设  x=ApB x=A⌈p⌉−B,其中  0B<p 0≤B<⌈p⌉,   0<Ap+1 0<A≤⌈p⌉+1,这样的话化简后的方程就是

aApbaB(modp) aA⌈p⌉≡b⋅aB(modp)

就可以不用求出逆元,要注意只是不用求出逆元,而不是没有用到逆元的存在

现在来看  m m 不是质数的情况,同样可以设  x=Am+B x=A⌈m⌉+B,根据上面的推导,会发现需要用到的性质就是  aB aB 的逆元存在,所以当  m m 和  a a 互质的时候这个方法仍然有效!

如果  (m,a)1 (m,a)≠1 该怎么办呢?我们要想办法把方程转化为  (m,a)=1 (m,a)=1 的情况

把要求的模方程写成另外一种形式

ax+km=b,kZ ax+km=b,k∈Z

设  g=(a,m) g=(a,m),这样的话可以确定如果  gb g∤b 那么该方程一定无解,所以当  gb g∣b 的时候,在方程左右两边同时除以  g g

agax1+kmg=bg,kZ agax−1+kmg=bg,k∈Z

这样便消去了一个因子,得到方程

agax1bg(modmg) agax−1≡bg(modmg)

令  m=mg,b=bg(ag)1 m′=mg,b′=bg(ag)−1(这里不可以把  g g 消掉),就可以得到新的方程

axb(modm) ax′≡b′(modm′)

得到解之后原方程的解  x=x+1 x=x′+1,不断重复这个过程最后一定会得到一个可以解的方程,套用刚刚的大步小步法解出后即可。要注意的是在这个过程中如果某一步发现  b=1 b′=1,那么就可以直接退出,因为这时候已经得到了解

NOTE:上面这个过程是可能执行多次的比如说  (a,m)=(6,16)(6,8)(6,4)(6,2) (a,m)=(6,16)→(6,8)→(6,4)→(6,2)

下面的是代码,题目是文章开头给的链接

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值