diff --git a/pom.xml b/pom.xml index d65a885..a04e522 100755 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,12 @@ 4.11 test + + org.mockito + mockito-all + 1.9.5 + test + diff --git a/src/org/kocakosm/nash/IV.java b/src/org/kocakosm/nash/IV.java index 0ae805e..3e55af0 100644 --- a/src/org/kocakosm/nash/IV.java +++ b/src/org/kocakosm/nash/IV.java @@ -72,12 +72,6 @@ public boolean[] getBits() return Arrays.copyOf(bits, bits.length); } - @Override - public String toString() - { - return Arrays.toString(bits); - } - @Override public int hashCode() { diff --git a/src/org/kocakosm/nash/Random.java b/src/org/kocakosm/nash/Random.java index df0e2b6..5f19b7b 100644 --- a/src/org/kocakosm/nash/Random.java +++ b/src/org/kocakosm/nash/Random.java @@ -44,19 +44,6 @@ static boolean[] nextBits(int n) return bits; } - /** - * Returns a pseudo-random {@code int} value, uniformly distributed - * between 0 (inclusive) and the given value (exclusive). - * - * @param n the bound on the random number to be returned. - * - * @throws IllegalArgumentException if {@code n} is negative. - */ - static int nextInt(int n) - { - return PRNG.nextInt(n); - } - /** * Shuffles the given values and returns them in a new array using the * optimized version of the Fisher-Yates shuffle algorithm (Fisher, diff --git a/test/org/kocakosm/nash/IVTest.java b/test/org/kocakosm/nash/IVTest.java new file mode 100644 index 0000000..eeb2409 --- /dev/null +++ b/test/org/kocakosm/nash/IVTest.java @@ -0,0 +1,63 @@ +/*----------------------------------------------------------------------------* + * This file is part of Nash-Cipher. * + * Copyright (C) 2012-2013 Osman KOCAK * + * * + * This program is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or (at your * + * option) any later version. * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * + * License for more details. * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + *----------------------------------------------------------------------------*/ + +package org.kocakosm.nash; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * {@link IV}'s unit tests. + * + * @author Osman KOCAK + */ +public final class IVTest +{ + @Test + public void testCreate() + { + IV iv = IV.create(32); + assertEquals(32, iv.getSize()); + assertEquals(32, iv.getBits().length); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateWithNegativeSize() + { + IV.create(-1); + } + + @Test + public void testEqualsAndHashCode() + { + IV iv = IV.create(32); + assertFalse(iv.equals(IV.create(16))); + assertFalse(iv.equals(IV.create(32))); + assertTrue(iv.equals(iv)); + assertEquals(iv.hashCode(), iv.hashCode()); + assertFalse(iv.equals((IV) (null))); + } + + @Test + public void testSerialization() throws Exception + { + IV iv = IV.create(32); + IV decoded = ObjectCodec.decode(ObjectCodec.encode(iv), IV.class); + assertNotSame(iv, decoded); + assertEquals(iv, decoded); + } +} diff --git a/test/org/kocakosm/nash/KeyTest.java b/test/org/kocakosm/nash/KeyTest.java new file mode 100644 index 0000000..32ff0d2 --- /dev/null +++ b/test/org/kocakosm/nash/KeyTest.java @@ -0,0 +1,66 @@ +/*----------------------------------------------------------------------------* + * This file is part of Nash-Cipher. * + * Copyright (C) 2012-2013 Osman KOCAK * + * * + * This program is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or (at your * + * option) any later version. * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * + * License for more details. * + * You should have receked a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + *----------------------------------------------------------------------------*/ + +package org.kocakosm.nash; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * {@link Key}'s unit tests. + * + * @author Osman KOCAK + */ +public final class KeyTest +{ + @Test + public void testCreate() + { + Key k = Key.create(32); + assertEquals(32, k.getSize()); + assertEquals(32, k.getRedBits().length); + assertEquals(32, k.getBlueBits().length); + assertEquals(32, k.getRedPermutations().length); + assertEquals(32, k.getBluePermutations().length); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateWithNegatkeSize() + { + Key.create(-1); + } + + @Test + public void testEqualsAndHashCode() + { + Key k = Key.create(32); + assertFalse(k.equals(Key.create(16))); + assertFalse(k.equals(Key.create(32))); + assertTrue(k.equals(k)); + assertEquals(k.hashCode(), k.hashCode()); + assertFalse(k.equals((Key) (null))); + } + + @Test + public void testSerialization() throws Exception + { + Key k = Key.create(32); + Key decoded = ObjectCodec.decode(ObjectCodec.encode(k), Key.class); + assertNotSame(k, decoded); + assertEquals(k, decoded); + } +} diff --git a/test/org/kocakosm/nash/NashCipherTest.java b/test/org/kocakosm/nash/NashCipherTest.java index 53c0595..1f631fe 100644 --- a/test/org/kocakosm/nash/NashCipherTest.java +++ b/test/org/kocakosm/nash/NashCipherTest.java @@ -29,18 +29,56 @@ */ public final class NashCipherTest { - private static final Random PRNG = new Random(); + private final IV iv = IV.create(64); + private final Key key = Key.create(64); + private final Random prng = new Random(); @Test - public void test() + public void testCipher() { - IV iv = IV.create(64); - Key k = Key.create(64); - NashCipher enc = new NashCipher(k, iv, NashCipher.Mode.ENCRYPTION); - NashCipher dec = new NashCipher(k, iv, NashCipher.Mode.DECRYPTION); - byte[] data = new byte[PRNG.nextInt(4096)]; - PRNG.nextBytes(data); + NashCipher enc = new NashCipher(key, iv, NashCipher.Mode.ENCRYPTION); + NashCipher dec = new NashCipher(key, iv, NashCipher.Mode.DECRYPTION); + byte[] data = new byte[prng.nextInt(4096)]; + prng.nextBytes(data); assertArrayEquals(data, dec.process(enc.process(data))); } + + @Test(expected = NullPointerException.class) + public void testCreateWithNullKey() + { + new NashCipher(null, iv, NashCipher.Mode.ENCRYPTION); + } + + @Test(expected = NullPointerException.class) + public void testCreateWithNullIV() + { + new NashCipher(key, null, NashCipher.Mode.ENCRYPTION); + } + + @Test(expected = NullPointerException.class) + public void testCreateWithNullMode() + { + new NashCipher(key, iv, null); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateWithDifferentKeyAndIVSize() + { + new NashCipher(Key.create(4), IV.create(8), NashCipher.Mode.DECRYPTION); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testProcessWithNegativeOffset() + { + NashCipher enc = new NashCipher(key, iv, NashCipher.Mode.ENCRYPTION); + enc.process(new byte[0], -1, 0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testProcessWithNegativeLength() + { + NashCipher enc = new NashCipher(key, iv, NashCipher.Mode.ENCRYPTION); + enc.process(new byte[0], 1, -1); + } } diff --git a/test/org/kocakosm/nash/ObjectCodec.java b/test/org/kocakosm/nash/ObjectCodec.java new file mode 100644 index 0000000..f156e73 --- /dev/null +++ b/test/org/kocakosm/nash/ObjectCodec.java @@ -0,0 +1,74 @@ +/*----------------------------------------------------------------------------* + * This file is part of Nash-Cipher. * + * Copyright (C) 2012-2013 Osman KOCAK * + * * + * This program is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or (at your * + * option) any later version. * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * + * License for more details. * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + *----------------------------------------------------------------------------*/ + +package org.kocakosm.nash; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Serialization utilities. + * + * @author Osman KOCAK + */ +final class ObjectCodec +{ + static byte[] encode(Serializable object) throws IOException + { + ObjectOutputStream oos = null; + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(out); + oos.writeObject(object); + oos.flush(); + return out.toByteArray(); + } finally { + close(oos); + } + } + + static T decode(byte[] object, Class t) + throws IOException + { + ObjectInputStream ois = null; + ByteArrayInputStream in = new ByteArrayInputStream(object); + try { + ois = new ObjectInputStream(in); + return (T) ois.readObject(); + } catch (ClassNotFoundException ex) { + throw new IOException(ex); + } finally { + close(ois); + } + } + + private static void close(Closeable stream) throws IOException + { + if (stream != null) { + stream.close(); + } + } + + private ObjectCodec() + { + /* ... */ + } +} diff --git a/test/org/kocakosm/nash/io/NashCipherInputStreamTest.java b/test/org/kocakosm/nash/io/NashCipherInputStreamTest.java new file mode 100644 index 0000000..57532ec --- /dev/null +++ b/test/org/kocakosm/nash/io/NashCipherInputStreamTest.java @@ -0,0 +1,121 @@ +/*----------------------------------------------------------------------------* + * This file is part of Nash-Cipher. * + * Copyright (C) 2012-2013 Osman KOCAK * + * * + * This program is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or (at your * + * option) any later version. * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * + * License for more details. * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + *----------------------------------------------------------------------------*/ + +package org.kocakosm.nash.io; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.kocakosm.nash.IV; +import org.kocakosm.nash.Key; +import org.kocakosm.nash.NashCipher; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Test; + +/** + * {@link NashCipherInputStream}'s unit tests. + * + * @author Osman KOCAK + */ +public final class NashCipherInputStreamTest +{ + private final IV iv = IV.create(8); + private final Key key = Key.create(8); + + @Test(expected = NullPointerException.class) + public void testCreateWithNullStream() + { + new NashCipherInputStream(key, iv, null); + } + + @Test + public void testAvailable() throws Exception + { + byte[] data = "Hello".getBytes("UTF-8"); + InputStream in = new ByteArrayInputStream(data); + InputStream nash = new NashCipherInputStream(key, iv, in); + assertEquals(in.available(), nash.available()); + } + + @Test + public void testClose() throws Exception + { + InputStream in = mock(InputStream.class); + new NashCipherInputStream(key, iv, in).close(); + verify(in).close(); + } + + @Test + public void testMarkSupported() throws Exception + { + InputStream in = mock(InputStream.class); + InputStream nash = new NashCipherInputStream(key, iv, in); + assertFalse(nash.markSupported()); + } + + @Test(expected = UnsupportedOperationException.class) + public void testMark() throws Exception + { + InputStream in = mock(InputStream.class); + new NashCipherInputStream(key, iv, in).mark(100); + } + + @Test(expected = IOException.class) + public void testReset() throws Exception + { + InputStream in = mock(InputStream.class); + new NashCipherInputStream(key, iv, in).reset(); + } + + @Test(expected = IOException.class) + public void testSkip() throws Exception + { + InputStream in = mock(InputStream.class); + new NashCipherInputStream(key, iv, in).skip(16); + } + + @Test + public void testRead() throws Exception + { + byte[] data = "Hello".getBytes("UTF-8"); + InputStream in = new ByteArrayInputStream(data); + InputStream nash = new NashCipherInputStream(key, iv, in); + byte[] decrypted = new byte[data.length]; + for (int i = 0; i < data.length; i++) { + decrypted[i] = (byte) nash.read(); + } + assertEquals(-1, nash.read()); + NashCipher cipher = new NashCipher(key, iv, NashCipher.Mode.DECRYPTION); + assertArrayEquals(cipher.process(data), decrypted); + } + + @Test + public void testReadArray() throws Exception + { + byte[] data = "Hello".getBytes("UTF-8"); + InputStream in = new ByteArrayInputStream(data); + InputStream nash = new NashCipherInputStream(key, iv, in); + byte[] decrypted = new byte[data.length]; + nash.read(decrypted); + assertEquals(-1, nash.read(new byte[data.length])); + NashCipher cipher = new NashCipher(key, iv, NashCipher.Mode.DECRYPTION); + assertArrayEquals(cipher.process(data), decrypted); + } +} diff --git a/test/org/kocakosm/nash/io/NashCipherOutputStreamTest.java b/test/org/kocakosm/nash/io/NashCipherOutputStreamTest.java new file mode 100644 index 0000000..762ba93 --- /dev/null +++ b/test/org/kocakosm/nash/io/NashCipherOutputStreamTest.java @@ -0,0 +1,88 @@ +/*----------------------------------------------------------------------------* + * This file is part of Nash-Cipher. * + * Copyright (C) 2012-2013 Osman KOCAK * + * * + * This program is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or (at your * + * option) any later version. * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * + * License for more details. * + * You should have received a copy of the GNU Lesser General Public License * + * along with this program. If not, see . * + *----------------------------------------------------------------------------*/ + +package org.kocakosm.nash.io; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.kocakosm.nash.IV; +import org.kocakosm.nash.Key; +import org.kocakosm.nash.NashCipher; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +import org.junit.Test; + +/** + * {@link NashCipherOutputStream}'s unit tests. + * + * @author Osman KOCAK + */ +public final class NashCipherOutputStreamTest +{ + private final IV iv = IV.create(8); + private final Key key = Key.create(8); + + @Test(expected = NullPointerException.class) + public void testCreateWithNullStream() + { + new NashCipherOutputStream(key, iv, null); + } + + @Test + public void testClose() throws Exception + { + OutputStream out = mock(OutputStream.class); + new NashCipherOutputStream(key, iv, out).close(); + verify(out).close(); + } + + @Test + public void testFlush() throws Exception + { + OutputStream out = mock(OutputStream.class); + new NashCipherOutputStream(key, iv, out).flush(); + verify(out).flush(); + } + + @Test + public void testWrite() throws Exception + { + byte[] data = "Hello".getBytes("UTF-8"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStream nash = new NashCipherOutputStream(key, iv, out); + for (byte b : data) { + nash.write(b); + } + nash.flush(); + NashCipher cipher = new NashCipher(key, iv, NashCipher.Mode.ENCRYPTION); + assertArrayEquals(cipher.process(data), out.toByteArray()); + } + + @Test + public void testWriteArray() throws Exception + { + byte[] data = "Hello".getBytes("UTF-8"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStream nash = new NashCipherOutputStream(key, iv, out); + nash.write(data); + nash.flush(); + NashCipher cipher = new NashCipher(key, iv, NashCipher.Mode.ENCRYPTION); + assertArrayEquals(cipher.process(data), out.toByteArray()); + } +} diff --git a/test/org/kocakosm/nash/io/NashCipherStreamsTest.java b/test/org/kocakosm/nash/io/NashCipherStreamsTest.java index 5bf1de0..349e96a 100644 --- a/test/org/kocakosm/nash/io/NashCipherStreamsTest.java +++ b/test/org/kocakosm/nash/io/NashCipherStreamsTest.java @@ -36,13 +36,12 @@ */ public final class NashCipherStreamsTest { - private static final Random PRNG = new Random(); - @Test public void test() throws Exception { - byte[] data = new byte[PRNG.nextInt(4096)]; - PRNG.nextBytes(data); + Random prng = new Random(); + byte[] data = new byte[prng.nextInt(4096)]; + prng.nextBytes(data); IV iv = IV.create(64); Key secret = Key.create(64);