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