热门标签 | 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);


}

 


推荐阅读
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 当iOS设备越狱后,某些插件可能会导致系统崩溃(白苹果)。此时,可以通过进入安全模式来排查并删除有问题的插件。本文将详细介绍如何通过特定按键组合进入不加载MobileSubstrate的安全模式,并提供相关背景知识。 ... [详细]
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社区 版权所有