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

📄 elgamal.c

📁 一款可视化的椭圆曲线Elgmal密码算法
💻 C
字号:
/*-------------------------------------------------------
/*  《加密与解密》 第6章 加密算法   
/*   ElGamal算法,签名算法在序列保护中的应用
/*  (c) www.PEDIY.com  by 段钢 2002.12
-------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* 本程序调用了MIRACL v4.74 大数运算库,编译前请参考MIRACL目 */
/* 录里的说明文件MSVISUAL.TXT,并安装 MIRACL 。              */
/* 各命令用法参考MIRACL目录里的MANUAL.DOC                    */
/* MIRACL官方主页:http://indigo.ie/~mscott/                 */
/*-----------------------------------------------------------*/

////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <windows.h>
#include "md5c.c"
#include "global.h"
#include <miracl.h>
#include "resource.h"

/*-------------------------------------------------------------*/
/* 定义子程序与全局变量、常量                                  */
/*-------------------------------------------------------------*/
HINSTANCE	hInst;
#define MAXINPUTLEN 200

/*-------------------------------------------------------------*/
/*  函数声明                                                   */
/*-------------------------------------------------------------*/
BOOL    CALLBACK MainDlg   (HWND, UINT, WPARAM, LPARAM) ;
BOOL    CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ;
BOOL    ElGamal( HWND) ;

/*-------------------------------------------------------------*/
/* WinMain - 基于WIN32的程序的入口                            */
/*-------------------------------------------------------------*/

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	hInst=hInstance;
	DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MAINDLG), NULL, (DLGPROC)MainDlg,0);
	return 0;
}

/*-------------------------------------------------------------*/
/* AboutDlgProc - 关于窗口                                    */
/*-------------------------------------------------------------*/

BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, 
                            WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case  WM_LBUTTONDOWN:
			PostMessage(hDlg, WM_NCLBUTTONDOWN, HTCAPTION, 0);
			return TRUE ;
        
		case WM_COMMAND :
			switch (LOWORD (wParam))  		            
			{
				case IDOK :
				case IDCANCEL :
				EndDialog (hDlg, 0) ;
				return TRUE ;
			}
			 break ;
	 }
     return FALSE ;
}


/*-------------------------------------------------------------*/
/*  MainDlg - 主对话窗口                                      */
/*-------------------------------------------------------------*/
BOOL CALLBACK MainDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{	

	switch (message)
	{    
	case WM_CLOSE:
		EndDialog(hDlg,0);
		break;


	case WM_COMMAND:
		switch (LOWORD(wParam))
		{ 
		

		case IDC_OK:			
			SetFocus (GetDlgItem(hDlg,IDC_TXT1));
			if(	ElGamal(hDlg))                            
			{
				MessageBoxA (NULL, TEXT ("注册成功!!"), TEXT ("恭喜!"), 0) ;
			}
			else
			{
				MessageBoxA (NULL, TEXT ("注册失败!!"), TEXT ("错误!"), 0) ;
			}

			break;

		case IDC_ABOUT :
		case IDM_HELP_ABOUT :
			DialogBox (hInst, MAKEINTRESOURCE (IDD_ABOUT), hDlg, AboutDlgProc) ;
			break;	

		case IDC_EXIT:
			PostQuitMessage(0);
		}
		break;
	case WM_INITDIALOG:
		SendMessage(hDlg,WM_SETICON,(WPARAM) 1,(LPARAM) LoadIconA(hInst,MAKEINTRESOURCE(IDI_ICON)));  
		                                                             

		break;
	}
     return 0;
}


/*-------------------------------------------------------------*/
/* ElGamal - 注册算法主函数                                */
/*-------------------------------------------------------------*/
BOOL ElGamal( HWND hWnd) 
{
	MD5_CTX context;
	int i,dtLength;
	big M,p,y,a,b,g,result1,result2,result3,result4,Buffer;
	miracl *mip=mirsys(100,0);

	TCHAR szName[MAXINPUTLEN]={0};
	TCHAR szHash[MAXINPUTLEN]={0};
	TCHAR szSerial[MAXINPUTLEN]={0}; // 为了方便阅读,多定义了几个数组
	TCHAR szSerial1[MAXINPUTLEN]={0};
	TCHAR szSerial2[MAXINPUTLEN]={0};

	dtLength=GetDlgItemText(hWnd, IDC_TXT1, szSerial, sizeof(szName)/sizeof(TCHAR)+1); // 取序列号
	if(32==dtLength) // 判断序列号的长度是不是32位
	{
		for(i=0;szSerial[i]!=0;i++)  // 检查输入的序列号是否为16进制数,为cinstr(M,szSerial)使用做准备
		{
			if(isxdigit(szSerial[i])==0)
			return FALSE;

		}
	
		strncpy(szSerial1,szSerial,16);  // 将szSerial字符成分成szSerial1和szSerial12两组,各16个字符
		strncpy(szSerial2,szSerial+16,16);

		dtLength=GetDlgItemText(hWnd, IDC_TXT0, szName, sizeof(szName)/sizeof(TCHAR)+1);  //取用户名
		if (strlen(szName)==0)//检查是否输入了用户名
		{
			return FALSE;
		}
		MD5Init(&context);//调用MD5运行库
		MD5Update(&context, szName, dtLength);
		MD5Final(szHash, &context);//szHash中就是用户名的MD5散列值


// MIRACL大数运算库运算 
//===================================================================================	
		mip->IOBASE=16;
		M=mirvar(0);
		p=mirvar(0);
		y=mirvar(0);
		a=mirvar(0);
		b=mirvar(0);
		g=mirvar(0);
		Buffer=mirvar(0);;
		result1=mirvar(0);  // 为了让代码可读性好些,特增加了几个中间变量放结果
		result2=mirvar(0);
		result3=mirvar(0);
		result4=mirvar(0);		

		bytes_to_big(16,&szHash,M);
		cinstr(Buffer,"0D06FB1D728E01403");    // 0D06FB1D728E01403为一随机数
    	power(M,3,Buffer,M);  // M = m ^ 3 mod p  模指数运算是频繁地用于密码学中的一种单向函数,将szHash散列成64位
		// MIRACL的操作手册MANUAL.DOC中如下定义power:
 		// Function: void power(x,n,z,w)
		// long n;
		// big x,z,w;
    	// Two big numbers x and z, and an integer n. On exit w=xn . If w and z are distinct, then w=x^n mod z
	
		//上面的计算过程为:M = szHash^3 mod (D06FB1D728E01403)   

		cinstr(a,szSerial1); // 转换成大数
		cinstr(b,szSerial2);
		cinstr(p,"0AE6F8E3B6399D3A3");
		cinstr(g,"092AFA3B6E8889333");
		cinstr(y,"2E646151C7E5A00F");

		powmod(y,a,p,result1); // result1=y ^ a mod p
		powmod(a,b,p,result2); // result2=a ^ b mod p
        mad(result1,result2,result1,p,p,result3) ; //result3=result1*result2 mod p,即result3=(y^a)*(a^b)(mod p)
		// MANUAL.DOC对mad的解释:
		// Function:	void mad(x,y,z,w,q,r)
		// Six big numbers x,y,z,w,q and r. On exit q=(x.y+z)/w and r contains the remainder. 
		// If w and q are not distinct variables then only the remainder is returned; 
		// if q and r are not distinct then only the quotient is returned. 
		// The addition of z is not done if x and z (or y and z) are the same.
    
		powmod(g,M,p,result4); // result4 = g^M(mode)p	

		if(compare(result3,result4)==0)  // 验证签名(y^a) *( a^b )( mod p ) = g^M ( mod p )
			return TRUE;
		else
			return FALSE;
		 
		mirkill(M);
		mirkill(p);
		mirkill(y);
		mirkill(a);
		mirkill(b);
		mirkill(g);
		mirkill(Buffer);
		mirkill(result1);
		mirkill(result2);
		mirkill(result3);
		mirkill(result4);		
		mirexit();		
		return TRUE;		
	} //if(dtLength==32)

return  FALSE;
}

⌨️ 快捷键说明

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