efrei/algebre-non-lineaire/elgamal.py

58 lines
1.3 KiB
Python
Executable file

#!/usr/bin/env python3
"""ElGamal encryption and decryption"""
import random
import sys
import inverse
def main() -> None:
""""""
if len(sys.argv) == 1:
command = input("command ('encrypt' or 'decrypt'): ")
else:
command = sys.argv[1]
if command == "encrypt":
x = int(input("x : "))
g = int(input("g : "))
e = int(input("e : "))
k = int(input("k (0 for random) : "))
if k == 0:
k = random.randint(1, p - 1)
p = int(input("p : "))
r, y = encrypt(x, g, e, k, p)
print(f"({r}, {y})")
elif command == "decrypt":
r = int(input("r : "))
y = int(input("y : "))
d = int(input("d : "))
p = int(input("p : "))
x = decrypt(r, y, d, p)
print(x)
def encrypt(x: int, g: int, e: int, k: int, p: int) -> tuple[int, int]:
"""Encrypt a message (x) using elgamal"""
r = pow(g, k, p)
y = x * pow(e, k, p) % p
return r, y
def decrypt(r: int, y: int, d: int, p: int) -> int:
"""Decrypt a message (r, y) using elgamal"""
inv = inverse.inverser(pow(r, d, p), p, quiet=True)
if inv is None:
raise ValueError("{p} is not prime")
x: int = (y * inv) % p
return x
if __name__ == "__main__":
main()