ECC加密算法 c完成
ECC加密算法的理解
本文主要参照:ECC椭圆曲线加解密原理详解(配图)
- 先理解一下这篇博客 ,ECC椭圆曲线加解密原理详解(配图)
- 通过对博客里面的有限域的椭圆曲线来进行实现里面的公式
- 下面是我的文档报告直接附上,可能有没有表述清楚的可以在评论区评论。代码部分只提供生成公钥的,前面博客中提到的编码到一个点上可以在网上搜索,以及博客中4,5, 6,步骤我会告诉你怎么做。
3.2 ECC算法
3.2.1 ECC算法简介
与 RSA(Ron Rivest,Adi Shamir,Len Adleman 三位天才的名字)一样,ECC(Elliptic Curves Cryptography,椭圆曲线加密)也属于公开密钥算法。
3.2.2 ECC算法中的关键变量
① 基点:基点G,G为椭圆曲线Ep(a,b)上的点
② 阶:如果椭圆曲线上一点P,存在最小的正整数n使得数乘n P = O ∞ ,则将n称为P的阶,若n不存在,则P是无限阶的.
③ 公钥K:则给定私钥k和基点G,根据加法法则,计算K很容易但反过来,给定K和G,求k就非常困难。因为实际使用中的ECC原则上把p取得相当大,n也相当大,要把n个解点逐一算出来列成上表是不可能的。
3.2.4 有限域上的椭圆运算算法
根据3.1.2的相关资料,我们只需要用代码实现算术式,但编程语言中分数和负数是不能对一个数取余的,因此我们需要进行一些转换和计算来将取余的值算出来。
图3-6 椭圆曲线上的加法运算
如图3-6中的k的计算,当P等于Q时需要注意y1可能为0,后面计算阶会对这种情况进行处理说明;计算k时:先判断分子分母的符号,判断是否同号,再将其全部转化为正数,然后判断分子大还是分母大,来计算最大因子,然后化简,化简后再来根据分母当做这个b × b − 1 ≡ 1 ( m o d p )公式的b;来将b的-1次方算出,然后根据分子分母是否同号,给他们附上符号,这样就是分母乘以分子的-1次方来mod p,求一个与他们同余的数字。这就是k。
计算x,y时只需要考虑负数的问题,将负数加上p的倍数就可以转换为一个正数来算出它取余p的值,这个负数的取余计算k也会用到。
对于计算阶-p逆元计算以及np的加法放在后面说,这里主要说一下P+Q当Q与P无任何联系的时候,就直接用上面的公式计算。这个会单独写个函数addDif出来给后面加密用。还会单独再写一个函数 everynp来给直接计算kC2,这是给后面解密用的,因为C2是结构体里没有的,不能直接调用,思想是一样的。计算阶的也会分两个函数写,详细的看3.2.5。
3.2.5 产生生成元和阶
代码会用到两个结构体,一个结构体用来装在有限域上的椭圆,里面的变量有他们的阶,x,y,序号,还有另外的一个结构体数组,这是来装这些点对应的mP的坐标,这里的m从-1到阶 没有 0 ,这个数组的下标就是m ,m为0 对应-P,这样将他的所有mP 保存起来,用于计算阶,以及后面的加密需要用到mp 。
先生成一个有限域椭圆曲线方程式y 2 ≡ x 3 + a x + b ( m o d p ),a,b得是大于0的整数,p需要是大素数
计算生成元就是椭圆曲线在有限域上的点。将0到p之间的x代入y 2 ≡ x 3 + a x + b ( m o d p )来计算这里的,y是小于p的整数,所以y的2次方是小于等于p-1的2次方的,这是一个限定条件,这样来找与x 3 + a x + b 同余的数。
找到生成元后来找阶,阶的定义是如果椭圆曲线上一点P,存在最小的正整数n使得数乘n P = O ∞ ,则将n称为P的阶,根据P + ( − P ) = O ∞ 就是找到mP=-P;P(x,y)的负元是 (x,-y mod p)= (x,p-y) ;若P的y的值为0则将它的阶设置为1024,视为无限阶,以及选择私钥也不能选择这个点,后面任意需要选点的情况都不能选择这个点。阶的话是要用到之前的1P,2P…mP的,因为3P=P+2P,需要两个函数,一个计算同点addsame和不同点 addnp,当点相同时,则从结构体调用m/2P的坐标来计算,不同点则调用m/2P+m/2+1P来计算,把他们保存起来,调用函数找,直到找到m 可以满足cP=-P 否则m为1024就不找了,视作无限阶。根据P + ( − P ) = O ∞推出这个点的阶=m+1;
3.2.6选择基点确定私钥产生公钥
选择一个椭圆上的点作为基点,然后选择一个私钥,私钥k小于这个基点的阶n,生成公开密钥K=kG。这里选择基点是靠输入基点的序号,根据序号找到基点,在调取基点结构体中的数组,找到下标为k的数组,里面的坐标就是kG,因为计算了阶,所以已经有kG的值了。
4 相关算法及实现步骤
4.1坐标结构体和NP结构体
struct add
{
int x;
int y;
//int jie;
};
struct pos
{
struct add np[1024];
int x;
int y;
int num;
int jie;
int a;
};
4.2 有限域上的椭圆运算算法
int calk(int x,int y)//计算k
{
int x1=x;
int y1=y;
int d=1;
int t=0;
int k=0;
if(x1==0||y1==0)
return 0;
if(x1<0)
{
x1=x1*(-1);
t++;
}
if(y1<0)
{
y1=y1*(-1);
t++;
}
// printf("%d,%d\n",x1,y1);
int i=1;
int m,n;
if(x1>y1)
{
m=x1;
n=y1;
}
else
{
m=y1;
n=x1;
}
while((i=m%n))
{
m=n;
n=i;
}
x1=x1/n;
y1=y1/n;
if(y1!=1)
{
for(d=0;;d++)
{
if((d*y1)%p==1)
{
break;
}
}
}
if(t%2