函数入口参数
void RSA(LL data,int mode,LL d,LL e,LL n)
data为要加密或解密的数,mode为模式(1加密,0解密),{e,n}为公钥,完成加密,{d,n}为私钥,完成解密。
算法流程
1.任取两个素数p,q;
2.计算n=p*q;
3.计算N=(p-1)*(q-1);
4.选取一奇数e,使得GCD(e,N)=1;
5.计算d,使得(e*d)%N=1,d的计算方法如下:
1)n1= N,n2=e,b1=0,b2=1
2)求 s 和 r,使 n1 = s×n2 + r
3)如果r≠0 则n1 =n2,n2=r,t=b2,b2=b1 - s×b2,b1=t 转2)
4)如果n2≠1,则不存在d
5)如果b2<0 则 b2 = b2 + N
6)d=b2
6.加密或解密,加密算法为C=(M^e) mod n,解密算法为M=(C^d) mod n;
完整代码
View Code
#include <stdio.h> #include <stdlib.h> #include <time.h> #define MAXN 1000000 typedef __int64 LL; int Prime[78500]; char Flag[MAXN]; int Cnt; void MakePrime() { int i,j; for(i=2; i<MAXN; ++i) { if(!Flag[i]) { Prime[Cnt++]=i; for(j=i<<1; j<MAXN; j+=i) { Flag[j]=1; } } } return; } LL GCD(LL a,LL b) { while(b!=0) { if(a>b) { a-=b; } else { b-=a; } } return a; } LL CalD(LL r,LL e) { LL n1=r,n2=e,b1=0,b2=1,t,S,R; S=n1/n2; R=n1%n2; while(R) { n1=n2; n2=R; t=b2; b2=b1-S*b2; b1=t; S=n1/n2; R=n1%n2; } if(n2!=1) { return -1; } if(b2<0) { b2+=r; } return b2; } LL ModExp(LL A,LL N,LL M) { LL ret=1; while(N) { if(N&1) { ret=(ret%M*A%M)%M; } A=(A*A)%M; N>>=1; } return ret; } LL EnCode(LL M,LL e,LL n) { return ModExp(M,e,n); } LL DeCode(LL C,LL d,LL n) { return ModExp(C,d,n); } void RSA(LL data,int mode,LL d,LL e,LL n) { LL r; r=mode?EnCode(data,e,n):DeCode(data,d,n); puts(mode?"密文;":"明文:"); printf("%I64d\n",r); return; } int main() { int p,q,M; LL n,r,e,d,Input; MakePrime(); //srand((unsigned int)time(NULL)); p=Prime[rand()%Cnt]; q=Prime[rand()%Cnt]; n=(LL)p*q; r=(LL)(p-1)*(q-1); for(e=3;; e+=2) { if(GCD(e,r)==1) { break; } } d=CalD(r,e); while(scanf("%I64d %d",&Input,&M)!=EOF) { RSA(Input,M,d,e,n); } return 0; }