# Privacy-preserving Ticket Booking With Commutative Encryption

Nov 8, 2020 · 5 min read

I know that the chances of many of us booking a seat at the theatre is quite low, but our world will go back to normal, soon, so let’s look at a bit of privacy-preserving ticketing.

With the ever increasing number of breaches, we are moving to a world where companies should not hold any personally sensitive information, as it is just too risky. So how could we create a trustworthy system, where someone can show up with a ticket, and where we can trust it, without actually revealing any personal information about where the person has booked their seat?

So how can we generate a receipt of the booking, but not give away your identity, or the details of the booking? Let’s take an example of booking a seat in a theatre at the festival, and how your privacy can be respected, but where the theatre will trust the ticket.

## Booking a ticket

Well it can be done with commutative encryption.

The steps would be:

• Initially the theatre company generates 100 receipts for each of the seats, and then encrypts them with its public key.
• Next when I want to make a booking they send me the encrypted receipts that they have left, and I select one at random, and then encrypt it with my public key.
• I send them all back, including the one I’ve encrypted.
• The theatre checks to see which one has been changed, and then decrypts it with its private key, and sends it back to me.
• I decrypt with my private key, and I can now view the receipt for my booking, and the theater company cannot determine which seat I have, but I will have the receipt of my booking.

So here is an example where the theatre encrypts all the seats with its key, the person then selects one, and encrypts with their key, and sends them all back again. Then the theater decrypts the one that has changed, and sends it back for the person to decrypt, and we have a booking. The theatre thus does not know who has booked the seat:

# Commutative encryption

One classic patent for commutative encryption was written by James Massey and Jim K. Omura created the Massey–Omura Cryptosystem in 1982 [1]. It took over three years to be assigned and was assigned to Omnet Associates [here]:

It uses exponentiation in the Galois field GF(2^n) for both the encryption and decryption functions. In this, if we have a message of M, the encryption is:

and

This are operated on with the Galois field. For this we define e within:

and we make sure that e does not share a factor with 2^n-1 using:

The decryption exponent d is defined as:

This works because the multiplicative group of the Galois field GF(2^n) has order 2^n−1, and where Lagrange’s theorem defines that m^{de}=m for all the values of m in GF(2^n). The coding is here [link]:

`import libnumimport randomimport sysfrom Crypto.Util.number import getPrimefrom Crypto.Random import get_random_bytesdef chunkstring(string, length):    return (string[0+i:length+i] for i in range(0, len(string), length)) def generate_keys(prime):	while True:		e = random.randint(0, prime-2)		if libnum.gcd(e, prime-1) == 1 and e > 2:			break	d = libnum.invmod(e, prime-1)	return e,ddef crypt(chunk, key,prime ):  num = 0  for c in chunk:    num *= 256    num += ord(c)  res = pow(num, key, prime)  vect = []  for i in range(0, len(chunk)):    vect.append(chr(res%256))    res = res // 256  return "".join(reversed(vect))primebits=64msg = "HellHe"if (len(sys.argv)>1):  primebits=int(sys.argv[1])if (len(sys.argv)>2):  msg=(sys.argv[2])FRAGMENT_SIZE = primebits//8msg = msg + " "*((FRAGMENT_SIZE - (len(msg)%FRAGMENT_SIZE))%FRAGMENT_SIZE)res=chunkstring(msg,FRAGMENT_SIZE)PRIME = getPrime(primebits, randfunc=get_random_bytes)e,d = generate_keys(PRIME)vect=[]for elem in res:  enc=str(crypt(elem, e,PRIME))  vect.append(enc)enc="".join(vect)dec=[]for elem in chunkstring(enc, FRAGMENT_SIZE):  dec.append(crypt(elem, d,PRIME))print (f"Msg={msg}")print (f"e={e}, d={d}")print("Decrypted: " + "".join(dec))`

`Msg=Hello   e=16153579288865179167, d=10300837874192230633Decrypted: Hello`

The code is here:

One of the advantages of the Massey–Omura Cryptosystem is that we can apply commutative encryption. In this way, Bob may have keys of (e_b,d_b) and Alice has keys of (e_a,d_a). We can then apply the keys in any order, such as encrypting with e_a and then encrypting with e_b, and where we can then decrypt with d_a and then decrypt with d_b, or decrypt with d_b first and then decrypt with d_a (as we would normally do).

To encrypt:

Cipher=E(a_b,E(e_a,M))=E(e_a,E(e_b,M))

To decrypt:

E(d_b,E(d_a,Cipher))=E(d_a,E(d_b,Cipher))

Here is an example:

Written by

Written by