⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eccdlg.cpp

📁 非对称密码系统,包含RSA,ECC,大数乘法。
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	char filemi[85];
	strcpy(filemi,filehead);
	strcat(filemi,"miwen");
	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<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);  
	}

	//  buf=""; 
 //strcat(buf,"ok!加密完毕!:\r\n");
		cout<<"\nok!加密完毕!"<<endl;
 //strcat(buf,"密文以二进制保存:\r\n");
	    cout<<"密文以二进制保存"<<endl;
 //strcat(buf,"密文存放路径为 :\r\n");
//strcat(buf,filemi);
	    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,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 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 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(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);


}




/////////////////////////////////////////////////////////////////////////////
// CEccDlg dialog


CEccDlg::CEccDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CEccDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CEccDlg)
	m_canshu = _T("");
	m_foot = _T("");
	m_path = _T("");
	m_result = _T("");
	//}}AFX_DATA_INIT
}


void CEccDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CEccDlg)
	DDX_Control(pDX, IDC_gc, m_gc);
	DDX_Control(pDX, IDC_enfile, m_enfile);
	DDX_Control(pDX, IDC_defile, m_defile);
	DDX_Text(pDX, IDC_canshu, m_canshu);
	DDX_Text(pDX, IDC_foot, m_foot);
	DDX_Text(pDX, IDC_path, m_path);
	DDX_Text(pDX, IDC_Result, m_result);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CEccDlg, CDialog)
	//{{AFX_MSG_MAP(CEccDlg)
	ON_BN_CLICKED(IDC_gc, Ongc)
	ON_BN_CLICKED(IDC_enfile, Onenfile)
	ON_BN_CLICKED(IDC_defile, Ondefile)
	ON_BN_CLICKED(IDC_introduceECC, OnintroduceECC)
	ON_BN_CLICKED(IDC_EccHelp, OnEccHelp)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEccDlg message handlers

void CEccDlg::Ongc() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	
	mp_init(&GX);
	mp_init(&GY);
	mp_init(&K);
	mp_init(&A);
	mp_init(&B);
	mp_init(&QX);
	mp_init(&QY);
	mp_init(&P);
	
    char buf[10000]="";
    time_t t;           
    srand( (unsigned) time( &t ) );
    strcat(buf,"椭圆曲线的参数如下(以十进制显示):\r\n");	
    GetPrime(&P,P_LONG);
	strcat(buf,"有限域 P 是:\r\n");	
	char temp[800]={0};
    mp_toradix(&P,temp,10);
   	strcat(buf,temp);	
    strcat(buf,"\r\n");

   GetPrime(&A,30);
   char tempA[800]={0};
   strcat(buf,"曲线参数 A 是:\r\n");
   mp_toradix(&A,tempA,10);
   strcat(buf,tempA);
   //printf("曲线参数 A 是:\n");	
   strcat(buf,"\r\n");
   //printf("%s\n",tempA); 
   Get_B_X_Y(&GX,&GY,&B,&A,&P);
   char tempB[800]={0};
   strcat(buf,"曲线参数 B 是:\r\n");
   //printf("曲线参数 B 是:\n");	
   mp_toradix(&B,tempB,10);
   strcat(buf,tempB);
   strcat(buf,"\r\n");
   //printf("%s\n",tempB); 
   char tempGX[800]={0};
   strcat(buf,"曲线G点X坐标是:\r\n");
   //printf("曲线G点X坐标是:\n");	
   strcat(buf,tempGX);
   strcat(buf,"\r\n");
   //printf("%s\n",tempGX);   
	char tempGY[800]={0};
   strcat(buf,"曲线G点Y坐标是:\r\n");
   //	printf("曲线G点Y坐标是:\n");
    mp_toradix(&GY,tempGY,10);
 strcat(buf,tempGY);
 strcat(buf,"\r\n");
   // printf("%s\n",tempGY); 
   //------------------------------------------------------------------
    GetPrime(&K,KEY_LONG);
    char tempK[800]={0};
 strcat(buf,"私钥 K 是:\r\n");
	//printf("私钥 K 是:\n");
    mp_toradix(&K,tempK,10);
 strcat(buf,tempK);
 strcat(buf,"\r\n");
   // printf("%s\n",tempK); 

	Ecc_points_mul(&QX,&QY,&GX,&GY,&K,&A,&P);
	

    char tempQX[800]={0};
 strcat(buf,"公钥X坐标是:\r\n");
	//printf("公钥X坐标是:\n");
    mp_toradix(&QX,tempQX,10);
 strcat(buf,tempQX);
 strcat(buf,"\r\n");
    //printf("%s\n",tempQX); 

	char tempQY[800]={0};
strcat(buf,"公钥Y坐标是:\r\n");
//	printf("公钥Y坐标是:\n");
    mp_toradix(&QY,tempQY,10);
  mp_toradix(&QX,tempQY,10);
 strcat(buf,tempQY);
    //printf("%s\n",tempQY); 
  	m_canshu.Format("%s",buf);
    UpdateData(false);
