基于TOM算法库的ECC加密算法的C语言设计与实现 研究生 徐立均 内容: 一、源代码下载 二、ECC算法的设计思想三、椭圆曲线参数的选取和基点的确定 四、椭圆曲线的点加和纯量乘法 五、加密文件的读入与输出 六、密文的存取和读入 七、ECC加密的实现八、ECC解密的实现 九、测试结果及分析

一、源代码下载

本文使用了TOM算法库实现了椭圆曲线公钥密码体制,能对各类不同的磁盘文件进行加密

和解密。

1 请下载可执行程序MY_ECC.exe,此程序无需任何额外的LIB或DLL,可在Windows下

独立运行,运行情况如下:

2 请下载源代码source.rar:

编译此源代码需要使用TOM的高精度算法库

MathLib.lib

和相关的头文件

tommath.h

tommath_class.h

tommath_superclass.h

一并打包在source.rar中,请下载

3 对于TOM的高精度算法库的详细说明,请看本站C语言:

二、 ECC算法的设计思想

根据椭圆曲线进行加密通信的过程,首先选定一个适合加密的椭圆曲线Ep(a,b),并取

椭圆曲线上一点,作为基点G。选择一个私有密钥k,并生成公开密钥K=kG。加密时,将

明文编码到Ep(a,b)上一点M,并产生一个随机整数r(r < n)。计算点C1=M+rK;C2=rG。

将C1、C2存入密文。解密时,从密文中读出C1、C2,计算C1-kC2,根据:

C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M,

解得的结果就是点M,即明文。

三、椭圆曲线参数的选取和基点的确定

并不是所有的椭圆曲线都适合加密,y^2=x^3+ax+b是一类可以用来加密的椭圆曲线,也

是最为简单的一类。下面我们就选用y^2=x^3+ax+b作为我们的加密曲线。这条曲线定义在Fp

上:两个满足下列条件的小于p(p为素数)的非负整数a、b:4a3+27b2≠0 (mod p) 则满足

下列方程的所有点(x,y),再加上 无穷远点∞ ,构成一条椭圆曲线。y^2=x^3+ax+b(mod p)

其中 x,y属于0到p-1间的整数,并将这条椭圆曲线记为Ep(a,b)。

参数P的选取:p 当然越大越安全,但越大,计算速度会变慢,200位左右可以满足一

般安全要求;我们将p取为200比特位的素数。

参数a、b的选取:先随机产生小于P-1的正整数作为参数a,依据条件

4a3+27b2≠0 (mod p)判断随机产生的小于P-1的正整数是否适合作为参数b.

基点的确定:随着参数a,b,p确定,这条曲线y^2=x^3+ax+b就定下来了。先随机产生0

到p-1间的整数作为基点x坐标,计算x^3+ax+b的结果再开方就得出基点y坐标。

上述具体程序实现如下:

……

while(1)

{

//4a3+27b2≠0 (mod p)

GetPrime(b,40);//先随机产生一个参数B

mp_expt_d(a, 3, &temp1);

mp_sqr(b, &temp2);

mp_mul_d(&temp1, 4, &temp3);

mp_mul_d(&temp2, 27, &temp4);

mp_add(&temp3, &temp4, &temp5);

mp_mod(&temp5,p,&temp);

if(mp_cmp(&temp, &compare)!=0 )

{

break; //满足条件跳出循环

}

}

//y2=x3+ax+b,随机产生X坐标,根据X坐标计算Y坐标

GetPrime(x1,30);// 随机产生30比特长的X坐标

mp_expt_d(x1, 3, &temp6);

mp_mul(a, x1, &temp7);

mp_add(&temp6, &temp7, &temp8);

mp_add(&temp8, b, &tempx);

mp_sqrt(&tempx, y1);//得到Y坐标

……..

私钥的确定:随机选取1到P-1之间的素数作为私钥d.

公钥的确定:由d乘我们所确定的基点得到公钥K,即K=dG。

四、 椭圆曲线的点加和纯量乘法

对于一般的椭圆曲线方程y^2+a1xy+a3y=x^3+a2x^2+a4x+a6, 设点P(x1,y1),Q(x2,y2)的和

R(x3,y3)的坐标。R(x3,y3)的计算公式如下:

x3=k^2+ka1+a2+x1+x2;

y3=k(x1-x4)-y1-a1x4-a3;

其中k= (y1-y2)/(x1-x2)

当P≠Q时

