This a a short introduction to the ElGamal cryptosystem in SageMath.

The ElGamal cryptosystem is a randomized cryptosystem designed in 1985 by Taher ElGamal.

In [9]:
from sage.all import *
In [10]:
def InstGen(sec):
    q = random_prime(2**(sec+1), lbound=2**(sec)) 
    G = IntegerModRing(q)                
    g = G.multiplicative_generator()
    x = ZZ.random_element(2,q-1)
    h = g**x
    pk = (G,q,g,h)
    sk = (G,q,g,x)
    return pk, sk
    
def Enc(pk, m):
    #assume m is an element of the group
    G,q,g,h = pk
    y = ZZ.random_element(1,q)
    c1 = g**y
    s = h**y
    c2 = m*s
    return c1,c2

def Dec(sk, c):
    G,q,g,x = sk
    c1, c2 = c
    s = c1**x
    m = c2 * s**-1
    return m

def sample_message(pk):
    G = pk[0]
    return G.random_element()    
In [13]:
PK,SK = InstGen(50)
print "PK: ", PK
print "SK: ", SK

m = sample_message(PK)
print "message: ", m

c = Enc(PK,m)
print "ciphertext: ", c

mprime = Dec(SK,c)
print "mprime: ", mprime
PK:  (Ring of integers modulo 1503047568552703, 1503047568552703, 3, 873212081429622)
SK:  (Ring of integers modulo 1503047568552703, 1503047568552703, 3, 101948496392641)
message:  570745943607369
ciphertext:  (964670799905441, 135599899405773)
mprime:  570745943607369
In [14]:
import time

G,q,g,h = PK
x = SK[3]
t0 = time.time()
dlog = discrete_log(h,g)
t = time.time() - t0
print "Discrete Log of h("+str(h)+") is: ", dlog
print "SageMathCloud took ", t," seconds to calculate Discrete Log in group of size", q, "(roughly 2^" +str(ZZ(ceil(log(t,2))))+ " seconds to solve in group of order size 2^" + str(ZZ(ceil(log(q,2)))) + "."  
Discrete Log of h(873212081429622) is:  101948496392641
SageMathCloud took  0.0190169811249  seconds to calculate Discrete Log in group of size 1503047568552703 (roughly 2^-5 seconds to solve in group of order size 2^51.
In [ ]: