RSA
2015-12-31 22:36
148 查看
#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 ; }
相关文章推荐
- windows和linux注册动态链接库的方法
- 《挑战程序设计竞赛》3.1.2 二分搜索-最大化平均值 POJ2976 3111
- NSOperation的其他设置
- [经使用有效]Sqlserver2005附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法
- 【数据结构】之队列的java实现(一)
- DES
- 2015年浅度总结
- Linux apt-get
- 【数据结构】之链栈的java实现
- shell脚本编程<二>:if-then,case结构化命令
- bzoj3996 线性代数 最大闭权子图&最小割
- python递归深度报错--RuntimeError: maximum recursion depth exceeded
- 【数据结构】之二叉树的java实现
- Spring - Jdbc的使用 和 Spring进行事务控制
- 写在2016开篇
- PHP---LAMP初步
- linux iptables
- Hadoop系列-Windows 环境中 Eclipse 用Maven构建Hadoop项目
- 3、进入32位模式并导入C语言
- Linux使用APT命令的介绍