k=(3x2+2a2x+a4 -a1y) /(2y+a1x+a3)

当P=Q时,对于椭圆曲线方程Y^2=X^3+aX+b,上述的公式变为:

x3=θ2- x1-x2;

y3=θ(x1-x3)-y1

其中θ=(y1-y2)/(x1-x2) 当P≠Q时;

θ=(3x1^2-a)/2y1 当P=Q时

由上述运算公式,可以得出点积mP的运算,即mP=P+P+…+P,共m个P相加,这里m∈N.

具体算法为:设m的二进制表示为

m=(m_n-1m_n-2…m1m0),其中m_n-1=1,Q=P,从左到右依次计算:

for(I=n-2 to 0)

{ Q=2Q;

if(mi ==1) Q=Q+P;

}

则Q=mP.

Return ;

函数原形为:

bool Ecc_points_mul(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *d,mp_int

*a,mp_int *p)

成功返回true。

int Two_points_add(mp_int *x1,mp_int *y1,mp_int *x2,mp_int *y2,mp_int *x3,mp_int

*y3,mp_int *a,bool zero,mp_int *p)

成功返回1。

五、加密文件的读入与输出

mp_digit只用28比特,因此一个单元最多可存放三个半字节。为充分利用存取空间,采用

一个单元放三个半字节。

1. 函数putin()实现将明文的二进制比特串赋给mp_int数a:

主要循环部分及说明如下:

//chlong为要存入的字符数组长

for(j=0;j<<="(mp_digit)CHAR_BIT;" 存入高8位并向左移8位,以便放入下一个字符="" 存入字符="" 左移8位="" 并向左移4位,以便放入下一个字符的高四位="" *temp--="" 255)="">> 4); //存放被切分的字符的高四位,temp跳回前一个单元

//存入第一单元

*temp |= (mp_digit)(ch[i-4] & yy); //存放被切分的字符的低四位,yy=(mp_digit)15

*temp <<= (mp_digit)CHAR_BIT; //向左移8位,以便放入下一个字符

*temp |= (mp_digit)(ch[i-5] & 255); //存入字符

*temp <<= (mp_digit)CHAR_BIT; //左移8位

*temp |= (mp_digit)(ch[i-6] & 255); //存入字符

*temp <<= (mp_digit)CHAR_BIT; //左移8位

*temp++ |= (mp_digit)(ch[i-7] & 255); //存放被切分的字符的低四位,temp跳到后一个单元

temp++; //再向后跳一单元,这样和下次的++temp实现每次循环跳两个单元

}

函数原型为:int putin(mp_int *a,char *ch,int chlong)

成功返回0

2.函数chdraw()实现将mp_int数a中的比特串还原为字符串并赋给字符串ch:

chdraw和putin是相反过程,将putin存入字符的过程反过来取出字符。

函数原型为:int chdraw(mp_int *a,char *ch)

成功返回0

六、密文的存取和读入

此过程难点是如何保证存入文件后,再从文件中读取密文并存入mp_int型数后,和原

存放密文的mp_int型数不能有一个比特位的改变。

存取时先存*mp->dp的最高8位,再依次往下存后面3个8位。依据*mp->dp的特点,

最高8位为0000xxxx,因此,可将255作为一个密文段的结束标志,把前一密文段和后一

密文段区分开。这样在密文文件中,密文的存取结构为:

0000xxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|0000xxxx|……|11111111|0000xxxx|xxxxxxxx|…..

0字节 1字节 2字节 3字节 4字节 4x字节 下一加密段

x为1或0

利用fgetc每次读取一个字符,并赋值给一个字符数组。当a[i]=255,且i%4=0时截止。

读出之后赋值就简单了。

存密文:int chmistore(mp_int *a,FILE *fp) 成功返回0

把密文赋给mp_int型数a:int miwendraw(mp_int *a,char *ch,int chlong) 成功返回0

七、ECC加密的实现

加密时因P长度取值为200比特,所以所取明文长度应在0到199比特之间,另外需

要一个附加的标志字节char(255),所以一次取明文最大长为191比特。在本程序中一次取

20字节。和RSA不同,ECC运算是基于点的运算。一个点有两个参数,一个X坐标,一

个Y坐标。所以取明文时需一次取两段,前一段做X坐标,后一段做Y坐标。因此,一次

加密明文为40字节。由于每次加密要取两段,引发了另外一个问题:当加密文件末尾所剩

明文长度小于20字节时的处理。在本程序中,我们的解决是将剩余明文取作X,而将Y取

作0,且不加标志字节char(255),这样解密时,程序在Y中找不到标志字节char(255),就

不会往解密文中存任何东西。

取得明文后,产生一个随机整数r(r

C2坐标c1x,c1y,c2x,c2y依次存入密文文件。

for(i=0; i 0)// Residue为剩余字符数

{

if (Residue <= enlongtemp )

{

fread(miwenx,1,Residue,fp);//读入字符串

miwenx[Residue]=char(255);

putin(&mx, miwenx,Residue+1);//文件存入

mp_zero(&my);

}

else

{

fread(miwenx,1,enlongtemp,fp);//读入字符串

miwenx[enlongtemp]=char(255);

fread(miweny,1,Residue-enlongtemp,fp);//读入字符串

miweny[Residue-enlongtemp]=char(255);

putin(&mx, miwenx,enlongtemp+1);//文件存入

putin(&my, miweny,Residue-enlongtemp+1);//文件存入

}

//加密

Ecc_points_mul(&c2x,&c2y,px,py,&r,a,p); //C2=rG

Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p); // rK

Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);// C1=M+rK

//保存密文

chmistore(&c1x,fq);

chmistore(&c1y,fq);

chmistore(&c2x,fq);

chmistore(&c2y,fq);

}

函数原型为:void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int

*a,mp_int *p);

八、ECC解密的实现

解密时,依据存密文时放入的结束标志255,读入密文。依次取4段,调用miwendraw

将密文存入mp_int型数中,还原为加密时存入的点C1和C2坐标c1x,c1y,c2x,c2y。依据

C1-dC2=M+rK-k(rG)=M+rK-r(kG)=M。计算C1-dC2 (d为私钥),得到明文点坐标mx,my。其

中两点减的计算可如下:

-Q=(X,-Y);P-Q=P+(-Q);-Y=P-Y;

计算C1-dC2完毕后调用chdraw取出mp_int中的明文比特串,依次存入解密文件中,

完成解密。

while(!feof(fp))

{

//取C1点X坐标

i=0;

while(1)

{

stemp[i]=fgetc(fp);

if(i%4==0)

{

if(int(stemp[i]&0xFF) == 255 ) goto L1;

}

i++;

}

L1: miwendraw(&c1x, stemp, i);

………… //取其他坐标

Ecc_points_mul(&tempx, &tempy, &c2x, &c2y, k, a, p); // 计算dC2

mp_neg(&tempy, &temp);// -Q=(X,-Y)

Two_points_add(&c1x,&c1y,&tempx,&temp,&mx,&my,a,zero,p);

int chtem;

chtem=chdraw(&mx,stemp);//从ming中取出字符串

//保存解密结果

for(int kk=0;kk < chtem;kk++)

{

fprintf(fq,"%c",stemp[kk]);

}

chtem=chdraw(&my,stemp);//从ming中取出字符串

//保存解密结果

for(kk=0;kk < chtem;kk++)

{

fprintf(fq,"%c",stemp[kk]);

}

}

函数原型为:void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p);

九、测试结果及分析

为验证系统的加密解密功能, 对系统进行了如下测试:

测试环境

Intel p4 CPU 1.5G 256M RAM windows2000 advanted server

测试结果

利用系统对文本文件、BMP、WORD、EXCEL、EXE等文件进行加密,然后解密。

验证结果表明,给定的明文经系统加密后再解密的结果完全一致,没有一个比特的偏差。较好

的实现了ECC的功能。

转载http://210.40.7.188/NEW/ECC_XLJ/index.htm

椭圆曲线密码体制算法C语言,椭圆曲线密码的C语言设计与实现相关推荐

  1. c语言字符密码验证码,c语言下的学生管理系统(含密码加密和验证码).docx

    c语言下的学生管理系统(含密码加密和验证码).docx #include #include #include #include #include #define N 20void input();// ...

  2. c语言作业 密码翻译,C语言作业 有一行电文,以按下面规律译成密码

    C语言的凯撒加密Description 有一行电文,请将电文中所有字母按A→F,B→G,--,U→Z,V→A,W→B,X #includeintmain(){charc;while((c=getcha ...

  3. c语言caesar密码编程,C语言程序设计#凯撒Caesar密码

    #include #include//颜色 using namespace std; int jiami(); int jiemi(); int main() { printf("***** ...

  4. 椭圆曲线密码体制(ECC)

    2002年,美国SUN公司将其开发的椭圆加密技术赠送给开放源代码工程 公钥密码体制根据其所依据的难题一般分为三类:大整数分解问题类.离散对数问题类.椭圆曲线类.有时也把椭圆曲线类归为离散对数类. 椭圆 ...

  5. SM2椭圆曲线公钥密码算法的C语言实现(基于Miracl大数运算库)

    SM2椭圆曲线公钥密码算法的C语言实现(基于Miracl大数运算库) 实验环境 预备知识 FpF_pFp​ 及椭圆曲线 素域 FpF_pFp​ FpF_pFp​ 上的椭圆曲线 FpF_pFp​ 上椭圆 ...

  6. 国密算法Go语言实现(详解)(九) ——SM2(椭圆曲线公钥密码算法)

    国密算法Go语言实现(详解)(九) --SM2(椭圆曲线公钥密码算法) 原创代码:https://github.com/ZZMarquis/gm 引用时,请导入原创代码库.本文仅以注释方式详解代码逻辑 ...

  7. 【密码算法 之十四】非对称算法,ECC椭圆曲线算法 之 ECDSA、ECDH、SM2、SM9等

    文章目录 1. ECC椭圆曲线 1.1 曲线类型 1.2 曲线标准 1.3 表示方法 1.4 曲线运算 1.4.1 点加(Point Addition) 1.4.2 点乘(Point Multipli ...

  8. 国密算法Go语言实现(详解)(十) ——SM2(椭圆曲线公钥密码算法)

    国密算法Go语言实现(详解)(十) --SM2(椭圆曲线公钥密码算法) 原创代码:https://github.com/ZZMarquis/gm 引用时,请导入原创代码库.本文仅以注释方式详解代码逻辑 ...

  9. 【密码学Sage代码】椭圆曲线加密/解密(基于《密码编码学与网络安全——原理与实践(第七版)》)

    [密码学Sage代码]椭圆曲线加密/解密(基于<密码编码学与网络安全--原理与实践(第七版)>) 教材内容: 实践的Sage代码: #[静水流深Sage代码]使用椭圆曲线密码体制进行加密/ ...

  10. GMSSL :SM2椭圆曲线公钥密码算法——数字签名算法4

    2021SC@SDUSC 目录 一.ECDSA介绍 二.代码分析 一.ECDSA介绍 ECDSA的全名是Elliptic Curve DSA,即椭圆曲线DSA.它是Digital Signature ...

最新文章

  1. 携号转网:欢迎比阻挠更为有效
  2. maven <skip></skip>属性
  3. 计算机房英语视频,雅思听力场景词汇:计算机房场景
  4. DL之DNN:自定义2层神经网络TwoLayerNet模型(计算梯度两种方法)利用MNIST数据集进行训练、预测
  5. 网工协议基础(3) IP地址
  6. cadence软件_IC苦逼搬运工入职之——Cadence基本操作(1)
  7. Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收(九)
  8. linux之ClamAV杀毒软件安装配置
  9. java.net.SocketException: socket failed: EACCES (Permission denied)
  10. imx6ull的boot, 之我的理解
  11. 集合经验模态分解matlab,LMD经验模态分解matlab程序(2)
  12. PD快速充电协议(转)
  13. 【方向盘】轰动从未停止,感动从未消失。他,是周杰伦
  14. 【技术贴】关于IE主页被篡改、假IE的根治方法。。。
  15. Java实现生成并下载Excel文件
  16. 小仙女讲JVM(1)—综述
  17. 端点科技春招笔试回忆(Java方向)
  18. Devart Excel Add-ins Crack
  19. centos 安装惠普打印机驱动
  20. 生信分析- Pysam应用

热门文章

  1. PID原理(图形并茂)
  2. Java 如何给现有PDF文档添加页码
  3. Windows徽标键(WinKey)的屏蔽和恢复
  4. 把计算机过程描述,计算机解决问题的过程
  5. CSS中的四种定位以及top和margin-top的区别
  6. 设置view 的MarginTop
  7. 酸了,深圳一普通中学老师工资单曝光,秒杀程序员!
  8. 点餐系统mysql设计,SpringBoot 微信点餐系统 1:数据库表设计
  9. 蚌埠学院教务系统自动导入课程表到小米/Redmi手机小爱同学课程表使用说明
  10. 我辞去了年收入50万的工作,去做在线教育的老师