密码学课设实验——DSAc++实现

一、实验目的

通过实现数字签名算法(DSA),加深对数字签名算法的理解,同时学习Hash算法的实现。

 

  • 实验内容

1)利用C\C++语言实现DSA算法。

2)DSA中的Hash函数采用SHA算法。

 

  • 实验步骤
  1. 调用了大整数库miracl。

extern "C"

{

#include

#include

#include

}

 

  1. 按照书上p163,求出大数p,q,g,x,y。
  2. 从网上找到了一个定义了sha-256算法的头文件,直接传入明文调用StrSHA256(M, filenum , sha256)函数,输出字符串sha256。(该头文件可以去我的资源中下载,直接调用就行
  3. 按照书上p164,实现签名与验证签名。

 

代码如下:

#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];

}*/

 

实验结果:

密码学课设实验——DSAc++实现_第1张图片

你可能感兴趣的:(密码学课设c++实现)