|
1 | | -/* |
2 | | - * TheAlgorithms (https://github.com/TheAlgorithms/Java) |
3 | | - * Author: Shewale41 |
4 | | - * This file is licensed under the MIT License. |
5 | | - */ |
6 | | - |
7 | 1 | package com.thealgorithms.ciphers; |
8 | 2 |
|
9 | 3 | import java.math.BigInteger; |
|
12 | 6 | /** |
13 | 7 | * Implementation of the ElGamal Encryption Algorithm. |
14 | 8 | * |
15 | | - * <p>This algorithm is based on the Diffie–Hellman key exchange and provides secure |
16 | | - * public-key encryption and decryption using modular arithmetic. |
| 9 | + * <p>ElGamal is an asymmetric key encryption algorithm based on |
| 10 | + * the Diffie–Hellman key exchange. It uses randomization |
| 11 | + * for security and is widely used in cryptographic systems.</p> |
17 | 12 | * |
18 | | - * <p>Reference: |
19 | | - * https://en.wikipedia.org/wiki/ElGamal_encryption |
| 13 | + * <p>Reference: Menezes, van Oorschot, and Vanstone, "Handbook of Applied Cryptography"</p> |
20 | 14 | */ |
21 | 15 | public final class ElGamalEncryption { |
22 | 16 |
|
23 | 17 | private static final SecureRandom RANDOM = new SecureRandom(); |
24 | 18 |
|
25 | | - /** Private constructor to prevent instantiation of utility class. */ |
| 19 | + // Private constructor to prevent instantiation |
26 | 20 | private ElGamalEncryption() { |
27 | 21 | throw new UnsupportedOperationException("Utility class"); |
28 | 22 | } |
29 | 23 |
|
30 | 24 | /** |
31 | | - * Demonstrates ElGamal encryption and decryption for a given message. |
| 25 | + * Runs the ElGamal encryption and decryption demonstration. |
32 | 26 | * |
33 | | - * @param message the message to encrypt |
34 | | - * @param bitLength the bit length for the prime number used |
| 27 | + * @param message the plaintext message to encrypt |
| 28 | + * @param bitLength the bit length for prime generation |
35 | 29 | */ |
36 | | - public static void runElGamal(String message, int bitLength) { |
37 | | - BigInteger p = BigInteger.probablePrime(bitLength, RANDOM); // prime modulus |
38 | | - BigInteger g = new BigInteger("2"); // primitive root |
39 | | - BigInteger x = new BigInteger(bitLength - 2, RANDOM); // private key |
40 | | - BigInteger y = g.modPow(x, p); // public key |
| 30 | + @SuppressWarnings({"PMD.SystemPrintln", "PMD.DataflowAnomalyAnalysis"}) |
| 31 | + public static void runElGamal(final String message, final int bitLength) { |
| 32 | + // Key generation |
| 33 | + final BigInteger p = BigInteger.probablePrime(bitLength, RANDOM); |
| 34 | + final BigInteger g = new BigInteger("2"); |
| 35 | + final BigInteger x = new BigInteger(bitLength - 2, RANDOM); |
| 36 | + final BigInteger y = g.modPow(x, p); |
41 | 37 |
|
42 | 38 | // Encryption |
43 | | - BigInteger k = new BigInteger(bitLength - 2, RANDOM); |
44 | | - BigInteger a = g.modPow(k, p); |
45 | | - BigInteger m = new BigInteger(message.getBytes()); |
46 | | - BigInteger b = (y.modPow(k, p).multiply(m)).mod(p); |
| 39 | + final BigInteger k = new BigInteger(bitLength - 2, RANDOM); |
| 40 | + final BigInteger a = g.modPow(k, p); |
| 41 | + final BigInteger m = new BigInteger(message.getBytes()); |
| 42 | + final BigInteger b = (y.modPow(k, p).multiply(m)).mod(p); |
47 | 43 |
|
48 | 44 | // Decryption |
49 | | - BigInteger aInverse = a.modPow(p.subtract(BigInteger.ONE).subtract(x), p); |
50 | | - BigInteger decrypted = (b.multiply(aInverse)).mod(p); |
| 45 | + final BigInteger aInverse = a.modPow(p.subtract(BigInteger.ONE).subtract(x), p); |
| 46 | + final BigInteger decrypted = (b.multiply(aInverse)).mod(p); |
51 | 47 |
|
| 48 | + // Display results |
52 | 49 | System.out.println("Prime (p): " + p); |
| 50 | + System.out.println("Generator (g): " + g); |
| 51 | + System.out.println("Private Key (x): " + x); |
53 | 52 | System.out.println("Public Key (y): " + y); |
54 | 53 | System.out.println("Ciphertext: (" + a + ", " + b + ")"); |
55 | 54 | System.out.println("Decrypted Message: " + new String(decrypted.toByteArray())); |
|
0 commit comments