spn decryption works

This commit is contained in:
Sebastian Hugentobler 2022-03-17 21:22:57 +01:00
parent 4c309352ed
commit 5bd4e640f2
2 changed files with 110 additions and 13 deletions

View File

@ -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<Integer, Integer> SBOX = Map.ofEntries(
public static final Map<Integer, Integer> 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<Integer, Integer> 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<Integer, Integer> 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<Integer, Boolean> 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<Integer, Integer> 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;
}

View File

@ -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));
}
}