密码学——ELGamel数字签名算法(C/C++实现)

C/C++代码

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

// 指数运算
// 输入a和b
// 输出a的b次方
int power(int a, int b)
{
	int temp = a;
	for(int i=1 ; i<b ; i++)
	{
		temp = temp * a;
	}
	return temp;
}

// 判断一个数是否为素数
// 输入一个数a 
// 返回:如果a是素数,返回true ; 否则返回false
bool Prime(int a)
{
	for(int i=2 ; i<= (a/2) ; i++)
	{
		if((a % i) == 0)
		{
			return false;
		}
	}
	return true;	
}

// 辗转相除法
// 输入 a 和 b
// 返回 a和b 的最大公约数
int gcd(int a , int b)
{
    while(b!=0)
    {
        int temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

// 欧拉函数
// 输入a
// 返回a的欧拉函数值
int euler(int a)
{
	int b = 0;
	for(int i=1 ; i<a ; i++)
	{
		if(gcd(a,i) == 1)
		{
			b += 1;
		}
	}
	return b;
}

// 求阶函数
int order(int a, int n, int b)
{
	int  p = 1;

	while( p<=n && power(b,p%a) != 1)
	{
		p += 1;
	}
	
	p = p - 1;

	if (p <= n)
	{
		return p;
	}
	else
	{
		return -1;
	}
}

// 公钥p的生成函数
int Generate_p()
{
	srand((unsigned int)time(NULL));
	int p = (rand() % (10000 - 1000 + 1) + 1000);

	for(; p<10000 ; p++)
	{
		if (Prime(p)==true)
		{
			return p;
		}
	}
}

// 公钥g的生成函数
int Generate_g(int p)
{

	int n = euler(p);

	for(int a = 2; a<p ; a++)
	{

		if(order(p,n,a) == n)
		{
			return a;
		}
	}
}

// 密钥d的生成函数
int Generate_d(int p)
{
	srand((unsigned int)time(NULL));
	int d = rand() % ( p-2-2+1) + 2;

	return d;
}

// 随机数X的生成函数
int Generate_X(int p)
{
	srand((unsigned int)time(NULL));
	int X = rand() % p;

	return X;
}
// 快速模幂运算
// 形式为 (a^b) mod c
// 输入 a 、b 和 c  因为要求a^b , 因此是长整数
// 返回 (a^b) mod c 计算结果
int modpow(long long a, long long b, int c) 
{
    int res = 1;
    while(b > 0)
    {
        if(b & 1) 
        {
            res = (res * a) % c;
        }
        
        b = b >> 1;
        a = (a * a) % c; 
    }   
    return res;
}


// 求解乘法逆元
// 输入num 和 mod。 求num 在 mod 下的乘法逆元
// 返回num 在 mod 下的乘法逆元
int inverse(int num,int mod)
{
    int a = num;
    int b = mod;
    int x = 0, y = 1, x0 = 1, y0 = 0;
    int qt, temp;
    
	while(b != 0)
	{
		qt = a / b;
        temp = a % b;
        
		a = b;
        b = temp;
        
		temp = x; x = x0 - qt * x; x0 = temp;
        temp = y; y = y0 - qt * y; y0 = temp;
	}

    if(x0 < 0)
    {
        x0 += mod;
    }
    
    return x0;
}

// ElGamal算法加密过程
// 输入公钥{g,y,p} , 明文m
// 返回密文对:C = {c1,c2} , 以数组形式
void Encryption(int y, int g, int p, int m, int &C1, int &C2)
{

	int r;
	int temp;
	int c1, c2;
	srand((unsigned)time(NULL));
	r = rand();

	c1 = modpow(g, r, p);
	temp = modpow(y, r, p);
	c2 = (m * temp)%p;
	cout << "加密后结果(密文对): " << "{" << c1 << "," << c2 << "}" << endl;
	
	C1 = c1;
	C2 = c2;
} 

// ElGamal解密过程
// 输入密文对:{c1,c2} ,密钥d 以及公钥p
// 返回明文m
int Decryption(int c1, int c2, int d, int p)
{
	int temp;
 	temp = modpow(c1, d, p);

	int temp1 = inverse(temp, p);

	int m = (c2*temp1)%p;

	return m;
} 


//ElGamal数字签名函数
void Sign(int c1, int c2, int g, int p, int x, int &R1, int &S1, int &R2, int &S2)
{
	int k, k1;
	int temp;
	int r1, r2, s1, s2;

	srand((unsigned int)time(NULL));
	k = rand()%p;
	
	r1 = modpow(g, k, p);
	temp = c1-x*r1;

	k1 = gcd(k, p-1);
	s1 = temp * k1 % (p-1);

	r2 = modpow(g, k, p);
	temp = c2 - x*r2;

	s2 = temp*k1%(p-1);
	
	if(s1 < 0)
	{
		s1 = s1 + p-1;
	}

	if(s2 < 0)
	{
		s2 = s2 + p-1;
	}
	
	cout << "密文的数字签名:" << "{" << r1 << "," << s1 << "}" << " " << "{" << r2 << "," << s2 << "}" << endl;

	R1 = r1;
	S1 = s1;
	R2 = r2;
	S2 = s2;
	
} 

//数字签名验证函数
int Vrfy(int y, int g, int r, int s, int m, int p)
{
	int temp1, temp2;
	int i, j;

	temp1 = modpow(y, r, p);
	temp2 = modpow(r, s, p);

	i = (temp1 * temp2) % p;
	j = modpow(g, m, p);

	if(i == j)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int main()
{
	// 随机生成一个素数p及其本原元g
	int p1 = Generate_p();
	int g1 = Generate_g(p1);

	int c1, c2, c3, c4;
	int r1, r2, r3, r4, s1, s2, s3, s4;
	
	cout << "4. Elgamel 数字签名算法(随机生成域参数、随机生成密钥对、签名生成、签名验证)"<< endl;
	cout << endl;

	//ElGamal加密:取一个素数p及其本原元g
	int p2 = Generate_p();
	int g2 = Generate_g(p1);
	int d = Generate_d(p2);
	int y1 = modpow(g2, d, p2);
	printf("加密过程中的公钥为:{%d, %d, %d}", y1, g2, p2);
	cout << endl;
	
	//ElGamal数字签名
	int p3 = Generate_p();
	int g3 = Generate_g(p1);
	int x = 10;
	int y2 = modpow(g3, x, p3);
	printf("数字签名的公钥为:y2 = %d", y2);
	cout << endl;
	
	//Alice选定一个整数XA,1<=XA<=p-2, 并计算YA=g^XA mod p,发送 YA给Bob
	int XA = Generate_X(p1);
	int YA = modpow(g1, XA, p1);
	
	printf("将YA进行ElGamal加密及数字签名后发送给Bob。\n");
	cout << endl;
	
	Encryption(g2, y1, YA, p2,c1,c2);
	
	Sign(c1, c2, g3, p3, x,r1,s1,r2,r3);
	
	//Bob选定一个整数XB:1<=XB<=p-2, 并计算YB=g^XB mod p。并将YB发送给Alice
	int XB = Generate_X(p1);
	int YB = modpow(g1, XB, p1);

	printf("将YB进行ElGamal加密及数字签名后发送给Alice.\n");
	cout << endl;
	
	Encryption(g2, y1, YB, p2,c3,c4);
	
	Sign(c3, c4, g3, p3, x,r3,s3,r4,s4);
	
	//Alice和Bob先验证数字签名, 再解密
	cout << endl;
	printf("程序验证数字签名的有效性");
	cout << endl;
	
	int z[4];
	z[0] = Vrfy(y2, g3, r3, s3, c3, p3);
	z[1] = Vrfy(y2, g3, r4, s4, c4, p3);
	z[2] = Vrfy(y2, g3, r1, s1, c1, p3);
	z[3] = Vrfy(y2, g3, r2, s2, c2, p3);

	if(z[0] && z[1] && z[2] && z[3])
	{
		printf("数字签名验证有效!"); 
		cout << endl;
	} 
	else
	{
		printf("数字签名无效!可能已经被修改"); 
		cout << endl;
	}
	
	int YA1 = Decryption(c1, c2, d, p2);
	int YB1 = Decryption(c3, c4, d, p2);
	
	int k = modpow(YB1, XA, p1);
	cout << endl;
	printf("Alice计算出的密钥为k = %d", k);
	cout << endl;
	
	//Bob计算k = YA^XB mod p
	k = modpow(YA1, XB, p1);
	printf("Bob计算出的密钥k = %d\n", k);
	cout << endl;
	
	system("pause");
	return 0;
}

运行结果

运行结果

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 密码学是研究如何保护信息安全的学科,主要包括加密算法和解密算法的设计与实现。C/C++语言是一种被广泛应用于密码学领域的编程语言,其提供了丰富的库函数和数据类型,方便实现各种密码学算法。 在密码学中,加密算法是用于将明文转换为密文的算法,而解密算法则是用于将密文转换回明文的算法。C/C++语言的灵活性和高效性使其成为实现这些算法的理想选择。 在C/C++语言中,可以使用各种库函数来实现密码学算法。例如,可以使用OpenSSL库函数来实现各种对称加密算法(如AES、DES)和非对称加密算法(如RSA、DSA)。这些库函数提供了一系列接口,可以方便地进行密钥生成、加密和解密操作。 此外,C/C++语言还提供了丰富的数据类型和运算操作,可以方便地进行数据处理和运算。例如,可以使用位运算来实现一些常见的密码学操作,如异或操作和循环左移操作。同时,C/C++语言还提供了高效的数据结构,如数组和指针,可以方便地进行数据存储和访问。 总之,C/C++语言在密码学中的应用广泛且灵活。通过使用C/C++语言,可以方便地实现各种加密算法和解密算法,并保护信息的安全。但是在使用C/C++语言实现密码学算法时,需要注意安全性和效率的问题,避免出现漏洞和性能问题。 ### 回答2: 密码学是一门关于保护信息安全的学科,它研究如何设计密码算法以及如何使用密码算法来加密和解密信息。C/C++是一种广泛使用的编程语言,它具有快速、高效的特点,非常适合用来实现密码学算法。 在密码学中,常用的算法有对称加密算法和非对称加密算法。对称加密算法使用同一个密钥来进行加密和解密,而非对称加密算法使用一对密钥,其中一个用于加密,另一个用于解密。 在C/C++中,我们可以使用库函数来实现密码学算法。例如,在对称加密算法中,可以使用openssl库中的函数来实现AES、DES等算法。这些函数提供了加密和解密的接口,我们只需要调用相应的函数,并传入待加密的明文和密钥参数即可实现加密和解密过程。 对于非对称加密算法,我们可以使用openssl库中的函数来实现RSA算法。这些函数提供了生成密钥对、公钥加密、私钥解密的功能,我们可以使用这些函数来实现基于RSA的加密和解密操作。 除了使用库函数外,我们还可以自己编写密码学算法实现。C/C++具有丰富的数据类型和数据结构,我们可以利用这些特性来实现不同的密码学算法,例如SHA-256哈希算法、AES加密算法等。只需要按照算法的规则进行编码,进行相关的运算和操作即可实现密码学算法。 总之,C/C++语言可以很方便地实现密码学算法,无论是使用库函数还是自己编写算法实现,都可以利用C/C++的特性和功能来保护信息的安全。 ### 回答3: 密码学是一项研究如何保护通信安全和数据保密性的学科。在密码学中,密钥起着至关重要的作用,因为正确的密钥是保护数据的关键。C/C++语言是一种广泛应用于软件开发的编程语言,可以实现各种密码学算法和协议。 在密码学中,常用的算法有对称加密算法和非对称加密算法。对称加密算法使用相同的密钥进行加密和解密,如AES和DES算法。我们可以使用C/C++语言实现这些算法,通过调用相应的函数来加密和解密数据。这需要理解算法的原理和加密过程,以及相关的库函数和语法。 非对称加密算法使用一对公私钥进行加密和解密,如RSA算法。在C/C++中,可以使用相关库函数来生成密钥对、加密和解密数据。这种加密算法更加安全,但由于复杂性和计算开销较大,通常只用于加密较短的数据或者用于对称密钥的安全传输。 除了加密算法,C/C++语言还可以实现密码学中的其他功能,如哈希函数和数字签名。哈希函数用于将任意长度的数据转化为固定长度的哈希值,常用的算法有MD5和SHA。数字签名用于验证数据的完整性和真实性,通过私钥对数据进行签名,再通过公钥进行验证。 总之,C/C++语言可以通过实现密码学算法和相关功能来保护通信安全和数据保密性。为了确保安全性,需要深入理解密码学的原理和算法设计,同时注意使用安全的库函数和保护密钥的安全存储。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rayme629

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值