同态加密 ElGamal方案

First Post:

Last Update:

Word Count:
692

Read Time:
3 min

同态加密 ElGamal方案

原理

ElGamal方案

  • generate_keys(p,g)
  • encrypt(m,p,g,y)

  • decrypt(c,x,p)

  • 同态加密过程

    • 生成一个大素数和生成元
    • generate_keys(p,g)生成公钥和私钥
    • 将字节串明文转换为大整数
    • encrypt(m,p,g,y)进行加密
  • 同态解密过程
    • decrypt(c,x,p)进行解密

乘法同态

  • homomorphic_addition(c1, c2, p)
  • 加密过程
    • 选择明文
    • encrypt(m, p, g, y)分别对进行加密,得到
    • homomorphic_addition(c1, c2, p)计算得到密文
  • 解密过程
    • decrypt(c3, x, p)进行解密

EXP

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import random
from Crypto.Util.number import *
from hashlib import sha256

def generate_keys(p, g):
"""生成公钥和私钥"""
x = random.randint(1, p-1)
y = pow(g, x, p)
return (x, y)

def encrypt(m, p, g, y):
"""加密明文m"""
k = random.randint(1, p-1)
a = pow(g, k, p)
b = (pow(y, k, p) * m) % p
return (a, b)

def decrypt(c, x, p):
"""解密密文c"""
a, b = c
m = (b * pow(a, p-1-x, p)) % p
return m

# 选择大素数p和生成元g
p = getPrime(215)
g = 3

# 生成公钥和私钥
x, y = generate_keys(p, g)

# 要加密的明文
pt = b'flag{f1rst_attempt}'
m = bytes_to_long(pt)

# 加密明文
c = encrypt(m, p, g, y)

# 解密密文
m_decrypted = decrypt(c, x, p)
plain_text=long_to_bytes(m_decrypted)

print("原始消息:", pt, m)
print("加密后的消息:", c)
print("解密后的消息:", m_decrypted, plain_text)

def homomorphic_addition(c1, c2, p):
"""密文的乘法同态"""
a1, b1 = c1
a2, b2 = c2
c = ((a1 * a2) % p, (b1 * b2) % p)
return c

# 选择两个明文m1和m2
m1 = 12345
m2 = 67890

# 分别加密明文m1和m2
c1 = encrypt(m1, p, g, y)
c2 = encrypt(m2, p, g, y)

# 对密文进行加法同态
c3 = homomorphic_addition(c1, c2, p)

# 解密得到加法结果
m3 = decrypt(c3, x, p)

print("加密前的明文:", m1, m2, m1*m2)
print("加密后的密文:", c1, c2)
print("同态加密后的密文:", c3)
print("解密后的明文:", m3)

Output

1
2
3
4
5
6
7
原始消息: b'flag{f1rst_attempt}' 2284117282071553800931956111894576012213646461
加密后的消息: (34326925946024248202348149516524597794238307293963587312465083699, 29257544864745339573358716821088326225971289538713175924341045784)
解密后的消息: 2284117282071553800931956111894576012213646461 b'flag{f1rst_attempt}'
加密前的明文: 12345 67890 838102050
加密后的密文: (37592138195462689660118434358852570152863680935153357241889524484, 1881167267842650302000965248563504534698498707009490637556715361) (10920357203713901658735049057071888229387493718439911523237682598, 19754766075170064385339139856259981647190642647308101159400975124)
同态加密后的密文: (25162036149156949807143289802167075308069263753806093110671488815, 28248364394465727513102472477303058997839331903759424249041835410)
解密后的明文: 838102050

不过,有一种简单的技巧可以实现基本的加法同态,它被称为“乘法同态转化”。具体方法是,对于明文,我们可以选择两个随机数,然后计算,然后对密文进行乘法同态运算,得到密文,然后解密得到的明文就是。因此,我们可以通过减去来获得的值,从而实现加法同态。

reward
Alipay
Wechat