椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)
/* 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.h>
#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 = ; x < len; x++) dst[x] = rand() & 0xFF;
return len;
} void 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[]={};
mp_toradix(&P,temp,);
printf("%s\n",temp); GetPrime(&A,);
char tempA[]={};
printf("曲线参数 A 是:\n");
mp_toradix(&A,tempA,);
printf("%s\n",tempA); Get_B_X_Y(&GX,&GY,&B,&A,&P); char tempB[]={};
printf("曲线参数 B 是:\n");
mp_toradix(&B,tempB,);
printf("%s\n",tempB); char tempGX[]={};
printf("曲线G点X坐标是:\n");
mp_toradix(&GX,tempGX,);
printf("%s\n",tempGX); char tempGY[]={};
printf("曲线G点Y坐标是:\n");
mp_toradix(&GY,tempGY,);
printf("%s\n",tempGY); //------------------------------------------------------------------
GetPrime(&K,KEY_LONG);
char tempK[]={};
printf("私钥 K 是:\n");
mp_toradix(&K,tempK,);
printf("%s\n",tempK); Ecc_points_mul(&QX,&QY,&GX,&GY,&K,&A,&P); char tempQX[]={};
printf("公钥X坐标是:\n");
mp_toradix(&QX,tempQX,);
printf("%s\n",tempQX); char tempQY[]={};
printf("公钥Y坐标是:\n");
mp_toradix(&QY,tempQY,);
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)
} int GetPrime(mp_int *m,int lon){
mp_prime_random_ex(m, , lon,
(rand()&)?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, );
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()
{ //4a3+27b2≠0 (mod p)
GetPrime(b,);
mp_expt_d(a, , &temp1);
mp_sqr(b, &temp2);
mp_mul_d(&temp1, , &temp3);
mp_mul_d(&temp2, , &temp4);
mp_add(&temp3, &temp4, &temp5);
mp_mod(&temp5,p,&temp); if(mp_cmp(&temp, &compare)!= )
{
break;
}
} //y2=x3+ax+b,随机产生X坐标,根据X坐标计算Y坐标
GetPrime(x1,);
mp_expt_d(x1, , &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[]={};
char cm=''; mp_toradix(d,Bt_array,); mp_init_set_int(&X3, );
mp_init_set_int(&Y3, );
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=;i<=KEY_LONG-;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,);
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)==-)
{ mp_add(&x2x1, p, &temp1);
mp_zero(&x2x1);
mp_copy(&temp1, &x2x1);
}
mp_sub(y2, y1, &y2y1);
if(mp_cmp(&y2y1,&tempzero)==-)
{ mp_add(&y2y1, p, &temp2);
mp_zero(&y2y1);
mp_copy(&temp2, &y2y1);
}
if(mp_cmp(&x2x1, &tempzero)!=)
{ mp_invmod(&x2x1,p,&tempk); mp_mulmod(&y2y1, &tempk, p, &k);
}
else
{
if(mp_cmp(&y2y1, &tempzero)==)
{ mp_mulmod(&temp3,y1,p,&tempy);
mp_invmod(&tempy,p,&tempk);
mp_sqr(x1, &temp4);
mp_mul_d(&temp4, , &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 ; } //二进制存储密文
int chmistore(mp_int *a,FILE *fp)
{ int i,j;
char ch;
char chtem[]; mp_digit yy=(mp_digit);
for (i=; i <= a->used - ; i++) { chtem[]=(char)(a->dp[i] & yy);
chtem[]=(char)((a->dp[i] >> (mp_digit)) & yy);
chtem[]=(char)((a->dp[i] >> (mp_digit)) & yy);
chtem[]=(char)((a->dp[i] >> (mp_digit)) & yy); for(j=;j<;j++)
{
fprintf(fp,"%c",chtem[j]);
} } ch=char();
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*/+)
{
if((res=mp_grow(a,chlong*/+))!=MP_OKAY)
return res;
} a->sign=;
mp_zero(a);
temp=a->dp;
i=;
yy=(mp_digit); if(chlong<)
{
for(j=chlong-;j>=;j--)
{
*temp |= (mp_digit)(ch[j] & );
*temp <<= (mp_digit)CHAR_BIT;
}
*temp >>= (mp_digit);
a->used=;
return MP_OKAY;
} if(chlong<)
{
i+=;
*++temp |= (mp_digit)(ch[i-] & yy);
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp-- |= (mp_digit)(ch[i-] & ); //存放被切分的字符的低四位 for(j=chlong-;j>=i;j--)
{
*temp |= (mp_digit)(ch[j] & );
*temp <<= (mp_digit)CHAR_BIT;
}
*temp >>= (mp_digit);
*temp |= (mp_digit)((ch[i-] & ) >> ); //存放被切分的字符的高四位 a->used=;
return MP_OKAY;
} //以7个字符为单元循环,把七个字符放入的mp_int 的两个单元中
for(j=;j<chlong/;j++)
{
i+=;
*++temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit);
*temp-- |= (mp_digit)((ch[i-] & ) >> ); //存放被切分的字符的高四位 *temp |= (mp_digit)(ch[i-] & yy); //存放被切分的字符的低四位
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp++ |= (mp_digit)(ch[i-] & ); temp++; } if((chlong>=)&&(chlong%!=)) //剩余字符的存放
{
if(chlong% < ) //剩余字符少余4个时,只需一个mp_digit单元存放
{
for(j=chlong-;j>=i;j--)
{
*temp |= (mp_digit)(ch[j] & );
*temp <<= (mp_digit)CHAR_BIT;
}
*temp >>= (mp_digit);
a->used=chlong*/+;
}
else
{ //剩余字符不小于4个时,需两个mp_digit单元存放
i+=;
*temp |= (mp_digit)(ch[i-] & yy);
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp++ |= (mp_digit)(ch[i-] & ); //存放被切分的字符的低四位 for(j=chlong-;j>=i;j--)
{
*temp |= (mp_digit)(ch[j] & );
*temp <<= (mp_digit)CHAR_BIT;
}
*temp >>= (mp_digit);
*temp |= (mp_digit)((ch[i-] & ) >> ); //存放被切分的字符的高四位 a->used=chlong*/+;
} }
else
{
a->used=chlong*/;
}
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[]={};
char miweny[]={};
char stemp[]={}; 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, ); char filehead[],filefoot[],filename[]={};
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();
} unsigned int FileLong=;//文件字符长度
char ChTem;//临时字符变
int Frequency=;
int Residue=; while( !feof(fp) )//找文件字符长度
{
ChTem = fgetc( fp );
FileLong++;
}
--FileLong; Frequency = FileLong/EN_LONG;
Residue = FileLong%EN_LONG; int enlongtemp=EN_LONG/;
//printf("%d\n",Frequency);
//printf("%d\n",Residue); char filemi[];
strcpy(filemi,filehead);
strcat(filemi,"密文");
strcat(filemi,filefoot); //打开保存密文文件
if((fq=fopen(filemi,"wb"))==NULL)
{
printf("can not open the file!\n");
exit();
} printf("\n开始加密...\n"); rewind(fp);
for(i=; i<Frequency; i++)
{ fread(miwenx,,enlongtemp,fp);//读入字符串
miwenx[enlongtemp]=char(); fread(miweny,,enlongtemp,fp);//读入字符串
miweny[enlongtemp]=char(); putin(&mx, miwenx,enlongtemp+);//文件存入
putin(&my, miweny,enlongtemp+);//文件存入 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 > )
{
if (Residue <= enlongtemp )
{
fread(miwenx,,Residue,fp);//读入字符串
miwenx[Residue]=char(); putin(&mx, miwenx,Residue+);//文件存入 mp_zero(&my); }
else
{ fread(miwenx,,enlongtemp,fp);//读入字符串
miwenx[enlongtemp]=char(); fread(miweny,,Residue-enlongtemp,fp);//读入字符串
miweny[Residue-enlongtemp]=char(); putin(&mx, miwenx,enlongtemp+);//文件存入 putin(&my, miweny,Residue-enlongtemp+);//文件存入
} 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/)
{
if((res=mp_grow(a,chlong/))!=MP_OKAY)
return res;
} a->alloc=chlong/;
a->sign=;
mp_zero(a);
temp=a->dp;
i=; for(j=;j<chlong/;j++)
{
i+=;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp |= (mp_digit)(ch[i-] & );
*temp <<= (mp_digit)CHAR_BIT;
*temp++ |= (mp_digit)(ch[i-] & );
}
a->used=chlong/;
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=;
yy=(mp_digit); //用于位与运算,取八位比特串
xx=(mp_digit); //用于位与运算,取四位比特串 for(j=;j<a->used/;j++) //以两个单元为循环,把两个单元的比特串赋给7个字符
{
i+=;
ch[i-]=(char)(*++temp & xx);
ch[i-]=(char)((*temp >> (mp_digit)) & yy);
ch[i-]=(char)((*temp >> (mp_digit)) & yy);
ch[i-]=(char)((*temp-- >> (mp_digit)) & yy); ch[i-]=(char)(*temp & yy);
ch[i-]=(char)((*temp >> (mp_digit)) & yy);
ch[i-]=(char)((*temp >> (mp_digit)) & yy);
ch[i-] <<= ;
ch[i-]+=(char)((*temp++ >> (mp_digit)) & xx);
temp++;
}
if(a->used%!=) //剩于一个单元的处理
{
ch[i++] = (char)(*temp & yy);
ch[i++] = (char)((*temp >> (mp_digit)) & yy);
ch[i++] = (char)((*temp >> (mp_digit)) & yy);
}
--i;
while(int(ch[i]&0xFF) != && i>) 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[]={};
FILE *fp,*fq;
bool zero=false; char filehead[],filefoot[],filename[]={};
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();
} //打开保存解密结果文件
char filemi[];
strcpy(filemi, filehead);
strcat(filemi, "解密");
strcat(filemi, filefoot); if((fq=fopen(filemi,"wb"))==NULL)
{
printf("can not open the file!");
exit();
} rewind(fp);
while(!feof(fp))
{
i=;
while()
{
stemp[i]=fgetc(fp);
if(i%==)
{
if(int(stemp[i]&0xFF) == ) goto L1;
}
i++;
} L1: miwendraw(&c1x, stemp, i);
i=;
while()
{
stemp[i]=fgetc(fp);
if(i%==)
{
if(int(stemp[i]&0xFF) == ) goto L2;
}
i++;
} L2: miwendraw(&c1y, stemp, i);
i=;
while()
{
stemp[i]=fgetc(fp);
if(i%==)
{
if(int(stemp[i]&0xFF) == ) goto L3;
}
i++;
} L3: miwendraw(&c2x, stemp, i);
i=;
while()
{
stemp[i]=fgetc(fp);
if(i%==)
{
if(int(stemp[i]&0xFF) == ) goto L4;
}
i++;
} L4: miwendraw(&c2y, stemp, i); mp_zero(&tempzero);
if(mp_cmp(&c1x, &tempzero)==) 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=;kk<chtem;kk++)
{
fprintf(fq,"%c",stemp[kk]); } chtem=chdraw(&my,stemp);//从ming中取出字符串 //保存解密结果
for(kk=;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); }
椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)的更多相关文章
- (原、整)Unreal源码 CoreUbject- Uobject
(原.整) Unreal源码 CoreUbject- Uobject 类别 [随笔分类]Unreal源码搬山 @author:白袍小道 随缘那啥 这里还是属于UE ...
- 【原】1.1RDD源码解读(一)
1.RDD(Resilient Distributed DataSet)是Spark生态系统中最基本的抽象,代表不可变的.可并行操作的分区元素集合.RDD这个类有RDD系列所有基本的操作,比如map. ...
- 【原】1.1RDD源码解读(二)
(6)transformation 操作,通过外在的不同RDD表现形式来达到内部数据的处理过程.这类操作并不会触发作业的执行,也常被称为lazy操作. 大部分操作会生成并返回一个新的RDD,例sort ...
- 原声js 五子棋 源码
Welcome to use MarkDown <style type="text/css"> .box{ width: 600px; height: 600px; b ...
- [原][译]JSBSim官方源码文档翻译(google翻译)
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS DOCUMENTATION ...
- 如何在源码里修改openwrt root密码
root密码在etc/shadow文件里,但里边的密码是加密过后的.具体的加密方式我不清楚,应该是Linux里的一套加密算法.但要达到修改源码密码的目的,我还是想到了一个间接的办法.首先在源码里改成t ...
- [转帖]cocos2D-X源码分析之从cocos2D-X学习OpenGL(3)----BATCH_COMMAND
原贴: cocos2D-X源码分析之从cocos2D-X学习OpenGL(3)----BATCH_COMMAND 上一篇介绍了QUAD_COMMAND渲染命令,顺带介绍了VAO和VBO,这一篇介绍批处 ...
- Netty-Channel架构体系源码解读
全文围绕下图,Netty-Channel的简化版架构体系图展开,从顶层Channel接口开始入手,往下递进,闲言少叙,直接开撸 概述: 从图中可以看到,从顶级接口Channel开始,在接口中定义了一套 ...
- STM32 IAP程序 源码 和测试代码 有详细的中文注释
http://bbs.21ic.com/forum.php?mod=viewthread&tid=588265&reltid=624002&pre_pos=2&ext= ...
随机推荐
- ioctl( ) 函数
ioctl( )函数 本函数影响由fd参数引用的一个打开的文件. #include<unistd.h> int ioctl( int fd, int request, .../* void ...
- (转)LSI SAS 1068E Raid CentOS 5.5 安装实例浪潮NF5220系列 分类: linux
新来了一批服务器,全都是清一色的国产服务器,相同的阵列卡,令人头疼的是Linux标准内核不包含该raid驱动,需要单独安装,如果是新升级内核,肯定需要编译进去该raid驱动.一.先把主板自带的驱动光盘 ...
- linux 系统调用exec()
系统调用execve()对当前进程进行替换,替换者为一个指定的程序,其参数包括文件名(filename).参数列表(argv)以及环境变量(envp).exec函数族当然不止一个,但它们大致相同,在 ...
- django-1366, "Incorrect string value: '\\xE6\\x88\\x9A\\xE4\\xBC\\x9F...'
今天把之前的一些代码转移到另外一台电脑的时候, python manage.py syncdb 的时候报了 (1366, "Incorrect string value: '\\xE6\\x ...
- connect-falsh的用法
借鉴博客 http://yunkus.com/connect-flash-usage/
- C#使用NOPI生成excel要点记载
很久没动手写博客了,最近由于公司比较忙,接触了不同类容,对自己的技术和业务理解有了更深入的理解.今天有点小空,将前段时间所运用到的一些知识点记录下来. 由于公司业务需要统计一些数据,所以对于我们来说, ...
- node-java模块
node-java模块 node-java使得开发人员,可以调用java优秀的jar包资源.有些方法逻辑,可能node不容易实现,但是java就可以很方便去做.这个时候,就可以使用node-java这 ...
- jquery.validate验证表单配合回调提交和h5.storage本地保存笔记
表单验证插件我使用:jquery.validate.js 支持中文提示,可扩展性强!教程地址 本地保存状态信息使用:h5提供的storage,浏览器支持5m的存储量,存储类型必须是string类型,并 ...
- 六十二 Web开发 使用模板
Web框架把我们从WSGI中拯救出来了.现在,我们只需要不断地编写函数,带上URL,就可以继续Web App的开发了. 但是,Web App不仅仅是处理逻辑,展示给用户的页面也非常重要.在函数中返回一 ...
- 如何让js在最后执行
$(window).bind("load", function () { var height = $(document.body).height(); $('.syntaxhig ...