4522: [Cqoi2016]密钥破解
Time Limit: 10 Sec
Memory Limit: 512 MB
Submit: 388
Solved: 193
[ Submit][ Status][ Discuss]
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
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
#include
#include
#include
#include
#include
#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);
}