RSA

来源:互联网 发布:特朗普增加军费知乎 编辑:程序博客网 时间:2024/04/29 16:07
#include<iostream>#include<cmath>#include<algorithm>#include<cstdio>#include<time.h>using namespace std;typedef long long LL;const int TIMES=5;     //米勒罗宾素数测试次数const int EXP=500000;   //p和q的差距LL p,q,n,e,d,t;LL big_rand(LL m)       //生成大的随机数{    LL x=rand();    x*=rand();    if(x<0) x=-x;    return x%=m;}LL mul(LL a,LL b,LL mod)   //快速乘法,解决模大数的时候乘法溢出的问题{    LL ans=0;    while(b)    {        if(b&1) ans=(ans+a)%mod;        b>>=1;        a=(a+a)%mod;    }    return ans;}LL quickpow(LL a,LL b,LL mod)   //快速幂{    LL ans=1;    while(b)    {        if(b&1) ans=mul(ans,a,mod);        b>>=1;        a=mul(a,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) //扩展gcd{    LL d;    if(!b) {x=1;y=0;return a;}    d=exgcd(b,a%b,y,x);    y-=a/b*x;    return d;}bool Miller_Rabbin(LL x)        //米勒-罗宾测试{    LL a,m=(x-1)>>2,i=1;    do{        a=(LL)rand()*rand()%(x-1)+1;        if(quickpow(a,x-1,x)!=1) return 0;    }while(i++<m);    return 1;}void get_prime(LL &x,LL &y)     //素数生成{    LL m=(LL)rand()*rand();    x=big_rand(m);    while(!Miller_Rabbin(x)) x=big_rand(m);    y=big_rand(m);    while(!(abs(x-y)<=EXP&&Miller_Rabbin(y))) y=big_rand(m);}LL get_e(LL n) //产生和互为素数的E{    LL e;    while(true)    {        e=(LL)rand()*rand();        if(e<t&&gcd(t,e)==1LL) return e;    }}void get_key()          //密钥生成{    LL y;    printf("密钥生成中,请等待……\n");    get_prime(p,q);     //产生两个值接近的素数    printf("生成的素数:%I64d %I64d\n",p,q);    n=p*q;    t=(p-1)*(q-1);      //n的欧拉函数值    e=get_e(t);         //生成和t互质的e    exgcd(e,t,d,y);   //求e模t的逆d    if(d<0) d+=t;       //为负数的话得加上t    puts("产生的密钥如下:");    printf("公钥:(n,e):(%I64d,%I64d)\n",n,e);    printf("私钥:(n,d):(%I64d,%I64d)\n",n,d);}LL encode(LL x)         //加密{    return quickpow(x,e,n);}LL decode(LL x)         //解密{    return quickpow(x,d,n);}void control()          //控制函数{    while(true)    {        puts("请选择:1.加密 2.解密");        int ch;        scanf("%d",&ch);        if(ch!=1&&ch!=2) break;        LL M;        printf("请输入明文或者密文:");        scanf("%I64d",&M);        if(ch==1) M=encode(M);        else M=decode(M);        printf("加/解密结果为:%I64d\n",M);    }}int main(){    srand(unsigned(time(NULL)));    get_key();    control();    return 0 ;}


0 0
原创粉丝点击