aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/HCFamilyVecTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/HCFamilyVecTest.java')
-rw-r--r--libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/HCFamilyVecTest.java199
1 files changed, 199 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/HCFamilyVecTest.java b/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/HCFamilyVecTest.java
new file mode 100644
index 000000000..a3c954f8a
--- /dev/null
+++ b/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/HCFamilyVecTest.java
@@ -0,0 +1,199 @@
+package org.spongycastle.crypto.test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import org.spongycastle.crypto.CipherParameters;
+import org.spongycastle.crypto.StreamCipher;
+import org.spongycastle.crypto.engines.HC128Engine;
+import org.spongycastle.crypto.engines.HC256Engine;
+import org.spongycastle.crypto.params.KeyParameter;
+import org.spongycastle.crypto.params.ParametersWithIV;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.encoders.Hex;
+import org.spongycastle.util.test.SimpleTest;
+
+/**
+ * HC-128 and HC-256 Tests. Based on the test vectors in the official reference
+ * papers, respectively:
+ *
+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf
+ * http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf
+ */
+public class HCFamilyVecTest
+ extends SimpleTest
+{
+ private static class PeekableLineReader extends BufferedReader
+ {
+ public PeekableLineReader(Reader r) throws IOException
+ {
+ super(r);
+
+ peek = super.readLine();
+ }
+
+ public String peekLine()
+ {
+ return peek;
+ }
+
+ public String readLine() throws IOException
+ {
+ String tmp = peek;
+ peek = super.readLine();
+ return tmp;
+ }
+
+ private String peek;
+ }
+
+ public String getName()
+ {
+ return "HC-128 and HC-256 (ecrypt)";
+ }
+
+ public void performTest() throws Exception
+ {
+ runTests(new HC128Engine(), "ecrypt_HC-128.txt");
+ runTests(new HC256Engine(), "ecrypt_HC-256_128K_128IV.txt");
+ runTests(new HC256Engine(), "ecrypt_HC-256_256K_128IV.txt");
+ runTests(new HC256Engine(), "ecrypt_HC-256_128K_256IV.txt");
+ runTests(new HC256Engine(), "ecrypt_HC-256_256K_256IV.txt");
+ }
+
+ private void runTests(StreamCipher hc, String fileName) throws IOException
+ {
+ Reader resource = new InputStreamReader(getClass().getResourceAsStream(fileName));
+ PeekableLineReader r = new PeekableLineReader(resource);
+ runAllVectors(hc, fileName, r);
+ }
+
+ private void runAllVectors(StreamCipher hc, String fileName, PeekableLineReader r)
+ throws IOException
+ {
+ for (;;)
+ {
+ String line = r.readLine();
+ if (line == null)
+ {
+ break;
+ }
+
+ line = line.trim();
+
+ if (line.startsWith("Set "))
+ {
+ runVector(hc, fileName, r, dellChar(line, ':'));
+ }
+ }
+ }
+
+ private String dellChar(String s, char c)
+ {
+ StringBuffer b = new StringBuffer();
+
+ for (int i = 0; i != s.length(); i++)
+ {
+ if (s.charAt(i) != c)
+ {
+ b.append(s.charAt(i));
+ }
+ }
+
+ return b.toString();
+ }
+
+ private void runVector(StreamCipher hc, String fileName, PeekableLineReader r, String vectorName)
+ throws IOException
+ {
+// System.out.println(fileName + " => " + vectorName);
+ String hexKey = readBlock(r);
+ String hexIV = readBlock(r);
+
+ CipherParameters cp = new KeyParameter(Hex.decode(hexKey));
+ cp = new ParametersWithIV(cp, Hex.decode(hexIV));
+ hc.init(true, cp);
+
+ byte[] input = new byte[64];
+ byte[] output = new byte[64];
+ byte[] digest = new byte[64];
+ int pos = 0;
+
+ for (;;)
+ {
+ String line1 = r.peekLine().trim();
+ int equalsPos = line1.indexOf('=');
+ String lead = line1.substring(0, equalsPos - 1);
+
+ String hexData = readBlock(r);
+ byte[] data = Hex.decode(hexData);
+
+ if (lead.equals("xor-digest"))
+ {
+ if (!Arrays.areEqual(data, digest))
+ {
+ fail("Failed in " + fileName + " for test vector: " + vectorName + " at " + lead);
+// System.out.println(fileName + " => " + vectorName + " failed at " + lead); return;
+ }
+ break;
+ }
+
+ int posA = lead.indexOf('[');
+ int posB = lead.indexOf("..");
+ int posC = lead.indexOf(']');
+ int start = Integer.parseInt(lead.substring(posA + 1, posB));
+ int end = Integer.parseInt(lead.substring(posB + 2, posC));
+
+ if (start % 64 != 0 || (end - start != 63))
+ {
+ throw new IllegalStateException(vectorName + ": " + lead + " not on 64 byte boundaries");
+ }
+
+ while (pos < end)
+ {
+ hc.processBytes(input, 0, input.length, output, 0);
+ xor(digest, output);
+ pos += 64;
+ }
+
+ if (!Arrays.areEqual(data, output))
+ {
+ fail("Failed in " + fileName + " for test vector: " + vectorName + " at " + lead);
+// System.out.println(fileName + " => " + vectorName + " failed at " + lead); return;
+ }
+ }
+ }
+
+ private static String readBlock(PeekableLineReader r) throws IOException
+ {
+ String first = r.readLine().trim();
+ String result = first.substring(first.lastIndexOf(' ') + 1);
+
+ for (;;)
+ {
+ String peek = r.peekLine().trim();
+ if (peek.length() < 1 || peek.indexOf('=') >= 0)
+ {
+ break;
+ }
+ result += r.readLine().trim();
+ }
+
+ return result;
+ }
+
+ private static void xor(byte[] digest, byte[] block)
+ {
+ for (int i = 0; i < digest.length; ++i)
+ {
+ digest[i] ^= block[i];
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ runTest(new HCFamilyVecTest());
+ }
+}