赞
踩
目录
今天介绍一下利用LibTommath数学库实现椭圆曲线加密算法的原理和源码。
1、用户A选定一条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上一点,作为基点G。
2、用户A选择一个私有密钥k,并生成公开密钥K=kG。
3、用户A将Ep(a,b)和点K,G传给用户B。
4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M,并产生一个随机整数r(r<n)。
5、用户B计算点C1=M+rK;C2=rG。
6、用户B将C1、C2传给用户A。
7、用户A接到信息后,计算C1-kC2,结果就是点M。因为
C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
再对点M进行解码就可以得到明文。
密码学中,描述一条Fp上的椭圆曲线,常用到六个参量: T=(p,a,b,G,n,h)。
(p 、a 、b 用来确定一条椭圆曲线,G为基点,n为点G的阶,h 是椭圆曲线上所有点的个数m与n相除的整数部分)
这几个参量取值的选择,直接影响了加密的安全性。参量值一般要求满足以下几个条件:
1、p 当然越大越安全,但越大,计算速度会变慢,200位左右可以满足一般安全要求;
2、p≠n×h;
3、pt≠1 (mod n),1≤t<20;
4、4a3+27b2≠0 (mod p);
5、n 为素数;
6、h≤4。
经评论区提醒,原LibTommath库已经删除了,大家可以在Github上来下载:https://github.com/libtom/libtommath。
以下内容可直接跳过:
首先下载LibTommath的源码,网址为:Best Open Source Mac Libraries Software 2022
下载后,解压如图所示:
打开bn.pdf文件后,这是该库的使用手册,在第10页会看到如下指令,在终端执行make命令即可生成静态库:libtommath.a。
附:在执行编译时可能会生成一些小问题,那就是需要把tommath.h和tommath_superclass.h需要钱修改一下,如下:
只是头文件包含的问题,视具体情况来修改。
下面是ECC源码。
- /* 1、用户A选定一条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上一点,作为基点G。
- 2、用户A选择一个私有密钥k,并生成公开密钥K=kG。
- 3、用户A将Ep(a,b)和点K,G传给用户B。
- 4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M,并产生一个随机整数r(r<n)。
- 5、用户B计算点C1=M+rK;C2=rG。
- 6、用户B将C1、C2传给用户A。
- 7、用户A接到信息后,计算C1-kC2,结果就是点M。因为
- C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M
- 再对点M进行解码就可以得到明文。
- 密码学中,描述一条Fp上的椭圆曲线,常用到六个参量:
- T=(p,a,b,G,n,h)。
- (p 、a 、b 用来确定一条椭圆曲线,G为基点,n为点G的阶,h 是椭圆曲线上所有点的个数m与n相除的整数部分)
- 这几个参量取值的选择,直接影响了加密的安全性。参量值一般要求满足以下几个条件:
- 1、p 当然越大越安全,但越大,计算速度会变慢,200位左右可以满足一般安全要求;
- 2、p≠n×h;
- 3、pt≠1 (mod n),1≤t<20;
- 4、4a3+27b2≠0 (mod p);
- 5、n 为素数;
- 6、h≤4。
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <iostream>
- #include "tommath.h"
- #include <time.h>
-
-
- #define BIT_LEN 800
- #define KEY_LONG 128 //私钥比特长
- #define P_LONG 200 //有限域P比特长
- #define EN_LONG 40 //一次取明文字节数(x,20)(y,20)
-
-
- //得到lon比特长素数
- int GetPrime(mp_int *m,int lon);
- //得到B和G点X坐标G点Y坐标
- void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p);
- //点乘
- 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);
- //点加
- 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);
- //二进制存储密文
- int chmistore(mp_int *a,FILE *fp);
- //把读取的字符存入mp_int型数
- int putin(mp_int *a,char *ch,int chlong);
- //ECC加密
- void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p);
- //ECC解密
- void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p);
- //实现将mp_int数a中的比特串还原为字符串并赋给字符串ch:
- int chdraw(mp_int *a,char *ch);
- //取密文
- int miwendraw(mp_int *a,char *ch,int chlong);
-
-
- int myrng(unsigned char *dst, int len, void *dat)
- {
- int x;
- for (x = 0; x < len; x++) dst[x] = rand() & 0xFF;
- return len;
- }
-
- using namespace std;
- int main(){
-
- cout<<"\n 本程序实现椭圆曲线的加密解密"<<endl;
-
- cout<<"\n------------------------------------------------------------------------\n"<<endl;
-
- mp_int GX;
- mp_int GY;
- mp_int K;//私有密钥
- mp_int A;
- mp_int B;
- mp_int QX;
- mp_int QY;
- mp_int P;//Fp中的p(有限域P)
-
-
- mp_init(&GX);
- mp_init(&GY);
- mp_init(&K);
- mp_init(&A);
- mp_init(&B);
- mp_init(&QX);
- mp_init(&QY);
- mp_init(&P);
-
-
- time_t t;
- srand( (unsigned) time( &t ) );
-
- printf("椭圆曲线的参数如下(以十进制显示):\n");
-
- GetPrime(&P,P_LONG);
- printf("有限域 P 是:\n");
- char temp[800]={0};
- mp_toradix(&P,temp,10);
- printf("%s\n",temp);
-
- GetPrime(&A,30);
- char tempA[800]={0};
- printf("曲线参数 A 是:\n");
- mp_toradix(&A,tempA,10);
- printf("%s\n",tempA);
-
- Get_B_X_Y(&GX,&GY,&B,&A,&P);
-
- char tempB[800]={0};
- printf("曲线参数 B 是:\n");
- mp_toradix(&B,tempB,10);
- printf("%s\n",tempB);
-
- char tempGX[800]={0};
- printf("曲线G点X坐标是:\n");
- mp_toradix(&GX,tempGX,10);
- printf("%s\n",tempGX);
-
- char tempGY[800]={0};
- printf("曲线G点Y坐标是:\n");
- mp_toradix(&GY,tempGY,10);
- printf("%s\n",tempGY);
-
-
- //------------------------------------------------------------------
- GetPrime(&K,KEY_LONG);
- char tempK[800]={0};
- printf("私钥 K 是:\n");
- mp_toradix(&K,tempK,10);
- printf("%s\n",tempK);
-
- Ecc_points_mul(&QX,&QY,&GX,&GY,&K,&A,&P);
-
-
- char tempQX[800]={0};
- printf("公钥X坐标是:\n");
- mp_toradix(&QX,tempQX,10);
- printf("%s\n",tempQX);
-
- char tempQY[800]={0};
- printf("公钥Y坐标是:\n");
- mp_toradix(&QY,tempQY,10);
- printf("%s\n",tempQY);
-
-
- printf("\n------------------------------------------------------------------------\n");
-
- Ecc_encipher(&QX,&QY,&GX,&GY,&A,&P);//加密
-
- printf("\n------------------------------------------------------------------------\n");
-
- Ecc_decipher(&K,&A,&P);//解密
-
- printf("\n------------------------------------------------------------------------\n");
-
- char cc;
- cout<<"\n\n请击一键退出!\n";
- cin>>cc;
-
- mp_clear(&GX);
- mp_clear(&GY);
- mp_clear(&K);//私有密钥
- mp_clear(&A);
- mp_clear(&B);
- mp_clear(&QX);
- mp_clear(&QY);
- mp_clear(&P);//Fp中的p(有限域P)
- return 0;
- }
-
-
- int GetPrime(mp_int *m,int lon){
- mp_prime_random_ex(m, 10, lon,
- (rand()&1)?LTM_PRIME_2MSB_OFF:LTM_PRIME_2MSB_ON, myrng, NULL);
- return MP_OKAY;
- }
-
- void Get_B_X_Y(mp_int *x1,mp_int *y1,mp_int *b, mp_int *a, mp_int *p)
- {
- mp_int tempx,tempy;
- mp_int temp;
- mp_int compare;
- mp_int temp1;
- mp_int temp2;
- mp_int temp3;
- mp_int temp4;
- mp_int temp5;
- mp_int temp6;
- mp_int temp7;
- mp_int temp8;
-
- mp_init_set_int (&compare, 0);
- mp_init(&tempx);
- mp_init(&tempy);
- mp_init(&temp);
- mp_init(&temp1);
- mp_init(&temp2);
- mp_init(&temp3);
- mp_init(&temp4);
- mp_init(&temp5);
- mp_init(&temp6);
- mp_init(&temp7);
- mp_init(&temp8);
-
-
- while(1)
- {
-
- //4a3+27b2≠0 (mod p)
- GetPrime(b,40);
- 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);
- 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);
-
-
-
- mp_clear(&tempx);
- mp_clear(&tempy);
- mp_clear(&temp);
- mp_clear(&temp1);
- mp_clear(&temp2);
- mp_clear(&temp3);
- mp_clear(&temp4);
- mp_clear(&temp5);
- mp_clear(&temp6);
- mp_clear(&temp7);
- mp_clear(&temp8);
-
-
- }
-
- 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)
- {
- mp_int X1, Y1;
- mp_int X2, Y2;
- mp_int X3, Y3;
- mp_int XX1, YY1;
- mp_int A,P;
-
- int i;
- bool zero=false;
- char Bt_array[800]={0};
- char cm='1';
-
- mp_toradix(d,Bt_array,2);
-
- mp_init_set_int(&X3, 0);
- mp_init_set_int(&Y3, 0);
- mp_init_copy(&X1, px);
- mp_init_copy(&X2, px);
- mp_init_copy(&XX1, px);
- mp_init_copy(&Y1, py);
- mp_init_copy(&Y2, py);
- mp_init_copy(&YY1, py);
-
- mp_init_copy(&A, a);
- mp_init_copy(&P, p);
-
- for(i=1;i<=KEY_LONG-1;i++)
- {
- mp_copy(&X2, &X1);
- mp_copy(&Y2, &Y1);
- Two_points_add(&X1,&Y1,&X2,&Y2,&X3,&Y3,&A,zero,&P);
- mp_copy(&X3, &X2);
- mp_copy(&Y3, &Y2);
- if(Bt_array[i]==cm)
- {
-
- mp_copy(&XX1, &X1);
- mp_copy(&YY1, &Y1);
- Two_points_add(&X1,&Y1,&X2,&Y2,&X3,&Y3,&A,zero,&P);
- mp_copy(&X3, &X2);
- mp_copy(&Y3, &Y2);
-
- }
-
- }
-
- if(zero)
- {
- cout<<"It is Zero_Unit!";
- return false;//如果Q为零从新产生D
- }
-
- mp_copy(&X3, qx);
- mp_copy(&Y3, qy);
-
- mp_clear(&X1);
- mp_clear(&Y1);
- mp_clear(&X2);
- mp_clear(&Y2);
- mp_clear(&X3);
- mp_clear(&Y3);
- mp_clear(&XX1);
- mp_clear(&YY1);
- mp_clear(&A);
- mp_clear(&P);
-
- return 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)
- {
- mp_int x2x1;
- mp_int y2y1;
- mp_int tempk;
- mp_int tempy;
- mp_int tempzero;
- mp_int k;
- mp_int temp1;
- mp_int temp2;
- mp_int temp3;
- mp_int temp4;
- mp_int temp5;
- mp_int temp6;
- mp_int temp7;
- mp_int temp8;
- mp_int temp9;
- mp_int temp10;
-
-
- mp_init(&x2x1);
- mp_init(&y2y1);
- mp_init(&tempk);
- mp_init(&tempy);
- mp_init(&tempzero);
- mp_init(&k);
- mp_init(&temp1);
- mp_init(&temp2);
- mp_init_set(&temp3,2);
- mp_init(&temp4);
- mp_init(&temp5);
- mp_init(&temp6);
- mp_init(&temp7);
- mp_init(&temp8);
- mp_init(&temp9);
- mp_init(&temp10);
-
-
- if(zero)
- {
- mp_copy(x1, x3);
- mp_copy(y1, y3);
- zero=false;
- goto L;
- }
- mp_zero(&tempzero);
- mp_sub(x2, x1, &x2x1);
- if(mp_cmp(&x2x1,&tempzero)==-1)
- {
-
- mp_add(&x2x1, p, &temp1);
- mp_zero(&x2x1);
- mp_copy(&temp1, &x2x1);
- }
- mp_sub(y2, y1, &y2y1);
- if(mp_cmp(&y2y1,&tempzero)==-1)
- {
-
- mp_add(&y2y1, p, &temp2);
- mp_zero(&y2y1);
- mp_copy(&temp2, &y2y1);
- }
- if(mp_cmp(&x2x1, &tempzero)!=0)
- {
-
- mp_invmod(&x2x1,p,&tempk);
-
- mp_mulmod(&y2y1, &tempk, p, &k);
- }
- else
- {
- if(mp_cmp(&y2y1, &tempzero)==0)
- {
-
- mp_mulmod(&temp3,y1,p,&tempy);
- mp_invmod(&tempy,p,&tempk);
- mp_sqr(x1, &temp4);
- mp_mul_d(&temp4, 3, &temp5);
- mp_add(&temp5, a, &temp6);
- mp_mulmod(&temp6, &tempk, p, &k);
-
- }
- else
- {
- zero=true;
- goto L;
- }
- }
-
- mp_sqr(&k, &temp7);
- mp_sub(&temp7, x1, &temp8);
- mp_submod(&temp8, x2, p, x3);
-
- mp_sub(x1, x3, &temp9);
- mp_mul(&temp9, &k, &temp10);
- mp_submod(&temp10, y1, p, y3);
-
-
- L:
-
- mp_clear(&x2x1);
- mp_clear(&y2y1);
- mp_clear(&tempk);
- mp_clear(&tempy);
- mp_clear(&tempzero);
- mp_clear(&k);
- mp_clear(&temp1);
- mp_clear(&temp2);
- mp_clear(&temp3);
- mp_clear(&temp4);
- mp_clear(&temp5);
- mp_clear(&temp6);
- mp_clear(&temp7);
- mp_clear(&temp8);
- mp_clear(&temp9);
- mp_clear(&temp10);
-
- return 1;
-
- }
-
- //二进制存储密文
- int chmistore(mp_int *a,FILE *fp)
- {
-
- int i,j;
- char ch;
- char chtem[4];
-
- mp_digit yy=(mp_digit)255;
- for (i=0; i <= a->used - 1; i++) {
-
- chtem[3]=(char)(a->dp[i] & yy);
- chtem[2]=(char)((a->dp[i] >> (mp_digit)8) & yy);
- chtem[1]=(char)((a->dp[i] >> (mp_digit)16) & yy);
- chtem[0]=(char)((a->dp[i] >> (mp_digit)24) & yy);
-
- for(j=0;j<4;j++)
- {
- fprintf(fp,"%c",chtem[j]);
- }
-
- }
-
- ch=char(255);
- fprintf(fp, "%c", ch);
- return MP_OKAY;
- }
-
-
- //把读取的字符存入mp_int型数
- int putin(mp_int *a,char *ch,int chlong)
- {
- mp_digit *temp,yy;
- int i,j,res;
- if(a->alloc<chlong*2/7+2)
- {
- if((res=mp_grow(a,chlong*2/7+2))!=MP_OKAY)
- return res;
- }
-
- a->sign=0;
- mp_zero(a);
- temp=a->dp;
- i=0;
- yy=(mp_digit)15;
-
- if(chlong<4)
- {
- for(j=chlong-1;j>=0;j--)
- {
- *temp |= (mp_digit)(ch[j] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- }
- *temp >>= (mp_digit)8;
- a->used=1;
- return MP_OKAY;
- }
-
- if(chlong<7)
- {
- i+=4;
- *++temp |= (mp_digit)(ch[i-1] & yy);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-2] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-3] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp-- |= (mp_digit)(ch[i-4] & 255); //存放被切分的字符的低四位
-
-
- for(j=chlong-1;j>=i;j--)
- {
- *temp |= (mp_digit)(ch[j] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- }
- *temp >>= (mp_digit)4;
- *temp |= (mp_digit)((ch[i-1] & 255) >> 4); //存放被切分的字符的高四位
-
- a->used=2;
- return MP_OKAY;
- }
-
- //以7个字符为单元循环,把七个字符放入的mp_int 的两个单元中
- for(j=0;j<chlong/7;j++)
- {
- i+=7;
- *++temp |= (mp_digit)(ch[i-1] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-2] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-3] & 255);
- *temp <<= (mp_digit)4;
- *temp-- |= (mp_digit)((ch[i-4] & 255) >> 4); //存放被切分的字符的高四位
-
- *temp |= (mp_digit)(ch[i-4] & yy); //存放被切分的字符的低四位
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-5] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-6] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp++ |= (mp_digit)(ch[i-7] & 255);
-
- temp++;
-
- }
-
- if((chlong>=7)&&(chlong%7!=0)) //剩余字符的存放
- {
- if(chlong%7 < 4) //剩余字符少余4个时,只需一个mp_digit单元存放
- {
- for(j=chlong-1;j>=i;j--)
- {
- *temp |= (mp_digit)(ch[j] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- }
- *temp >>= (mp_digit)8;
- a->used=chlong*2/7+1;
- }
- else
- { //剩余字符不小于4个时,需两个mp_digit单元存放
- i+=4;
- *temp |= (mp_digit)(ch[i-1] & yy);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-2] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-3] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp++ |= (mp_digit)(ch[i-4] & 255); //存放被切分的字符的低四位
-
-
- for(j=chlong-1;j>=i;j--)
- {
- *temp |= (mp_digit)(ch[j] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- }
- *temp >>= (mp_digit)4;
- *temp |= (mp_digit)((ch[i-1] & 255) >> 4); //存放被切分的字符的高四位
-
- a->used=chlong*2/7+2;
- }
-
- }
- else
- {
- a->used=chlong*2/7;
- }
- return MP_OKAY;
- }
-
-
- void Ecc_encipher(mp_int *qx,mp_int *qy, mp_int *px, mp_int *py,mp_int *a,mp_int *p){ //公钥X、Y坐标,曲线G点X、Y坐标,曲线参数A,有限域P
-
- mp_int mx, my;
- mp_int c1x, c1y;
- mp_int c2x, c2y;
- mp_int r;
- mp_int tempx, tempy;
- bool zero=false;
- FILE *fp,*fq;
- int i;
- char miwenx[280]={0};
- char miweny[280]={0};
- char stemp[650]={0};
-
-
- mp_init(&mx);
- mp_init(&my);
- mp_init(&c1x);
- mp_init(&c1y);
- mp_init(&c2x);
- mp_init(&c2y);
- mp_init(&r);
- mp_init(&tempx);
- mp_init(&tempy);
-
- GetPrime(&r, 100);
-
-
- char filehead[60],filefoot[20],filename[85]={0};
- cout<<"请输入您要加密文件的存放路径和文件名(如: c:\\000\\大整数运算 ):"<<endl;
- cin>>filehead;
- cout<<"请输入您要加密文件的扩展名(如: .doc ):"<<endl;
- cin>>filefoot;
- strcpy(filename,filehead);
- strcat(filename,filefoot);
-
-
- //打开要加密文件
- if((fp=fopen(filename,"rb"))==NULL)
- {
- printf("can not open the file!");
- exit(1);
- }
-
- unsigned int FileLong=0;//文件字符长度
- char ChTem;//临时字符变
- int Frequency=0;
- int Residue=0;
-
- while( !feof(fp) )//找文件字符长度
- {
- ChTem = fgetc( fp );
- FileLong++;
- }
- --FileLong;
-
-
- Frequency = FileLong/EN_LONG;
- Residue = FileLong%EN_LONG;
- printf("Frequency= %d, Residue= %d\n", Frequency, Residue);
-
- int enlongtemp=EN_LONG/2;
- //printf("%d\n",Frequency);
- //printf("%d\n",Residue);
-
- char filemi[85];
- strcpy(filemi,filehead);
- strcat(filemi,"密文");
- strcat(filemi,filefoot);
-
-
- //打开保存密文文件
- if((fq=fopen(filemi,"wb"))==NULL)
- {
- printf("can not open the file!\n");
- exit(1);
- }
-
- printf("\n开始加密...\n");
-
- rewind(fp);
- clock_t start, finish;
- double duration;
-
- for(i=0; i<Frequency; i++)
- {
-
- fread(miwenx,1,enlongtemp,fp);//读入字符串
- miwenx[enlongtemp]=char(255);
-
- fread(miweny,1,enlongtemp,fp);//读入字符串
- miweny[enlongtemp]=char(255);
-
- putin(&mx, miwenx,enlongtemp+1);//文件存入
- putin(&my, miweny,enlongtemp+1);//文件存入
-
-
- Ecc_points_mul(&c2x,&c2y,px,py,&r,a,p);//加密
- Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p);
- Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);
-
- //保存密文
- chmistore(&c1x,fq);
- chmistore(&c1y,fq);
- chmistore(&c2x,fq);
- chmistore(&c2y,fq);
-
- }
- //剩余字符处理
- if ( Residue > 0)
- {
- 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);//加密
- Ecc_points_mul(&tempx,&tempy,qx,qy,&r,a,p);
- Two_points_add(&mx,&my,&tempx,&tempy,&c1x,&c1y,a,zero,p);
-
-
- //保存密文
- chmistore(&c1x,fq);
-
- chmistore(&c1y,fq);
-
- chmistore(&c2x,fq);
-
- chmistore(&c2y,fq);
- }
-
- cout<<"\nok!加密完毕!"<<endl;
- cout<<"密文以二进制保存"<<endl;
- cout<<"密文存放路径为 "<<filemi<<endl ;
-
-
- fclose(fq);
- fclose(fp);
- mp_clear(&mx);
- mp_clear(&my);
- mp_clear(&c1x);
- mp_clear(&c1y);
- mp_clear(&c2x);
- mp_clear(&c2y);
- mp_clear(&r);
- mp_clear(&tempx);
- mp_clear(&tempy);
-
-
- }
-
- //取密文
-
- int miwendraw(mp_int *a,char *ch,int chlong)
- {
- mp_digit *temp;
- int i,j,res;
-
- if(a->alloc<chlong/4)
- {
- if((res=mp_grow(a,chlong/4))!=MP_OKAY)
- return res;
- }
-
- a->alloc=chlong/4;
- a->sign=0;
- mp_zero(a);
- temp=a->dp;
- i=0;
-
- for(j=0;j<chlong/4;j++)
- {
- i+=4;
- *temp |= (mp_digit)(ch[i-4] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-3] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp |= (mp_digit)(ch[i-2] & 255);
- *temp <<= (mp_digit)CHAR_BIT;
- *temp++ |= (mp_digit)(ch[i-1] & 255);
- }
- a->used=chlong/4;
- return MP_OKAY;
- }
-
- //实现将mp_int数a中的比特串还原为字符串并赋给字符串ch:
- int chdraw(mp_int *a,char *ch)
- {
- int i,j;
- mp_digit *temp,xx,yy;
-
- temp=a->dp;
- i=0;
- yy=(mp_digit)255; //用于位与运算,取八位比特串
- xx=(mp_digit)15; //用于位与运算,取四位比特串
-
- for(j=0;j<a->used/2;j++) //以两个单元为循环,把两个单元的比特串赋给7个字符
- {
- i+=7;
- ch[i-4]=(char)(*++temp & xx);
- ch[i-3]=(char)((*temp >> (mp_digit)4) & yy);
- ch[i-2]=(char)((*temp >> (mp_digit)12) & yy);
- ch[i-1]=(char)((*temp-- >> (mp_digit)20) & yy);
-
- ch[i-7]=(char)(*temp & yy);
- ch[i-6]=(char)((*temp >> (mp_digit)8) & yy);
- ch[i-5]=(char)((*temp >> (mp_digit)16) & yy);
- ch[i-4] <<= 4;
- ch[i-4]+=(char)((*temp++ >> (mp_digit)24) & xx);
- temp++;
- }
- if(a->used%2!=0) //剩于一个单元的处理
- {
- ch[i++] = (char)(*temp & yy);
- ch[i++] = (char)((*temp >> (mp_digit)8) & yy);
- ch[i++] = (char)((*temp >> (mp_digit)16) & yy);
- }
- --i;
- while(int(ch[i]&0xFF) != 255 && i>0) i--;
- return i;
-
- }
-
- void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p){
-
- mp_int c1x, c1y;
- mp_int c2x, c2y;
- mp_int tempx, tempy;
- mp_int mx, my;
- mp_int temp;
-
- mp_init(&temp);
- mp_init(&c1x);
- mp_init(&c1y);
- mp_init(&c2x);
- mp_init(&c2y);
- mp_init(&tempx);
- mp_init(&tempy);
- mp_init(&mx);
- mp_init(&my);
-
- mp_int tempzero;
- mp_init(&tempzero);
-
- int i;
- char stemp[700]={0};
- FILE *fp,*fq;
- bool zero=false;
- clock_t start, finish;
- double duration;
-
-
- char filehead[60],filefoot[20],filename[85]={0};
- cout<<"请输入您要解密的文件的存放路径和文件名(如: c:\\000\\大整数运算 ):"<<endl;
- cin>>filehead;
- cout<<"请输入您要解密的文件的扩展名(如: .doc ):"<<endl;
- cin>>filefoot;
- strcpy(filename,filehead);
- strcat(filename,filefoot);
-
- printf("\n开始解密\n");
-
- if((fp=fopen(filename,"rb"))==NULL)
- {
- printf("can not open the file!");
- exit(1);
- }
-
- //打开保存解密结果文件
- char filemi[80];
- strcpy(filemi, filehead);
- strcat(filemi, "解密");
- strcat(filemi, filefoot);
-
- if((fq=fopen(filemi,"wb"))==NULL)
- {
- printf("can not open the file!");
- exit(1);
- }
-
-
- rewind(fp);
- while(!feof(fp))
- {
- 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);
- i=0;
- while(1)
- {
- stemp[i]=fgetc(fp);
- if(i%4==0)
- {
- if(int(stemp[i]&0xFF) == 255 ) goto L2;
- }
- i++;
- }
-
- L2: miwendraw(&c1y, stemp, i);
- i=0;
- while(1)
- {
- stemp[i]=fgetc(fp);
- if(i%4==0)
- {
- if(int(stemp[i]&0xFF) == 255 ) goto L3;
- }
- i++;
- }
-
- L3: miwendraw(&c2x, stemp, i);
- i=0;
- while(1)
- {
- stemp[i]=fgetc(fp);
- if(i%4==0)
- {
- if(int(stemp[i]&0xFF) == 255 ) goto L4;
- }
- i++;
- }
-
- L4: miwendraw(&c2y, stemp, i);
-
- mp_zero(&tempzero);
- if(mp_cmp(&c1x, &tempzero)==0) break;
-
- Ecc_points_mul(&tempx, &tempy, &c2x, &c2y, k, a, p);
-
- mp_neg(&tempy, &temp);
- 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(int kk=0;kk<chtem;kk++)
- {
- fprintf(fq,"%c",stemp[kk]);
-
- }
-
-
- }
-
- cout<<"\nok!解密完毕!"<<endl;
- cout<<"解密后的文字存放路径为 "<<filemi<<endl;
-
- fclose(fq);
- fclose(fp);
- mp_clear(&c1x);
- mp_clear(&c1y);
- mp_clear(&c2x);
- mp_clear(&c2y);
- mp_clear(&tempx);
- mp_clear(&tempy);
- mp_clear(&mx);
- mp_clear(&my);
- mp_clear(&temp);
-
-
- }
在命令行执行:
$ g++ ecc.cpp -o main libtommath.a
生成可执行文件main。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。