diff --git a/ciphers/AES.java b/ciphers/AES.java index 2323e09f..33e54413 100644 --- a/ciphers/AES.java +++ b/ciphers/AES.java @@ -242,26 +242,38 @@ public class AES { new BigInteger("0"), new BigInteger("0"), new BigInteger("0"), new BigInteger("0"), new BigInteger("0"), new BigInteger("0"), new BigInteger("0"), }; + // initialize rcon iteration + int rconCounter = 1; + for (int i = 1; i < 11; i++) { // get the previous 32 bits the key BigInteger t = roundKeys[i - 1].remainder(new BigInteger("100000000", 16)); + + // split previous key into 8-bit segments + BigInteger[] prevKey = { + roundKeys[i - 1].remainder(new BigInteger("100000000", 16)), + roundKeys[i - 1].remainder(new BigInteger("10000000000000000", 16)).divide(new BigInteger("100000000", 16)), + roundKeys[i - 1].remainder(new BigInteger("1000000000000000000000000", 16)).divide(new BigInteger("10000000000000000", 16)), + roundKeys[i - 1].divide(new BigInteger("1000000000000000000000000", 16)), + }; - // initialize rcon iteration - int rconCounter = 1; - - // schedule core + // run schedule core t = scheduleCore(t, rconCounter); rconCounter += 1; - BigInteger t1 = t.multiply(new BigInteger("100000000", 16)); - BigInteger t2 = t.multiply(new BigInteger("10000000000000000", 16)); - BigInteger t3 = t.multiply(new BigInteger("1000000000000000000000000", 16)); - t = t.add(t1).add(t2).add(t3); + + // Calculate partial round key + BigInteger t0 = t.xor(prevKey[3]); + BigInteger t1 = t0.xor(prevKey[2]); + BigInteger t2 = t1.xor(prevKey[1]); + BigInteger t3 = t2.xor(prevKey[0]); + + // Join round key segments + t2 = t2.multiply(new BigInteger("100000000", 16)); + t1 = t1.multiply(new BigInteger("10000000000000000", 16)); + t0 = t0.multiply(new BigInteger("1000000000000000000000000", 16)); + roundKeys[i] = t0.add(t1).add(t2).add(t3); - BigInteger xorMask = roundKeys[i - 1].divide(new BigInteger("100000000", 16)); - xorMask = xorMask.multiply(new BigInteger("100000000", 16)); - t = t.xor(xorMask); - roundKeys[i] = t; } return roundKeys; @@ -511,11 +523,13 @@ public class AES { public static void main(String[] args) { boolean encrypt = false; - BigInteger key = new BigInteger("f0f1f2f3f4f5f6f708090a0b0c0d0e0f", 16); + BigInteger key = new BigInteger("0", 16); BigInteger plaintext = new BigInteger("0", 16); BigInteger ciphertext = new BigInteger("adcfc0ed15292419cb796167bc02b669", 16); BigInteger output; + System.out.println(keyExpansion(key)[2].xor(new BigInteger("9b9898c9f9fbfbaa9b9898c9f9fbfbaa",16)).toString(16)); + if (encrypt) { output = encrypt(plaintext, key); } else { diff --git a/ciphers/AESTest.java b/ciphers/AESTest.java deleted file mode 100644 index b986514a..00000000 --- a/ciphers/AESTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package ciphers; - -import static org.junit.Assert.*; - -import java.math.BigInteger; - -import org.junit.Test; - -public class AESTest { - - @Test - public void testSubBytes() { - BigInteger x = new BigInteger("00ff01ff02ff03ff04ff05ff06ff07ff",16); - BigInteger expected = new BigInteger("63167c1677167b16f2166b166f16c516",16); - - assertEquals(expected,AES.subBytes(x)); - } - - @Test - public void testSubBytesDec() { - BigInteger x = new BigInteger("63167c1677167b16f2166b166f16c516",16); - BigInteger expected = new BigInteger("00ff01ff02ff03ff04ff05ff06ff07ff",16); - - assertEquals(expected,AES.subBytesDec(x)); - } - - @Test - public void testShiftRows() { - BigInteger x = new BigInteger("00102030011121310212223203132333",16); - BigInteger expected = new BigInteger("00112233011223300213203103102132",16); - - assertEquals(expected,AES.shiftRows(x)); - } - - @Test - public void testShiftRowsDec() { - BigInteger x = new BigInteger("00112233011223300213203103102132",16); - BigInteger expected = new BigInteger("00102030011121310212223203132333",16); - - assertEquals(expected,AES.shiftRowsDec(x)); - } - - @Test - public void testMixColumns() { - BigInteger x = new BigInteger("db135345f20a225c010101012d26314c",16); - BigInteger expected = new BigInteger("8e4da1bc9fdc589d010101014d7ebdf8",16); - - assertEquals(expected,AES.mixColumns(x)); - } - - @Test - public void testMixColumnsDec() { - BigInteger x = new BigInteger("8e4da1bc9fdc589d010101014d7ebdf8",16); - BigInteger expected = new BigInteger("db135345f20a225c010101012d26314c",16); - - assertEquals(expected,AES.mixColumnsDec(x)); - } - - @Test - public void testEncryptAndDecryptCorrectKey() { - // Plaintext/Ciphertext pairing with correct key - BigInteger key = new BigInteger("f0f1f2f3f4f5f6f708090a0b0c0d0e0f", 16); - BigInteger plaintext = new BigInteger("e9870a476d8d0bc43abde33cba26747e", 16); - BigInteger ciphertext = new BigInteger("adcfc0ed15292419cb796167bc02b669", 16); - - BigInteger encryptedPlaintext = AES.encrypt(plaintext,key); - BigInteger decryptedCiphertext = AES.decrypt(ciphertext,key); - - assertEquals(plaintext,decryptedCiphertext); - assertEquals(ciphertext,encryptedPlaintext); - } - - @Test - public void testEncryptAndDecryptWrongKey() { - // Plaintext/Ciphertext Pairing with incorrect key - BigInteger key = new BigInteger("f4f1f2f3f4f5f6f708090a0b0c0d0e0f", 16); - BigInteger plaintext = new BigInteger("e9870a476d8d0bc43abde33cba26747e", 16); - BigInteger ciphertext = new BigInteger("adcfc0ed15292419cb796167bc02b669", 16); - - BigInteger encryptedPlaintext = AES.encrypt(plaintext,key); - BigInteger decryptedCiphertext = AES.decrypt(plaintext,key); - - assertNotEquals(plaintext,decryptedCiphertext); - assertNotEquals(ciphertext,encryptedPlaintext); - } - -}