C/C++代码
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int power(int a, int b)
{
int temp = a;
for(int i=1 ; i<b ; i++)
{
temp = temp * a;
}
return temp;
}
bool Prime(int a)
{
for(int i=2 ; i<= (a/2) ; i++)
{
if((a % i) == 0)
{
return false;
}
}
return true;
}
int gcd(int a , int b)
{
while(b!=0)
{
int temp = a % b;
a = b;
b = temp;
}
return 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;
}
}
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;
}
}
}
int Generate_g(int p)
{
int n = euler(p);
for(int a = 2; a<p ; a++)
{
if(order(p,n,a) == n)
{
return a;
}
}
}
int Generate_d(int p)
{
srand((unsigned int)time(NULL));
int d = rand() % ( p-2-2+1) + 2;
return d;
}
int Generate_X(int p)
{
srand((unsigned int)time(NULL));
int X = rand() % p;
return X;
}
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;
}
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;
}
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;
}
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;
}
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()
{
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;
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;
int p3 = Generate_p();
int g3 = Generate_g(p1);
int x = 10;
int y2 = modpow(g3, x, p3);
printf("数字签名的公钥为:y2 = %d", y2);
cout << endl;
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);
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);
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;
k = modpow(YA1, XB, p1);
printf("Bob计算出的密钥k = %d\n", k);
cout << endl;
system("pause");
return 0;
}
运行结果
![运行结果](https://img-blog.csdnimg.cn/aeb1d24c98ff4eee980f351cf582eb7b.jpeg#pic_center)