private void testBlockCiphers() { for (String algorithm : new String[] {"AES", "XTEA", "FOG"}) { byte[] test = new byte[4096]; BlockCipher cipher = CipherFactory.getBlockCipher(algorithm); cipher.setKey("abcdefghijklmnop".getBytes()); for (int i = 0; i < 10; i++) { cipher.encrypt(test, 0, test.length); } assertFalse(isCompressible(test)); for (int i = 0; i < 10; i++) { cipher.decrypt(test, 0, test.length); } assertEquals(new byte[test.length], test); assertTrue(isCompressible(test)); } }
private byte[] initTweak(long id) { byte[] tweak = new byte[CIPHER_BLOCK_SIZE]; for (int j = 0; j < CIPHER_BLOCK_SIZE; j++, id >>>= 8) { tweak[j] = (byte) (id & 0xff); } cipher.encrypt(tweak, 0, CIPHER_BLOCK_SIZE); return tweak; }
/** * Encrypt the data. * * @param id the (sector) id * @param len the number of bytes * @param data the data * @param offset the offset within the data */ void encrypt(long id, int len, byte[] data, int offset) { byte[] tweak = initTweak(id); int i = 0; for (; i + CIPHER_BLOCK_SIZE <= len; i += CIPHER_BLOCK_SIZE) { if (i > 0) { updateTweak(tweak); } xorTweak(data, i + offset, tweak); cipher.encrypt(data, i + offset, CIPHER_BLOCK_SIZE); xorTweak(data, i + offset, tweak); } if (i < len) { updateTweak(tweak); swap(data, i + offset, i - CIPHER_BLOCK_SIZE + offset, len - i); xorTweak(data, i - CIPHER_BLOCK_SIZE + offset, tweak); cipher.encrypt(data, i - CIPHER_BLOCK_SIZE + offset, CIPHER_BLOCK_SIZE); xorTweak(data, i - CIPHER_BLOCK_SIZE + offset, tweak); } }
/** * Decrypt the data. * * @param id the (sector) id * @param len the number of bytes * @param data the data * @param offset the offset within the data */ void decrypt(long id, int len, byte[] data, int offset) { byte[] tweak = initTweak(id), tweakEnd = tweak; int i = 0; for (; i + CIPHER_BLOCK_SIZE <= len; i += CIPHER_BLOCK_SIZE) { if (i > 0) { updateTweak(tweak); if (i + CIPHER_BLOCK_SIZE + CIPHER_BLOCK_SIZE > len && i + CIPHER_BLOCK_SIZE < len) { tweakEnd = Arrays.copyOf(tweak, CIPHER_BLOCK_SIZE); updateTweak(tweak); } } xorTweak(data, i + offset, tweak); cipher.decrypt(data, i + offset, CIPHER_BLOCK_SIZE); xorTweak(data, i + offset, tweak); } if (i < len) { swap(data, i, i - CIPHER_BLOCK_SIZE + offset, len - i + offset); xorTweak(data, i - CIPHER_BLOCK_SIZE + offset, tweakEnd); cipher.decrypt(data, i - CIPHER_BLOCK_SIZE + offset, CIPHER_BLOCK_SIZE); xorTweak(data, i - CIPHER_BLOCK_SIZE + offset, tweakEnd); } }
private void testAES() { BlockCipher test = CipherFactory.getBlockCipher("AES"); String r; byte[] data; // test vector from // http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip // ECBVarTxt128e.txt // COUNT = 0 test.setKey(StringUtils.convertHexToBytes("00000000000000000000000000000000")); data = StringUtils.convertHexToBytes("80000000000000000000000000000000"); test.encrypt(data, 0, data.length); r = StringUtils.convertBytesToHex(data); assertEquals("3ad78e726c1ec02b7ebfe92b23d9ec34", r); // COUNT = 127 test.setKey(StringUtils.convertHexToBytes("00000000000000000000000000000000")); data = StringUtils.convertHexToBytes("ffffffffffffffffffffffffffffffff"); test.encrypt(data, 0, data.length); r = StringUtils.convertBytesToHex(data); assertEquals("3f5b8cc9ea855a0afa7347d23e8d664e", r); // test vector test.setKey(StringUtils.convertHexToBytes("2b7e151628aed2a6abf7158809cf4f3c")); data = StringUtils.convertHexToBytes("6bc1bee22e409f96e93d7e117393172a"); test.encrypt(data, 0, data.length); r = StringUtils.convertBytesToHex(data); assertEquals("3ad77bb40d7a3660a89ecaf32466ef97", r); test.setKey(StringUtils.convertHexToBytes("000102030405060708090A0B0C0D0E0F")); byte[] in = new byte[128]; byte[] enc = new byte[128]; test.encrypt(enc, 0, 128); test.decrypt(enc, 0, 128); if (!Arrays.equals(in, enc)) { throw new AssertionError(); } for (int i = 0; i < 10; i++) { test.encrypt(in, 0, 128); test.decrypt(enc, 0, 128); } }