四、设计概要:
五、实验代码
#include
#include
#include
#include
#define mn 200
int mod_invese(int n, int d) //求d模n的逆,n 为正整数
{
int a,b,q,r,u=0,v=1,t;
a=n;
b=(d>=0)?(d%n):-(d%n);
while(b!=0)
{
q=(int)a/b;
r=a-b*q;
a=b;
b=r;
t=v;
v=u-q*v;
u=t;
}
if(a!=1) return(-a);
return((u<0)?u+n:u);
}
int mod_power(int k, int a, int n) //要求 n 为正整数
//采用从右向左算法,从左向右
{
int x,y,t;
y=a;
t=k;
if(t<0)
{
y=mod_invese(y, n);
if(y<0) return(0);//没有模逆
t=-t;
}
x=1;
if(t==0) return(1);
while(t>1)
{
if(t&0x00000001) x=(x*y)%n;
y=(y*y)%n;
t>>=1;
}
x=(x*y)%n;
return(x);
}
int gcd(int a,int b)//判断a,b是否互素
{
int r;
while(1)
{
r=a%b;
if(r!=0)
{
a=b;
b=r;}
else break;
}
if(b==1) return 1;
else return b;
}
int suiji(int t[mn])//随机生成200个小于2^16的正整数
{
int q;
srand((unsigned)time(NULL));
for(q=0;q
{t[q]=rand()%65536+1;
//printf("%7d",t[q]);
//if(q%10==0)printf("\n");
}
return t[q];
}
int su(int n) //判断是否是素数
{
int j;
for(j=2;j<=sqrt(n)-1;j++)
{
if((n%j)==0) break;
}
if(j>sqrt(n)-1)
{
printf("%8d",n);
}
return n;
}
void rsa()
{
printf("---------------------------------生成若干个素---
int t[mn],i;
suiji(t);
printf("随机生成200个大整数,其中是素数的有:\n");
for(i=0;i
su(t[i]);
printf("\n");
int n,fn,e,d,m,c,p,q;
printf("\n----------------------------------RSA算法-
printf("请从上面的素数中选择两个分别作为p和q:");
scanf("%d",&p);
scanf("%d",&q);
n=p*q;
fn=(p-1)*(q-1);
printf("\nfn=(p-1)*(q-1)=%d\n",fn);
printf("\n");
printf("请输入正整数e:");
scanf("%d",&e);
while(1)
{
if(gcd(fn,e)==1)
break;
else{
printf("\n");
printf("请重新输入,满足fn与e互素:");
scanf("%d",&e);printf("\n");
}
}
d=mod_invese(fn,e);
if(d==0) printf("错误!\n");
else{printf("\n公钥k1=(e,n)=(%d,%d)\n\n",e,n);
printf("私钥k2=d=%d\n\n",d);
printf("输入明文:");
scanf("%d",&m);printf("\n");
c=mod_power(e,m,n);
printf("加密:c = %d的%d次方mod %d = %d\n\n",m,e,n,c);
printf("解密:m=%d的%d次方mod %d = %d\n\n",c,d,n,mod_po
}
}
void ElGama()
{
printf("----------------------------------EIGamal算
int d,t,m,c1,c2,k,p,a,r,x,y,g;
printf("请从上面生成的素数中选择一个素数(p):");
scanf("%d",&p);printf("\n");
int h,w,s,sum=0;
w=p-1;
printf("为了节省空间,这里只给出%d的20个原根:\n",p);
for(h=2;h
{
s=mod_power(w,h,p);
if(s==1)
{
printf("%3d",h);
sum=sum+1;
if(sum==20)break;//如果想要全部的原根,去掉break做相应修改。
}
}
printf("\n\n");
printf("请从上面的原根中选择一个输入(a):");
scanf("%d",&a);
printf("\n");
printf("输入整数d:");
scanf("%d",&d);
printf("\n");
t=mod_power(d,a,p);
printf("t=a的d次方mod p=%d\n",t);printf("\n");
printf("公钥:(p,a,t)=(%d,%d,%d)\n",p,a,t);
printf("\n");
printf("私钥:d=%d\n",d);
printf("\n");
printf("请输入明文m:");
scanf("%d",&m);
printf("\n");
printf("请输入正整数k,其中(1
scanf("%d",&k);
printf("\n");
c1=mod_power(k,a,p);
c2=(m*mod_power(k,t,p))%p;
printf("加密:c=(c1,c2)=(%d,%d)\n",c1,c2);
printf("\n");
m=mod_power(d,c1,p);
m=mod_invese(p,m);
m=m*c2%p;
printf("解密:m=%d\n",m);
printf("\n");
printf("\n------------------------------------签名--
printf("请输入大素数p:");
scanf("%d",&p);
printf("\n");
printf("输入一个原根g:");
scanf("%d",&g);
printf("\n");
printf("请输入正整数x(1<=x<=p-2):");
scanf("%d",&x);
printf("\n");
y=mod_power(x,g,p);
printf("y=%d是公开密钥,x=%d是保密密钥.\n",y,x);
printf("\n");
printf("秘密选取一随机数k其中(0
scanf("%d",&k);
printf("\n");
printf("请输入要加密的消息m=");
scanf("%d",&m);
printf("\n");
r=mod_power(k,g,p);
d=mod_invese((p-1),k);
d=d*((m-x*r)%(p-1))%(p-1)+p-1;
printf("签名:(r,d)=(%d,%d)\n",r,d);
printf("\n");
printf("验证:");
if(mod_power(r,y,p)*mod_power(d,r,p)%p==mod_power
{printf("(r,d)为真.\n");printf("\n");}
else
printf("(r,d)为假.\n");
}
void main()
{
rsa();
ElGama();
}
六、思考题
本实验是一个综合性实验,你认为它都涉及到了你们学过的哪些知识?(不限于本课程去列举)
七、实验体会