在密码学中,ElGamal加密算法是一个基于DH密钥交换的非对称加密算法.
EIGamal公开密钥密码体制是基于有限域中离散对数间题的难解性。它所根据的原理是:求解离散对数是困难的,而其逆运算可以应用平方乘的方法有效的计算出来。在相应的群 G中,指数函数是单向函数。
ElGamal加密算法由三部分组成:密钥生成、加密和解密。
密钥生成
密钥生成的步骤如下:
Alice利用生成元g产生一个q阶循环群G的有效描述。该循环群需要满足一定的安全性质。
Alice从中随机选择一个 x。
Alice计算。
Alice公开h以及G,q,g的描述作为其公钥,并保留x作为其私钥。私钥保密。
加密
使用Alice的公钥(G,q,g,h)向她加密一条消息m的加密算法工作方式如下:
Bob从随机选择一个y,然后计算。
Bob计算共享秘密。
Bob把他要发送的秘密消息m映射为G上的一个元素m’。
Bob计算。
Bob将密文发送给Alice。
值得注意的是,如果一个人知道了m’,那么它很容易就能知道的值。因此对每一条信息都产生一个新的y可以提高安全性。
解密
利用私钥x对密文进行解密的算法工作方式如下:
Alice计算共享秘密
然后计算,并将其映射回明文 m,其中是s在群G上的逆元。(例如:如果G是整数模n乘法群的一个子群,那么逆元就是模逆元)。
ElGamal 公钥加密算法可以在椭圆密码体制中实现,另外通常可以用ElGamal 公钥加密算法做数字签名。
以下为ElGamal 公钥加密算法的C++代码实现:
//密码学实验
//ElGamal 公钥加密算法
#include
#include
#include
#include
using namespace std;
int pow_mod(int a, int b, int p);//预定义
//加密算法
void encryption(int m, int pub, int p, int g, int* c1, int* c2) {
int k = 5;
*c1 = pow_mod(g, k, p);
*c2 = m * pow_mod(pub, k, p) % p;
}
//解密算法
int decryption(int c1, int c2, int pri, int p, int g) {
int m;
int c1_ = pow_mod(c1, p - 2, p);
m = c2 * pow_mod(c1_, pri, p) % p;
return m;
}
//判断是否为素数
int is_prime(int p) {
int i;
for (i = 2; i <= sqrt(p); i++) {
if (p % i == 0)
return 0;
}
return 1;
}
//公钥产生算法
int pow_mod(int a, int b, int p) {
int ans = 1;
int tmp = a % p;
while (b) {
if (b & 1)
ans = ans * tmp % p;
b >>= 1;
tmp = tmp * tmp % p;
}
return ans % p;
}
//测试加解密算法
int main() {
int p;//素数
int g = 2;
do {
cout << "Please enter a prime number:" << endl;
cin>>p;
} while (!is_prime(p));
cout << endl;
cout << "Enter the private key of user A:" << endl;;
int pri;
cin>>pri;
cout << endl;
int pub;
pub = pow_mod(g, pri, p);
cout << "the private key of user A:"<< endl<<pub<<endl;
cout << "Input plaintext(smaller than "<< p<<":"<<endl;
int m;
cin>>m;
int c1, c2;
encryption(m, pub, p, g, &c1, &c2);
cout << "The ciphertext encrypted with the public key is:" << endl << "c1= " << c1 << " " << "c2= " <<c2 << endl;;
int m_ = decryption(c1, c2, pri, p, g);
cout << "Plaintext decrypted with private key:"<< m_;
system("pause");
}