一、实验目的
通过实现数字签名算法(DSA),加深对数字签名算法的理解,同时学习Hash算法的实现。
1)利用C\C++语言实现DSA算法。
2)DSA中的Hash函数采用SHA算法。
extern "C"
{
#include
#include
#include
}
代码如下:
#include "pch.h"
#include
#include
#include
#include"sha256.h"
extern "C"
{
#include
#include
#include
}
using namespace std;
int main()
{
srand(time(NULL));
miracl *mip = mirsys(2000, 2);
int L, j;
L = 512;//L是一个指定的整数,L=512+64j,0<=j<=8
j = rand() % 9;//随机范围为[0,8]中的整数
L += 64 * j;
cout << "L:" << L << endl;
cout << endl;
big q, p, temp, g, p_1;
q = mirvar(160);
temp = mirvar(512);
p = mirvar(512);
g = mirvar(512);
p_1 = mirvar(512);
//初始化参数q
/*bigdig(160, 2, q);//生成一个160位的二进制数
nxprime(q, q);//找一个素数
if (isprime(q))
{
cout << "q:";
mip->IOBASE = 2;
cotnum(q, stdout);
cout << endl;
}
//初始化参数p
bigdig(L - 160, 2, temp);//把temp当作(p-1)/q
fft_mult(temp, q, p_1);
incr(p_1, 1, p);
cout << "p:";
mip->IOBASE = 2;
cotnum(p, stdout);
cout << endl;*/
char *string;
string = (char *)malloc(L * sizeof(char));
while (!isprime(p)) {
bigdig(160, 2, temp);
if (!isprime(temp))
nxprime(temp, q);
else
copy(temp, q);
bigdig(L - 160, 2, temp);
multiply(q, temp, p);
incr(p, 1, p);
int Len = cotstr(p, string);
if (Len < L) {
decr(p, 1, p);
add(p, p, p);
}
incr(p, 1, p);
}
cout << "q:";
mip->IOBASE = 2;
cotnum(q, stdout);
cout << endl;
cout << "p:";
mip->IOBASE = 2;
cotnum(p, stdout);
cout << endl;
//初始化参数g
big h, num_1;
h = mirvar(512);
num_1 = mirvar(512);
convert(1, num_1);
bigrand(p_1,h);//随机选取h在(1,p-1)
powmod(h, temp, p, g);
while (mr_compare(g, num_1) != 1)
{
//incr(h, 1, h);
bigrand(p_1, h);
powmod(h, temp, p, g);
}
cout << "g:";
mip->IOBASE = 2;
cotnum(g , stdout);
cout << endl;
//初始化参数x
big x;
x = mirvar(512);
bigrand(q, x);
cout << "x:";
mip->IOBASE = 2;
cotnum(x, stdout);
cout << endl;
//初始化参数y
big y;
y = mirvar(512);
powmod(g, x, p, y);
cout << "y:";
mip->IOBASE = 2;
cotnum(y, stdout);
cout << endl;
//从文件中读取明文
char M[256] = {0};//存明文
char filename[81];
ifstream encfile;
char c;
int i = 0, filenum;//filenum存取文件中字符数
rewind(stdin); //清空缓冲区
cout << endl;
cout << "输入要加密的文件名:";
cin.getline(filename, 81);
encfile.open(filename, ios::in | ios::out);
if (!encfile)
{
cout << "Open input file error!" << endl;
exit(0);
}
while (!encfile.eof())
{
encfile.get(c);
M[i] = c;
i++;
}
encfile.close();
filenum = i - 1;
//输出明文
cout << endl;
cout << "明文为:";
for (int num = 0; num < filenum; num++)
cout << M[num];
cout << endl;
char sha256[256];
StrSHA256(M, filenum , sha256);
cout << "执行Hash函数SHA算法后的结果如下:\n";
cout << sha256 << endl;
int tmp_hm;
big hm;
hm = mirvar(0);
//hash后的16进制字符串转换为big型数据。
for (int i = 0; i < 64; i++)
{
if (sha256[i] >= '0'&&sha256[i] <= '9')
tmp_hm = sha256[i] - 48;
else
tmp_hm = sha256[i] - 55;
premult(hm, 16, hm);
incr(hm, tmp_hm, hm);
}
/*mip->IOBASE = 16;
cotnum(hm, stdout);
cout << endl;*/
//DSA的签名过程
//Alice
big k, temp_r,r;
k = mirvar(1);
temp_r = mirvar(1);
r = mirvar(1);
bigrand(q, k);//随机选取h在(1,p-1)
powmod(g, k, p, temp_r);
powmod(temp_r, num_1, q, r);
big xr, k_1, hm_xr, temp_s, s;
xr = mirvar(1);
hm_xr = mirvar(1);
k_1 = mirvar(1);
temp_s = mirvar(1);
s = mirvar(1);
multiply(x, r, xr);
add(xr, hm, hm_xr);
xgcd(k, q, k_1, k_1, k_1);//模逆
multiply(k_1, hm_xr, temp_s);
powmod(temp_s, num_1, q, s);//s = temp_s mod q
cout << "Alice的签名是:(r,s)"<IOBASE = 16;
cout << "r:";
cotnum(r, stdout);
cout << "s:";
cotnum(s, stdout);
cout << endl;
//Bob
big w, temp_u1, u1, temp_u2, u2;
w = mirvar(1);
u1 = mirvar(1);
u2 = mirvar(1);
temp_u1 = mirvar(1);
temp_u2 = mirvar(1);
xgcd(s, q, w, w, w);
multiply(hm, w, temp_u1);
powmod(temp_u1, num_1, q, u1);
multiply(r, w, temp_u2);
powmod(temp_u2, num_1, q, u2);
big g_u1, y_u2,temp_Bob,Bob;
g_u1 = mirvar(1);
y_u2 = mirvar(1);
temp_Bob = mirvar(1);
Bob = mirvar(1);
powmod(g, u1, p, g_u1);
powmod(y, u2, p, y_u2);
multiply(g_u1, y_u2, temp_Bob);
powmod(temp_Bob, num_1, p, temp_Bob);
powmod(temp_Bob, num_1, q, Bob);
cout << "Bob:";
cotnum(Bob, stdout);
cout << endl;
cout << "验证签名...";
if (mr_compare(Bob, r) == 0)
cout << "verify!";
else
cout << "error!";
}
//Round1
/*int f1(int X, int Y, int Z)
{
return (X&Y) | (~X&Z);
}
//Round2
int f2(int X, int Y, int Z)
{
return X ^ Y ^ Z;
}
//Round3
int f3(int X, int Y, int Z)
{
return (X&Y) | (X&Z) | (Y&Z);
}
//Round4
int f4(int X, int Y, int Z)
{
return X ^ Y ^ Z;
}
void Init_R()
{
Register[0] = 0x67452301;
Register[1] = 0xefcdab89;
Register[2] = 0x98badcfe;
Register[3] = 0x10325476;
Register[4] = 0xc3d2e1f0;
}
void SHA_1()
{
//初始化A,B,C,D,E
int A, B, C, D, E;
A = Register[0];
B = Register[1];
C = Register[2];
D = Register[3];
E = Register[4];
}*/
实验结果: