-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCryptography.java
More file actions
187 lines (134 loc) · 5.79 KB
/
Cryptography.java
File metadata and controls
187 lines (134 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import java.util.Scanner;
import java.util.ArrayList;
import java.math.BigInteger;
public class Cryptography {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Step 1: Choose a prime number p
System.out.print("Enter The Upper Limit Of p: ");
int limp = input.nextInt();
ArrayList<Integer> primesp = new ArrayList<>();
// Find all prime numbers ≤ limp
for (int i = limp; i >= 2; i--) {
if (isPrime(i)) {
primesp.add(i);
}
}
// Choose the largest prime less than or equal to limp
int p = primesp.get(0);
System.out.println("The Value Of p = " + p);
// Step 2: Choose a prime number q
System.out.print("Enter The Upper Limit Of q: ");
int limq = input.nextInt();
ArrayList<Integer> primesq = new ArrayList<>();
// Find all prime numbers ≤ limq
for (int j = limq; j >= 2; j--) {
if (isPrime(j)) {
primesq.add(j);
}
}
// Choose the largest prime less than or equal to limq
int q = primesq.get(0);
System.out.println("The Value Of q = " + q);
// Step 3: Calculate n = p * q and m = (p-1)*(q-1)
calculate(p, q);
// Step 4: Choose public exponent e such that 1 < e < m and gcd(e, m) = 1
ArrayList<Integer> eCalc = new ArrayList<>();
for (int i = 2; i < (p - 1) * (q - 1); i++) {
if (calculateE((p - 1) * (q - 1), i)) {
eCalc.add(i);
}
}
// Choose the smallest valid e
int e = eCalc.get(0);
System.out.println("The Value Of e = " + e);
// Step 5: Calculate private key d such that (d * e) % m = 1
int d = 0;
for (int k = 0; k <= e; k++) {
int x = ((p - 1) * (q - 1) * k) + 1;
if (x % e == 0) {
d = x / e;
}
}
System.out.println("The Value Of d = " + d);
// Convert values to BigInteger for large number support
BigInteger bigE = BigInteger.valueOf(e);
BigInteger bigN = BigInteger.valueOf(p * q);
BigInteger bigD = BigInteger.valueOf(d);
input.nextLine(); // Consume newline
System.out.print("Enter The Original Message: ");
String message = input.nextLine();
// Step 6: Encrypt the message
String cipherText = encryption(message, bigE, bigN);
System.out.println("The Encrypted Message Is : " + cipherText);
// Step 7: Decrypt the message
String decryptedMessage = decryption(cipherText, bigD, bigN);
System.out.println("The Decrypted Message Is: " + decryptedMessage);
input.close();
}
// Function to check if a number is prime
public static boolean isPrime(int num) {
if (num < 2) return false;
for (int i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) return false;
}
return true;
}
// Function to calculate and print n and m
public static int[] calculate(int p, int q) {
int n = p * q;
int m = (p - 1) * (q - 1);
int[] arr = {n, m};
System.out.println("The Value Of n = " + arr[0]);
System.out.println("The Value Of m = " + arr[1]);
return arr;
}
// Function to check if e is coprime with m
public static boolean calculateE(int m, int e) {
return BigInteger.valueOf(m).gcd(BigInteger.valueOf(e)).intValue() == 1;
}
// Function to calculate base^exponent % number using modular exponentiation
public static BigInteger modularExponent(BigInteger base, BigInteger exponent, BigInteger number) {
BigInteger result = BigInteger.ONE;
if (base.compareTo(BigInteger.ZERO) > 0 &&
exponent.compareTo(BigInteger.ZERO) > 0 &&
number.compareTo(BigInteger.ZERO) > 0) {
result = base.modPow(exponent, number);
}
return result;
}
// Encrypt the message using RSA: C = P^e % n
public static String encryption(String message, BigInteger e, BigInteger n) {
StringBuilder cipher = new StringBuilder();
for (char c : message.toCharArray()) {
BigInteger P = BigInteger.valueOf((int) c); // Convert char to int
BigInteger encrypted = modularExponent(P, e, n); // Encrypt it
// Convert encrypted number into printable ASCII characters using base 126
while (encrypted.compareTo(BigInteger.ZERO) > 0) {
int toAscii = encrypted.mod(BigInteger.valueOf(126)).intValue();
cipher.append((char) toAscii);
encrypted = encrypted.divide(BigInteger.valueOf(126));
}
cipher.append(" "); // Separator between characters
}
return cipher.toString();
}
// Decrypt the message using RSA: P = C^d % n
public static String decryption(String cipher, BigInteger d, BigInteger n) {
StringBuilder message = new StringBuilder();
String[] encryptedmesg = cipher.split(" "); // Split by space
for (String encrypt : encryptedmesg) {
BigInteger C = BigInteger.ZERO;
// Reconstruct original encrypted number from base-126 encoded characters
for (int i = encrypt.length() - 1; i >= 0; i--) {
int decryptInt = (int) encrypt.charAt(i);
C = C.multiply(BigInteger.valueOf(126)).add(BigInteger.valueOf(decryptInt));
}
// Decrypt the number using modular exponentiation
BigInteger decrypted = modularExponent(C, d, n);
char originalChar = (char) decrypted.intValue(); // Convert back to character
message.append(originalChar);
}
return message.toString();
}
}