LG4718 【模板】Pollard-Rho算法 和 [Cqoi2016]密钥破解
Pollard-Rho算法
总结了各种卡常技巧的代码:
#define int long long
typedef __int128 LL;
IN int fpow(int a,int b,int mod){
int ans=1%mod;
for(;b;b>>=1,a=(LL)a*a%mod)
if(b&1) ans=(LL)ans*a%mod;
return ans;
}
CO int p[3]={2,61,10007};
bool Miller_Rabbin(int n){
if(n==1) return 0;
for(int i=0;i<3;++i)
if(p[i]==n) return 1;
for(int i=0;i<3;++i){
if(fpow(p[i],n-1,n)!=1) return 0;
int k=n-1,r=0; // k*2^r
while(~k&1) k>>=1,++r;
int last=fpow(p[i],k,n);
for(int i=1;i<=r;++i){
int now=(LL)last*last%n;
if(now==1 and last!=1 and last!=n-1) return 0;
last=now;
}
}
return 1;
}
int Pollard_Rho(int n){
if(Miller_Rabbin(n)) return n;
while(1){
int seed=(rand()|rand()<<15)%n;
auto calc=[seed,n](int x){
return ((LL)x*x+seed)%n;
};
int x=(rand()|rand()<<15)%n,y=x;
int sum=1,step=0,point=1;
while(sum){
x=calc(x);
sum=(LL)sum*(y+n-x)%n;
if(++step==point){
int d=__gcd(sum,n);
if(1<d and d<n) return max(Pollard_Rho(d),Pollard_Rho(n/d));
y=x,point<<=1;
}
}
}
}
void real_main(){
int n=read<int>();
int ans=Pollard_Rho(n);
if(ans==n) puts("Prime");
else printf("%lld\n",ans);
}
signed main(){
// freopen("LG4718.in","r",stdin),freopen("LG4718.out","w",stdout);
srand(20030506);
for(int T=read<int>();T--;) real_main();
return 0;
}
密钥破解
一种非对称加密算法的密钥生成过程如下:
- 任选两个不同的质数 p ,q
- 计算 N=pq , r=(p-1)(q-1)
- 选取小于r ,且与 r 互质的整数 e
- 计算整数 d ,使得 ed≡1 mod r
- 二元组 (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)快速乘
queue<LL> arr;
il LL mul(LL a,LL b,LL mod){
LL ans=a*b-(LL)((long double)a/mod*b+1e-8)*mod;
return ans<0?ans+mod:ans;
}
LL pow(LL a,LL b,LL mod){
LL ans=1;
for(;b;b>>=1,a=mul(a,a,mod))
if(b&1) ans=mul(ans,a,mod);
return ans;
}
LL gcd(LL a,LL b) {return b?gcd(b,a%b):a;}
LL exgcd(LL a,LL b,LL&x,LL&y){
if(!b) return x=1,y=0,a;
LL z=exgcd(b,a%b,y,x);
return y-=a/b*x,z;
}
LL Pollard_Rho(LL n,LL sed){
LL i=1,k=2,x=rand()%(n-1)+1,y=x;
while(true){
x=(mul(x,x,n)+sed)%n;
LL p=gcd(n,(y-x+n)%n);
if(p!=1&&p!=n) return p;
if(y==x) return n;
if(++i==k) y=x,k<<=1;
}
}
LL x[100];
bool Miller_Rabbin(LL n){
if(n==2) return 1;
LL s=20,t=0,u=n-1;
while(!(u&1)) ++t,u>>=1;
while(s--){
LL a=rand()*rand()%(n-2)+2;
x[0]=pow(a,u,n);
for(int i=1;i<=t;++i){
x[i]=mul(x[i-1],x[i-1],n);
if(x[i]==1&&x[i-1]!=1&&x[i-1]!=n-1) return 0;
}
if(x[t]!=1) return 0; // Fermat
}
return 1;
}
void find(LL n,LL sed){
if(n==1) return;
if(Miller_Rabbin(n)) return arr.push(n);
LL p=n,k=sed;
while(p==n) p=Pollard_Rho(p,sed--);
find(p,k),find(n/p,k);
}
LL p,q,e,d,N,c,r;
int main(){
srand(19260817);
read(e),read(N),read(c);
find(N,107);
p=arr.front(),arr.pop();
q=arr.front(),arr.pop();
exgcd(e,r=(p-1)*(q-1),d,*(new LL));
d=(d%r+r)%r;
printf("%lld %lld\n",d,pow(c,d,N));
return 0;
}
LG4718 【模板】Pollard-Rho算法 和 [Cqoi2016]密钥破解的更多相关文章
- Pollard Rho算法浅谈
Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
- Pollard Rho 算法简介
\(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...
- 大整数分解质因数(Pollard rho算法)
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...
- BZOJ4522: [Cqoi2016]密钥破解
pollard's rho模板题. 调参调到160ms无能为力了,应该是写法问题,不玩了. #include<bits/stdc++.h> using namespace std; typ ...
- BZOJ 4522: [Cqoi2016]密钥破解
http://www.lydsy.com/JudgeOnline/problem.php?id=4522 题目:给你RSA密钥的公钥和密文,求私钥和原文,其中\(N=pq\le 2^{62}\),p和 ...
随机推荐
- 在ensp上配置Hybrid接口
Hybrid接口是华为特有的一种接口 Hybrid接口是既可以连接普通终端的接入链路,又可以连接交换机间的干道链路. 简单说就是Hybrid接口既能实现Access的功能又能实现Trunk接口的功能. ...
- 下载 m3u8 直播流的方法
下载 FFmpeg http://ffmpeg.org/download.html 查找直播流地址 找到目标视频对应的 m3u8 播放列表. 执行脚本 ffmpeg -i https://nhkmov ...
- Java开发笔记(一百三十七)JavaFX的标签
前面介绍了JavaFX的窗口框架,其中舞台.场景.窗格都能与AWT/Swing体系的相关概念一一对应,不仅如此,JavaFX的常见控件也能在Swing中找到相应的控件.比如JavaFX的按钮控件名叫B ...
- Spring 框架的概述以及Spring中基于XML的IOC配置
Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...
- day28——C/S与B/S架构、网络通信原理、osi七层协议、UDP、TCP协议、TCP的三次握手与四次挥手
day28 C/S B/S架构 C:client 客户端 B:browse浏览器 S:server 服务端 C/S C/S架构:基于客户端与服务端之间的通信 QQ.游戏.皮皮虾 优点:个性化设 ...
- AVR单片机教程——数字输出
从上一篇教程中我们了解到,按键与开关的输入本质上就是数字信号的读取.这一篇教程要讲的是,控制LED的原理是数字信号的输出.数字IO是单片机编程之有别于桌面编程的各项内容中最简单.最基础的. 在讲数字信 ...
- beego 读取配置
不知道是不是坑 官方文档 https://beego.me/docs/module/config.md . 解决办法: 1 导入 config "github.com/astaxie/bee ...
- SQL 向表中添加字段
如果要在数据表中添加一个字段,应该如何表示呢?下面就为您介绍表添加字段的SQL语句的写法,希望可以让您对SQL语句有更深的认识. 通用式: alter table [表名] add [字段名] 字段属 ...
- jwt 0.9.0(三)jwt客户端存储状态可行性分析,及Java代码案例
Jwt客户端存储状态可行性分析 1.前端首次访问后台,后台生成token,放在http header的Authorization里(官网推荐,可解决跨域cookie跨域问题),并且Authorizat ...
- UOJ343 清华集训2017 避难所 构造、打表
传送门 玄学题 考虑构造三个数\(p_1p_2,p_1p_2,p_1p_2\)满足贪心分解会分解为\(p_1^3,p_2,p_2,p_2\),那么需要满足条件 1.\(p_1 , p_2 \in Pr ...