4522: [Cqoi2016]密钥破解
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 388 Solved: 193
Description
一种非对称加密算法的密钥生成过程如下:
1.任选两个不同的质数p,q
2.计算N=pq,r=(p?1)(q?1)
3.选取小于r,且与r互质的整数e
4.计算整数d,使得ed≡1KQ/r
5.二元组(N,e)称为公钥,二元组(N,d)称为私钥
当需要加密消息M时(假设M是一个小于L整数,因为任何格式的消息都可转为整数表示),
使用公钥(N,e),按照n^e≡cKQ/N运算,可得到密文C。
对密文C解密时,用私钥(N,d),按照c^d≡nKQ/N运算,可得到原文M。算法正确性证明省略。
由于用公钥加密的密文仅能用对应的私钥解密,而不能用公钥解密,因此称为非对称加密算法。
通常情况下,公钥由消息的接收方公开,而私钥由消息的接收方自己持有。这样任何发送消息的
人都可以用公钥对消息加密,而只有消息的接收方自己能够解密消息。
现在,你的任务是寻找一种可行的方法来破解这种加密算法,即根据公钥破解出私钥,并据此解密密文。
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
数论模板的应用
Pollard-Rho算法求质因数+扩展欧几里得+快速幂+快速乘
分享一个Pollard-Rho算法的讲解:http://www.cnblogs.com/jackiesteed/articles/2019910.html
(不管你们看懂没,反正我是没看懂)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long using namespace std; ll a,c,d,e,n,p,q,r,ans; inline ll read() { ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll getmul(ll x,ll y,ll mod) { ll ret=0; for(;y;y>>=1,x=x*2%mod) if (y&1) ret=(ret+x)%mod; return ret; } ll getpow(ll x,ll y,ll mod) { ll ret=1; for(;y;y>>=1,x=getmul(x,x,mod)) if (y&1) ret=getmul(ret,x,mod); return ret; } ll gcd(ll x,ll y) { return y?gcd(y,x%y):x; } void exgcd(ll x,ll y,ll &a,ll &b) { if (!y){a=1;b=0;return;} exgcd(y,x%y,b,a); b-=x/y*a; } ll getinv(ll x,ll y) { ll ret,t; exgcd(x,y,ret,t); ret=(ret%y+y)%y; return ret; } ll f(ll x) { return (getmul(x,x,n)+a)%n; } ll pollard_rho(ll n) { ll x1,x2,tmp; while (1) { a=rand()%100; x1=x2=2; do { x1=f(x1);x2=f(f(x2)); tmp=gcd(abs(x2-x1),n); if (tmp>1) return tmp; }while (x1!=x2); } } int main() { srand(909475573); e=read();n=read();c=read(); p=pollard_rho(n);q=n/p; r=(p-1)*(q-1); d=getinv(e,r); ans=getpow(c,d,n); printf("%lld %lld\n",d,ans); }
时间: 2025-01-06 14:07:34