热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)

*1、用户A选定一条适合加密的椭圆曲线Ep(a,b)(如:y2x3+ax+b),并取椭圆曲线上一点,作为基点G。2、用户A选择一个私有密钥k,并生成公开密钥KkG。3、用户A

image

 

/* 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  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

#include
<string.h>
#include

#include

#include
"tommath.h"
#include



#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 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[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)
}


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->alloc2/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;j7;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;

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);
for(i=0; 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
<<"密文存放路径为 "<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->alloc4)
{
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;j4;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;jused/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;


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)
{
fprintf(fq,"%c",stemp[kk]);

}

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


//保存解密结果
for(kk=0;kk)
{
fprintf(fq,"%c",stemp[kk]);

}


}

cout
<<"\nok!解密完毕!"<<endl;
cout
<<"解密后的文字存放路径为 "<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);


}

 


推荐阅读
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • Halcon之图像梯度、图像边缘、USM锐化
    图像梯度、图像边缘、USM锐化图像梯度、图像边缘、USM锐化图像梯度、图像边缘、USM锐化图像卷积:1.模糊2.梯度3.边缘4.锐化1.视频教程:B站、 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • 在iOS开发中,基于HTTPS协议的安全网络请求实现至关重要。HTTPS(全称:HyperText Transfer Protocol over Secure Socket Layer)是一种旨在提供安全通信的HTTP扩展,通过SSL/TLS加密技术确保数据传输的安全性和隐私性。本文将详细介绍如何在iOS应用中实现安全的HTTPS网络请求,包括证书验证、SSL握手过程以及常见安全问题的解决方法。 ... [详细]
  • 每年,意甲、德甲、英超和西甲等各大足球联赛的赛程表都是球迷们关注的焦点。本文通过 Python 编程实现了一种生成赛程表的方法,该方法基于蛇形环算法。具体而言,将所有球队排列成两列的环形结构,左侧球队对阵右侧球队,首支队伍固定不动,其余队伍按顺时针方向循环移动,从而确保每场比赛不重复。此算法不仅高效,而且易于实现,为赛程安排提供了可靠的解决方案。 ... [详细]
  • 哈希表(Hash Table)是一种高效的查找算法,与传统的链表和树结构相比,其在查找过程中无需进行逐个元素的比较。本文将深入探讨哈希表的基本原理、应用场景以及优化策略,帮助读者全面理解其在实际开发中的优势和局限性。通过实例分析和代码示例,我们将展示如何有效利用哈希表提高数据处理效率,并解决常见的冲突问题。 ... [详细]
  • 本文介绍了 NOI Open Judge 6049 购书问题的详细解法,代码简洁易懂,并附有详细的注释和解释。 ... [详细]
  • 本文详细介绍了如何使用OpenSSL自建CA证书的步骤,包括准备工作、生成CA证书、生成服务器待签证书以及证书签名等过程。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 在Java基础中,私有静态内部类是一种常见的设计模式,主要用于防止外部类的直接调用或实例化。这种内部类仅服务于其所属的外部类,确保了代码的封装性和安全性。通过分析JDK源码,我们可以发现许多常用类中都包含了私有静态内部类,这些内部类虽然功能强大,但其复杂性往往让人感到困惑。本文将深入探讨私有静态内部类的作用、实现方式及其在实际开发中的应用,帮助读者更好地理解和使用这一重要的编程技巧。 ... [详细]
  • 本文详细探讨了使用纯JavaScript开发经典贪吃蛇游戏的技术细节和实现方法。通过具体的代码示例,深入解析了游戏逻辑、动画效果及用户交互的实现过程,为开发者提供了宝贵的参考和实践经验。 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
  • 通过使用CIFAR-10数据集,本文详细介绍了如何快速掌握Mixup数据增强技术,并展示了该方法在图像分类任务中的显著效果。实验结果表明,Mixup能够有效提高模型的泛化能力和分类精度,为图像识别领域的研究提供了有价值的参考。 ... [详细]
author-avatar
猥琐的爆米花
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有