算法的基础代码,针对字符串或者流数据的加解密的算法需要根据具体应用场景自行定义。(基于大素数生成公钥私钥的方法不在本文介绍)
#ifndef __ELGAMAL_H__
#define __ELGAMAL_H__
typedef long long llong;
typedef struct ELG_CIPHER_ELEMENT
{
llong c1;
llong c2;
}ELG_CIPHER_ELEMENT, *PELG_CIPHER_ELEMENT;
//计算lPrimitiveElement^n % mod
llong qpow(llong lRandom, llong n, llong mod);
//求Zlp*的本原元
llong CalcPrimitiveElement(llong lp);
//求逆元——扩展欧几里得算法
llong inv(llong la, llong lp);
//加密类
typedef class CElgamal_Encrypt
{
public:
CElgamal_Encrypt(llong lPrime, llong lPubKey) :m_lPrime(lPrime), m_lPubKey(lPubKey)
{
m_lPrimitiveElement = CalcPrimitiveElement(lPrime);
};
~CElgamal_Encrypt() {};
public:
ELG_CIPHER_ELEMENT EncryptSingleNumber(llong num);
private:
llong m_lPrime; //约定大素数
llong m_lPrimitiveElement; //本原元
llong m_lPubKey; //公钥
}CElgamal_Encrypt, * PCElgamal_Encrypt;
//解密类
typedef class CElgamal_Decrypt
{
public:
CElgamal_Decrypt(llong lPrime, llong lPrivateKey) :m_lPrime(lPrime), m_lPrivateKey(lPrivateKey) {};
~CElgamal_Decrypt() {};
public:
llong DecryptSingleNumber(ELG_CIPHER_ELEMENT num_cipher);
private:
llong m_lPrime; //约定大素数
llong m_lPrivateKey; //私钥
}CElgamal_Decrypt, * PCElgamal_Decrypt;
#endif
#include "Elgamal.h"
//计算lPrimitiveElement^n % mod
llong qpow(llong lRandom, llong n, llong mod)
{
llong re = 1;
while (n) {
if (n & 1)
re = (re * lRandom) % mod;
n >>= 1;
lRandom = (lRandom * lRandom) % mod;
}
return re % mod;
}
//求Zlp*的本原元
llong CalcPrimitiveElement(llong lp)
{
bool flag;
for (llong i = 2; i < lp; i++) {
flag = true;
for (llong j = 2; j < lp - 1; j++) {
if ((lp - 1) % j == 0) {
if (qpow(i, j, lp) == 1) flag = false;
}
}
if (flag) return i;
}
return -1;
}
//求逆元——扩展欧几里得算法
llong inv(llong la, llong lp)
{
if (la == 1) return 1;
return inv(lp % la, lp) * (lp - lp / la) % lp;
}
ELG_CIPHER_ELEMENT CElgamal_Encrypt::EncryptSingleNumber(llong num)
{
ELG_CIPHER_ELEMENT cipher = { 0, 0 };
llong lRandom = num + 996;
cipher.c1 = qpow(m_lPrimitiveElement, lRandom, m_lPrime);
cipher.c2 = (num * qpow(m_lPubKey, lRandom, m_lPrime)) % m_lPrime;
return cipher;
}
llong CElgamal_Decrypt::DecryptSingleNumber(ELG_CIPHER_ELEMENT num_cipher)
{
num_cipher.c1 = qpow(num_cipher.c1, m_lPrivateKey, m_lPrime);
if (0 == num_cipher.c1)
{
return -1;
}
num_cipher.c1 = inv(num_cipher.c1, m_lPrime);
return (num_cipher.c2 * num_cipher.c1) % m_lPrime;
}
测试demo:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "Elgamal.h"
using namespace std;
int main() {
CElgamal_Encrypt Enc(99600077, 33893714);
ELG_CIPHER_ELEMENT cipher = Enc.EncryptSingleNumber(5173);
CElgamal_Decrypt Dec(99600077, 996007);
cout << Dec.DecryptSingleNumber(cipher) << endl;
//脏数据测试
cout << Dec.DecryptSingleNumber({ 1, 2 }) << endl;
}