From 5bd4e640f28f125fc5fdcca55168e9a8f80afab5 Mon Sep 17 00:00:00 2001 From: Sebastian Hugentobler Date: Thu, 17 Mar 2022 21:22:57 +0100 Subject: [PATCH] spn decryption works --- src/main/java/ch/fhnw/kry/SPN.java | 98 +++++++++++++++++++++++--- src/test/java/ch/fhnw/kry/SPNTest.java | 25 ++++++- 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/src/main/java/ch/fhnw/kry/SPN.java b/src/main/java/ch/fhnw/kry/SPN.java index e76fc1f..3b9ef91 100644 --- a/src/main/java/ch/fhnw/kry/SPN.java +++ b/src/main/java/ch/fhnw/kry/SPN.java @@ -1,12 +1,30 @@ package ch.fhnw.kry; +import java.util.HashMap; import java.util.Map; import static java.util.Map.entry; public class SPN { - private final static int ROUND_KEY_LENGTH = 16; - private final Map SBOX = Map.ofEntries( + public static final Map SBOX = Map.ofEntries( + entry(0, 0xE), + entry(1, 4), + entry(2, 0xD), + entry(3, 1), + entry(4, 2), + entry(5, 0xF), + entry(6, 0xB), + entry(7, 8), + entry(8, 3), + entry(9, 0xA), + entry(0xA, 6), + entry(0xB, 0xC), + entry(0xC, 5), + entry(0xD, 9), + entry(0xE, 0), + entry(0xF, 7) + ); + public static final Map SBOX_REVERSE = Map.ofEntries( entry(0xE, 0), entry(4, 1), entry(0xD, 2), @@ -24,14 +42,57 @@ public class SPN { entry(0, 0xE), entry(7, 0xF) ); + private final static int ROUND_KEY_LENGTH = 16; + private final Map PERMUTATION = Map.ofEntries( + entry(0, 0), + entry(1, 4), + entry(2, 8), + entry(3, 12), + entry(4, 1), + entry(5, 5), + entry(6, 9), + entry(7, 13), + entry(8, 2), + entry(9, 6), + entry(10, 10), + entry(11, 14), + entry(12, 3), + entry(13, 7), + entry(14, 11), + entry(15, 15) + ); public String decrypt(int key, String chiffre) { return null; } - public int sp(int key, int x) { - x = init(key, x); + public int encryptBlock(int key, int x) { + x = init(key, x, 0); + + for (int i = 1; i < 4; i++) { + x = substitution(x, SBOX); + x = permutation(x); + x ^= k(key, i); + } + + x = substitution(x, SBOX); + x ^= k(key, 4); + + return x; + } + + public int decryptBlock(int key, int x) { + x = init(key, x, 4); + + for (int i = 3; i > 0; i--) { + x = substitution(x, SBOX_REVERSE); + x = permutation(x); + x ^= k(key, i); + } + + x = substitution(x, SBOX_REVERSE); + x ^= k(key, 0); return x; } @@ -40,19 +101,32 @@ public class SPN { i *= 4; int mask = 0xFFFF_0000 >>> i; - return key & mask >>> ROUND_KEY_LENGTH - i; + return (key & mask) >>> ROUND_KEY_LENGTH - i; } - public int init(int key, int x) { - return x ^ k(key, 4); + public int init(int key, int x, int r) { + return x ^ k(key, r); } - public int substitution(int x) { + public int permutation(int x) { + Map blocked = new HashMap<>(); + + for (int i = 0; i < 16; i++) { + int target = PERMUTATION.get(i); + if (!blocked.containsKey(target)) { + x = swapBits(x, i, target); + blocked.put(i, true); + } + } + return x; + } + + public int substitution(int x, Map sbox) { int mask = 0xF000; for (int i = 0; i < 4; i++) { int j = 4 * i; int key = (x & mask) >>> 12 - j; - int val = SBOX.get(key); + int val = sbox.get(key); int replMask = ~(0xf << 12 - j); // Maske mit 4 0-Bits vorbereiten zur Vorbereitung vom Einfügen x = x & replMask | (val << 12 - j); // x an der Stelle der 4 0-Bits mit val überschreiben @@ -65,8 +139,10 @@ public class SPN { a = 15 - a; b = 15 - b; - x ^= (1 << a); - x ^= (1 << b); + if ((((x & 1 << a) >> a) ^ ((x & 1 << b) >> b)) == 1) { // only swap if the positions are not the same + x ^= (1 << a); + x ^= (1 << b); + } return x; } diff --git a/src/test/java/ch/fhnw/kry/SPNTest.java b/src/test/java/ch/fhnw/kry/SPNTest.java index 83dd4eb..782408b 100644 --- a/src/test/java/ch/fhnw/kry/SPNTest.java +++ b/src/test/java/ch/fhnw/kry/SPNTest.java @@ -23,10 +23,9 @@ class SPNTest { //given int x = 0xEF45; int r = 0x051C; - System.out.print(Integer.toHexString(x)); //when - int y = spn.substitution(x); + int y = spn.substitution(x, SPN.SBOX_REVERSE); // then assertEquals(r, y); @@ -51,5 +50,27 @@ class SPNTest { assertEquals(r, y); assertEquals(r, yy); assertEquals(x, yyy); + + assertEquals(0x100A, spn.swapBits(0x80A, 3, 4)); + } + + @Test + void permutation() { + var spn = new SPN(); + + int x = spn.permutation(0xEF45); + assertEquals(0xCFC5, x); + } + + @Test + void sp() { + var spn = new SPN(); + + int x = 0x128F ; + int key = 0x11288C00; + int y = 0xAEB4; + + assertEquals(y, spn.encryptBlock(key, x)); + assertEquals(x, spn.decryptBlock(key, y)); } }