分解因子算法——Pollard ρ\rhoρ 算法

攻击RSA密码体制最明显的方法就是分解大整数。关于大整数分解的算法有许多,常见的有试除法、p±1p\pm1p±1算法、Pollard ρ\rhoρ算法、数域筛法、二次筛法等等。这篇分享的就是其中之一的Pollard ρ\rhoρ算法。

我们说因子分解,很多时候并不一定要把大整数nnn彻底分解成素数乘积,而是求出nnn的某个非平凡因子即可。求大整数的一个因子固然困难,但是Euclidean算法告诉我们求两个数的最大公因子是可以在O(log⁡n)O(\log n)O(logn)的时间得到的。Pollard ρ\rhoρ算法利用的就是这个思想。

问题描述

设大整数为nnn,我们要找到nnn的一个因子ppp。

Pollard ρ\rhoρ 算法

为了利用Euclidean算法找到ppp,我们设想存在两个整数x,x′∈Znx,x'\in \mathbb{Z}_{n}x,x′∈Zn​,满足x≡x′(modp)x\equiv x'\pmod{p}x≡x′(modp),这样的话就有p∣(x−x′)p|(x-x')p∣(x−x′),又因为p∣np|np∣n,所以有p≤gcd(x−x′,n)<np\le gcd(x-x',n)<np≤gcd(x−x′,n)<n——这句话的意思是:gcd(x−x′,n)gcd(x-x',n)gcd(x−x′,n)一定是nnn的非平凡因子。这就完成了因子分解。问题归结为:如何找到满足条件的xxx和x′x'x′。

一个朴素的想法就是:随机选择一个子集X⊂ZnX\subset \mathbb{Z}_{n}X⊂Zn​,然后对所有不同的x,x′∈Xx,x'\in Xx,x′∈X,判断gcd(x−x′,n)gcd(x-x',n)gcd(x−x′,n)是否为1。这个方法能够成功当且仅当映射x→x(modp)x \rarr x\pmod{p}x→x(modp)在XXX中至少存在一个碰撞。根据生日攻击可以分析:如果∣X∣≈1.71p|X| \approx 1.71\sqrt{p}∣X∣≈1.71p​时,至少存在一个碰撞的概率是50%,为了找到XXX中存在的这个碰撞,我们需要求(∣X∣2)\begin{pmatrix}|X|\\2 \end{pmatrix}(∣X∣2​)次gcd。

Pollard ρ\rhoρ算法减少了求解gcd的次数。它并不是随机产生一个子集XXX,而是事先确定一个整系数多项式fff,并取x1∈Znx_{1}\in \mathbb{Z}_{n}x1​∈Zn​,令
xi+1=f(xi)modn,i=1,2,3⋯x_{i+1}=f(x_{i})\mod{n},i=1,2,3\cdots xi+1​=f(xi​)modn,i=1,2,3⋯
这就产生了集合X={x1,x2,⋯,xm}X=\lbrace x_{1},x_{2},\cdots,x_{m} \rbraceX={x1​,x2​,⋯,xm​}。下面描述这个集合是如何减少gcd计算次数的。

核心思想:如果xi≡xj(modp)x_{i}\equiv x_{j} \pmod{p}xi​≡xj​(modp),由于fff是整系数多项式,所以f(xi)≡f(xj)(modp)f(x_{i})\equiv f(x_{j}) \pmod{p}f(xi​)≡f(xj​)(modp) 。又因为p∣np|np∣n,所以
xi+1modp=(f(xi)modn)modp=f(xi)modpx_{i+1}\mod{p}=(f(x_{i})\mod{n})\mod{p}=f(x_{i})\mod{p} xi+1​modp=(f(xi​)modn)modp=f(xi​)modp
同理有xj+1modp=f(xj)modpx_{j+1}\mod{p}=f(x_{j})\mod{p}xj+1​modp=f(xj​)modp。因此xi+1≡xj+1(modp)x_{i+1} \equiv x_{j+1}\pmod{p}xi+1​≡xj+1​(modp)。

进一步有:如果xi≡xj(modp)x_{i}\equiv x_{j} \pmod{p}xi​≡xj​(modp),则对∀δ≥0\forall \delta \ge0∀δ≥0 ,有xi+δ≡xj+δ(modp)x_{i+\delta}\equiv x_{j+\delta} \pmod{p}xi+δ​≡xj+δ​(modp)。

记l=j−il=j-il=j−i,可知xi′≡xj′(modp)x_{i'} \equiv x_{j'} \pmod{p}xi′​≡xj′​(modp)如果j′≥i′≥ij'\ge i'\ge ij′≥i′≥i且j′−i′≡0(modl)j'-i'\equiv0\pmod{l}j′−i′≡0(modl)。

这样序列X就可以看成带有一个“尾巴”
x1→x2→⋯→xi(modp)x_{1}\rarr x_{2} \rarr \cdots \rarr x_{i} \pmod{p} x1​→x2​→⋯→xi​(modp)
和一个“环”
xi→xi+1→⋯→xj=xi(modp)x_{i} \rarr x_{i+1} \rarr \cdots \rarr x_{j}=x_{i} \pmod{p} xi​→xi+1​→⋯→xj​=xi​(modp)
看成图的话就像希腊字母ρ\rhoρ,这正是算法名字的由来。

对这个算法,我们需要计算(j−12)+i\begin{pmatrix}j-1\\2 \end{pmatrix}+i(j−12​)+i次gcd才能得到第一个碰撞xi,xjx_{i},x_{j}xi​,xj​。

进一步改进:我们只要求得一个碰撞即可,不一定是xix_{i}xi​和xjx_{j}xj​,也可以是xi+δx_{i+\delta}xi+δ​和xj+δx_{j+\delta}xj+δ​。所以在找碰撞的时候,不必逐个逐个求gcd,可以跳跃着求。我们断言:在第一个“环”xi→xi+1→⋯→xj=xi(modp)x_{i} \rarr x_{i+1} \rarr \cdots \rarr x_{j}=x_{i} \pmod{p}xi​→xi+1​→⋯→xj​=xi​(modp)中,一定存在i′i'i′满足x2i′≡xi′(modp)x_{2i'} \equiv x_{i'}\pmod{p}x2i′​≡xi′​(modp)。事实上,只要2i′−i′=i′=kl2i'-i'=i'=kl2i′−i′=i′=kl,就有x2i′≡xi′(modp)x_{2i'} \equiv x_{i'}\pmod{p}x2i′​≡xi′​(modp)成立;而i≤i′=kl≤j−1i\le i'=kl\le j-1i≤i′=kl≤j−1,所以最多找jjj次就可以得到i′i'i′。

算法流程

Pollard ρ\rhoρ (n,x1x_{1}x1​)

x=x1,x′=f(x)modnx=x_{1},x'=f(x)\mod{n}x=x1​,x′=f(x)modn

p=gcd(x−x′,n)p=gcd(x-x',n)p=gcd(x−x′,n)

while p==1p==1p==1

//第i次迭代

​      x=xi,x′=x2ix=x_{i},x'=x_{2i}x=xi​,x′=x2i​

​       x=f(x)modpx=f(x)\mod{p}x=f(x)modp

​       x′=f(x′)modpx'=f(x')\mod{p}x′=f(x′)modp

​       x′=f(x′)modpx'=f(x')\mod{p}x′=f(x′)modp

​       p=gcd(x−x′,n)p=gcd(x-x',n)p=gcd(x−x′,n)

end

if p==n

​       return “failure”

else

​      return p

算法性能分析

假设f=x2+1f=x^{2}+1f=x2+1,则jjj的最大值为p\sqrt{p}p​(因为xjx_{j}xj​是第一个环中的数),所以最多需要p\sqrt{p}p​次gcd计算。而p<np<\sqrt{n}p<n​,所以算法的期望复杂度是O(n14)O(n^{\frac{1}{4}})O(n41​)。需要强调的是,这是一个启发式算法,不是严格的数学证明。算法可能会失败,此时是因为子集XXX中没有碰撞,需要重新选择初始值x1x_{1}x1​或者选择不同的函数fff产生新的集合XXX。

例子

设n=7171n=7171n=7171,f(x)=x2+1,x1=1f(x) = x^{2}+1,x_{1} = 1f(x)=x2+1,x1​=1。

计算集合XXX部分元素为:
1,2,5,26,677,6557,4105,6347,4903,2218,219,4936,4210,4560,4872,375,4377,4389,2016,5471,88⋯1,2,5,26,677,6557,4105,6347,4903,2218,219,4936,4210,4560,4872,375,4377,4389,2016,5471,88\cdots 1,2,5,26,677,6557,4105,6347,4903,2218,219,4936,4210,4560,4872,375,4377,4389,2016,5471,88⋯
计算gcd(x1−x2,n),gcd(x2−x4,n),gcd(x3−x6,n)⋯gcd(x_{1}-x_{2},n),gcd(x_{2}-x_{4},n),gcd(x_{3}-x_{6},n)\cdotsgcd(x1​−x2​,n),gcd(x2​−x4​,n),gcd(x3​−x6​,n)⋯,发现gcd(x11−x22,n)=71gcd(x_{11}-x_{22}, n)=71gcd(x11​−x22​,n)=71,这就找到了nnn的一个因子71。

参考书籍:Stinson D , 斯廷森, 冯登国. 密码学原理与实践[M]. 电子工业出版社, 2009.

分解因子算法——Pollard rho算法相关推荐

  1. 大整数分解——Pollard Rho算法

    延续上一篇,这次来讲一讲大整数分解算法的应用. 要解决的问题很简单,对一个整数进行分解质因数. 首先还是效率非常低的暴力算法,相信大家都会,不多提. 和上次一样,当数达到非常大的时候,分解将变得非常困 ...

  2. c语言用rho函数求复数模长,Pollard Rho 算法简介

    $\text{update 2019.8.18}$ 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点图. ...

  3. 数学--数论--随机算法--Pollard Rho 大数分解算法 (带输出版本)

    RhoPollard Rho是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:MillerRabinMillerRabin素数测试. 操作流程 首先,我们先用MillerRabinMille ...

  4. 数学--数论--随机算法--Pollard Rho 大数分解算法(纯模板带输出)

    ACM常用模板合集 #include <bits/stdc++.h> using namespace std; typedef long long ll; ll pr; ll pmod(l ...

  5. BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...

  6. 素数判定质因数分解(数论)(Miller Rabin)(Pollard Rho)

    太玄学了! 我真的被概率的魅力折服了.此前我认为1便是1,0.9999999999-便是0.9999999999-. 但实际上它们有着千丝万缕的关系. 试想,如果一件事发生的概率是0.99999999 ...

  7. 简述大数分解算法Pollard Rho和Pollard p-1

    大数分解问题其实至今都是一个世界级难题,最常见的分解法是从2一直找到sqr(N),作为一个密码学专业的学生,每次看到别人这么做来进行因子分解,自己都控制不住想要制止他,因为这个算法的效率简直太太太太太 ...

  8. 因数分解 Pollard rho

    因数分解 Pollard rho 算法思路 随机生成两个数a,ba,ba,b,然后求gcd⁡(n,a−b)\gcd\pod{n,a-b}gcd(n,a−b),如果其值不为111,则这个数就是nnn的一 ...

  9. 【快速因数分解】Pollard's Rho 算法

    算法目的 给一个数n,快速提取n的一个因数. 算法根据:生日悖论 讲生日悖论之前,先看一个东西. 给出[1-1000]的数,从中任意选出一个数为k的概率是110001\over 100010001​. ...

  10. 4.2 Pollard p-1算法

    文章目录 算法 Python实现 算法   1974年,John Pollard发明了p-1算法,其灵感来自于费马小定理.p-1算法一个重要的概念就是B-powersmooth,这个不太好翻译,pow ...

最新文章

  1. 网络端口的转发和重定向
  2. stm32入门c语言下载,STM32入门C语言详解.docx
  3. Unity3D-GUI初试
  4. Ubuntu12.04 下配置tomcat
  5. OpenShift 4.6 新特性 - 用 Windows MachineConfig Operator 管理 Windows Container
  6. 在线文本中插入符号工具
  7. java初学总结_Java初学总结
  8. APP适配安卓手机刘海屏
  9. Python 进阶 —— 可变参数(*args, **kw)与参数收集的逆过程
  10. 2015年 不可不知的五大热点话题
  11. 使用listen()和accept()函数
  12. php opendir(),PHP opendir()用法及代码示例
  13. qq四国军旗2.1 beat03 builde017记牌器开发思路(二)
  14. Premiere Pro CC 2018 经典教程
  15. 好看的个人网站源码_新手想建个人网站,都要注意哪些关于自助建站源码的坑?...
  16. android微信分享怎么自定义样式,微信更新!主题皮肤终于支持自定义了,样式超多有个性...
  17. 敏捷软件开发(2)--- 设计原则
  18. 全国中学生计算机竞赛被取消,叫停4个月,中国计算机学会发布通知,恢复信奥联赛...
  19. Emulator: emulator: INFO: QtLogger.cpp:68: Critical: Uncaught ReferenceError: $ is not defined (qrc:
  20. Python查询手机号码所在地区

热门文章

  1. 多目标水母搜索(MOJS)算法(Matlab实现)
  2. 微商开始洗牌,怎么样你的团队才能活下来?
  3. blastall参数详解
  4. nginx压缩静态文件
  5. Windows挂起进程
  6. python正则表达式抽取mysql慢查询sql本身,de-parameterize,将参数值改为?
  7. 2020-11-19学习记录(keer‘s bug与gdb bug)
  8. 打包一个包含手表端应用的手机端APK应用—Ticwear
  9. 软件版本的GA 代表什么意思?
  10. Pocket PC C#