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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| import random
def is_prime(n, k=5): if n <= 1 or n % 2 == 0: return False if n == 2 or n == 3: return True r, d = 0, n - 1 while d % 2 == 0: r += 1 d //= 2 for _ in range(k): a = random.randrange(2, n - 1) x = pow(a, d, n) if x == 1 or x == n - 1: continue for _ in range(r - 1): x = pow(x, 2, n) if x == n - 1: break else: return False return True
def generate_large_prime(bits=128): while True: p = random.getrandbits(bits) p |= (1 << bits - 1) | 1 if is_prime(p): return p
def mod_exp(base, exponent, mod): result = 1 base %= mod while exponent > 0: if exponent % 2: result = (result * base) % mod exponent //= 2 base = (base * base) % mod return result
def find_primitive_root(p): if p == 2: return 1 phi = p - 1 factors = set() n = phi i = 2 while i * i <= n: if n % i == 0: factors.add(i) while n % i == 0: n //= i i += 1 if n > 1: factors.add(n) for g in range(2, p): if all(pow(g, phi // f, p) != 1 for f in factors): return g return None
def generate_keys(p): g = find_primitive_root(p) x = random.randint(2, p - 2) y = mod_exp(g, x, p) return (p, g, y), x
def encrypt(p, g, y, m): k = random.randint(2, p - 2) a = mod_exp(g, k, p) b = (m * mod_exp(y, k, p)) % p return a, b, k
def decrypt(p, x, a, b): s = mod_exp(a, x, p) s_inv = pow(s, -1, p) m = (b * s_inv) % p return m, s, s_inv
if __name__ == "__main__": try: bits = int(input("请输入要生成素数的位数:")) if bits < 8: raise ValueError("位数应当大于等于 8 位") except ValueError as e: print(f"输入无效: {e}") exit(1)
print(f"正在生成 {bits} 位素数用于 ElGamal 密钥,请稍等...") p = generate_large_prime(bits) public_key, private_key = generate_keys(p) g, y = public_key[1], public_key[2] x = private_key
print("\n密钥生成完毕:") print(f"私钥 x: {x}") print(f"公钥 (g={g}, y={y})")
message = int(input("\n请输入要加密的整数消息(必须小于 p): ")) if message >= p: raise ValueError("消息必须小于 p") a, b, k = encrypt(p, g, y, message) print("\n 加密过程:") print(f"随机 k: {k}") print(f"计算 a = g^k mod p = {a}") print(f"计算 b = m * y^k mod p = {b}")
m_decrypted, s, s_inv = decrypt(p, x, a, b) print("\n解密过程:") print(f"计算共享密钥 s = a^x mod p = {s}") print(f"计算 s 的逆 s^(-1) mod p = {s_inv}") print(f"解密后消息 m = b * s^(-1) mod p = {m_decrypted}")
print("\n解密是否成功?", "是" if m_decrypted == message else "否")
|