for(int a=0;a<10000;a++)buf[a]='\0';
  return;	
}

void CEccDlg::Onenfile() 
{
	// TODO: Add your control notification handler code here
    UpdateData(true);

			if(m_path == "")
		{
			m_result=_T("请先输入要加密文件的文件名!");
			UpdateData(FALSE);
			return;
		}
			if(m_foot == "")
		{
			m_result=_T("请先输入要加密文件的后缀名!(如“.txt”)");
			UpdateData(FALSE);
			return;
		}
			

    //char buf[10000]="";
    Ecc_encipher(&QX,&QY,&GX,&GY,&A,&P,m_path,m_foot);
//	m_result.Format("%s",buf);
    m_result = _T("文件加密成功");
    UpdateData(false);
}

void CEccDlg::Ondefile() 
{
	// TODO: Add your control notification handler code here
	    UpdateData(true);
    //char buf[10000]="";
			if(m_path == "")
		{
			m_result=_T("请先输入要解密文件的文件名!");
			UpdateData(FALSE);
			return;
		}
			if(m_foot == "")
		{
			m_result=_T("请先输入要解密文件的后缀名!(如“.txt”)");
			UpdateData(FALSE);
			return;
		}
    Ecc_decipher(&K,&A,&P,m_path,m_foot);
//	m_result.Format("%s",buf);
    m_result = _T("文件解密成功");
    UpdateData(false);
}

void CEccDlg::OnintroduceECC() 
{
	// TODO: Add your control notification handler code here
	m_canshu = _T("                                 ECC算法介绍                                      ECC(Elliptic Curve Cryptosystems )椭圆曲线密码体制2002年,美国SUN公司将其开发的椭圆加密技术赠送给开放源代码工程公钥密码体制根据其所依据的难题一般分为三类:大整数分解问题类、离散对数问题类、椭圆曲线类。有时也把椭圆曲线类归为离散对数类。椭圆曲线密码体制来源于对椭圆曲线的研究,所谓椭圆曲线指的是由韦尔斯特拉斯(Weierstrass)方程:y2+a1xy+a3y=x3+a2x2+a4x+a6 (1)所确定的平面曲线。其中系数ai(I=1,2,…,6)定义在某个域上,可以是有理数域、实数域、复数域,还可以是有限域GF(pr),椭圆曲线密码体制中用到的椭圆曲线都是定义在有限域上的。椭圆曲线上所有的点外加一个叫做无穷远点的特殊点构成的集合连同一个定义的加法运算构成一个Abel群。在等式mP=P+P+…+P=Q (2)中,已知m和点P求点Q比较容易,反之已知点Q和点P求m却是相当困难的,这个问题称为椭圆曲线上点群的离散对数问题。椭圆曲线密码体制正是利用这个困难问题设计而来。椭圆曲线应用到密码学上最早是由Neal Koblitz 和Victor Miller在1985年分别独立提出的。椭圆曲线密码体制是目前已知的公钥体制中,对每比特所提供加密强度最高的一种体制。解椭圆曲线上的离散对数问题的最好算法是Pollard rho方法,其时间复杂度为,是完全指数阶的。其中n为等式(2)中m的二进制表示的位数。当n=234, 约为2117,需要1.6x1023 MIPS 年的时间。而我们熟知的RSA所利用的是大整数分解的困难问题,目前对于一般情况下的因数分解的最好算法的时间复杂度是子指数阶的,当n=2048时,需要2x1020MIPS年的时间。也就是说当RSA的密钥使用2048位时,ECC的密钥使用234位所获得的安全强度还高出许多。它们之间的密钥长度却相差达9倍,当ECC的密钥更大时它们之间差距将更大。更ECC密钥短的优点是非常明显的,随加密强度的提高,密钥长度变化不大。");
    UpdateData(false);
}

void CEccDlg::OnEccHelp() 
{
	// TODO: Add your control notification handler code here
    m_canshu = _T("                                    使用帮助                                      首先点击“生成密钥和参数”按钮生成密钥和参数,然后在“请在加密或解密文件前输入文件的文件名”框内输入要加密的文件的文件名,在“请在加密或解密文件前输入文件的后缀名”框内输入要加密文件的后缀名(注意!后缀名要带“.”号,如“.txt”),输入文件名及后缀名以后点击“加密”按钮,这时会弹出一个文件选择窗口,选定文件后即可加密。解密文件的时候先在“请在加密或解密文件前输入文件的文件名”框内输入要解密的文件的文件名,在“请在加密或解密文件前输入文件的后缀名”框内输入要解密文件的后缀名(注意!后缀名要带“.”号,如“.txt”),输入文件名及后缀名以后点击“解密”按钮,这时会弹出一个文件选择窗口,选定待解密文件后即可解密。");
    UpdateData(false);	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -