EIGamal公钥加密

密码学

本文最后更新于 <span id="expire-date"></span> 天前,文中部分描述可能已经过时。

EIGamal公钥加密算法

如题

  1. 验收明文为150为以内接近150位的大整数
  2. 大素数p和本原根g自己生成
  3. 大素数选取形式为p=2q+1形式的强素数,要求p为150位的大素数,q也是素数。强素数使得p-1只有四个因子:1,2,q,p-1,从而使本原元的判断变的简单,只需要验证2和q即可
  4. 中间数据显示,包括p,q,g,公私钥对,及密文c=(c1, c2)
  5. 解密出的结果要与明文对比,验证解密是否正确

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from random import randint
import sympy
import sys
with open('C:\\Users\\吴文之\\Desktop\\验收数据\\plaintext4.txt') as file_object:
lines = file_object.readlines()
m = int(lines[0])
def fast(a,e,m): #快速计算模幂
a = a % m
r = 1
while e != 0:
if e&1:
r= (r*a)%m
e >>= 1 #右移一位
a = (a * a)%m
return r
def primitive(p, q): #调用快速取模幂求原根
while True:
g = randint(2,p-2)
if fast(g,2,p) != 1 and fast(g,q,p) != 1:
return g
def e_gcd(a,b):
if b == 0:
return a,1,0
g,x,y = e_gcd(b,a%b)
return g,y,x-a//b*y
while True: #生成一个大素数p
q = sympy.randprime(pow(10,149),pow(10,150)/2-1) #生成范围内的随机数
if sympy.isprime(q): #判断q是否是素数
p = 2 * q + 1 #生成强素数
if sympy.isprime(p) and len(str(p)) == 150:
break
print("q = " + str(q))
print("p = " + str(p))
g = primitive(p, q) #生成模𝑝的一个原根g
print("g = "+str(g))
a = randint(1,11) #随机选取整a
print("公钥对: (p,g,g^a) = "+"\n"+str(p)+"\n"+str(g)+"\n"+str(pow(g,a)%p))
y = fast(g,a,p)
#加密过程
k = randint(2, p-2)
c1 = fast(g, k, p)
c2 = (m*fast(y,k,p))%p
print("c1 = " + str(c1))
print("c2 = " + str(c2))
#解密过程
v = fast(c1,a,p)
v_ = e_gcd(v,p)[1]
m_ = c2*v_%p
if(m == m_):
print("相同")
else:
print("不同")

本文作者:Mosquito

本文链接: http://example.com/2022/01/24/EIGamal%E5%85%AC%E9%92%A5%E5%8A%A0%E5%AF%86/

Mosquito 天使之吻手打

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。