ElGamal Encryption
November 28, 2018 ยท View on GitHub
Prerequisites:
- Cyclic Groups, Generators
- Basic Number Theory (Euler's Theorem, Fermat's Little Theorem)
ElGamal Encryption System is an Asymmetric Key Encryption System based on Discrete Logarithm Problem (DLP) and Diffie-Hellman Key Exchange.
For illustrative purposes, we will consider Alice as the receiver and Bob as the sender.
There are different steps involved while encrypting or decrypting data with ElGamal, let's list them first and then study each of them in detail:
- Key Generation: Alice generates a public and private key and shares the public key.
- Encryption: Bob uses Alice's public to encrypt message that he wants to send to Alice, and hence generates a pair of ciphertext (c1, c2). Shares the ciphertext pair.
- Decryption: Alice then uses her private key to decrypt the ciphertext (c1, c2).
Key Generation
This is the first step in the process of transferring a messages securely, between Alice and Bob. In this step, Alice does the following:
- Selects a Cyclic Group
Gof orderqand generatorg. Note that either the cyclic group should be generated over a safe primep, or the generatorgshould generate prime-order-subgroups; otherwise it is vulnerable to Small Subgroup Attacks. - Generates a random number
xsuch that1 <= x <= q-1and assigns it as the private key (Note thatqis the group order). - Calculates

- Shares
h,g,qas Public Key xis the Private Key which only Alice should know, and that's where the security of the encryption system lies.
Here is a python-2.7 implementation of the above step:
def _generate_key():
# Assigning the largest 1024-bit safe prime as p
p = (1 << 1024) - 1093337
x = randint(2, p-2)
g = 23
q = p - 1
h = pow(g, x, p)
pubkey = PublicKey(h, p, g, q)
privkey = PrivateKey(x, p, g, q)
return (pubkey, privkey)
Encryption
Bob receives Alice's Public Key and encrypts the message that he wants to send to Alice as follows:
- Selects a random number
ysuch that1 <= y <= q-1. Note that a new value ofyis chosen for sending every message. Hence,yis known as ephemeral key. - Chooses a message
msuch that1 < m < q-1 - Diffie Hellman Step: Calculates

- Diffie Hellman Step, also
sis known as the shared secret: Calculates
- Calculates

- Shares (c1, c2) as the ciphertext
Here is a python-2.7 implementation of the above step:
def _encrypt(message, pubkey):
h = pubkey.h
p = pubkey.p
g = pubkey.g
q = pubkey.q
m = bytes_to_long(message)
# Generating ephemeral key: `y`
y = randint(2, p-2)
c1 = pow(g, y, p)
# Computing the shared secret: `s`
s = pow(h, y, p)
c2 = (m*s) % p
return (c1, c2)
Decryption
Alice receives (c1, c2), we can write them as:


- Alice then calculates the following to get the shared secret
s:
- To get back the message
mfrom c2, Alice does the following:

Here is a python-2.7 implementation of the above step:
def _decrypt(ciphertext, privkey):
c1, c2 = ciphertext
g = privkey.g
p = privkey.p
x = privkey.x
s = pow(c1, x, p)
m = (c2*inverse(s, p)) % p
return m
Check out the full implementation/example of ElGamal encryption/decryption here