?? eccdlg.cpp
字號:
// EccDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ASYMMETRIC KEY CRYPTOSYSTEM.h"
#include "EccDlg.h"
#include "string.h"
#include "iostream.h"
#include "tommath.h"
#include "ECC.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BIT_LEN 800
#define KEY_LONG 128 //私鑰比特長
#define P_LONG 200 //有限域P比特長
#define EN_LONG 40 //一次取明文字節數(x,20)(y,20)
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)
//得到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,CString,CString);
//ECC解密
void Ecc_decipher(mp_int *k, mp_int *a,mp_int *p,CString,CString);
//實現將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;
}
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,CString filehead,CString filefoot)
{
CFileDialog fd(TRUE);
CString filen;
char fn[40];
if(IDOK==fd.DoModal()) // 啟動用于選擇文件的對話框
{
//選擇了文件
filen=fd.GetFileName(); //獲取選擇的文件的文件名
strcpy(fn,filen.GetBuffer(0));
}
else return; //按了取消按鈕
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],
char filename[85]={0};
strcpy(filename,fn);
//cout<<"請輸入您要加密文件的存放路徑和文件名(如: c:\\000\\大整數運算 ):"<<endl;
//cin>>filehead;
// cout<<"請輸入您要加密文件的擴展名(如: .doc ):"<<endl;
// cin>>filefoot;
//strcpy(filename,filehead);
//strcat(filename,filefoot);
//打開要加密文件
if((fp=fopen(filename,"rb"))==NULL)
{
AfxMessageBox("Can not open 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);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -