ECC算法C语言实现

密码学实验:ECC算法实现

1.实验内容

                  ECC算法C语言实现_第1张图片

2.运行结果: 

1.椭圆曲线上的点集

                    ECC算法C语言实现_第2张图片

2.椭圆曲线生成元以及对应的阶

                     ECC算法C语言实现_第3张图片

3.加解密算法

                    ECC算法C语言实现_第4张图片 

代码如下: 

/*

(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
#include 
#include
#include
#include
#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>%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

 

你可能感兴趣的:(密码学)