A homomorphism is a structure preserving map between two algebraic structures. Let’s consider a simple function from the integers to themselves (endomorphism):

*f : ℤ → ℤ, f(x) = ** x + x*

This function simply doubles its argument. It preserves group structure, in this case addition, because the following is satisfied

*f(a) + f(b) = f(a + b)*

Applying + at the range of the function gives us the same as mapping after we apply + at its domain, for example:

f(1) + f(2) = 2 + 4 = 6 = f(1 + 2)

To make explicit what structure is being preserved this notation is available

*f : (ℤ, +)→(ℤ, +)*

the preserved structure in the domain and range is addition.

### Encryption

Homomorphic encryption is simply encryption that is homomorphic. If we denote our encryption function with E, the function E must satisfy

*E(a) ⊕ E(b) = E(a ⊗ b)*

for some choice of operators *⊕* and *⊗*. With our previous notation:

*E : (X, ⊗)→(Y, ⊕)*

where X and Y are the algebraic structures the encryption function operates on. ElGamal encryption is a case of homomorphic encryption. Consider ElGamal when used with a safe prime modulus, p = 2q + 1 (this is necessary for semantic security), as described by:

*E : G _{q }→ G_{q }x G_{q}*

where G_{q} is a subgroup order q of (ℤ_{p})^{*}, the multiplicative group of integers modulo p. The function E for ElGamal is specified as:

Let

- x: secret key
- h: public key
- g: generator
- m: message
- r: randomness

Then

- E(m) = (g
^{r}, m · h^{r})

The pair of values on the right corresponds to the product space G_{q }x G_{q }above, ie a pair of two values each in G_{q}. ElGamal as defined is multiplicatively homomorphic:

*E : (G _{q}, •)→(G_{q }x G_{q}, •)*

where • denotes multiplication. This means that:

*E(m _{1}) · E(m_{2}) = E(m_{1} · m_{2})*

Let’s check:

which shows that ElGamal encryption is in fact homomorphic with respect to multiplication. We can see this in action using the unicrypt library by the E-Voting Group at the Bern University of Applied Sciences. The following code[1] encrypts the values ‘4’ and ‘5’, then multiplies them together in the ciphertext space. After that, it calculates 4·5 in the plaintext space and *then* encrypts the result. Both values are compared, and should match by the homomorphic property.

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 | import ch.bfh.unicrypt.math.algebra.general.interfaces.Element import ch.bfh.unicrypt.math.algebra.multiplicative.classes.GStarModSafePrime import ch.bfh.unicrypt.crypto.schemes.encryption.classes.ElGamalEncryptionScheme import ch.bfh.unicrypt.crypto.encoder.classes.ZModPrimeToGStarModSafePrime // set up encryption machinery val group = GStarModSafePrime.getFirstInstance(2048) val generator = group.getDefaultGenerator() val elGamal = ElGamalEncryptionScheme.getInstance(generator) val keyPair = elGamal.getKeyPairGenerator().generateKeyPair() val privateKey = keyPair.getFirst() val publicKey = keyPair.getSecond() // the messages are 4 and 5 val four = elGamal.getMessageSpace().getElementFrom(4) val five = elGamal.getMessageSpace().getElementFrom(5) // encrypt val four_e = elGamal.encrypt(publicKey, four) val five_e = elGamal.encrypt(publicKey, five) // calculate 4 * 5 in the ciphertext space, E(4) * E(5) val combined = four_e.apply(five_e) val result = elGamal.decrypt(privateKey, combined) // get 4 * 5 in the plaintext space val expected = elGamal.getMessageSpace().getElementFrom(4 * 5) println(combined) println(result, expected) println(expected == result) |

gives this output, which verifies. On the first line you can see how the encryption is a pair corresponding to G_{q }x G_{q}.

1 2 3 | Pair[GStarModElement[11523167560233945251440201471759789012022099533806640201046722457165498396652670027542497229832915250395284089241397523497863080811491243507868284189187462297200401916629197547133656096495797025104310703691800385978254281777175287663287848017638687227016738631631877306257455563308182190391976530245187654356114282245637013477991847993194184909486865933075824180316626338970838794128101348375468619887658828169374227944770449973965480698992043360750781306685880021819363849445411780066821178997571454397334764216104001995454190122883503956540944830959372953885001691537078100555246686706101430464478287531334291823911], GStarModElement[14774785746222892045282659242313221549058637345312152943218629794117969018574750849783871141836292258332642225936041255758699552880912503037381783469997961869873244054649705571760324454129691058687465803666381741002556218178694744341433830344142083712196045033625232069304349172868400828195747194832050349995802886358427100063593240747157556763663472564316201910018740962488663943222380244593736818607086695634107214393069477977470828774489463366872064051308146668982460565938061204474480764248526825390667266110684011163778465567656789348020334540226700723565683728322503696852776270942819225939380710201749566187795]] (GStarModElement[20],GStarModElement[20]) true |

The multiplicative homorphic property of standard ElGamal is used, for example, in voting protocols that employ a re-encryption mixnet. In such a scheme each mixing authority permutes and re-encrypts votes handling them as input to the next authority. The re-encryption of each vote is necessary, otherwise a simple permutation would allow identifying votes by matching ciphertexts. This re-encryption step corresponds to this operation

*E(1) · E(m)*

which multiplies, in the ciphertext space, the original vote by 1. This allows changing the ciphertext without changing the vote it represents

*E(1) · E(m) = E(1 · m) = E(m)*

And the vote is unchanged, by the multiplicative homomorphic property.

### Additively Homomorphic ElGamal

We just saw how we can do multiplication operations in the ciphertext space when using ElGamal encryption. It turns out that with a small change you can support addition instead of multiplication. In this case we have

*E : Z _{q }→ G_{q }x G_{q}*

and as before:

Let

- x: secret key
- h: public key
- g: generator
- m: message
- r: randomness

But now, we have a different function

- E(m) = (g
^{r}, g^{m}· h^{r})

as opposed to standard ElGamal, our previous case, where we had

- E(m) = (g
^{r}, m · h^{r})

When encrypting a message m, we are now first transforming it into g^{m} and then we proceed as before. In other words, the scheme is the same as before except the message takes the form g^{m }instead of m. This alternate scheme, sometimes called exponential ElGamal, is additively homomorphic:

*E : (G _{q}, •)→(G_{q }x G_{q}, +)*

featuring the + on the right hand side, and should satisfy

*E(m _{1}) · E(m_{2}) = E(m_{1} + m_{2})*

Let’s verify it

*E(m _{1}) · E(m_{2})*

*= (g ^{r1}, g^{m1} · h^{r1}) · (g^{r2}, g^{m2} · h^{r2}) *

*= (g ^{r1+r2}, g^{m1} g^{m2}· h^{r1+r2}) *

*= (g ^{r1+r2}, g^{m1+}^{m2}· h^{r1+r2}) *

*= E(m _{1} + m_{2})*

All ok. Let’s see it in action

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // exponential elgamal, the messages are encoded by exponentiating val four = generator.selfApply(4) val five = generator.selfApply(5) val four_e = elGamal.encrypt(publicKey, four) val five_e = elGamal.encrypt(publicKey, five) // calculate 4 + 5 in the ciphertext space val combined = four_e.apply(five_e) val result = elGamal.decrypt(privateKey, combined) // calculate 4 + 5 in the message space (again, by exponentiating) val expected = generator.selfApply(4 + 5) println(combined) println(result, expected) println(expected == result) |

which produces

1 2 3 | Pair[GStarModElement[12314693492966625461574150891785368148574723260852235545576861634693450593171220652989877363346635958314925735717510203887518211413946724979245573624050599709419019619653800027179715372875110423574987108667271722547023711028699388105313091962895094113187146768028297506156738668212767957542560135551144422284421539936556468495077615026521364801468003511429488042535710177424012058196354767224766138464123046738304186753811328642602372365396394815051175383061108671810693492683632200962316324754902874822581502720208289505007669066751387452973364140001536120903602052984293451418127302072204164242029768571861666251992], GStarModElement[1655311568353528201716488999943606715101548228025140379486655297323490182174716773521888830752820149812819633481115521567587100981103724256351234355326542074170331208942332309489805338801227535462354709317364978894875111970790523914144164854011377858447158192908902296449445454391732411111950140756035672098932165159902586289260697724112942495662032580212523194503950433789057917375664410726292472003602835276879409131386129739877605349368802128963026528975637146288512998304336942748401157735160807618829196163508584070991689692823906459971277323409990294695556899587407752052389659028238588079756125826562172213939]] (GStarModElement[262144],GStarModElement[262144]) true |

Note that exponential ElGamal has* Z _{q}* as its message space. Before encryption the message is encoded as g

^{m}. After encryption, g

^{m }has to be decoded to yield m. This step is missing in the output above, which is why we see 262144 (which is 4

^{9}).

But wait a minute, isn’t this last step taking a discrete logarithm which is exactly what is supposed to be infeasible for the scheme to be safe? That is correct, which is why exponential ElGamal can only be practically used when the values to be decrypted are expected to be small, and a look up table can be used to do the final conversion. In fact, the code above mimics this process, as it is calculating the modular exponentiation g^{m }and then comparing it to the output of decryption, so the original message is extracted as the value 9.

Additively homomorphic ElGamal is useful in voting schemes that carry out the tally by virtue of applying the + operation in the ciphertext space, thus avoiding the need to decrypt individual votes. In such a scheme, only the final ciphertext obtained by applying the sum operation is decrypted by the authorities. This final value corresponds to the election result. Such schemes are referred to in the literature as “based on homomorphic encryption”, although as we saw before re-encryption mixnets also employ this property (multiplicatively). One well known example of such a scheme is detailed in Cramer, Gennaro, Schoenmakers: A Secure and Optimally Efficient Multi-Authority Election Scheme.

which should sound familiar.

### Fully Homomorphic Encryption

We have seen how standard ElGamal encryption is multiplicatively homomorphic, and how a small change can make it additive. These properties allow computing in the ciphertext space, maintaining privacy.

Above we have computed using multiplication or addition, but not both at the same time. An encryption scheme that allows both operations simultaneously is said to be fully homomorphic. The combination of addition and multiplication allows arbitrary functions to be computed on encrypted data. Fully homomorphic encryption is an active area of research. Although currently experimental[2], a successful scheme would have very important privacy implications, opening the door for all sorts of cloud services that perform arbitrary operations on user data while maintaining privacy.

Notes

[1] We have not bothered with encoding messages from the ring Z* _{q}* into

*G*since the numbers we are using are quadratic residues.

_{q}[2] See for example https://github.com/shaih/HElib