RSA.h #ifndef _RSA_H #define _RSA_H #include<stdio.h> #include<iostream> #include<math.h> /* 密钥产生: 1.随机选定两个大素数p, q. 2.计算公钥和私钥的公共模数 n = pq . 3.计算模数n的欧拉函数 φ(n) . 4.选定一个正整数e, 使1 < e < φ(n) , 且e与φ(n)互质. 5.计算d, 知足 de ≡ 1 (mod φ(n) ), (k为某个正整数). 6.n与e决定公钥, n与d决定私钥. */ /* 加密:C=M^e mod n */ /* 解密:C=M^d mod n */ //#define RAND_MAX_64 9223372036854775807//最大素数2^63-1 //#define RAND_MIN_64 2147483647//最小素数2^31-1 #define RAND_MAX_64 1000000 #define RAND_MIN_64 1000 #define Max_64 9223372036854775807 #define Times 10//测试素数次数 class RSA { public: RSA(); ~RSA(void); void encryption(__int64 *M,__int64 *C); void decryption(__int64 *C,__int64 *M); void getKey();//生成密钥 __int64 get_p(){return p;}; __int64 get_q(){return q;}; __int64 get_n(){return n;}; __int64 get_o(){return o;}; __int64 get_e(){return e;}; __int64 get_d(){return d;}; private: __int64 Sqrt(__int64 num); //大数开平方根 __int64 get_Prime(); //获得大素数 __int64 mod(__int64 a,__int64 m,__int64 n);//快速求模 __int64 Euclid(__int64 a,__int64 b); //欧几里德算法 bool Prime_test(__int64 n); //肯定性测试 bool Witness(__int64 a,__int64 n); //几率测试 bool Extended_Euclid(__int64 a,__int64 n,__int64 *d); //扩展的欧几里德算法 //公钥KU={e,n} //私钥KR={d,p,q}/{d,n} __int64 p;//素数p __int64 q;//素数q __int64 n;//n=p*q __int64 o;//φ(n)=(p-1)(q-1) __int64 e;//随机整数 __int64 d;//d=e^-1 }; #endif
RSA.cpp #include"RSA.h" //构造函数 RSA::~RSA(){}; //析构函数 RSA::RSA(){}; //加密 void RSA::encryption(__int64 *M,__int64 *C){ *C=RSA::mod(*M,this->e,this->n); } //解密 void RSA::decryption(__int64 *C,__int64 *M){ *M=RSA::mod(*C,this->d,this->n); } //快速求模 //d=a^m mod n b[k]=m=(101010010) __int64 RSA::mod(__int64 a,__int64 m,__int64 n){ __int64 b[500],k=0,i; __int64 c, d; for(;m!=0;m>>=1){ if(m%2==0) b[k]=0; else b[k]=1; k++; } c=0; d=1; for(i=k;i>=0;i--){ c=2*c; d=(d*d)%n; if(b[i]==1){ c=c+1; d=(d*a)%n; } //printf("%lld ",c); //printf("%lld\n",d); } return d; } //肯定性测试 //n素数 bool RSA::Prime_test(__int64 n){ __int64 r=2; while(r<Sqrt(n)){ if(n%r==0) return false; r=r+1; } return true; } //几率测试 //n为素数,a<n bool RSA::Witness(__int64 a,__int64 n){ __int64 m=n-1; __int64 b[500],k=0,i; __int64 d,x; for(;m!=0;m>>=1){ if(m%2==0) b[k]=0; else b[k]=1; k++; } d=1; for(i=k;i>=0;i--){ x=d; d=(d*d)%n; if(d==1&&x!=1&&x!=n-1) return true;//合数 if(b[i]==1) d=(d*a)%n; } if(d!=1) return true;//合数 return false;//多是素数 } //欧几里德算法 __int64 RSA::Euclid(__int64 a,__int64 b){ __int64 x=b,y=a,r=0; if(y>0){ r=x%y; x=y; y=r; } return x; } //扩展的欧几里德算法 //d=e^-1 mod n bool RSA::Extended_Euclid(__int64 a,__int64 n,__int64 *d){ __int64 x1=1,x2=0,x3; __int64 y1=0,y2=1,y3; __int64 t1,t2,t3,q; x3=(n>=a)?n:a;//大的数 y3=(n>=a)?a:n;//小的数 while(1){ if(y3==0){ *d=x3; return false; } if(y3==1){ *d=y2; return true; } q=x3/y3; t1=x1-q*y1; t2=x2-q*y2; t3=x3-q*y3; x1=y1;x2=y2;x3=y3; y1=t1;y2=t2;y3=t3; } } //获得大素数 __int64 RSA::get_Prime(){ int flag=0; // int times=0;//测试素数次数 __int64 a,n=0; while(flag==0){ //步骤1 step_1:flag=0; n = (__int64)(rand()%(RAND_MAX_64 - RAND_MIN_64+1))+RAND_MIN_64; n=(n/2)*2+1; printf("%lld%\r",n); //步骤2 if(Prime_test(n)==false){ //返回步骤1 goto step_1; } else{ //步骤3 step_3:a = (__int64)(rand()%(n-1-0+1))+1;//0<a<n //步骤4 if(Witness(a,n)==true){ //返回步骤1 goto step_1; } else{ times++; if(times>=Times){ flag=1; return n; } else{ //返回步骤3 goto step_3; } } } } return 0; } //密钥的生成 void RSA::getKey(){ this->p = get_Prime(); this->q = get_Prime(); this->n = this->p*this->q;//n=p*q this->o = (this->p-1)*(this->q-1);//φ(n)=(p-1)(q-1) do{ this->e = (__int64)(rand()%(this->o+1));//0<e<φ(n) }while(1==Euclid(this->e,this->o));//e与φ(n)互质 //this->e = 3; if(true==Extended_Euclid(this->e,this->o,&(this->d))){ while(this->d<=Sqrt(Sqrt(this->n))){ Extended_Euclid(this->e,this->o,&(this->d)); } printf("密钥生成成功:%lld\n",this->d); } else{ RSA::getKey(); } } //大数开根 __int64 RSA::Sqrt(__int64 num){ __int64 low ,mid ,up; low = 1 ,up = num; if(up > Max_64) up = Max_64; __int64 mk = 0; while(low <= up){ mid = (low + up) / 2; if(mid * mid > num){ up = mid - 1; } else{ low = mid + 1; mk = mid; } } return mk; }
TEST.cpp #include"RSA.h" #include<stdio.h> int main(){ __int64 M=0,C=0; RSA rsa = RSA(); printf("----------生成密钥----------\n"); rsa.getKey(); printf("----------输出密钥----------\n"); printf("p:%lld\n",rsa.get_p()); printf("q:%lld\n",rsa.get_q()); printf("n:%lld\n",rsa.get_n()); printf("o:%lld\n",rsa.get_o()); printf("e:%lld\n",rsa.get_e()); printf("d:%lld\n",rsa.get_d()); printf("----------加密信息----------\n"); printf("请输入明文:\n"); scanf("%lld",&M); rsa.encryption(&M,&C); printf("加密后密文:%lld\n",C); printf("----------解密信息----------\n"); printf("请输入密文:\n"); scanf("%lld",&C); rsa.decryption(&C,&M); printf("解密后明文:%lld\n",M); system("pause"); return 0; }