📄 elgamal.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 + -