Pollard-Rho算法

总结了各种卡常技巧的代码:

  1. #define int long long
  2. typedef __int128 LL;
  3. IN int fpow(int a,int b,int mod){
  4. int ans=1%mod;
  5. for(;b;b>>=1,a=(LL)a*a%mod)
  6. if(b&1) ans=(LL)ans*a%mod;
  7. return ans;
  8. }
  9. CO int p[3]={2,61,10007};
  10. bool Miller_Rabbin(int n){
  11. if(n==1) return 0;
  12. for(int i=0;i<3;++i)
  13. if(p[i]==n) return 1;
  14. for(int i=0;i<3;++i){
  15. if(fpow(p[i],n-1,n)!=1) return 0;
  16. int k=n-1,r=0; // k*2^r
  17. while(~k&1) k>>=1,++r;
  18. int last=fpow(p[i],k,n);
  19. for(int i=1;i<=r;++i){
  20. int now=(LL)last*last%n;
  21. if(now==1 and last!=1 and last!=n-1) return 0;
  22. last=now;
  23. }
  24. }
  25. return 1;
  26. }
  27. int Pollard_Rho(int n){
  28. if(Miller_Rabbin(n)) return n;
  29. while(1){
  30. int seed=(rand()|rand()<<15)%n;
  31. auto calc=[seed,n](int x){
  32. return ((LL)x*x+seed)%n;
  33. };
  34. int x=(rand()|rand()<<15)%n,y=x;
  35. int sum=1,step=0,point=1;
  36. while(sum){
  37. x=calc(x);
  38. sum=(LL)sum*(y+n-x)%n;
  39. if(++step==point){
  40. int d=__gcd(sum,n);
  41. if(1<d and d<n) return max(Pollard_Rho(d),Pollard_Rho(n/d));
  42. y=x,point<<=1;
  43. }
  44. }
  45. }
  46. }
  47. void real_main(){
  48. int n=read<int>();
  49. int ans=Pollard_Rho(n);
  50. if(ans==n) puts("Prime");
  51. else printf("%lld\n",ans);
  52. }
  53. signed main(){
  54. // freopen("LG4718.in","r",stdin),freopen("LG4718.out","w",stdout);
  55. srand(20030506);
  56. for(int T=read<int>();T--;) real_main();
  57. return 0;
  58. }

密钥破解

一种非对称加密算法的密钥生成过程如下:

  1. 任选两个不同的质数 p ,q
  2. 计算 N=pq , r=(p-1)(q-1)
  3. 选取小于r ,且与 r 互质的整数 e
  4. 计算整数 d ,使得 ed≡1 mod r
  5. 二元组 (N,e) 称为公钥,二元组 (N,d) 称为私钥

当需要加密消息 n 时(假设 n 是一个小于 N 整数,因为任何格式的消息都可转为整数表示),使用公钥 (N,e),按照

n^e≡c mod N

运算,可得到密文 c 。

对密文 c 解密时,用私钥 (N,d) ,按照

c^d≡n mod N

运算,可得到原文 n 。算法正确性证明省略。

由于用公钥加密的密文仅能用对应的私钥解密,而不能用公钥解密,因此称为非对称加密算法。通常情况下,公钥由消息的接收方公开,而私钥由消息的接收方自己持有。这样任何发送消息的人都可以用公钥对消息加密,而只有消息的接收方自己能够解密消息。

现在,你的任务是寻找一种可行的方法来破解这种加密算法,即根据公钥破解出私钥,并据此解密密文。

Input

输入文件内容只有一行,为空格分隔的j个正整数e,N,c。N<=2^62,c<N

Output

输出文件内容只有一行,为空格分隔的k个整数d,n。

Sample Input

3 187 45

Sample Output

107 12

//样例中 p = 11, q = 17

题解

CQOI破解密码专场。推荐MoebiusMeow的博客。

虽然不知道为什么\(x^{k(p-1)(q-1)+1}\equiv 1\ (\bmod pq)\),但是分析题意我们只需要把\(p,q\)分解出来就行了。

所以用上Pollard-Rho大整数分解算法,以及Miller-Rabbin素性测试。然后其他的就是常规同余内用了。

最后说一下O(1)快速乘

  1. queue<LL> arr;
  2. il LL mul(LL a,LL b,LL mod){
  3. LL ans=a*b-(LL)((long double)a/mod*b+1e-8)*mod;
  4. return ans<0?ans+mod:ans;
  5. }
  6. LL pow(LL a,LL b,LL mod){
  7. LL ans=1;
  8. for(;b;b>>=1,a=mul(a,a,mod))
  9. if(b&1) ans=mul(ans,a,mod);
  10. return ans;
  11. }
  12. LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
  13. LL exgcd(LL a,LL b,LL&x,LL&y){
  14. if(!b) return x=1,y=0,a;
  15. LL z=exgcd(b,a%b,y,x);
  16. return y-=a/b*x,z;
  17. }
  18. LL Pollard_Rho(LL n,LL sed){
  19. LL i=1,k=2,x=rand()%(n-1)+1,y=x;
  20. while(true){
  21. x=(mul(x,x,n)+sed)%n;
  22. LL p=gcd(n,(y-x+n)%n);
  23. if(p!=1&&p!=n) return p;
  24. if(y==x) return n;
  25. if(++i==k) y=x,k<<=1;
  26. }
  27. }
  28. LL x[100];
  29. bool Miller_Rabbin(LL n){
  30. if(n==2) return 1;
  31. LL s=20,t=0,u=n-1;
  32. while(!(u&1)) ++t,u>>=1;
  33. while(s--){
  34. LL a=rand()*rand()%(n-2)+2;
  35. x[0]=pow(a,u,n);
  36. for(int i=1;i<=t;++i){
  37. x[i]=mul(x[i-1],x[i-1],n);
  38. if(x[i]==1&&x[i-1]!=1&&x[i-1]!=n-1) return 0;
  39. }
  40. if(x[t]!=1) return 0; // Fermat
  41. }
  42. return 1;
  43. }
  44. void find(LL n,LL sed){
  45. if(n==1) return;
  46. if(Miller_Rabbin(n)) return arr.push(n);
  47. LL p=n,k=sed;
  48. while(p==n) p=Pollard_Rho(p,sed--);
  49. find(p,k),find(n/p,k);
  50. }
  51. LL p,q,e,d,N,c,r;
  52. int main(){
  53. srand(19260817);
  54. read(e),read(N),read(c);
  55. find(N,107);
  56. p=arr.front(),arr.pop();
  57. q=arr.front(),arr.pop();
  58. exgcd(e,r=(p-1)*(q-1),d,*(new LL));
  59. d=(d%r+r)%r;
  60. printf("%lld %lld\n",d,pow(c,d,N));
  61. return 0;
  62. }

LG4718 【模板】Pollard-Rho算法 和 [Cqoi2016]密钥破解的更多相关文章

  1. Pollard Rho算法浅谈

    Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...

  2. Miller Rabin素数检测与Pollard Rho算法

    一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...

  3. Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

    BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1044  Solved: 322[Submit][ ...

  4. 初学Pollard Rho算法

    前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...

  5. Pollard Rho 算法简介

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

  6. 大整数分解质因数(Pollard rho算法)

    #include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...

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

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

  8. BZOJ4522: [Cqoi2016]密钥破解

    pollard's rho模板题. 调参调到160ms无能为力了,应该是写法问题,不玩了. #include<bits/stdc++.h> using namespace std; typ ...

  9. BZOJ 4522: [Cqoi2016]密钥破解

    http://www.lydsy.com/JudgeOnline/problem.php?id=4522 题目:给你RSA密钥的公钥和密文,求私钥和原文,其中\(N=pq\le 2^{62}\),p和 ...

随机推荐

  1. 【剑指offer】面试题 21. 调整数组顺序使奇数位于偶数前面

    面试题 21. 调整数组顺序使奇数位于偶数前面

  2. python 之网络编程(基于TCP协议Socket通信的粘包问题及解决)

    8.4 粘包问题 粘包问题发生的原因: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包),这样接收端,就难于分辨出来了,必须提供科学的拆包机制. ...

  3. 11 IO流(八)——装饰器设计模式,Filter装饰流

    声明:本文部分图片及内容引用自:https://www.cnblogs.com/qiumingcheng/p/5219631.html java装饰器设计模式 举一个形象的例子,人可以说话,而扩音器可 ...

  4. Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

    倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...

  5. LeetCode977.Squares of a Sorted Array

    题目 977. Squares of a Sorted Array Given an array of integers A sorted in non-decreasing order, retur ...

  6. JSVC安装

    执行./start-all.sh启动hadoop时报错 Starting datanodes node1: ERROR: Cannot set priority of datanode process ...

  7. webpack4打包报错ERROR in multi ./src/main.js dist/bundle.js

    webpack打包测试: 上边将mode01.js模块及main.js主文件编写完成,下边使用webpack对这些js文件进行打包 1.进入程序目录,执行webpack main.js build.j ...

  8. 【转载】C#使用Math.Sqrt方法进行开平方操作

    在C#的数学数值运算中,有时候需要进行对数值进行开平方操作,C#的数值计算类Math类中内置了开平方操作的方法Sqrt,直接调用此方法可计算出相应的平方值,Math.Sqrt方法签名为:double ...

  9. 接口认证:Bearer Token(Token 令牌)

    因为HTTP协议是开放的,可以任人调用.所以,如果接口不希望被随意调用,就需要做访问权限的控制,认证是好的用户,才允许调用API. 目前主流的访问权限控制/认证模式有以下几种: 1)Bearer To ...

  10. Bootstrap框架 简单使用

    目录 Bootstrap框架 简单使用 什么是Bootstrap 下载 Bootstrap 项目结构 Bootstrap 简单使用 表格格式 Bootstrap 按钮颜色 尺寸 Bootstrap框架 ...