diff options
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.java | 199 |
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()); + } +} |