Below is my JAVA code for encrypting clear text (not numbers). Code includes both encryption and decryption.
The decrypted text doesn't match clear text, what am I doing work?
My code works if I replace BigInteger m = new BigInteger(msg.getBytes());
with this code BigInteger m = new BigInteger(msg);
package com.porsche.main;
import java.util.*;
import java.math.BigInteger;
public class ElGamal {
// Get user input for prime.
// static BigInteger p = new BigInteger("13256401");
static BigInteger p = new BigInteger("14893003337626352152463254152616458181260144281");
// Calculate a generator.
// static BigInteger g = new BigInteger("957");
static BigInteger g = new BigInteger("4893003337626352152463254152616458181260144281");
// Pick a secret a.
// BigInteger a = new BigInteger(p.bitCount()-1, r);
static BigInteger a = new BigInteger("843900337326351225463254152616458181260144281");
public static void main(String[] args) {
Random r = new Random();
// Calculate the corresponding public b.
BigInteger b = g.modPow(a, p);
// Print out our public keys.
System.out.println("p = " + p);
System.out.println("g = " + g);
System.out.println("b = " + b);
// When we send a message, the sender picks a random k.
BigInteger k = new BigInteger(p.bitCount()-1, r);
// Here, the sender starts calculating parts of the cipher text that
// don't involve the actual message.
BigInteger c1 = g.modPow(k, p);
BigInteger c2 = b.modPow(k, p);
// Here we get the message from the user.
String msg = "12345678901234567890123456789012345678901234567";
BigInteger m = new BigInteger(msg.getBytes());
System.out.println("The message encryption = " + msg);
// Now, we can calculate the rest of the second cipher text.
c2 = c2.multiply(m);
c2 = c2.mod(p);
// Print out the two cipher texts.
System.out.println("The corresponding cipher texts are");
System.out.println("c1 = " + c1);
System.out.println("c2 = " + c2);
// First, determine the inverse of c1 raised to the a power mod p.
BigInteger temp = c1.modPow(a,p);
temp = temporariness(p);
// Print this out.
System.out.println("Here is c1^ -a = "+temp);
// Now, just multiply this by the second cipher text
BigInteger recover = temp.multiply(c2);
recover = recover.mod(p);
// And this will give us our original message back!
System.out.println("The decrypted message = "+recover);
}
}
You gave very less information about the "El Gamal" algorithm so it is hard to find why your code is not working as expected. Searching a little bit in the net I found a working example code that is very similar to your's and it is working (http://faculty.washington.edu/moishe/javademos/Security/ElGamal.java).
Please keep in mind that working with BigInteger variables mean you will get very large numbers and this is limiting the size of data ("cleartext") you can work with. The sample code has a limit of 19 chars that can be encrypted & decrypted, longer cleartexts won't work. For that reason I used a different cleartext from yours ("9876543210987654321").
The result is here:
Thats the working code (minimal changed from the linked one):
Edit: Regarding your comment "Thanks for the reply. Does the clear text need to be all numbers only, can it be a text something like "Hellow World!"?":
According to the JavaDocs (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigInteger.html) a BigInteger is created with these constructors and all have one thing in common - it has to be a number that represents a BigInteger-value and that's not a char: