一,ElGamal算法介绍
该算法的复杂性理论基础为离散对数困难问题(DLP),属于随机性加密(由于密钥是随机选取的)。
二,知识
群环域相关
- 循环群
- 求本原元
- 求逆元
三,C++代码实现
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 typedef long long ll; 5 6 ll p,a,x,y,r,c1,c2,m; 7 8 ll qpow(ll r, ll n, ll mod){//计算a^n % mod 9 ll re = 1; 10 while(n){ 11 if(n & 1) 12 re = (re * r) % mod; 13 n >>= 1; 14 r = (r * r) % mod; 15 } 16 return re % mod; 17 } 18 19 ll byy(ll lp){//求Zlp*的本原元 20 bool flag; 21 for(ll i=2;i<lp;i++){ 22 flag=true; 23 for(ll j=2;j<lp-1;j++){ 24 if((lp-1)%j==0){ 25 if(qpow(i,j,lp)==1) flag=false; 26 } 27 } 28 if(flag) return i; 29 } 30 } 31 32 ll inv(ll la, ll lp){//求逆元——扩展欧几里得算法 33 if(la == 1) return 1; 34 return inv(lp%la,lp)*(lp-lp/la)%lp; 35 } 36 37 void encode(ll la,ll lp,ll ly,ll lr){ 38 printf("\n======加密======\n"); 39 c1=qpow(la,lr,lp); 40 c2=(m*qpow(ly,lr,lp))%lp; 41 printf("得到的密文为c1=%lld c2=%lld\n",c1,c2); 42 } 43 44 void decode(ll lx,ll lp){ 45 printf("\n======解密======\n"); 46 c1=qpow(c1,lx,lp); 47 c1=inv(c1,lp); 48 m=(c2*c1)%lp; 49 printf("得到的明文为m=%lld\n",m); 50 } 51 52 int main(){ 53 printf("请输入参数p并随机选取密钥x(0<x<p-1):"); 54 scanf("%lld%lld",&p,&x); 55 a=byy(p); 56 y=qpow(a,x,p); 57 printf("计算出本原元a=%lld 公钥y=%lld\n",a,y); 58 printf("请输入要加密的明文m(m=Zp*):"); 59 scanf("%lld",&m); 60 printf("请输入随机产生的参数r(r=Zp*,gcd(r,p-1)=1):"); 61 scanf("%lld",&r); 62 63 encode(a,p,y,r); //加密 64 decode(x,p); //解密 65 }
四,实现截图