Tog bort kommentarer och är klar nu

This commit is contained in:
dDogge 2025-02-16 13:04:09 +01:00
parent ffad3d5118
commit 81f0baf2a7
6 changed files with 39 additions and 58 deletions

View file

@ -1,3 +1,4 @@
//Douglas Fjällrud, Axel Blomén
package src.rsa;
import java.math.BigInteger;
@ -8,23 +9,20 @@ public class EuclideanAlgorithm {
BigInteger m0 = m, t, q;
BigInteger x0 = BigInteger.ZERO, x1 = BigInteger.ONE;
if (m.equals(BigInteger.ONE)) return BigInteger.ZERO; // Ingen invers om m = 1
if (m.equals(BigInteger.ONE)) return BigInteger.ZERO;
while (a.compareTo(BigInteger.ONE) > 0) {
q = a.divide(m); // Kvoten
q = a.divide(m);
t = m;
// m = a % m, liknar Euklides algoritm
m = a.mod(m);
a = t;
t = x0;
// Uppdatera x0 och x1
x0 = x1.subtract(q.multiply(x0));
x1 = t;
}
// Hantera negativa x1
if (x1.compareTo(BigInteger.ZERO) < 0) {
x1 = x1.add(m0);
}
@ -40,18 +38,15 @@ public class EuclideanAlgorithm {
}
}
// 3 Testa algoritmen med några stora tal
public static void main(String[] args) {
System.out.println("=== Test av modular invers ===");
BigInteger a = new BigInteger("65537"); // Typiskt RSA e = 2^16 + 1
BigInteger m = new BigInteger("973157123091"); // Slumpmässigt stort tal
BigInteger a = new BigInteger("65537");
BigInteger m = new BigInteger("973157123091");
// Kontrollera om invers finns
if (gcd(a, m).equals(BigInteger.ONE)) {
BigInteger inv = modularInverse(a, m);
System.out.println("Modulär invers av " + a + " mod " + m + " är: " + inv);
// Kontroll: Ska ge 1 (a * inv) % m == 1
System.out.println("Verifiering: (" + a + " * " + inv + ") mod " + m + " = " + a.multiply(inv).mod(m));
} else {
System.out.println("Ingen invers existerar för a mod m.");

View file

@ -1,3 +1,4 @@
//Douglas Fjällrud, Axel Blomén
package src.rsa;
import java.math.BigInteger;
@ -7,7 +8,6 @@ public class Main {
public static void main(String[] args) {
System.out.println("=== Startar RSA-programmet ===");
// 1 Generera RSA-nycklar
int bitLength = 512;
RSAKeyGenerator rsa = new RSAKeyGenerator(bitLength);
BigInteger[] publicKey = rsa.getPublicKey();
@ -17,19 +17,15 @@ public class Main {
System.out.println("Publik nyckel: N = " + publicKey[0] + ", e = " + publicKey[1]);
System.out.println("Privat nyckel: N = " + privateKey[0] + ", d = " + privateKey[1]);
// 2 Skapa ett slumpmässigt meddelande som är mindre än N
BigInteger message = new BigInteger(bitLength - 1, new Random());
System.out.println("\nOriginal meddelande: " + message);
// 3 Kryptera meddelandet
BigInteger ciphertext = RSAEncryptor.encrypt(message, publicKey);
System.out.println("Krypterat meddelande: " + ciphertext);
// 4 Dekryptera meddelandet
BigInteger decrypted = RSAEncryptor.decrypt(ciphertext, privateKey);
System.out.println("Dekrypterat meddelande: " + decrypted);
// 5 Verifiera att dekrypteringen fungerar
boolean isCorrect = message.equals(decrypted);
System.out.println("\nStämmer dekrypteringen? " + (isCorrect ? "JA! ✅" : "NEJ ❌"));
}

View file

@ -1,5 +0,0 @@
package src.rsa;
public class PerformanceTest {
}

View file

@ -1,3 +1,4 @@
//Douglas Fjällrud, Axel Blomén
package src.rsa;
import java.math.BigInteger;
@ -6,13 +7,11 @@ import java.security.SecureRandom;
public class PrimeGenerator {
private static final SecureRandom random = new SecureRandom();
// 1 Implementera Rabin-Miller primtalstest
public static boolean isPrime(BigInteger n, int k) {
if (n.equals(BigInteger.ONE) || n.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
return false; // 1 eller jämna tal är inte primtal (förutom 2)
return false;
}
// Skriv n-1 som 2^r * s, där s är udda
BigInteger s = n.subtract(BigInteger.ONE);
int r = 0;
while (s.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
@ -20,13 +19,12 @@ public class PrimeGenerator {
r++;
}
// Kör testet k gånger med slumpmässiga baser
for (int i = 0; i < k; i++) {
BigInteger a = uniformRandom(BigInteger.TWO, n.subtract(BigInteger.ONE)); // Slumpmässig bas
BigInteger a = uniformRandom(BigInteger.TWO, n.subtract(BigInteger.ONE));
BigInteger x = a.modPow(s, n);
if (x.equals(BigInteger.ONE) || x.equals(n.subtract(BigInteger.ONE))) {
continue; // Möjligt primtal
continue;
}
boolean isComposite = true;
@ -39,14 +37,13 @@ public class PrimeGenerator {
}
if (isComposite) {
return false; // n är sammansatt
return false;
}
}
return true; // n är möjligen primtal
return true;
}
// Hjälpmetod för att generera ett slumpmässigt BigInteger mellan min och max
private static BigInteger uniformRandom(BigInteger min, BigInteger max) {
BigInteger result;
do {
@ -55,16 +52,14 @@ public class PrimeGenerator {
return result;
}
// 2 Generera ett primtal med angiven bitstorlek
public static BigInteger generatePrime(int bitLength) {
BigInteger prime;
do {
prime = new BigInteger(bitLength, random).setBit(0); // Se till att det är udda
} while (!isPrime(prime, 20)); // Testa med 20 iterationer av Rabin-Miller
prime = new BigInteger(bitLength, random).setBit(0);
} while (!isPrime(prime, 20));
return prime;
}
// 3 Generera 100 primtal av viss storlek och mät tiden
public static void benchmarkPrimes(int bitLength) {
long startTime = System.nanoTime();
@ -73,7 +68,7 @@ public class PrimeGenerator {
}
long endTime = System.nanoTime();
double elapsedTime = (endTime - startTime) / 1_000_000_000.0; // Konvertera till sekunder
double elapsedTime = (endTime - startTime) / 1_000_000_000.0;
System.out.println("Bitlängd: " + bitLength + " | Tid: " + elapsedTime + " sekunder");
}
@ -82,18 +77,17 @@ public class PrimeGenerator {
System.out.println("| Bitlängd | Antal | Tid (ms) |");
System.out.println("|----------|-------|----------|");
int[] bitSizes = {512, 1024, 2048, 4096}; // Bitstorlekar att testa
int[] bitSizes = {512, 1024, 2048, 4096};
for (int bitSize : bitSizes) {
long startTime = System.currentTimeMillis(); // Starta tidtagning
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
generatePrime(bitSize); // Generera primtal
generatePrime(bitSize);
}
long endTime = System.currentTimeMillis(); // Sluta tidtagning
long elapsedTime = endTime - startTime; // Total tid i ms
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
// Skriv ut tabellrad
System.out.printf("| %8d | %4d | %8d |\n", bitSize, 100, elapsedTime);
}

View file

@ -1,3 +1,4 @@
//Douglas Fjällrud, Axel Blomén
package src.rsa;
import java.math.BigInteger;
@ -7,37 +8,39 @@ public class RSAEncryptor {
public static BigInteger encrypt(BigInteger message, BigInteger[] publicKey) {
BigInteger N = publicKey[0];
BigInteger e = publicKey[1];
return message.modPow(e, N); // Effektiv modular exponentiation
return message.modPow(e, N);
}
public static BigInteger decrypt(BigInteger ciphertext, BigInteger[] privateKey) {
BigInteger N = privateKey[0];
BigInteger d = privateKey[1];
return ciphertext.modPow(d, N); // Effektiv modular exponentiation
return ciphertext.modPow(d, N);
}
public static void main(String[] args) {
System.out.println("=== Test av RSA Kryptering/Dekryptering ===");
// 1 Generera RSA-nycklar
RSAKeyGenerator rsa = new RSAKeyGenerator(512);
BigInteger[] publicKey = rsa.getPublicKey();
BigInteger[] privateKey = rsa.getPrivateKey();
// 2 Slumpmässigt meddelande att kryptera
BigInteger message = new BigInteger("123456789");
System.out.println("Original meddelande: " + message);
testEncryptionDecryption(message, publicKey, privateKey);
testEncryptionDecryption(BigInteger.ZERO, publicKey, privateKey);
testEncryptionDecryption(BigInteger.ONE, publicKey, privateKey);
}
private static void testEncryptionDecryption(BigInteger message, BigInteger[] publicKey, BigInteger[] privateKey) {
System.out.println("\nTestar meddelande: " + message);
// 3 Kryptera meddelandet
BigInteger ciphertext = encrypt(message, publicKey);
System.out.println("Krypterat meddelande: " + ciphertext);
// 4 Dekryptera meddelandet
BigInteger decrypted = decrypt(ciphertext, privateKey);
System.out.println("Dekrypterat meddelande: " + decrypted);
// 5 Verifiera att dekrypteringen är korrekt
System.out.println("Stämmer dekrypteringen? " + message.equals(decrypted));
}
}

View file

@ -1,3 +1,4 @@
//Douglas Fjällrud, Axel Blomén
package src.rsa;
import java.math.BigInteger;
@ -5,7 +6,6 @@ import java.math.BigInteger;
public class RSAKeyGenerator {
private BigInteger p, q, N, e, d;
// 1 Konstruktor: Generera nycklar
public RSAKeyGenerator(int bitLength) {
generateKeys(bitLength);
}
@ -13,20 +13,19 @@ public class RSAKeyGenerator {
private void generateKeys(int bitLength) {
System.out.println("Genererar RSA-nycklar med " + bitLength + "-bitars primtal...");
// 1 Generera stora primtal p och q
p = PrimeGenerator.generatePrime(bitLength);
q = PrimeGenerator.generatePrime(bitLength);
// 2 Beräkna N = p * q
//Beräkna N = p * q
N = p.multiply(q);
// 3 Beräkna Euler φ(N) = (p-1) * (q-1)
//Beräkna Euler φ(N) = (p-1) * (q-1)
BigInteger phi = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
// 4 Välj publik exponent e (standard är 65537)
//Välj publik exponent e (standard är 65537)
e = new BigInteger("65537");
// 5 Beräkna privat exponent d = e¹ mod φ(N) med utökade Euklides algoritm
//Beräkna privat exponent d = e¹ mod φ(N) med utökade Euklides algoritm
d = EuclideanAlgorithm.modularInverse(e, phi);
System.out.println("Nycklar genererade!");
@ -41,7 +40,6 @@ public class RSAKeyGenerator {
return new BigInteger[]{N, d};
}
public static void main(String[] args) {
RSAKeyGenerator rsa = new RSAKeyGenerator(512);