ElGamal加密及其乘法同态

ElGamal加密方案

ElGamal加密方案是基于离散对数问题的公钥加密方案。其加密运算是随机的,即同一明文在相同密钥加密下,所得到的密文是不一样的。

离散对数问题

实例:对于乘法群G,其中一个n阶元素alpha,有beta属于由alpha生成的子群。

问题:找到唯一的整数a,0<=a<=n-1,满足:

alpha^{a}=beta

将这个整数a记作 \log_{alpha}beta,称为beta的离散对数。

求解离散对数(可能)是困难的,目前没有已知的多项式时间算法的解决,而其逆,即指数运算,可以通过模重复平方算法快速求解。

所以,可认为在适当的群G中,指数函数是单向的。为ElGamal加密的安全提供了保障。

在素域p上的ElGamal加密

设p是一个整数,使得在\mathbb{Z}_{p}^{*}上的离散对数问题是困难的,令alpha为一个本原元。

则公钥为p,alpha,beta;

私钥为a,满足alpha^{a}=beta

 加密x:

E(x,k)=(y_{1},y_{2})

y_{1}=alpha^{k} mod p

y_{2}=x*beta^{k} mod p

解密:

D(y_{1},y_{2})=y_{2}*(y_{1}^{a})^{-1} mod p

ElGamal加密的乘法同态

ElGamal加密是满足乘法同态的。

即,对于明文x1,x2,分别加密成密文c1和c2,c1*c2解密的明文为x1*x2。

其中c1*c2定义为(c1.y1*c2.y1,c1.y2*c2.y2)。

c1.y_{1}=alpha^{k1} mod p

c1.y_{2}=x1*beta^{k1} mod p

c2.y_{1}=alpha^{k2} modp

c2.y_{2}=x2*beta^{k2} mod p

c1.y_{1}*c2.y_{1}=alpha^{k1+k2} mod p

c1.y_{2}*c2.y_{2}=x1*x2*beta^{k1+k2} mod p

所以,可以看到c1*c2相当于用随机数k1+k2对x1*x2加密。即ElGamal加密满足乘法同态,而且,该乘法同态没有次数限制。可以进行任意次乘法运算。

c++简单实现(基于NTL库)

#include<NTL/ZZ.h>
#include<iostream>
#include<ctime>
using namespace std;
using namespace NTL;
pair<ZZ,ZZ> encrypt(ZZ x, ZZ alpha, ZZ beta,ZZ p){
	ZZ k;
	SetSeed(to_ZZ(time(NULL)));
	k=RandomBnd(p);
	while(k<2){
		k=RandomBnd(p);
	}
	ZZ y1,y2;
	PowerMod(y1,alpha,k,p);
	PowerMod(y2,beta,k,p);
	y2=MulMod(y2,x,p);
	return make_pair(y1,y2);
}
ZZ decrypt(pair<ZZ,ZZ> ctxt,ZZ a,ZZ p){
	ZZ t;
	t=PowerMod(ctxt.first,a,p);
	t=InvMod(t,p);
	t=MulMod(t,ctxt.second,p);
	return t;
}
pair<ZZ,ZZ> ctxtMul(const pair<ZZ,ZZ> &c1,const pair<ZZ,ZZ>& c2,ZZ& p){
	pair<ZZ,ZZ> res;
	res.first=MulMod(c1.first,c2.first,p);
	res.second=MulMod(c1.second,c2.second,p);
	return res;
}
int main(){
	ZZ p,alpha,a,beta;
	p=2579;
	alpha=2;
	a=765;
	beta=949;
	pair<ZZ,ZZ> ctxt1,ctxt2,ctxt3;
	cout<<"Input the plaintext x1:"<<endl;
	ZZ x1;
	cin>>x1;
	ctxt1=encrypt(x1,alpha,beta,p);
	cout<<"The ciphertext of x1 is:"<<endl;
	cout<<"y1:"<<ctxt1.first<<endl;
	cout<<"y2:"<<ctxt1.second<<endl;

	cout<<"Input the plaintext x2:"<<endl;
	ZZ x2;
	cin>>x2;
	ctxt2=encrypt(x2,alpha,beta,p);
	cout<<"The ciphertext of x2 is:"<<endl;
	cout<<"y1:"<<ctxt2.first<<endl;
	cout<<"y2:"<<ctxt2.second<<endl;

	ZZ x3;
	x3=x1*x2%p;
	cout<<"x1*x2 is "<<x3<<endl;

	ctxt3=ctxtMul(ctxt1,ctxt2,p);
	cout<<"The ciphertext of ctxt1*ctxt2 is:"<<endl;
	cout<<"y1:"<<ctxt3.first<<endl;
	cout<<"y2:"<<ctxt3.second<<endl;
	
	ZZ result;
	result=decrypt(ctxt3,a,p);
	cout<<"Decrypted:"<<result<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/watqw/article/details/120744560