import java.io.*; import java.util.*; import junit.framework.*; import org.noreply.fancydress.crypto.CryptoPrimitives; import org.noreply.fancydress.misc.Util; public class CryptoPrimitivesTest extends TestCase { public CryptoPrimitivesTest(String name) { super(name); } /** * Test if xor returns an array of the same size as the input arrays. */ public void testXorLengthMatchesInputs() { byte[] a = new byte[30]; byte[] b = new byte[30]; byte[] r = CryptoPrimitives.xor(a,b); assertEquals(30, r.length); } /** * Test if rand returns n bytes */ public void testRandLength() { byte[] r; r = CryptoPrimitives.rand(0); assertEquals(0, r.length); r = CryptoPrimitives.rand(30); assertEquals(30, r.length); r = CryptoPrimitives.rand(300); assertEquals(300, r.length); r = CryptoPrimitives.rand(30000); assertEquals(30000, r.length); } /** * Test if zero returns n bytes */ public void testZeroLength() { byte[] r; r = CryptoPrimitives.zero(0); assertEquals(0, r.length); r = CryptoPrimitives.zero(30); assertEquals(30, r.length); r = CryptoPrimitives.zero(300); assertEquals(300, r.length); r = CryptoPrimitives.zero(30000); assertEquals(30000, r.length); } /** * Test if hash returns HASH_LEN bytes */ public void testHashLength() { byte[] r; r = CryptoPrimitives.hash(new byte[0]); assertEquals(CryptoPrimitives.HASH_LEN, r.length); r = CryptoPrimitives.hash(new byte[2000]); assertEquals(CryptoPrimitives.HASH_LEN, r.length); r = CryptoPrimitives.hash(new byte[0], new byte[0]); assertEquals(CryptoPrimitives.HASH_LEN, r.length); r = CryptoPrimitives.hash(new byte[2000], new byte[2000]); assertEquals(CryptoPrimitives.HASH_LEN, r.length); r = CryptoPrimitives.hash(new byte[0], new byte[0], new byte[0]); assertEquals(CryptoPrimitives.HASH_LEN, r.length); r = CryptoPrimitives.hash(new byte[2000], new byte[2000], new byte[2000]); assertEquals(CryptoPrimitives.HASH_LEN, r.length); } /** * Test if hash is sane sha-1 */ public void testHash() { String s1 = ""; byte[] b1 = Util.toOctets(s1); byte[] h1 = Util.fromHex("da39a3ee5e6b4b0d3255bfef95601890afd80709"); String s2 = "I couldn't possibly fail to disagree with you less."; byte[] b2 = Util.toOctets(s2); byte[] h2 = Util.fromHex("90ecb7803dd428bd64ed296600d650a981268f1c"); String s3 = "Everyone writes on the walls except me. -Said to be graffiti seen in Pompeii"; byte[] b3 = Util.toOctets(s3); byte[] h3 = Util.fromHex("fcdbe159e7c4c2d25f329a75c19c209fd27fc10d"); String s4 = "Freedom of the press is for those who happen to own one."; byte[] b4 = Util.toOctets(s4); byte[] h4 = Util.fromHex("12dbc37c1f71491a8fae55ae305ab888b852f70d"); /* Test hash with one arg. */ assertTrue(Util.equal(CryptoPrimitives.hash(b1) , h1)); assertTrue(Util.equal(CryptoPrimitives.hash(b2) , h2)); assertTrue(Util.equal(CryptoPrimitives.hash(b3) , h3)); assertTrue(Util.equal(CryptoPrimitives.hash(b4) , h4)); byte[] b; /* Test hash with two args. */ b = Util.concat(b1,b2); assertTrue(Util.equal( CryptoPrimitives.hash(b), CryptoPrimitives.hash(b1,b2))); b = Util.concat(b2,b3); assertTrue(Util.equal( CryptoPrimitives.hash(b), CryptoPrimitives.hash(b2,b3))); b = Util.concat(b2,b3); assertTrue(! Util.equal( CryptoPrimitives.hash(b), CryptoPrimitives.hash(b3,b2))); /* Test hash with three args. */ b = Util.concat(b1,Util.concat(b2,b3)); assertTrue(Util.equal( CryptoPrimitives.hash(b), CryptoPrimitives.hash(b1,b2,b3))); b = Util.concat(b4,Util.concat(b3,b2)); assertTrue(Util.equal( CryptoPrimitives.hash(b), CryptoPrimitives.hash(b4,b3,b2))); b = Util.concat(b4,Util.concat(b3,b2)); assertTrue(! Util.equal( CryptoPrimitives.hash(b), CryptoPrimitives.hash(b2,b3,b4))); } /** * Test the PRNG as defined in the mixminion spec. */ public void testPRNG() { byte[] key = Util.fromHex("02 13 24 35 46 57 68 79 8A 9B AC BD CE DF E0 F1"); byte[] keystream1 = Util.fromHex("CA F3 E8 F6 23 B9 87 20 D2 F7 A8 66 9C B6 DE 01 71" + "31 CC 3E 74 20 80 99 62 2D 7D DF 98 59 D7 5B A6 77 78 FE 3C 22 C1 B5 AE 1F 8E" + "79 78 72 3D 0F 51 B7 EA 19 F7 93 7F F6 DC 21 EC 2C 13 54 DD 98"); byte[] keystream2 = Util.fromHex("81 AE AE FB 58 E0 A2 FE 37 27 31 8E 5B C4 90 B9" + "86 99 95 78 C0 F6 BC AC 9A A6 16 DF BA 0B 4E 6C 0A 10 C5 8F 7B 67 54 19 D7 EA" + "8C 4A A7 0E C7 77 6B 25 51 68 88 1C 7C 4D EB 83 8C A0 3F 4A 85 32"); byte[] keystream0 = CryptoPrimitives.prng(key, 0x300); assertTrue(Util.equal( Util.slice(keystream0, 0 , 0x40), keystream1)); assertTrue(Util.equal( Util.slice(keystream0, 0x2c0, 0x40), keystream2)); } /** * Test encrypt */ public void testEncrypt() { byte[] key = Util.fromHex("02 13 24 35 46 57 68 79 8A 9B AC BD CE DF E0 F1"); byte[] msg = Util.fromHex("48 65 6C 6C 6F 20 77 6F 72 6C 64 21"); byte[] ciphertext = Util.fromHex("82 96 84 9A 4C 99 F0 4F A0 9B CC 47"); assertTrue(Util.equal( CryptoPrimitives.encrypt(key, msg), ciphertext)); } /** * Test sprp_encrypt (LIONESS) */ /* FIXME: test SPRPEncrypt with 3 args */ public void testSPRPEncrypt() { byte[] key = Util.fromHex("AE BB 71 FA E1 F4 70 6C 0C 60 83 83 83 26 70 E3 60 63 37 EA"); byte[] msg = Util.fromHex("49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E" + "20 63 6F 64 65 20 75 6E 74 69 6C 20 69 74 27 73 20 72 75 6E 6E 69 6E 67 2C 20" + "61 6E 64 20 49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E 20 74 68 65" + "20 6E 65 78 74 20 72 65 6C 65 61 73 65 20 75 6E 74 69 6C 20 69 74 27 73 20 6F" + "75 74 2E"); byte[] ciphertext = Util.fromHex("1D 46 61 E1 CC 16 FA 17 5C B8 06 66 19 17 4C 09 44 B7" + "BC BC 57 8B 2E EB 06 19 4C E1 F0 0F 67 1B 1B A2 76 E9 3E 77 BF 7C 00 3D A2 91" + "3A 23 62 0A 4C DE 7A 52 E8 29 03 2A 93 B7 1F EC 5C A8 5C 84 7A 3F 45 A5 80 0A" + "0B B6 B5 DF E1 25 B0 DE CC 10 4D 46 45 EF 11 F7 CF 44 01 66 9D EC 36 BF CE 46" + "97 60 3D"); assertTrue(Util.equal( CryptoPrimitives.sprpEncrypt(key, msg), ciphertext)); } /** * Test sprp_decrypt (LIONESS) */ /* FIXME: test SPRPDecrypt with 3 args */ public void testSPRPDecrypt() { byte[] key = Util.fromHex("AE BB 71 FA E1 F4 70 6C 0C 60 83 83 83 26 70 E3 60 63 37 EA"); byte[] msg = Util.fromHex("49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E" + "20 63 6F 64 65 20 75 6E 74 69 6C 20 69 74 27 73 20 72 75 6E 6E 69 6E 67 2C 20" + "61 6E 64 20 49 20 6E 65 76 65 72 20 62 65 6C 69 65 76 65 20 69 6E 20 74 68 65" + "20 6E 65 78 74 20 72 65 6C 65 61 73 65 20 75 6E 74 69 6C 20 69 74 27 73 20 6F" + "75 74 2E"); byte[] plaintext = Util.fromHex("F3 5E 91 70 2F 43 14 9F E0 A0 3B 18 8E A9 FC 17 0A 3A" + "3F C0 EB A5 18 F6 03 4E E3 88 F7 B7 C3 2E 01 80 E1 D7 A1 86 B5 7D D8 38 B8 4D" + "DD 3E 3D D2 D2 15 CA 31 71 DF F7 85 7C 1C 95 20 5A B6 19 22 16 54 F1 4E 09 8E" + "BC 8E C1 02 F6 F5 CE EB 34 53 7F 52 A1 7B 3A 04 78 D8 4C 9C 18 34 FD 5D 63 DD" + "F0 E4 FD"); assertTrue(Util.equal( CryptoPrimitives.sprpDecrypt(key, msg), plaintext)); } public static Test suite() { TestSuite suite= new TestSuite(); // suite.addTest(new CryptoPrimitivesTest("testXorLengthThrows")); suite.addTest(new CryptoPrimitivesTest("testXorLengthMatchesInputs")); suite.addTest(new CryptoPrimitivesTest("testRandLength")); suite.addTest(new CryptoPrimitivesTest("testZeroLength")); suite.addTest(new CryptoPrimitivesTest("testHashLength")); suite.addTest(new CryptoPrimitivesTest("testHash")); suite.addTest(new CryptoPrimitivesTest("testPRNG")); suite.addTest(new CryptoPrimitivesTest("testEncrypt")); suite.addTest(new CryptoPrimitivesTest("testSPRPEncrypt")); suite.addTest(new CryptoPrimitivesTest("testSPRPDecrypt")); return suite; } public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } }