javakotlincryptographybouncycastleelgamal

ElGamal homomorphic multiplication using Bouncy Castle


Long story short: I'm in need of using ElGamal encryption to perform multiplication on encoded numbers.

I'm currently using Kotlin with OpenJDK 1.8 and found nice provider for JCE called Bouncy Castle. It provides ElGamal encryption within standard JCE API. However, I have no idea at all how to perform multiplication on encrypted messages I get out of it.

Security.addProvider(BouncyCastleProvider())

val keys = KeyPairGenerator.getInstance("ElGamal", "BC").generateKeyPair()
val cipher = Cipher.getInstance("ElGamal/None/NoPadding", "BC")
cipher.init(Cipher.ENCRYPT_MODE, keys.public)
val eleven = BigInteger.valueOf(11)
val three = BigInteger.valueOf(3)
val eleven_e = cipher.doFinal(eleven.toByteArray())
val three_e = cipher.doFinal(three.toByteArray())
//Do three_e * eleven_e

Solution

  • I've managed to investigate a little bit the source code of the Bouncy Castle. It seems that contrary to what @PresidentJamesMoveonPolk says below code should be able to multiply two encoded numbers:

    fun multiplyElGamal(num1: ByteArray, num2: ByteArray, p: BigInteger): ByteArray {
        val a1 = num1.copyOfRange(0, num1.size / 2)
        val b1 = num1.copyOfRange(num1.size / 2, num1.size)
        val a2 = num2.copyOfRange(0, num2.size / 2)
        val b2 = num2.copyOfRange(num2.size / 2, num2.size)
        return (BigInteger(1, a1) * BigInteger(1, a2) % p).toByteArray() + (BigInteger(1, b1) * BigInteger(1, b2) % p).toByteArray()
    }
    

    This might be only partial solution. The problem is that, part p of the key is 1025 bits, while parts a and b of the message got to be 1024 bit (resulting in a byte array of length 256). Modulus operation sometimes returns numbers larger than that which results in org.bouncycastle.crypto.DataLengthException: input too large for ElGamal cipher.