ECC加密解密算法

#include <stdio.h>
#include <math.h>
int xy[22];
#define N 23
#define A 1
//#define M 29
#define a1 1
#define b1 4
Point;typedef struct generator{
	Point p;
	int p_class;
}GENE_SET;typedef struct ecc{
	struct point p[100];
	int len;
}ECCPoint;
typedef struct point{
	int x;
	int y;
}
ECCPoint eccPoint;
Point mul(Point p1,Point p2);
Point addTwoPoints(Point p1,Point p2);
GENE_SET genCoordinateList[100];
int genNumber;
//判断平方根是否为整数 
int int_sqrt(int s)
{
	int temp;
	temp=(int)sqrt(s);//转为整型 
	if(temp*temp==s)
	{
		return temp;
	}else{
		return -1;
	}
}
//取模函数
int mod_p(int s)
{
	int i;	//保存s/p的倍数
	int result;	//模运算的结果
	i = s / N;
	result = s - i * N;
	if (result >= 0)
	{
		return result;
	}
	else
	{
		return result + N;
	}
}
//打印点集 
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].x,eccPoint.p[i].y);
	}
	printf("\n");
}
//任务1:求出椭圆曲线上所有点 
void getAllPoints()
{
	int i=0;
	int j=0;
	int s,y=0;
	int n=0,q=0;
	int modsqrt=0; 
	int flag=0;
	if ( a1 * a1 * a1 + b1 * b1+4 != 0)
	{
		for(i=0;i<=N-1;i++)
		{
			flag=0;
			n=1;
			y=0;
			s= i * i * i + a1 * i + b1;
			while(s<0)
			{
				s+=N;
			}
			s=mod_p(s);
			modsqrt=int_sqrt(s);
			if(modsqrt!=-1)
			{
				flag=1;
				y=modsqrt;
			}else{
				while(n<=N-1)
				{
					q=s+n*N;
					modsqrt=int_sqrt(q);
					if(modsqrt!=-1)
					{
						y=modsqrt;
						flag=1;
						break;
					}
						flag=0;
						n++;
				}
			}
			if(flag==1)
			{
				eccPoint.p[j].x=i;
				eccPoint.p[j].y=y;
				j++;
				if(y!=0)
				{
					eccPoint.p[j].x=i;
					eccPoint.p[j].y=(N-y) % N;
					j++;
				}				
			}
		}
		eccPoint.len=j;//点集个数 
		print(); //打印点集 
	}	
}
 
//任务3:求生成元以及阶
void getGeneretor()
{	
	int i,j=0;
	int count=1;
	Point p1,p2;
	getAllPoints();	
	printf("\n**********************************输出生成元以及阶:*************************************\n");
	for(i=0;i<eccPoint.len;i++)
	{
		count=1;
		p1.x=p2.x=eccPoint.p[i].x;
		p1.y=p2.y=eccPoint.p[i].y;		
		while(1)
		{	
			p2=addTwoPoints(p1,p2);					
			if(p2.x==-1 && p2.y==-1)
			{
				break;
			}
			count++;
			if(p2.x==p1.x)
			{
				break;
			}						
		}
		count++;
		if(count<=eccPoint.len+1)
		{
			genCoordinateList[j].p.x=p1.x;
			genCoordinateList[j].p.y=p1.y;
			genCoordinateList[j].p_class=count;
			printf("(%d,%d)--->>%d\t",genCoordinateList[j].p.x,genCoordinateList[j].p.y,genCoordinateList[j].p_class);
			j++;
			if(j % 6 ==0){
				printf("\n");
			}
		}
		genNumber=j;	
	}
}
 
// 求 a mod b 的逆元
void exGcd(int a, int b) {
    if (b == 0) {
        xy[0] = 1;
        xy[1] = 0;
    } else {
        exGcd(b, a % b);
        int x = xy[0];
        xy[0] = xy[1];
        xy[1] = x - (a / b) * xy[1];
    }
   
}
int calculate3(int y,int k,int p){

	int l=1;
	for(int i = 0;i<k;i++){
		l=l*y;
		l=l%p;
	}

	return l;
}

Point eccmutiply(int n,Point p){
	int a,b,l,k,m;
	a=p.x;
	b=p.y;
	for(int i = 0;i<n-1;i++){
		
		if(a==p.x&&b==p.y){
			exGcd(2*p.y,N);
			k=xy[0];
			if(k<0)k=k+N;
			printf("逆元=%d\n",k);
			l=(3*p.x*p.x+A)*k;
			l=calculate3(l,1,N);
			if(l<0){
				l=l+N;
			}
		}else{
			exGcd(a-p.x+N,N);
			k=xy[0];
			if(k<0)k=k+N;
			printf("else逆元=%d\n",k);
			l=(b-p.y)*k;
			l=calculate3(l,1,N);
			if(l<0){
				l=l+N;
			}
			printf("l=%d\n",l);
		}
		m=p.x;
		a=l*l-a-p.x;
		a=calculate3(a,1,N);
		if(a<0){
			a=a+N;
		}
		b=l*(m-a)-p.y;
		b=calculate3(b,1,N);
	
		if(b<0){
			b=b+N;
		}
		printf("%d(a,b)=(%d,%d)\n",i+2,a,b);
		//if(a==4&&b==5)break;
	}
	Point p3;
	p3.x=a;
	p3.y=b;
	return p3;
}
Point mul(Point p1,Point p2){
	int k,l;
	exGcd(p2.x-p1.x+N,N);
	k=xy[0];
	if(k<0)k=k+N;
	//printf("else逆元=%d\n",k);
	l=(p2.y-p1.y)*k;
	l=calculate3(l,1,N);
	if(l<0){
		l=l+N;
	}
	//printf("l=%d\n",l);	
	Point p3;
	p3.x=l*l-p1.x-p2.x;
	p3.x=calculate3(p3.x,1,N);
	if(p3.x<0)p3.x=p3.x+N;
	
	p3.y=l*(p1.x-p3.x)-p1.y;
	p3.y=calculate3(p3.y,1,N);
	if(p3.y<0)p3.y=p3.y+N;
	return p3;
} 

//求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; 
	} 
}
//两点的加法运算 
Point addTwoPoints(Point p1,Point p2)
{
	long t;
	int x1=p1.x;
	int y1=p1.y;
	int x2=p2.x;
	int y2=p2.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+a1)*inverse(N,2*y1) % N;
		}
	}else{
		//不同点相加
		ty=y2-y1;
		tx=x2-x1;
		while(ty<0)
		{
			ty+=N;
		}
		while(tx<0)
		{
			tx+=N;
		} 
		if(tx==0 && ty !=0)
		{
			flag=1;
		}else{
			t=ty*inverse(N,tx) % N;
		}
	}
	if(flag==1)
	{
		p2.x=-1;
		p2.y=-1;
	}else{
		x3=(t*t-x1-x2) % N;
		y3=(t*(x1-x3)-y1) % N;
	//使结果在有限域GF(P)上 
		while(x3<0)
		{
			x3+=N;
		}
		while(y3<0)
		{
			y3+=N;
		}
		p2.x=x3;
		p2.y=y3;
	}	
	return p2;
}
//任务2:倍点运算的递归算法
Point timesPiont(int k,Point p0)
{
	if(k==1){
		return p0;
	} 		
	else if(k==2){
		return addTwoPoints(p0,p0);
	}else{
		return addTwoPoints(p0,timesPiont(k-1,p0));
	} 
}
main(){
	getGeneretor();//求生成元以及阶
	Point p1,p2,p,p4,p5,p6,p7,p8,p9,p10;
	int na,k,h,r,s,u1,u2; 
	printf("选择生成元");
	scanf("%d%d",&p1.x,&p1.y);
	int j=0;
	while(j<N){

		if(genCoordinateList[j].p.x==p1.x&&genCoordinateList[j].p.y==p1.y){
			break;
		}
		printf("j=%d\n",j);
		++j;
	}
	int M = genCoordinateList[j].p_class;
	printf("M=%d",M);

	printf("请输入私钥");
	scanf("%d",&na);
	p2=eccmutiply(na,p1);//	p1.x=0;p1.y=2;p.x=20;p.y=1;
	printf("公钥为(%d,%d)",p2.x,p2.y);
	//p2=mul(p,p1);
	//printf("(%d,%d)",p2.x,p2.y);
	//签名过程
	printf("输入随机数k\n");
	scanf("%d",&k);
	printf("输入hash\n");
	scanf("%d",&h);
	
	p4=eccmutiply(k,p1);
	r=calculate3(p4.x,1,N);
	if(r<0)r=r+N;
	s=inverse(M,k)*(h+na*r)%M;
	if(s<0)s=s+N;
	printf("签名为(%d,%d)\n",r,s);
	printf("========================");
	u1=h*inverse(M,s)%M;	//验证过程
	if(u1<0)u1=u1+M;
	u2=r*inverse(M,s)%M;
	if(u2<0)u2=u2+M;
	printf("u1u2=%d,%d\n",u1,u2);
	p5=eccmutiply(u1,p1);
	printf("sG=(%d,%d)\n",p5.x,p5.y);
	
	p6=eccmutiply(u2,p2);
	printf("HP=(%d,%d)\n",p6.x,p6.y);

	p7=addTwoPoints(p5,p6);
	printf("sG+HP=(%d,%d)\n",p7.x,p7.y);
	if(calculate3(p7.x,1,N)==r){
		printf("通过");
	}else{
		printf("失败");
	}
	 
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值