diff --git a/src/rsa/EuclideanAlgorithm.java b/src/rsa/EuclideanAlgorithm.java index 30af72e..ec16986 100644 --- a/src/rsa/EuclideanAlgorithm.java +++ b/src/rsa/EuclideanAlgorithm.java @@ -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."); diff --git a/src/rsa/Main.java b/src/rsa/Main.java index 7dd31ea..4e2d538 100644 --- a/src/rsa/Main.java +++ b/src/rsa/Main.java @@ -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 ❌")); } diff --git a/src/rsa/PerformanceTest.java b/src/rsa/PerformanceTest.java deleted file mode 100644 index c2a573b..0000000 --- a/src/rsa/PerformanceTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package src.rsa; - -public class PerformanceTest { - -} diff --git a/src/rsa/PrimeGenerator.java b/src/rsa/PrimeGenerator.java index fbba7ce..50df1bd 100644 --- a/src/rsa/PrimeGenerator.java +++ b/src/rsa/PrimeGenerator.java @@ -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); } diff --git a/src/rsa/RSAEncryptor.java b/src/rsa/RSAEncryptor.java index 930ac02..a802e99 100644 --- a/src/rsa/RSAEncryptor.java +++ b/src/rsa/RSAEncryptor.java @@ -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); - - // 3️⃣ Kryptera meddelandet + 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); + 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)); } - -} \ No newline at end of file +} diff --git a/src/rsa/RSAKeyGenerator.java b/src/rsa/RSAKeyGenerator.java index 040858a..1610891 100644 --- a/src/rsa/RSAKeyGenerator.java +++ b/src/rsa/RSAKeyGenerator.java @@ -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);