提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录- 一、算法
- 二、源码
- 1.加密
- 2.解密
- 三、运行结果
一、算法
实验目标:实现RSA加密算法,根据已知明文计算出RSA的加密密文,并解密。
实验算法:
1、 选择一对不同的、足够大的素数p,q。
2、 计算n=pq。
3、 计算Euler(n)=(p-1)(q-1),同时对p, q严加保密,不让任何人知道。
4、 找一个与Euler(n)互质的数e,且1
*这里要解释一下,≡是数论中表示同余的符号。公式中,≡符号的左边必须和符号右边同余,也就是两边模运算结果相同。显而易见, 不管f(n)取什么值,符号右边1 mod f(n)的结果都等于1;符号的左边d与e的乘积做模运算后的结果也必须等于1。这就需要计算出d的值,让这个同余等式能够成立。*本实验采用平方乘算法。
6、 公钥KU=(e,n),私钥KR=(d,n)。
7、 加密时,先将明文变换成0至n-1的一个整数M。若明文较长,可先分割成适当的组,然后再进行交换。
#include#include #include #include #include //#include using namespace std; unsigned int ProduceRandomOdd(){//UINT无符号整形,各伪随机数放在RandomArray数组中 time_t t;//c++时间类型 unsigned int RandomNumber;//记录随机数 do{ srand((unsigned)time(&t));//srand(seed)用于给rand()函数设定种子,此处用系统时间 //生成 RandomNumber=(rand()<<3); cout< >1; } return a; } //Miller-Rabin素数检测 bool rabinmiller(size_t n, size_t k){ int s=0; int temp=n-1; //将n-1表示为(2^s)*t while ((temp&0x1)==0&&temp){ temp=temp>>1; s++; } size_t t = temp; //判断k轮误判概率不大于(1/4)^k while(k--){ srand((unsigned)time(0)); size_t b = rand()%(n-2)+2; //生成一个b(2≤a ≤n-2) size_t y = repeatMod(b,t,n); if (y == 1 || y == (n-1)) return true; for(int j = 1; j<=(s-1) && y != (n-1); ++j){ y = repeatMod(y,2,n); if (y == 1) return false; } if (y != (n-1)) return false; } return true; } unsigned int Euler(unsigned int n)//欧拉函数 求1到n中有多少个整数与n互质 { unsigned int rs=1; for(unsigned int i=2;i*i<=n;i++) { if(n%i==0) { rs*=(i-1); n/=i; while(n%i==0) { rs*=(i-1); n/=i; } } } if(n>1) rs*=(n-1); return rs; } unsigned int gcd(unsigned int a,unsigned int b)//求a,b的最大公约数 { if(b==0) return a; return gcd(b,a%b); } unsigned int check(unsigned int n)//判断n是不是素数 { if(n==1) return 0; if(n==2) return 1; for(int i=3;i*i<=n;i=i+2) { if(n%i==0) return 0; } return 1; } unsigned int gnerating_primes(unsigned int n)//产生小于等于n的第一个素数 { if(n%2==0) n--; for(unsigned int i=n;i>1;i=i-2) { if(check(i)==1) return i; } return -1;//表示没有小于等于n的素数 } unsigned int multiplicative_inverse_element(unsigned int a,unsigned int r)//求a对于r的乘法逆元 { unsigned int rs=1; if(check(r)==1)//r是素数 采用费马小定理 { for(unsigned int i=1;i<=r-2;i++) rs*=a,rs%=r; }else //r不是素数,采用欧拉定理的推论 { unsigned int k=Euler(r)-1; for(unsigned int i=1;i<=k;i++) rs*=a,rs%=r; } return rs; } unsigned int get_pk(int w) { unsigned int pk=2; for(pk=2;pk 2.解密 #includeusing namespace std; unsigned int Euler(unsigned int n)//欧拉函数 求1到n中有多少个整数与n互质 { unsigned int rs=1; for(unsigned int i=2;i*i<=n;i++) { if(n%i==0) { rs*=(i-1); n/=i; while(n%i==0) { rs*=(i-1); n/=i; } } } if(n>1) rs*=(n-1); return rs; } unsigned int gcd(unsigned int a,unsigned int b)//求a,b的最大公约数 { if(b==0) return a; return gcd(b,a%b); } unsigned int check(unsigned int n)//判断n是不是素数 { if(n==1) return 0; if(n==2) return 1; for(int i=3;i*i<=n;i=i+2) { if(n%i==0) return 0; } return 1; } unsigned int gnerating_primes(unsigned int n)//产生小于等于n的第一个素数 { if(n%2==0) n--; for(unsigned int i=n;i>1;i=i-2) { if(check(i)==1) return i; } return -1;//表示没有小于等于n的素数 } unsigned int multiplicative_inverse_element(unsigned int a,unsigned int r)//求a对于r的乘法逆元 { unsigned int rs=1; if(check(r)==1)//r是素数 采用费马小定理 { for(unsigned int i=1;i<=r-2;i++) rs*=a,rs%=r; }else //r不是素数,采用欧拉定理的推论 { unsigned int k=Euler(r)-1; for(unsigned int i=1;i<=k;i++) rs*=a,rs%=r; } return rs; } unsigned int get_pk(int w) { unsigned int pk=2; for(pk=2;pk 三、运行结果



