Poj 2447 RSA

RSA解密

http://www.cnblogs.com/inpeace7/archive/2012/03/17/2403076.html

#include <stdio.h>

#include <iostream>

#include <stdlib.h>

#include <time.h>

#include <cmath>

#include <algorithm>

using namespace std;

typedef long long ll;

ll prfactor;

ll gcd(ll a,ll b)

{

if(b==0) return a;

else return gcd(b,a%b);

}

 

ll mulmod(ll a,ll b,ll n) //a*b%n

{

ll ret=0;

a%=n;

while(b>=1)//注意此处不能为while(b),否则tle

{

if(b&1)

{

ret+=a;

if(ret>=n) ret-=n;

}

a<<=1;

if(a>=n) a-=n;

b>>=1;

}

return ret;

}

 

ll exmod(ll a,ll b,ll n)

{

ll ret=1;

a%=n;

while(b>=1)

{

if(b&1)

ret=mulmod(ret,a,n);

a=mulmod(a,a,n);

b>>=1;

}

return ret;

}

 

 

ll rho(ll n,int c)

{

ll i,k,x,y,d;

srand(time(NULL));

i=1;k=2;

y=x=rand()%n;

while(1)

{

i++;

x=(mulmod(x,x,n)+c)%n;

d=gcd(y-x,n);

if(d>1 && d<n) return d;

if(y==x) break;

if(i==k){y=x;k*=2;}

}

return n;

}

 

void pollard(ll n,int c)

{

if(n<=1) return;

ll m=n;

while(m>=n)

m=rho(m,c--);

prfactor=m;

return;

}

 

ll exgcd(ll a,ll b,ll &x,ll &y)

{

if(0==b){x=1;y=0;return a;}

ll d=exgcd(b,a%b,x,y);

ll t=x;x=y;y=t-a/b*y;

return d;

}

 

ll invmod(ll a,ll n)//求a对n的乘法逆元

{

ll x,y;

if(exgcd(a,n,x,y)!=1) return -1;

return (x%n+n)%n;

}

 

int main()

{

ll c,e,n,phi,d,m;

int i,j;

freopen("in.txt","r",stdin);

while(scanf("%lld%lld%lld",&c,&e,&n)!=EOF)

{

 

pollard(n,107);

phi=(prfactor-1)*(n/prfactor-1);

d=invmod(e,phi);

m=exmod(c,d,n);

printf("%lld\n",m);

}

return 1;

}

posted on 2012-03-17 13:03  Inpeace7  阅读(227)  评论(0编辑  收藏  举报

导航