赞
踩
密码学实验:ECC算法实现
1.实验内容
2.运行结果:
1.椭圆曲线上的点集
2.椭圆曲线生成元以及对应的阶
3.加解密算法
代码如下:
- /*
- (1)编程计算该椭圆曲线上所有在有限域GF(89)上的点;
- (2)编程实现椭圆曲线上任意一个点P(例如P=(12,5))的倍点运算的递归算法,即计算k*P( k=2,3,…);(重点!)
- (3)利用此递归算法找出椭圆曲线上的所有生成元G以及它们的阶n,即满足n*G=O;
- (4)设计实现某一用户B的公钥、私钥算法,即得到public key=(n, G, PB, Ep(a, b))
- secure key=nB(小于n)
- (5)假如用户A发送明文消息“yes”并加密传输给用户B,用户B接收消息后要能解密为明文。试用ECC密码体制实现此功能。
- */
-
-
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<math.h>
- #include<time.h>
- #define MAX 100
-
- typedef struct point{
- int point_x;
- int point_y;
- }Point;
- typedef struct ecc{
- struct point p[MAX];
- int len;
- }ECCPoint;
- typedef struct generator{
- Point p;
- int p_class;
- }GENE_SET;
-
- void get_all_points();
- int int_sqrt(int s);
- Point timesPiont(int k,Point p);
- Point add_two_points(Point p1,Point p2);
- int inverse(int n,int b);
- void get_generetor_class();
- void encrypt_ecc();
- void decrypt_ecc();
- int mod_p(int s);
- void print();
- int isPrime(int n);
-
- char alphabet[26]="abcdefghijklmnopqrstuvwxyz";
- int a=-1,b=0,p=89;//椭圆曲线为E89(-1,0): y2=x3-x (mod 89)
- ECCPoint eccPoint;
- GENE_SET geneSet[MAX];
- int geneLen;
- char plain[]="yes";
- int m[MAX];
- int cipher[MAX];
- int nB;//私钥
- Point P1,P2,Pt,G,PB;
- Point Pm;
- int C[MAX];
-
- int main()
- {
- get_generetor_class();
- encrypt_ecc();
- decrypt_ecc();
- return 0;
- }
- //task4:加密
- void encrypt_ecc()
- {
- int num,i,j;
- int gene_class;
- int num_t;
- int k;
- srand(time(NULL));
- //明文转换过程
- for(i=0;i<strlen(plain);i++)
- {
- for(j=0;j<26;j++) //for(j=0;j<26;j++)
- {
- if(plain[i]==alphabet[j])
- {
- m[i]=j;//将字符串明文换成数字,并存到整型数组m里面
- }
- }
- }
- //选择生成元
- num=rand()%geneLen;
- gene_class=geneSet[num].p_class;
- while(isPrime(gene_class)==-1)//不是素数
- {
- num=rand()%(geneLen-3)+3;
- gene_class=geneSet[num].p_class;
- }
- //printf("gene_class=%d\n",gene_class);
- G=geneSet[num].p;
- //printf("G:(%d,%d)\n",geneSet[num].p.point_x,geneSet[num].p.point_y);
- nB=rand()%(gene_class-1)+1;//选择私钥
- PB=timesPiont(nB,G);
- printf("\n公钥:\n");
- printf("{y^2=x^3%d*x+%d,%d,(%d,%d),(%d,%d)}\n",a,b,gene_class,G.point_x,G.point_y,PB.point_x,PB.point_y);
- printf("私钥:\n");
- printf("nB=%d\n",nB);
- //加密
- //
- k=rand()%(gene_class-2)+1;
- P1=timesPiont(k,G);
- //
- num_t=rand()%eccPoint.len; //选择映射点
- Pt=eccPoint.p[num_t];
- //printf("Pt:(%d,%d)\n",Pt.point_x,Pt.point_y);
- P2=timesPiont(k,PB);
- Pm=add_two_points(Pt,P2);
- printf("加密数据:\n");
- printf("kG=(%d,%d),Pt+kPB=(%d,%d),C={",P1.point_x,P1.point_y,Pm.point_x,Pm.point_y);
- for(i=0;i<strlen(plain);i++)
- {
- // num_t=rand()%eccPoint.len; //选择映射点
- // Pt=eccPoint.p[num_t];
- C[i]=m[i]*Pt.point_x+Pt.point_y;
- printf("{%d}",C[i]);
- }
- printf("}\n");
- }
- //task5:解密
- void decrypt_ecc()
- {
- Point temp,temp1;
- int m,i;
- temp=timesPiont(nB,P1);
- temp.point_y=0-temp.point_y;
- temp1=add_two_points(Pm,temp);//求解Pt
- // printf("(%d,%d)\n",temp.point_x,temp.point_y);
- // printf("(%d,%d)\n",temp1.point_x,temp1.point_y);
- printf("\n解密结果:\n");
- for(i=0;i<strlen(plain);i++)
- {
- m=(C[i]-temp1.point_y)/temp1.point_x;
- printf("%c",alphabet[m]);//输出密文
- }
- printf("\n");
- }
- //判断是否为素数
- int isPrime(int n)
- {
- int i,k;
- k = sqrt(n);
- for (i = 2; i <= k;i++)
- {
- if (n%i == 0)
- break;
- }
- if (i <=k){
- return -1;
- }
- else {
- return 0;
- }
- }
- //task3:求生成元以及阶
- void get_generetor_class()
- {
- int i,j=0;
- int count=1;
- Point p1,p2;
- get_all_points();
- // p1.point_x=p2.point_x=3;
- // p1.point_y=p2.point_y=2;
- // while(1)
- // {
- // printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
- // p2=add_two_points(p1,p2);
- // count++;
- // if(p2.point_x==-1 && p2.point_y==-1)
- // {
- // break;
- // }
- // }
- // printf("\n\n(%d,%d)---%d\n",p1.point_x,p1.point_y,count);
- //
- // do{
- // printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
- // p2=add_two_points(p1,p2);
- // count++;
- //
- // } while(!((p2.point_x==p1.point_x)&&(p2.point_y==p1.point_y)));
- // printf("(%d,%d)+(%d,%d)---%d\n",p1.point_x,p1.point_y,p2.point_x,p2.point_y,count);
- // count ++ ;
- // printf("\n\n(%d,%d)---%d\n",p1.point_x,p1.point_y,count);
- printf("\n**********************************输出生成元以及阶:*************************************\n");
- for(i=0;i<eccPoint.len;i++)
- {
- count=1;
- p1.point_x=p2.point_x=eccPoint.p[i].point_x;
- p1.point_y=p2.point_y=eccPoint.p[i].point_y;
- while(1)
- {
- p2=add_two_points(p1,p2);
- if(p2.point_x==-1 && p2.point_y==-1)
- {
- break;
- }
- count++;
- if(p2.point_x==p1.point_x)
- {
- break;
- }
- }
- count++;
- if(count<=eccPoint.len+1)
- {
- geneSet[j].p.point_x=p1.point_x;
- geneSet[j].p.point_y=p1.point_y;
- geneSet[j].p_class=count;
- printf("(%d,%d)--->>%d\t",geneSet[j].p.point_x,geneSet[j].p.point_y,geneSet[j].p_class);
- j++;
- if(j % 6 ==0){
- printf("\n");
- }
- }
- geneLen=j;
- }
- }
-
- //task2:倍点运算的递归算法
- Point timesPiont(int k,Point p0)
- {
- if(k==1){
- return p0;
- }
- else if(k==2){
- return add_two_points(p0,p0);
- }else{
- return add_two_points(p0,timesPiont(k-1,p0));
- }
- }
-
- //两点的加法运算
- Point add_two_points(Point p1,Point p2)
- {
- long t;
- int x1=p1.point_x;
- int y1=p1.point_y;
- int x2=p2.point_x;
- int y2=p2.point_y;
- int tx,ty;
- int x3,y3;
- int flag=0;
- //求
- if((x2==x1)&& (y2==y1) )
- {
- //相同点相加
- if(y1==0)
- {
- flag=1;
- }else{
- t=(3*x1*x1+a)*inverse(p,2*y1) % p;
- }
- //printf("inverse(p,2*y1)=%d\n",inverse(p,2*y1));
- }else{
- //不同点相加
- ty=y2-y1;
- tx=x2-x1;
- while(ty<0)
- {
- ty+=p;
- }
- while(tx<0)
- {
- tx+=p;
- }
- if(tx==0 && ty !=0)
- {
- flag=1;
- }else{
- t=ty*inverse(p,tx) % p;
- }
- }
- if(flag==1)
- {
- p2.point_x=-1;
- p2.point_y=-1;
- }else{
- x3=(t*t-x1-x2) % p;
- y3=(t*(x1-x3)-y1) % p;
- //使结果在有限域GF(P)上
- while(x3<0)
- {
- x3+=p;
- }
- while(y3<0)
- {
- y3+=p;
- }
- p2.point_x=x3;
- p2.point_y=y3;
- }
- return p2;
- }
- //求b关于n的逆元
- int inverse(int n,int b)
- {
- int q,r,r1=n,r2=b,t,t1=0,t2=1,i=1;
- while(r2>0)
- {
- q=r1/r2;
- r=r1%r2;
- r1=r2;
- r2=r;
- t=t1-q*t2;
- t1=t2;
- t2=t;
- }
- if(t1>=0)
- return t1%n;
- else{
- while((t1+i*n)<0)
- i++;
- return t1+i*n;
- }
- }
- //task1:求出椭圆曲线上所有点
- void get_all_points()
- {
- int i=0;
- int j=0;
- int s,y=0;
- int n=0,q=0;
- int modsqrt=0;
- int flag=0;
- if (4 * a * a * a + 27 * b * b != 0)
- {
- for(i=0;i<=p-1;i++)
- {
- flag=0;
- n=1;
- y=0;
- s= i * i * i + a * i + b;
- while(s<0)
- {
- s+=p;
- }
- s=mod_p(s);
- modsqrt=int_sqrt(s);
- if(modsqrt!=-1)
- {
- flag=1;
- y=modsqrt;
- }else{
- while(n<=p-1)
- {
- q=s+n*p;
- modsqrt=int_sqrt(q);
- if(modsqrt!=-1)
- {
- y=modsqrt;
- flag=1;
- break;
- }
- flag=0;
- n++;
- }
- }
- if(flag==1)
- {
- eccPoint.p[j].point_x=i;
- eccPoint.p[j].point_y=y;
- j++;
- if(y!=0)
- {
- eccPoint.p[j].point_x=i;
- eccPoint.p[j].point_y=(p-y) % p;
- j++;
- }
- }
- }
- eccPoint.len=j;//点集个数
- print(); //打印点集
- }
- }
-
- //取模函数
- int mod_p(int s)
- {
- int i; //保存s/p的倍数
- int result; //模运算的结果
- i = s / p;
- result = s - i * p;
- if (result >= 0)
- {
- return result;
- }
- else
- {
- return result + p;
- }
- }
-
- //判断平方根是否为整数
- int int_sqrt(int s)
- {
- int temp;
- temp=(int)sqrt(s);//转为整型
- if(temp*temp==s)
- {
- return temp;
- }else{
- return -1;
- }
- }
- //打印点集
- void print()
- {
- int i;
- int len=eccPoint.len;
- printf("\n该椭圆曲线上共有%d个点(包含无穷远点)\n",len+1);
- for(i=0;i<len;i++)
- {
- if(i % 8==0)
- {
- printf("\n");
- }
- printf("(%2d,%2d)\t",eccPoint.p[i].point_x,eccPoint.p[i].point_y);
- }
- printf("\n");
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。