I am having a trouble not knowing how to do a java code that will take user string then encrypt it using Elgamal algorithm as following
Elgamal algorithm Pseudo code:

  • Select Q where Q is a prime number
  • Select α where α is a primitive root of Q and α < Q.
  • Select Random Xa such that Xa < Q -1
  • Calculate Ya , such that Ya = αXa mod Q
  • Public key = { Q, α, Ya}
  • Private key = { Xa}
  • Plain Text M < Q
  • Select random k0 such that k0 < Q
  • Calculate K1 such that K1 = Yak mod Q
  • Calculate C1 = αk0 mod Q
  • Calculate C2 = K1 * M mod Q
  • Cipher = (C1, C2)
  • Decryption: Cipher = C1,C2
  • Calculate K1 such that K1 = C1 Xa mod Q
  • PlainText M = (C2K1-1
    ) mod Q
    How can I do it

How far have you got? How much Java do you know? What exactly are you stuck on?

intermediate knowledge
My problem that I don't know how I am going to generate the prime number
and how I am getting the pirmitive root
I suppose I will have three methods one for generating the public, private key one for encryption one for decryption
The main method will have a form calling that will take the input string

I assume that I will use the modpow(); to calculate the other steps

,I feel my self confused am I moving right?

There's no method called modpow in the standard Java API, so it looks like you have access to another library - maybe that has methods that will help? If not there are two easy popular ways to generate primes (sieve and testing for factors) - just Google "java generate prime number"

I am going to use Math library and BigInteger

OK, that's modPow not modpow then.
Did you mean java.lang.Math or some other Math library?
java.lang.Math has no support for BigInteger

import java.math.BigInteger;
Do you have idea if it contains method that generates prime number and the primitive root

I also have a question about the encryption method what will be the parameters

Do you have idea if it contains method that generates prime number and the primitive root

That's what the API documentation is for. It lists every public method in the class

Thanks a lot
I finished the code ,but I have a problem
The user input a string
and I want the output after decryption to be string also know it is number
,so I write the following

BigInteger recover = temp.multiply(c2);
            recover = recover.mod(Q);
               byte  test[]= recover.toByteArray();

                       String str= new String (test);

            // And this will give us our original message back!
            System.out.println("The original message = "+ (str));

My problem when I enter one letter ,such as h the output is h
but when I enter a word, such as hello the output is square
How can I solve this
Thanks a lot for your tips above

My encryption and decryption are working fine when I tried numbers the problem is with converting the string
We get it from the user but it scanner change it to byte array then converting it to big integer after decryption I passed you the code above
So the problem is with the converting how can I solve it

What code are you using to convert user input from Scanner to a byte array? WIthout seeing the code it's not possible to tell youwhat is wrong with the code!

Scanner stdin = new Scanner(System.in);
System.out.println("Please enter your message. ");
                          String foo= stdin.next();      
                          byte[] fooBytes = foo.getBytes();
                         BigInteger m = new BigInteger(fooBytes);

This my code for converting the String to BigInteger

You are mixing character representations of numbers ('1'. '2' etc) and numeric Unicode/ASCII values incorrectly.

I'm assuming your input string consists of valid ASCII characters (Unicode values <128) - if not this gets more complicated

foo.getBytes() returns an array of bytes each representing 1 character from the input string. Your data is still in ASCII/Unicode character format, ie '1' is encoded as hex 31

new BigInteger(fooBytes)requires a byte array where each byte is the next 8 bits of the big integer value - ie it takes hex 31 as a number, not as the character it represents (see the API doc!)

If that's not clear, copy and run this code - it takes "12" as input, but gives biginteger value of 12594 - look closely a the output..

   byte[] b = "12".getBytes();
   BigInteger bi = new BigInteger(b); // bi is 12594.  why? see below...

   System.out.println("ASCII: " + (char) b[0] + " " + (char) b[1]);
   System.out.printf("Hex %02x  %02x\n", b[0], b[1]);
   System.out.println("bi (hex): " + bi.toString(16));
   System.out.println("bi (decimal): " + bi);

If you want to convert a user-input string to a BigInteger you could use the public BigInteger(String val) constructor. As I said before, the API doc is your essential reference here. If you want to create a BigInteger then your very first action is to go to the API doc and see what constructors there are for BigInteger.

What about the opposite afteer decryption I am changing the Big Integer to string
As I saw above the changing will be on the system.out ??

Yes. println (and the other similar methods) automatically call toString() for each of the objects they are printing.
BigInteger's toString() method returns a printable version of it's value, just like you would hope.
Trying to do it via a byte array won't work, for exactly the same reasons as converting String to BigInteger via a byte array won't work (see above).

I am sorry for disturbing you
But I didn't know how I will use the constructor to convert

Just create a new BigInteger using the constructor that takes a String, eg

String s = "123";
BigInteger bi = new BigInteger(s);

at the end I did,     But the output is numbers not string

 BigInteger recover = temp.multiply(c2);

                recover = recover.mod(Q);
                   //byte  test[]= recover.toByteArray();

                           String str= recover.toString();

                // And this will give us our original message back!
                System.out.println("The original message = "+ (str));

The output still number not string

I mean if I encrypt Hello for example the deciphered message should be Hello also not numbers

Thanks a lot for helping me I just need to finish this last step

OK, looking back I think I've been diverted by the talk about numbers, and maybe sent you in a wrong direction.

If you want to store the characters of a string in a BI, but you don't care how they are represented inside the BI as long as you can get them back again.. then the byte array will work

        // store string in BI
        String s = "abc";
        byte[] b = s.getBytes();
        BigInteger bi = new BigInteger(b);

        // get it out again
        byte[] bb = bi.toByteArray();
        String ss = new String(bb);

... but you won't be able to make any sense of the string when its in the BI.

I make this code already when I enter one charachter I get the output
but when I enter a string I get a square

That conversion String -> BI -> String works, so it looks like the problem is somewhere else in the code. (The square just means you have generated an invalid character code. Depending on what character sets you have installed it's most probabaly a numeric value that's higher than any character in the character set.)

Can I get your email to sent the whole program

DaniWeb is a resource that everyone can contribute to and everybody can use, so please keep your question in the forum so others can help answer it and more people can learn from it. In any case I don't have any more time right now (bedtime where I live), so you will need someone else to get involved. JC