import java.io.
*;
import java.util.*;
class Rsa {
public static int gcd(int a, int b) {
if (a == 0) return b;
return gcd(b % a, a);
}
public static int modInverse(int a, int m) {
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) {
return x;
}
}
return 1; // Edge case, shouldn't reach here in valid RSA setup
}
public static int modExp(int base, int exp, int mod) {
int result = 1;
base = base % mod;
while (exp > 0) {
if ((exp & 1) == 1) {
result = (result * base) % mod;
}
exp = exp >> 1;
base = (base * base) % mod;
}
return result;
}
public static void main(String[] args) {
int p, q, en, e, d = 0, n, m, c;
System.out.println("Enter any two prime numbers:");
Scanner s = new Scanner(System.in);
p = s.nextInt();
q = s.nextInt();
n = p * q;
en = (p - 1) * (q - 1);
System.out.println("n value is " + n);
System.out.println("en value is " + en);
List<Integer> eCandidates = new ArrayList<>();
for (int k = 2; k < en; k++) {
if (gcd(k, en) == 1) {
eCandidates.add(k);
}
}
System.out.println("Possible values for e: " + eCandidates);
System.out.println("Choose any value from the above list:");
e = s.nextInt();
d = modInverse(e, en);
System.out.println("Modular inverse of e (d) is " + d);
System.out.println("Enter a message to encrypt (less than " + n + "):");
m = s.nextInt();
c = modExp(m, e, n);
System.out.println("The encrypted value of the given message is " + c);
m = modExp(c, d, n);
System.out.println("The decrypted value of the cipher text is " + m);
}
}