1 package org.bouncycastle.crypto.test; 2 3 import java.security.SecureRandom; 4 5 import org.bouncycastle.crypto.BlockCipher; 6 import org.bouncycastle.crypto.engines.ARIAEngine; 7 import org.bouncycastle.crypto.params.KeyParameter; 8 import org.bouncycastle.util.Arrays; 9 import org.bouncycastle.util.encoders.Hex; 10 import org.bouncycastle.util.test.SimpleTest; 11 12 public class ARIATest 13 extends SimpleTest 14 { 15 private static SecureRandom R = new SecureRandom(); 16 17 private static final String[][] TEST_VECTORS_RFC5794 = { 18 { 19 "128-Bit Key", 20 "000102030405060708090a0b0c0d0e0f", 21 "00112233445566778899aabbccddeeff", 22 "d718fbd6ab644c739da95f3be6451778" 23 }, 24 { 25 "192-Bit Key", 26 "000102030405060708090a0b0c0d0e0f1011121314151617", 27 "00112233445566778899aabbccddeeff", 28 "26449c1805dbe7aa25a468ce263a9e79" 29 }, 30 { 31 "256-Bit Key", 32 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", 33 "00112233445566778899aabbccddeeff", 34 "f92bd7c79fb72e2f2b8f80c1972d24fc" 35 }, 36 }; 37 getName()38 public String getName() 39 { 40 return "ARIA"; 41 } 42 performTest()43 public void performTest() throws Exception 44 { 45 checkTestVectors_RFC5794(); 46 47 for (int i = 0; i < 100; ++i) 48 { 49 checkRandomRoundtrips(); 50 } 51 52 new MyARIAEngine().checkImplementation(); 53 } 54 checkRandomRoundtrips()55 private void checkRandomRoundtrips() 56 { 57 ARIAEngine ce = new ARIAEngine(); 58 ARIAEngine cd = new ARIAEngine(); 59 60 byte[] txt = new byte[ce.getBlockSize()]; 61 byte[] enc = new byte[ce.getBlockSize()]; 62 byte[] dec = new byte[ce.getBlockSize()]; 63 64 for (int keyLen = 16; keyLen <= 32; keyLen += 8) 65 { 66 byte[] K = new byte[keyLen]; 67 68 R.nextBytes(K); 69 70 KeyParameter key = new KeyParameter(K); 71 ce.init(true, key); 72 cd.init(false, key); 73 74 R.nextBytes(txt); 75 76 for (int i = 0; i < 100; ++i) 77 { 78 ce.processBlock(txt, 0, enc, 0); 79 cd.processBlock(enc, 0, dec, 0); 80 81 isTrue(Arrays.areEqual(txt, dec)); 82 83 System.arraycopy(enc, 0, txt, 0, enc.length); 84 } 85 } 86 } 87 checkTestVector_RFC5794(String[] tv)88 private void checkTestVector_RFC5794(String[] tv) 89 { 90 String name = "'" + tv[0] + "'"; 91 92 BlockCipher c = new ARIAEngine(); 93 int blockSize = c.getBlockSize(); 94 isTrue("Wrong block size returned from getBlockSize() for " + name, 16 == blockSize); 95 96 KeyParameter key = new KeyParameter(Hex.decode(tv[1])); 97 byte[] plaintext = Hex.decode(tv[2]); 98 byte[] ciphertext = Hex.decode(tv[3]); 99 100 isTrue("Unexpected plaintext length for " + name, blockSize == plaintext.length); 101 isTrue("Unexpected ciphertext length for " + name, blockSize == ciphertext.length); 102 103 c.init(true, key); 104 105 byte[] actual = new byte[blockSize]; 106 int num = c.processBlock(plaintext, 0, actual, 0); 107 108 isTrue("Wrong length returned from processBlock() (encryption) for " + name, blockSize == num); 109 isTrue("Incorrect ciphertext computed for " + name, Arrays.areEqual(ciphertext, actual)); 110 111 c.init(false, key); 112 num = c.processBlock(ciphertext, 0, actual, 0); 113 114 isTrue("Wrong length returned from processBlock() (decryption) for " + name, blockSize == num); 115 isTrue("Incorrect plaintext computed for " + name, Arrays.areEqual(plaintext, actual)); 116 } 117 checkTestVectors_RFC5794()118 private void checkTestVectors_RFC5794() 119 { 120 for (int i = 0; i < TEST_VECTORS_RFC5794.length; ++i) 121 { 122 checkTestVector_RFC5794(TEST_VECTORS_RFC5794[i]); 123 } 124 } 125 main(String[] args)126 public static void main(String[] args) 127 { 128 runTest(new ARIATest()); 129 } 130 131 private class MyARIAEngine extends ARIAEngine 132 { checkImplementation()133 public void checkImplementation() 134 { 135 checkInvolution(); 136 checkSBoxes(); 137 } 138 checkInvolution()139 private void checkInvolution() 140 { 141 byte[] x = new byte[16], y = new byte[16]; 142 143 for (int i = 0; i < 100; ++i) 144 { 145 R.nextBytes(x); 146 System.arraycopy(x, 0, y, 0, 16); 147 A(y); 148 A(y); 149 ARIATest.this.isTrue(Arrays.areEqual(x, y)); 150 } 151 } 152 checkSBoxes()153 private void checkSBoxes() 154 { 155 for (int i = 0; i < 256; ++i) 156 { 157 byte x = (byte)i; 158 159 ARIATest.this.isTrue(x == SB1(SB3(x))); 160 ARIATest.this.isTrue(x == SB3(SB1(x))); 161 162 ARIATest.this.isTrue(x == SB2(SB4(x))); 163 ARIATest.this.isTrue(x == SB4(SB2(x))); 164 } 165 } 166 } 167 } 168