aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.codecov.yml27
-rw-r--r--.github/workflows/build.yml6
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java62
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java14
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java38
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java2
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java17
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java115
-rw-r--r--docs/FORMAT.md4
-rw-r--r--reader/build.gradle.kts10
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/command/Command.java1
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java16
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java65
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java119
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java6
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java14
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java6
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java32
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java15
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java6
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java37
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java20
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java22
-rw-r--r--reader/src/test/java/cz/crcs/ectester/reader/AppTests.java141
-rw-r--r--reader/src/test/java/cz/crcs/ectester/reader/XFail.java86
-rw-r--r--reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java86
-rw-r--r--standalone/build.gradle.kts8
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java4
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java7
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java33
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java8
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/base/PerformanceTest.java2
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java2
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java43
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java56
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java28
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java120
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java116
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java173
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java119
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java54
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java28
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java26
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java47
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java120
-rw-r--r--standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java111
-rw-r--r--standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp14
47 files changed, 1066 insertions, 1020 deletions
diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 0000000..a25c148
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,27 @@
+comment:
+ layout: "condensed_header, condensed_files, diff, components, condensed_footer" # show component info in the PR comment
+
+component_management:
+ default_rules: # default rules that will be inherited by all components
+ statuses:
+ - type: project # in this case every component that doesn't have a status defined will have a project type one
+ target: auto
+ branches:
+ - "!master"
+ individual_components:
+ - component_id: applet_package
+ name: Applet
+ paths:
+ - applet/**
+ - component_id: common_package
+ name: Common
+ paths:
+ - common/**
+ - component_id: reader_package
+ name: Reader
+ paths:
+ - reader/**
+ - component_id: standalone_package
+ name: Standalone
+ paths:
+ - standalone/** \ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index fea8fe5..b626eb0 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -81,6 +81,12 @@ jobs:
path: |
reader/build/libs/ECTesterReader.jar
+ - name: Upload code coverage
+ uses: codecov/codecov-action@v4
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ slug: crocs-muni/ECTester
+
standalone:
runs-on: ubuntu-latest
permissions:
diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java
index e26fc44..7147c18 100644
--- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java
+++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Curve.java
@@ -5,6 +5,7 @@ import org.bouncycastle.math.ec.ECCurve;
import java.math.BigInteger;
import java.security.spec.*;
+import java.util.Arrays;
/**
* An Elliptic curve, contains parameters Fp/F2M, A, B, G, R, (K)?.
@@ -53,6 +54,27 @@ public class EC_Curve extends EC_Params {
return "<" + getId() + "> " + (field == EC_Consts.ALG_EC_FP ? "Prime" : "Binary") + " field Elliptic curve (" + String.valueOf(bits) + "b)" + (desc == null ? "" : ": " + desc) + System.lineSeparator() + super.toString();
}
+ private int[] getPowers() {
+ if (this.field == EC_Consts.ALG_EC_F2M) {
+ byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M);
+ int e1 = ByteUtil.getShort(fieldData[1], 0);
+ int e2 = ByteUtil.getShort(fieldData[2], 0);
+ int e3 = ByteUtil.getShort(fieldData[3], 0);
+ int[] powers = Arrays.stream(new int[]{e1, e2, e3}).sorted().toArray();
+ e1 = powers[0];
+ e2 = powers[1];
+ e3 = powers[2];
+ if (e1 == 0 && e2 == 0) {
+ powers = new int[]{e3};
+ } else {
+ powers = new int[]{e3, e2, e1};
+ }
+ return powers;
+ } else {
+ return null;
+ }
+ }
+
public EllipticCurve toCurve() {
ECField field;
if (this.field == EC_Consts.ALG_EC_FP) {
@@ -60,15 +82,7 @@ public class EC_Curve extends EC_Params {
} else {
byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M);
int m = ByteUtil.getShort(fieldData[0], 0);
- int e1 = ByteUtil.getShort(fieldData[1], 0);
- int e2 = ByteUtil.getShort(fieldData[2], 0);
- int e3 = ByteUtil.getShort(fieldData[3], 0);
- int[] powers;
- if (e2 == 0 && e3 == 0) {
- powers = new int[]{e1};
- } else {
- powers = new int[]{e1, e2, e3};
- }
+ int[] powers = getPowers();
field = new ECFieldF2m(m, powers);
}
@@ -78,6 +92,26 @@ public class EC_Curve extends EC_Params {
return new EllipticCurve(field, a, b);
}
+ /**
+ * Constructs EllipticCurve from EC_Curve even if the parameters of the curve are wrong.
+ */
+ public EllipticCurve toCustomCurve() {
+ ECField field;
+ if (this.field == EC_Consts.ALG_EC_FP) {
+ field = new CustomECFieldFp(new BigInteger(1, this.getData(0)));
+ } else {
+ byte[][] fieldData = this.getParam(EC_Consts.PARAMETER_F2M);
+ int m = ByteUtil.getShort(fieldData[0], 0);
+ int[] powers = getPowers();
+ field = new CustomECFieldF2m(m, powers);
+ }
+
+ BigInteger a = new BigInteger(1, this.getParam(EC_Consts.PARAMETER_A)[0]);
+ BigInteger b = new BigInteger(1, this.getParam(EC_Consts.PARAMETER_B)[0]);
+
+ return new CustomEllipticCurve(field, a, b);
+ }
+
public ECCurve toBCCurve() {
if (this.field == EC_Consts.ALG_EC_FP) {
BigInteger p = new BigInteger(1, getParam(EC_Consts.PARAMETER_FP)[0]);
@@ -89,14 +123,16 @@ public class EC_Curve extends EC_Params {
} else {
byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M);
int m = ByteUtil.getShort(fieldData[0], 0);
- int e1 = ByteUtil.getShort(fieldData[1], 0);
- int e2 = ByteUtil.getShort(fieldData[2], 0);
- int e3 = ByteUtil.getShort(fieldData[3], 0);
BigInteger a = new BigInteger(1, getParam(EC_Consts.PARAMETER_A)[0]);
BigInteger b = new BigInteger(1, getParam(EC_Consts.PARAMETER_B)[0]);
BigInteger r = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]);
BigInteger k = new BigInteger(1, getParam(EC_Consts.PARAMETER_K)[0]);
- return new ECCurve.F2m(m, e1, e2, e3, a, b, r, k);
+ int[] powers = getPowers();
+ if (powers.length == 1) {
+ return new ECCurve.F2m(m, powers[0], 0, 0, a, b, r, k);
+ } else {
+ return new ECCurve.F2m(m, powers[2], powers[1], powers[0], a, b, r, k);
+ }
}
}
diff --git a/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java
index 538539b..a90bc56 100644
--- a/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java
+++ b/common/src/main/java/cz/crcs/ectester/common/output/BaseTextTestWriter.java
@@ -156,12 +156,16 @@ public abstract class BaseTextTestWriter implements TestWriter {
for (Throwable t = error; t != null; t = t.getCause()) {
sb.append("═══ ").append(t.toString()).append(" ═══");
sb.append(System.lineSeparator());
+ sb.append("═══ Stack trace: ═══").append(System.lineSeparator());
+ for (StackTraceElement s : t.getStackTrace()) {
+ sb.append("═══ ").append(s.toString()).append(" ═══");
+ sb.append(System.lineSeparator());
+ }
+ if (t.getCause() != null) {
+ sb.append("═══ Caused by: ═══").append(System.lineSeparator());
+ }
}
- sb.append("═══ Stack trace: ═══").append(System.lineSeparator());
- for (StackTraceElement s : error.getStackTrace()) {
- sb.append("═══ ").append(s.toString()).append(" ═══");
- sb.append(System.lineSeparator());
- }
+
return sb.toString();
}
diff --git a/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java b/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java
index ba4ad4f..e5d68dc 100644
--- a/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java
+++ b/common/src/main/java/cz/crcs/ectester/common/test/CompoundTest.java
@@ -2,6 +2,7 @@ package cz.crcs.ectester.common.test;
import java.util.Arrays;
import java.util.Objects;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -16,13 +17,35 @@ public class CompoundTest extends Test implements Cloneable {
private Test[] tests;
private String description = "";
- private final static Consumer<Test[]> RUN_ALL = tests -> {
+ public final static BiFunction<Result.ExpectedValue, Test[], Result> EXPECT_ALL = (what, tests) -> {
+ for (Test test : tests) {
+ if (!Result.Value.fromExpected(what, test.ok()).ok()) {
+ return new Result(Result.Value.FAILURE, "Some sub-tests did not have the expected result.");
+ }
+ }
+ return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result.");
+ };
+
+ public final static Function<Test[], Result> EXPECT_ALL_SUCCESS = tests -> EXPECT_ALL.apply(Result.ExpectedValue.SUCCESS, tests);
+ public final static Function<Test[], Result> EXPECT_ALL_FAILURE = tests -> EXPECT_ALL.apply(Result.ExpectedValue.FAILURE, tests);
+ public final static Function<Test[], Result> EXPECT_ALL_ANY = tests -> EXPECT_ALL.apply(Result.ExpectedValue.ANY, tests);
+
+ public final static Consumer<Test[]> RUN_ALL = tests -> {
for (Test t : tests) {
t.run();
}
};
- private final static Consumer<Test[]> RUN_GREEDY_ALL = tests -> {
+ public final static Consumer<Test[]> RUN_ALL_IF_FIRST = tests -> {
+ tests[0].run();
+ if (tests[0].getResult().getValue().equals(Result.Value.SUCCESS) || tests[0].getResult().getValue().equals(Result.Value.UXSUCCESS)) {
+ for (int i = 1; i < tests.length; i++) {
+ tests[i].run();
+ }
+ }
+ };
+
+ public final static Consumer<Test[]> RUN_GREEDY_ALL = tests -> {
for (Test t : tests) {
t.run();
if (!t.ok()) {
@@ -31,7 +54,7 @@ public class CompoundTest extends Test implements Cloneable {
}
};
- private final static Consumer<Test[]> RUN_GREEDY_ANY = tests -> {
+ public final static Consumer<Test[]> RUN_GREEDY_ANY = tests -> {
for (Test t : tests) {
t.run();
if (t.ok()) {
@@ -68,14 +91,7 @@ public class CompoundTest extends Test implements Cloneable {
}
private static CompoundTest expectAll(Result.ExpectedValue what, Consumer<Test[]> runCallback, Test[] all) {
- return new CompoundTest((tests) -> {
- for (Test test : tests) {
- if (!Result.Value.fromExpected(what, test.ok()).ok()) {
- return new Result(Result.Value.FAILURE, "Some sub-tests did not have the expected result.");
- }
- }
- return new Result(Result.Value.SUCCESS, "All sub-tests had the expected result.");
- }, runCallback, all);
+ return new CompoundTest((tests) -> EXPECT_ALL.apply(what, tests), runCallback, all);
}
public static CompoundTest all(Result.ExpectedValue what, Test... all) {
diff --git a/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java b/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java
index 091b008..0f2b1b0 100644
--- a/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java
+++ b/common/src/main/java/cz/crcs/ectester/common/test/TestSuite.java
@@ -53,7 +53,7 @@ public abstract class TestSuite {
* @return The test that was run.
* @throws TestException
*/
- protected <T extends Test> T runTest(T t) {
+ private <T extends Test> T runTest(T t) {
running = t;
writer.beginTest(t);
t.run();
diff --git a/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java
index eeb2159..2ab2d26 100644
--- a/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java
+++ b/common/src/main/java/cz/crcs/ectester/common/util/CardUtil.java
@@ -456,6 +456,23 @@ public class CardUtil {
}
}
+ public static String getSigTypeAlgoString(byte sigType) {
+ switch (sigType) {
+ case EC_Consts.Signature_ALG_ECDSA_SHA:
+ return "SHA1withECDSA";
+ case EC_Consts.Signature_ALG_ECDSA_SHA_224:
+ return "SHA224withECDSA";
+ case EC_Consts.Signature_ALG_ECDSA_SHA_256:
+ return "SHA256withECDSA";
+ case EC_Consts.Signature_ALG_ECDSA_SHA_384:
+ return "SHA384withECDSA";
+ case EC_Consts.Signature_ALG_ECDSA_SHA_512:
+ return "SHA512withECDSA";
+ default:
+ return "unknown";
+ }
+ }
+
public static byte getSigType(String sigTypeString) {
switch (sigTypeString) {
case "ECDSA_SHA":
diff --git a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java
index e7f138e..6eb0b1a 100644
--- a/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java
+++ b/common/src/main/java/cz/crcs/ectester/common/util/ECUtil.java
@@ -14,6 +14,8 @@ import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey;
import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey;
import org.bouncycastle.jcajce.interfaces.XDHPrivateKey;
import org.bouncycastle.jcajce.interfaces.XDHPublicKey;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
import java.io.FileInputStream;
import java.io.IOException;
@@ -200,7 +202,7 @@ public class ECUtil {
}
}
- private static byte[] hashCurve(EC_Curve curve) {
+ public static byte[] hashCurve(EC_Curve curve) {
int bytes = (curve.getBits() + 7) / 8;
byte[] result = new byte[bytes];
SHA1Digest digest = new SHA1Digest();
@@ -244,64 +246,87 @@ public class ECUtil {
}
public static EC_Params fullRandomPoint(EC_Curve curve) {
- EllipticCurve ecCurve = curve.toCurve();
-
- BigInteger p;
- if (ecCurve.getField() instanceof ECFieldFp) {
+ if (curve.getField() == EC_Consts.ALG_EC_FP) {
+ EllipticCurve ecCurve = curve.toCurve();
ECFieldFp fp = (ECFieldFp) ecCurve.getField();
- p = fp.getP();
+ BigInteger p = fp.getP();
if (!p.isProbablePrime(20)) {
return null;
}
+ BigInteger x;
+ BigInteger rhs;
+ do {
+ x = new BigInteger(ecCurve.getField().getFieldSize(), rand).mod(p);
+ rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
+ } while (!isResidue(rhs, p));
+ BigInteger y = modSqrt(rhs, p);
+ if (rand.nextBoolean()) {
+ y = p.subtract(y);
+ }
+
+ byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize());
+ byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize());
+ return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
} else {
- //TODO
- return null;
- }
- BigInteger x;
- BigInteger rhs;
- do {
- x = new BigInteger(ecCurve.getField().getFieldSize(), rand).mod(p);
- rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
- } while (!isResidue(rhs, p));
- BigInteger y = modSqrt(rhs, p);
- if (rand.nextBoolean()) {
- y = p.subtract(y);
- }
+ ECCurve.F2m bcCurve = (ECCurve.F2m) curve.toBCCurve();
+ BigInteger b = new BigInteger(bcCurve.getFieldSize(), rand);
+ org.bouncycastle.math.ec.ECPoint point;
+ while (true) {
+ try {
+ ECFieldElement.F2m x = (ECFieldElement.F2m) bcCurve.fromBigInteger(b);
+ byte[] pointTry = ByteUtil.concatenate(new byte[]{0x02}, x.getEncoded());
+ point = bcCurve.decodePoint(pointTry);
+ break;
+ } catch (IllegalArgumentException iae) {
+ b = new BigInteger(bcCurve.getFieldSize(), rand);
+ }
+ }
- byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize());
- byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize());
- return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
+ return new EC_Params(EC_Consts.PARAMETER_W, new byte[][] {point.getAffineXCoord().getEncoded(), point.getAffineYCoord().getEncoded()});
+ }
}
public static EC_Params fixedRandomPoint(EC_Curve curve) {
- EllipticCurve ecCurve = curve.toCurve();
-
- BigInteger p;
- if (ecCurve.getField() instanceof ECFieldFp) {
+ if (curve.getField() == EC_Consts.ALG_EC_FP) {
+ EllipticCurve ecCurve = curve.toCurve();
ECFieldFp fp = (ECFieldFp) ecCurve.getField();
- p = fp.getP();
+ BigInteger p = fp.getP();
if (!p.isProbablePrime(20)) {
return null;
}
- } else {
- //TODO
- return null;
- }
+ BigInteger x = new BigInteger(1, hashCurve(curve)).mod(p);
+ BigInteger rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
+ while (!isResidue(rhs, p)) {
+ x = x.add(BigInteger.ONE).mod(p);
+ rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
+ }
+ BigInteger y = modSqrt(rhs, p);
+ if (y.bitCount() % 2 == 0) {
+ y = p.subtract(y);
+ }
- BigInteger x = new BigInteger(1, hashCurve(curve)).mod(p);
- BigInteger rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
- while (!isResidue(rhs, p)) {
- x = x.add(BigInteger.ONE).mod(p);
- rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
- }
- BigInteger y = modSqrt(rhs, p);
- if (y.bitCount() % 2 == 0) {
- y = p.subtract(y);
+ byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize());
+ byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize());
+ return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
+ } else {
+ ECCurve.F2m bcCurve = (ECCurve.F2m) curve.toBCCurve();
+ BigInteger b = new BigInteger(1, hashCurve(curve));
+ while (b.bitLength() > bcCurve.getFieldSize()) {
+ b = b.shiftRight(1);
+ }
+ org.bouncycastle.math.ec.ECPoint point;
+ while (true) {
+ try {
+ ECFieldElement.F2m x = (ECFieldElement.F2m) bcCurve.fromBigInteger(b);
+ byte[] pointTry = ByteUtil.concatenate(new byte[]{0x02}, x.getEncoded());
+ point = bcCurve.decodePoint(pointTry);
+ break;
+ } catch (IllegalArgumentException iae) {
+ b = b.add(BigInteger.ONE);
+ }
+ }
+ return new EC_Params(EC_Consts.PARAMETER_W, new byte[][] {point.getAffineXCoord().getEncoded(), point.getAffineYCoord().getEncoded()});
}
-
- byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize());
- byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize());
- return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
}
public static ECPoint toPoint(EC_Params params) {
@@ -352,11 +377,11 @@ public class ECUtil {
/**
* Validate DER or PLAIN signature format.
*
- * @throws IllegalArgumentException in case of invalid format.
* @param signature
* @param params
* @param hashAlgo
* @param sigType
+ * @throws IllegalArgumentException in case of invalid format.
*/
public static void validateSignatureFormat(byte[] signature, ECParameterSpec params, String hashAlgo, String sigType) {
BigInteger n = params.getOrder();
diff --git a/docs/FORMAT.md b/docs/FORMAT.md
index 5c29d58..4d30ea6 100644
--- a/docs/FORMAT.md
+++ b/docs/FORMAT.md
@@ -17,7 +17,7 @@ In the rest of this documentation the following notation is used
- `p` - prime F_p
- `m` - binary field exponent F_2^m
- `e1` - largest exponent of the field polynomial
- - `e2` - middle exponenet of the field polynomial, or `0000` if field poly is a trinomial
+ - `e2` - middle exponent of the field polynomial, or `0000` if field poly is a trinomial
- `e3` - smallest exponent (except zero) of the field polynomial, or `0000` if field poly is a trinomial
- `a` - a parameter in short Weierstrass curve equation
- `b` - b parameter in short Weierstrass curve equation
@@ -26,7 +26,7 @@ In the rest of this documentation the following notation is used
- `n` - the base-point order
- `h` - the base-point cofactor
- `wx` - the x coordinate of the public key
- - `wy` - the y coordinate of th public key
+ - `wy` - the y coordinate of the public key
- `s` - the private key value
## Curves
diff --git a/reader/build.gradle.kts b/reader/build.gradle.kts
index 0386ea5..1abecdc 100644
--- a/reader/build.gradle.kts
+++ b/reader/build.gradle.kts
@@ -1,6 +1,7 @@
plugins {
application
jacoco
+ id("jacoco-report-aggregation")
id("com.adarshr.test-logger") version "4.0.0"
}
@@ -35,18 +36,21 @@ application {
tasks.named<Test>("test") {
useJUnitPlatform()
// Report is always generated after tests run
- finalizedBy(tasks.jacocoTestReport)
+ finalizedBy(tasks.named<JacocoReport>("testCodeCoverageReport"))
}
-tasks.jacocoTestReport {
+tasks.named<JacocoReport>("testCodeCoverageReport") {
reports {
+ html.required = true
+ html.outputLocation.set(layout.buildDirectory.dir("reports/jacoco/test/html"))
xml.required = true
+ xml.outputLocation.set(layout.buildDirectory.file("reports/jacoco/test/jacocoTestReport.xml"))
}
}
testlogger {
theme = com.adarshr.gradle.testlogger.theme.ThemeType.MOCHA
- showStandardStreams = true
+ showStandardStreams = false
}
tasks.register<Jar>("uberJar") {
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java b/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java
index 892a481..2bd4c77 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/command/Command.java
@@ -19,6 +19,7 @@ import javax.smartcardio.ResponseAPDU;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java
index a28c2a7..bba211a 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompositeSuite.java
@@ -36,13 +36,8 @@ public class CardCompositeSuite extends CardTestSuite {
for (Map.Entry<EC_Curve, List<EC_Key>> curveKeys : mappedKeys.entrySet()) {
EC_Curve curve = curveKeys.getKey();
List<Test> tests = new LinkedList<>();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate));
- continue;
- }
- tests.add(allocate);
- tests.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY));
+ Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS);
+ Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.ANY);
String name;
if (cfg.testOptions.contains("preset")) {
@@ -50,13 +45,16 @@ public class CardCompositeSuite extends CardTestSuite {
} else {
name = "generated private key";
}
- tests.add(setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL));
+ Test setKeypair = setupKeypairs(curve, ExpectedValue.ANY, CardConsts.KEYPAIR_LOCAL);
+ Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare keypair on " + curve.getId() + ".", allocate, set, setKeypair);
+
for (EC_Key key : curveKeys.getValue()) {
Command ecdhCommand = new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, key.flatten());
Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.");
tests.add(CompoundTest.greedyAllTry(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with " + name + ", " + key.getDesc(), ecdh));
}
- doTest(CompoundTest.all(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", tests.toArray(new Test[0])));
+ Test ecdhTest = CompoundTest.all(ExpectedValue.SUCCESS, "Do ECDH.", tests.toArray(new Test[0]));
+ doTest(CompoundTest.greedyAll(ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", prepare, ecdhTest));
}
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java
index 8390cd3..418ed2f 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardCompressionSuite.java
@@ -70,56 +70,40 @@ public class CardCompressionSuite extends CardTestSuite {
String spec = keyLength + "b " + CardUtil.getKeyTypeString(field);
byte curveId = EC_Consts.getCurve(keyLength, field);
- Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), Result.ExpectedValue.SUCCESS));
- if (!allocateFirst.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for compression test on " + spec + ".", allocateFirst));
- continue;
- }
-
List<Test> compressionTests = new LinkedList<>();
+ Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), Result.ExpectedValue.SUCCESS);
+ Test setCustom = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curveId, domain, null), Result.ExpectedValue.SUCCESS);
+ Test genCustom = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS);
compressionTests.add(allocateFirst);
- Test setCustom = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curveId, domain, null), Result.ExpectedValue.SUCCESS));
- Test genCustom = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), Result.ExpectedValue.SUCCESS));
compressionTests.add(setCustom);
compressionTests.add(genCustom);
- Response.Export key = new Command.Export(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W).send();
- byte[] pubkey = key.getParameter(CardConsts.KEYPAIR_REMOTE, EC_Consts.KEY_PUBLIC);
EC_Curve secgCurve = EC_Store.getInstance().getObject(EC_Curve.class, "secg", CardUtil.getCurveName(curveId));
- ECPoint pub;
- try {
- pub = ECUtil.fromX962(pubkey, secgCurve.toCurve());
- } catch (IllegalArgumentException iae) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "", compressionTests.toArray(new Test[0])));
- continue;
- }
+ ECPoint pub = ECUtil.toPoint(ECUtil.fixedRandomPoint(secgCurve));
List<Test> kaTests = new LinkedList<>();
for (byte kaType : EC_Consts.KA_TYPES) {
List<Test> thisTests = new LinkedList<>();
- Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS));
- if (allocate.ok()) {
- Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.SUCCESS));
+ Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), Result.ExpectedValue.SUCCESS);
+ Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), Result.ExpectedValue.SUCCESS);
- thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement setup and basic test.", allocate, ka));
- if (ka.ok()) {
- // tests of the good stuff
- Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), Result.ExpectedValue.SUCCESS);
- Test kaHybrid = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS_HYBRID, kaType), Result.ExpectedValue.SUCCESS);
- thisTests.add(CompoundTest.any(Result.ExpectedValue.SUCCESS, "Tests of compressed and hybrid form.", kaCompressed, kaHybrid));
+ thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement setup and basic test.", allocate, ka));
+ // tests of the good stuff
+ Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), Result.ExpectedValue.SUCCESS);
+ Test kaHybrid = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS_HYBRID, kaType), Result.ExpectedValue.SUCCESS);
+ thisTests.add(CompoundTest.any(Result.ExpectedValue.SUCCESS, "Tests of compressed and hybrid form.", kaCompressed, kaHybrid));
- // tests the bad stuff here
- byte[] pubHybrid = ECUtil.toX962Hybrid(pub, keyLength);
- pubHybrid[pubHybrid.length - 1] ^= 1;
- byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid);
- Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE);
+ // tests the bad stuff here
+ byte[] pubHybrid = ECUtil.toX962Hybrid(pub, keyLength);
+ pubHybrid[pubHybrid.length - 1] ^= 1;
+ byte[] pubHybridEncoded = ByteUtil.prependLength(pubHybrid);
+ Test kaBadHybrid = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubHybridEncoded), Result.ExpectedValue.FAILURE);
- byte[] pubInfinityEncoded = {0x01, 0x00};
- Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE);
- thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity));
- }
- kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0])));
- }
+ byte[] pubInfinityEncoded = {0x00};
+ Test kaBadInfinity = CommandTest.expect(new Command.ECDH_direct(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_INFINITY, kaType, pubInfinityEncoded), Result.ExpectedValue.FAILURE);
+ thisTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests of corrupted hybrid form and infinity.", kaBadHybrid, kaBadInfinity));
+
+ kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyAgreement tests of " + CardUtil.getKATypeString(kaType) + ".", thisTests.toArray(new Test[0])));
}
compressionTests.addAll(kaTests);
if (cfg.cleanup) {
@@ -137,12 +121,7 @@ public class CardCompressionSuite extends CardTestSuite {
for (EC_Key.Public key : compressionKeys) {
EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve());
List<Test> tests = new LinkedList<>();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for non-residue test on " + curve.getBits() + "b " + curve.getId() + ".", allocate));
- continue;
- }
- tests.add(allocate);
+ tests.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
tests.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS));
tests.add(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS));
byte[] pointData = ECUtil.toX962Compressed(key.getParam(EC_Consts.PARAMETER_W));
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java
index ebb1d3f..c365d52 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDefaultSuite.java
@@ -13,7 +13,7 @@ import cz.crcs.ectester.reader.command.Command;
import java.util.LinkedList;
import java.util.List;
-import java.util.Random;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -44,19 +44,13 @@ public class CardDefaultSuite extends CardTestSuite {
short[] keySizes = field == EC_Consts.ALG_EC_FP ? EC_Consts.FP_SIZES : EC_Consts.F2M_SIZES;
short domain = field == EC_Consts.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M;
for (short keyLength : keySizes) {
-
List<Test> supportTests = new LinkedList<>();
- Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS));
- if (!allocateFirst.ok()) {
- doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + keyLength + "b " + CardUtil.getKeyTypeString(field) + ".", allocateFirst));
- continue;
- }
+ Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS);
+ Test genDefault = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS);
+ Test allocateSecond = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS);
+ Test setCustom = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), domain, null), ExpectedValue.SUCCESS);
+ Test genCustom = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS);
supportTests.add(allocateFirst);
-
- Test genDefault = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS));
- Test allocateSecond = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, field), ExpectedValue.SUCCESS));
- Test setCustom = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.getCurve(keyLength, field), domain, null), ExpectedValue.SUCCESS));
- Test genCustom = runTest(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS));
supportTests.add(genDefault);
supportTests.add(allocateSecond);
supportTests.add(setCustom);
@@ -64,68 +58,77 @@ public class CardDefaultSuite extends CardTestSuite {
List<Test> kaTests = new LinkedList<>();
for (byte kaType : EC_Consts.KA_TYPES) {
- Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS));
- if (allocate.ok()) {
- Command ecdh = new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType);
- Test ka = runTest(CommandTest.expect(ecdh, ExpectedValue.SUCCESS));
- Test kaCompressed = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS));
+ Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS);
+ Command ecdh = new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType);
+ Test ka = CommandTest.expect(ecdh, ExpectedValue.SUCCESS);
+ Test kaCompressed = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_LOCAL, CardConsts.KEYPAIR_REMOTE, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_COMPRESS, kaType), ExpectedValue.SUCCESS);
- String kaDesc = "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement.";
- Function<Test[], Result> kaCallback = (tests) -> {
- if (tests[1].ok() || tests[2].ok()) {
- return new Result(Value.SUCCESS, "Some ECDH is supported.");
+ String kaDesc = "Test of the " + CardUtil.getKATypeString(kaType) + " KeyAgreement.";
+ Function<Test[], Result> kaCallback = (tests) -> {
+ if (tests[1].ok() || tests[2].ok()) {
+ return new Result(Value.SUCCESS, "Some ECDH is supported.");
+ } else {
+ return new Result(Value.FAILURE, "ECDH failed.");
+ }
+ };
+
+ Consumer<Test[]> runCallback = tests -> {
+ for (Test t : tests) {
+ if (t instanceof PerformanceTest) {
+ if (tests[0].ok() && tests[1].ok()) {
+ t.run();
+ }
} else {
- return new Result(Value.FAILURE, "ECDH failed.");
+ t.run();
}
- };
-
- Test compound;
- if (ka.ok()) {
- Test perfTest = runTest(PerformanceTest.repeat(this.card, ecdh, 10));
- compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed, perfTest));
- } else {
- compound = runTest(CompoundTest.function(kaCallback, kaDesc, allocate, ka, kaCompressed));
}
+ };
- kaTests.add(compound);
- } else {
- runTest(allocate);
- kaTests.add(allocate);
- }
+ Test perfTest = PerformanceTest.repeat(this.card, ecdh, 10);
+ Test compound = CompoundTest.function(kaCallback, runCallback, kaDesc, allocate, ka, kaCompressed, perfTest);
+ kaTests.add(compound);
}
- Test kaTest = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "KeyAgreement tests.", kaTests.toArray(new Test[0])));
+ Test kaTest = CompoundTest.any(ExpectedValue.SUCCESS, "KeyAgreement tests.", kaTests.toArray(new Test[0]));
supportTests.add(kaTest);
List<Test> signTests = new LinkedList<>();
for (byte sigType : EC_Consts.SIG_TYPES) {
- Test allocate = runTest(CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS));
- if (allocate.ok()) {
- Command ecdsa = new Command.ECDSA(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_FALSE, null);
- Test expect = runTest(CommandTest.expect(ecdsa, ExpectedValue.SUCCESS));
+ Test allocate = CommandTest.expect(new Command.AllocateSignature(this.card, sigType), ExpectedValue.SUCCESS);
+ Command ecdsa = new Command.ECDSA(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_FALSE, null);
+ Test sign = CommandTest.expect(ecdsa, ExpectedValue.SUCCESS);
- String signDesc = "Test of the " + CardUtil.getSigTypeString(sigType) + " signature.";
+ String signDesc = "Test of the " + CardUtil.getSigTypeString(sigType) + " signature.";
- Random rand = new Random();
- byte[] sigData = new byte[64];
- rand.nextBytes(sigData);
+ byte[] sigData = new byte[]{(byte) domain, sigType};
- Test compound;
- if (expect.ok()) {
- Command ecdsaSign = new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_TRUE, sigData);
- PerformanceTest signTest = runTest(PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10));
- byte[] signature = signTest.getResponses()[0].getParam(0);
- Command ecdsaVerify = new Command.ECDSA_verify(this.card, CardConsts.KEYPAIR_LOCAL, sigType, sigData, signature);
- PerformanceTest verifyTest = runTest(PerformanceTest.repeat(this.card, "Verify", ecdsaVerify, 10));
- compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect, signTest, verifyTest));
+ Function<Test[], Result> sigCallback = (tests) -> {
+ if (tests[1].ok()) {
+ return new Result(Value.SUCCESS, "Some ECDSA is supported.");
} else {
- compound = runTest(CompoundTest.all(ExpectedValue.SUCCESS, signDesc, allocate, expect));
+ return new Result(Value.FAILURE, "ECDSA failed.");
+ }
+ };
+ Consumer<Test[]> runCallback = tests -> {
+ for (Test t : tests) {
+ if (t instanceof PerformanceTest) {
+ if (tests[0].ok() && tests[1].ok()) {
+ t.run();
+ }
+ } else {
+ t.run();
+ }
}
- signTests.add(compound);
- } else {
- signTests.add(allocate);
- }
+ };
+
+ Command ecdsaSign = new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, sigType, CardConsts.EXPORT_TRUE, sigData);
+ PerformanceTest signTest = PerformanceTest.repeat(this.card, "Sign", ecdsaSign, 10);
+
+ CommandTestable.FunctionCommandTestable verifyTestable = new CommandTestable.FunctionCommandTestable(() -> new Command.ECDSA_verify(this.card, CardConsts.KEYPAIR_LOCAL, sigType, sigData, signTest.getResponses()[0].getParam(0)));
+ PerformanceTest verifyTest = PerformanceTest.repeat(this.card, "Verify", verifyTestable, 10);
+ Test compound = CompoundTest.function(sigCallback, runCallback, signDesc, allocate, sign, signTest, verifyTest);
+ signTests.add(compound);
}
- Test signTest = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Signature tests.", signTests.toArray(new Test[0])));
+ Test signTest = CompoundTest.any(ExpectedValue.SUCCESS, "Signature tests.", signTests.toArray(new Test[0]));
supportTests.add(signTest);
ExpectedValue[] testExpects = {ExpectedValue.SUCCESS, ExpectedValue.ANY, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS, ExpectedValue.SUCCESS};
List<ExpectedValue> expects = Stream.of(testExpects).collect(Collectors.toList());
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
index e2c07da..c731416 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardDegenerateSuite.java
@@ -36,11 +36,7 @@ public class CardDegenerateSuite extends CardTestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate));
- continue;
- }
+ Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
index 0a82da3..fb24e30 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
@@ -143,15 +143,11 @@ public class CardEdgeCasesSuite extends CardTestSuite {
curves.add(EC_Store.getInstance().getObject(EC_Curve.class, "cofactor/cofactor160p4"));
Random rand = new Random();
for (EC_Curve curve : curves) {
- Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS));
- if (!key.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + curve.getId() + ".", key));
- continue;
- }
+ Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
CommandTest export = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), Result.ExpectedValue.SUCCESS);
- Test setup = runTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export));
+ Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate, export);
/*
byte[] pParam = curve.getParam(EC_Consts.PARAMETER_FP)[0];
@@ -268,11 +264,7 @@ public class CardEdgeCasesSuite extends CardTestSuite {
Arrays.sort(ps);
Arrays.sort(zeros);
- Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, secp160r1.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS));
- if (!key.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.FAILURE, "No support for " + secp160r1.getBits() + "b secp160r1.", key));
- return;
- }
+ Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, secp160r1.getBits(), EC_Consts.ALG_EC_FP), Result.ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, secp160r1.getParams(), secp160r1.flatten()), Result.ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
Test setup = CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPair setup.", key, set, generate);
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java
index 4657de0..2fd457d 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardInvalidSuite.java
@@ -40,11 +40,7 @@ public class CardInvalidSuite extends CardTestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate));
- continue;
- }
+ Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), ExpectedValue.SUCCESS);
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java
index da4c0b5..3ffe07c 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardMiscSuite.java
@@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -49,23 +50,36 @@ public class CardMiscSuite extends CardTestSuite {
}
private void testCurve(EC_Curve curve, String catName, Result.ExpectedValue expected) {
- Test allocateFirst = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
- if (!allocateFirst.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst));
- return;
- }
-
+ Test allocateFirst = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
- Test generate = setupKeypairs(curve, Result.ExpectedValue.ANY, CardConsts.KEYPAIR_BOTH);
+ Test generate = setupKeypairs(curve, Result.ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH);
Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), expected);
Test sig = CommandTest.expect(new Command.ECDSA_sign(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, CardConsts.EXPORT_FALSE, null), expected);
Test perform = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH and ECDSA.", ka, sig);
+ Function<Test[], Result> callback = (tests) -> {
+ if (!tests[0].ok()) {
+ return new Result(Result.Value.FAILURE, "Could not allocate keypairs.");
+ }
+ if (!tests[1].ok()) {
+ return new Result(Result.Value.FAILURE, "Could not set curve data.");
+ }
+ if (!tests[2].ok()) {
+ return new Result(Result.Value.FAILURE, "Could not generate keypairs.");
+ }
+ for (int i = 3; i < tests.length; i++) {
+ if (!tests[i].ok() && !(tests[i] instanceof CompoundTest)) {
+ return new Result(Result.Value.FAILURE, "ECDH or ECDSA did not work.");
+ }
+ }
+ return new Result(Result.Value.SUCCESS, "OK");
+ };
+
if (cfg.cleanup) {
Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
- doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup));
+ doTest(CompoundTest.function(callback, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup));
} else {
- doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform));
+ doTest(CompoundTest.function(callback, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform));
}
}
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
index 07b38d0..4c222cb 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTestVectorSuite.java
@@ -63,13 +63,7 @@ public class CardTestVectorSuite extends CardTestSuite {
throw new IOException("Test vector keys couldn't be located.");
}
List<Test> testVector = new LinkedList<>();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate));
- continue;
- }
-
- testVector.add(allocate);
+ testVector.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), ExpectedValue.SUCCESS));
@@ -112,12 +106,7 @@ public class CardTestVectorSuite extends CardTestSuite {
testCurves.addAll(EC_Store.getInstance().getObjects(EC_Curve.class, "brainpool").values().stream().filter((curve) -> curve.getField() == EC_Consts.ALG_EC_FP).collect(Collectors.toList()));
for (EC_Curve curve : testCurves) {
List<Test> testVector = new LinkedList<>();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate));
- continue;
- }
- testVector.add(allocate);
+ testVector.add(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS));
testVector.add(CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_BOTH), ExpectedValue.SUCCESS));
CommandTest exportLocal = CommandTest.expect(new Command.Export(this.card, CardConsts.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, EC_Consts.PARAMETER_W), ExpectedValue.ANY);
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java
index 5c35be7..ea127e0 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardTwistSuite.java
@@ -34,11 +34,7 @@ public class CardTwistSuite extends CardTestSuite {
EC_Curve curve = e.getKey();
List<EC_Key.Public> keys = e.getValue();
- Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
- if (!allocate.ok()) {
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getId() + ".", allocate));
- continue;
- }
+ Test allocate = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
Test generate = CommandTest.expect(new Command.Generate(this.card, CardConsts.KEYPAIR_LOCAL), Result.ExpectedValue.SUCCESS);
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java
index 0b030b8..605b2ec 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CardWrongSuite.java
@@ -42,24 +42,17 @@ public class CardWrongSuite extends CardTestSuite {
for (Map.Entry<String, EC_Curve> e : curves.entrySet()) {
EC_Curve curve = e.getValue();
List<Test> tests = new LinkedList<>();
- Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
- if (!key.ok()) {
- doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()), key));
- continue;
- }
- tests.add(key);
- Test set = runTest(CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE));
- Test generate = runTest(setupKeypairs(curve, ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH));
- Test setup = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", set, generate));
+ Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS);
+ Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE);
+ Test generate = setupKeypairs(curve, ExpectedValue.SUCCESS, CardConsts.KEYPAIR_BOTH);
+ Test setup = CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", key, set, generate);
tests.add(setup);
for (byte kaType : EC_Consts.KA_TYPES) {
- Test allocate = runTest(CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS));
- if (allocate.ok()) {
- Test ka = runTest(CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE));
- Test kaTest = runTest(CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka));
- tests.add(kaTest);
- }
+ Test allocate = CommandTest.expect(new Command.AllocateKeyAgreement(this.card, kaType), ExpectedValue.SUCCESS);
+ Test ka = CommandTest.expect(new Command.ECDH(this.card, CardConsts.KEYPAIR_REMOTE, CardConsts.KEYPAIR_LOCAL, CardConsts.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, kaType), ExpectedValue.FAILURE);
+ Test kaTest = CompoundTest.all(ExpectedValue.SUCCESS, "Allocate and perform KA.", allocate, ka);
+ tests.add(kaTest);
}
doTest(CompoundTest.function((tsts) -> {
for (int i = 0; i < tsts.length; ++i) {
@@ -82,11 +75,7 @@ public class CardWrongSuite extends CardTestSuite {
Random r = new Random();
for (short keyLength : EC_Consts.FP_SIZES) {
byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_FP);
- Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS));
- if (!key.ok()) {
- doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_FP.", key));
- continue;
- }
+ Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_FP), ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_FP, null), ExpectedValue.SUCCESS);
Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set);
@@ -113,7 +102,7 @@ public class CardWrongSuite extends CardTestSuite {
Test randomG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, (short) (EC_Consts.TRANSFORMATION_FULLRANDOM | EC_Consts.TRANSFORMATION_04_MASK)), "Set G = random non-point/point-like.", "ECDH with non-point G.");
Test fullRandomG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_FULLRANDOM), "Set G = random data.", "ECDH with G = random data.");
- Test zeroG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = inifnity.", "ECDH with G = infinity.");
+ Test zeroG = ecdhTest(new Command.Transform(this.card, CardConsts.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETER_G, EC_Consts.TRANSFORMATION_INFINITY), "Set G = infinity.", "ECDH with G = infinity.");
Test wrongG = CompoundTest.all(ExpectedValue.SUCCESS, "Tests with corrupted G parameter.", randomG, fullRandomG, zeroG);
byte[] originalR = EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_R);
@@ -162,11 +151,7 @@ public class CardWrongSuite extends CardTestSuite {
*/
for (short keyLength : EC_Consts.F2M_SIZES) {
byte curve = EC_Consts.getCurve(keyLength, EC_Consts.ALG_EC_F2M);
- Test key = runTest(CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_F2M), ExpectedValue.SUCCESS));
- if (!key.ok()) {
- doTest(CompoundTest.all(ExpectedValue.FAILURE, "No support for " + keyLength + "b ALG_EC_F2M.", key));
- continue;
- }
+ Test key = CommandTest.expect(new Command.Allocate(this.card, CardConsts.KEYPAIR_BOTH, keyLength, EC_Consts.ALG_EC_F2M), ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, CardConsts.KEYPAIR_BOTH, curve, EC_Consts.PARAMETERS_DOMAIN_F2M, null), ExpectedValue.SUCCESS);
Test setup = CompoundTest.all(ExpectedValue.SUCCESS, "KeyPair setup.", key, set);
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java b/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java
index f670534..7733e11 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/CommandTestable.java
@@ -6,13 +6,14 @@ import cz.crcs.ectester.reader.command.Command;
import cz.crcs.ectester.reader.response.Response;
import javax.smartcardio.CardException;
+import java.util.function.Supplier;
/**
* @author Jan Jancar johny@neuromancer.sk
*/
public class CommandTestable extends BaseTestable {
- private Command command;
- private Response response;
+ protected Command command;
+ protected Response response;
public CommandTestable(Command command) {
this.command = command;
@@ -41,4 +42,19 @@ public class CommandTestable extends BaseTestable {
ok = true;
}
}
+
+ public static class FunctionCommandTestable extends CommandTestable {
+ private Supplier<Command> supplier;
+
+ public FunctionCommandTestable(Supplier<Command> supplier) {
+ super(null);
+ this.supplier = supplier;
+ }
+
+ @Override
+ public void run() {
+ this.command = supplier.get();
+ super.run();
+ }
+ }
}
diff --git a/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java b/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java
index a725dc2..1171154 100644
--- a/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java
+++ b/reader/src/main/java/cz/crcs/ectester/reader/test/PerformanceTest.java
@@ -26,26 +26,38 @@ public class PerformanceTest extends SimpleTest<CommandTestable> {
private int count;
private String desc;
+ private PerformanceTest(CardMngr cardManager, CommandTestable testable, TestCallback<CommandTestable> callback, int count, String desc) {
+ super(testable, callback);
+ this.cardManager = cardManager;
+ this.count = count;
+ this.desc = desc;
+ }
+
private PerformanceTest(CardMngr cardManager, CommandTestable testable, int count, String desc) {
- super(testable, new TestCallback<CommandTestable>() {
+ this(cardManager, testable, new TestCallback<CommandTestable>() {
@Override
public Result apply(CommandTestable testable) {
return new Result(Result.Value.SUCCESS);
}
- });
- this.cardManager = cardManager;
- this.count = count;
- this.desc = desc;
+ }, count, desc);
}
public static PerformanceTest repeat(CardMngr cardManager, Command cmd, int count) {
return new PerformanceTest(cardManager, new CommandTestable(cmd), count, null);
}
+ public static PerformanceTest repeat(CardMngr cardManager, CommandTestable testable, int count) {
+ return new PerformanceTest(cardManager, testable, count, null);
+ }
+
public static PerformanceTest repeat(CardMngr cardManager, String desc, Command cmd, int count) {
return new PerformanceTest(cardManager, new CommandTestable(cmd), count, desc);
}
+ public static PerformanceTest repeat(CardMngr cardManager, String desc, CommandTestable testable, int count) {
+ return new PerformanceTest(cardManager, testable, count, desc);
+ }
+
@Override
public String getDescription() {
String rest = String.format("Mean = %d ns, Median = %d ns, Mode = %d ns", mean, median, mode);
diff --git a/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java
new file mode 100644
index 0000000..173f7e2
--- /dev/null
+++ b/reader/src/test/java/cz/crcs/ectester/reader/AppTests.java
@@ -0,0 +1,141 @@
+package cz.crcs.ectester.reader;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.StdIo;
+import org.junitpioneer.jupiter.StdOut;
+
+import java.time.Duration;
+
+import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class AppTests {
+
+ @Test
+ @StdIo()
+ public void help(StdOut out) {
+ ECTesterReader.main(new String[]{"-h"});
+ String s = out.capturedString();
+ assertTrue(s.contains("ECTesterReader"));
+ }
+
+ @Test
+ @StdIo()
+ public void listSuites(StdOut out) {
+ ECTesterReader.main(new String[]{"--list-suites"});
+ String s = out.capturedString();
+ assertTrue(s.contains("default test suite"));
+ }
+
+ @Test
+ @StdIo()
+ public void listData(StdOut out) {
+ ECTesterReader.main(new String[]{"--list-named"});
+ String s = out.capturedString();
+ assertTrue(s.contains("secg"));
+ }
+
+ // Add StdIo to all the suite tests when this is resolved: https://github.com/junit-pioneer/junit-pioneer/issues/822
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void defaultSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "default", "-s"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ @Disabled
+ public void testVectorSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "test-vectors", "-s"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void compressionSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "compression", "-s"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ @Disabled
+ public void wrongSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "wrong", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void degenerateSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "degenerate", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ @Disabled
+ public void cofactorSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "cofactor", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ @Disabled
+ public void compositeSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "composite", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void invalidSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "invalid", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void edgeCasesSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "edge-cases", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void signatureSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "signature", "-s"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void twistSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "twist", "-s", "-y"}));
+ }
+
+ @Test
+ @XFail(value = "JCardSim sometimes times-out.")
+ public void miscellaneousSuite() {
+ assertTimeoutPreemptively(Duration.ofSeconds(60), () -> ECTesterReader.main(new String[]{"-t", "miscellaneous", "-s", "-y"}));
+ }
+
+ @Test
+ public void generate() {
+ ECTesterReader.main(new String[]{"-g", "10", "-s", "-fp", "-o", "/dev/null", "-b", "256"});
+ }
+
+ @Test
+ public void ecdh() {
+ ECTesterReader.main(new String[]{"-dh", "-fp", "-b", "256", "-s"});
+ }
+
+ @Test
+ public void ecdsa() {
+ ECTesterReader.main(new String[]{"-dsa", "-fp", "-b", "256", "-s"});
+ }
+
+ @Test
+ public void export() {
+ ECTesterReader.main(new String[]{"-e", "-fp", "-b", "256", "-s", "-o", "/dev/null"});
+ }
+
+ @Test
+ public void info() {
+ ECTesterReader.main(new String[]{"-nf", "-s"});
+ }
+}
diff --git a/reader/src/test/java/cz/crcs/ectester/reader/XFail.java b/reader/src/test/java/cz/crcs/ectester/reader/XFail.java
new file mode 100644
index 0000000..f42f530
--- /dev/null
+++ b/reader/src/test/java/cz/crcs/ectester/reader/XFail.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016-2023 the original author or authors.
+ * Taken from https://github.com/junit-pioneer/junit-pioneer/blob/98cef28462c8b7ab66231cc5b7e8daef3b329f67/src/main/java/org/junitpioneer/jupiter/ExpectedToFail.java
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v2.0 which
+ * accompanies this distribution and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v20.html
+ */
+
+package cz.crcs.ectester.reader;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * {@code @ExpectedToFail} is a JUnit Jupiter extension to mark test methods as temporarily
+ * 'expected to fail'. Such test methods will still be executed but when they result in a test
+ * failure or error the test will be aborted. However, if the test method unexpectedly executes
+ * successfully, it is marked as failure to let the developer know that the test is now
+ * successful and that the {@code @ExpectedToFail} annotation can be removed.
+ *
+ * <p>The big difference compared to JUnit's {@link org.junit.jupiter.api.Disabled @Disabled}
+ * annotation is that the developer is informed as soon as a test is successful again.
+ * This helps to avoid creating duplicate tests by accident and counteracts the accumulation
+ * of disabled tests over time.</p>
+ *
+ * <p>Further, the {@link #withExceptions()} attribute can be used to restrict the extension's behavior
+ * to specific exceptions. That is, only if the test method ends up throwing one of the specified exceptions
+ * will the test be aborted. This can, for example, be used when the production code temporarily throws
+ * an {@link UnsupportedOperationException} because some feature has not been implemented yet, but the
+ * test method is already implemented and should not fail on a failing assertion.
+ * </p>
+ *
+ * <p>The annotation can only be used on methods and as meta-annotation on other annotation types.
+ * Similar to {@code @Disabled}, it has to be used in addition to a "testable" annotation, such
+ * as {@link org.junit.jupiter.api.Test @Test}. Otherwise the annotation has no effect.</p>
+ *
+ * <p><b>Important:</b> This annotation is <b>not</b> intended as a way to mark test methods
+ * which intentionally cause exceptions. Such test methods should use
+ * {@link org.junit.jupiter.api.Assertions#assertThrows(Class, org.junit.jupiter.api.function.Executable) assertThrows}
+ * or similar means to explicitly test for a specific exception class being thrown by a
+ * specific action.</p>
+ *
+ * <p>For more details and examples, see
+ * <a href="https://junit-pioneer.org/docs/expected-to-fail-tests/" target="_top">the documentation on <code>@ExpectedToFail</code></a>.</p>
+ *
+ * @since 1.8.0
+ * @see org.junit.jupiter.api.Disabled
+ */
+@Documented
+@Retention(RUNTIME)
+/*
+ * Only supports METHOD and ANNOTATION_TYPE as targets but not test classes because there
+ * it is not clear what the 'correct' behavior would be when only a few test methods
+ * execute successfully. Would the developer then have to remove the @ExpectedToFail annotation
+ * from the test class and annotate methods individually?
+ */
+@Target({ METHOD, ANNOTATION_TYPE })
+@ExtendWith(XFailExtension.class)
+public @interface XFail {
+
+ /**
+ * Defines the message to show when a test is aborted because it is failing.
+ * This can be used for example to briefly explain why the tested code is not working
+ * as intended at the moment.
+ * An empty string (the default) causes a generic default message to be used.
+ */
+ String value() default "";
+
+ /**
+ * Specifies which exceptions are expected to be thrown and will cause the test to be aborted rather than fail.
+ * An empty array is considered a configuration error and will cause the test to fail. Instead, consider leaving
+ * the attribute set to the default value when any exception should cause the test to be aborted.
+ */
+ Class<? extends Throwable>[] withExceptions() default { Throwable.class };
+
+} \ No newline at end of file
diff --git a/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java b/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java
new file mode 100644
index 0000000..b190e1a
--- /dev/null
+++ b/reader/src/test/java/cz/crcs/ectester/reader/XFaillExtension.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016-2023 the original author or authors.
+ * Taken from https://github.com/junit-pioneer/junit-pioneer/blob/98cef28462c8b7ab66231cc5b7e8daef3b329f67/src/main/java/org/junitpioneer/jupiter/ExpectedToFailExtension.java
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v2.0 which
+ * accompanies this distribution and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v20.html
+ */
+
+package cz.crcs.ectester.reader;
+
+import java.lang.reflect.Method;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionConfigurationException;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.InvocationInterceptor;
+import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
+import org.junit.platform.commons.support.AnnotationSupport;
+import org.opentest4j.AssertionFailedError;
+import org.opentest4j.TestAbortedException;
+
+class XFailExtension implements Extension, InvocationInterceptor {
+
+ @Override
+ public void interceptTestMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext,
+ ExtensionContext extensionContext) throws Throwable {
+ invokeAndInvertResult(invocation, extensionContext);
+ }
+
+ private static void invokeAndInvertResult(Invocation<Void> invocation, ExtensionContext extensionContext)
+ throws Throwable {
+ XFail expectedToFail = getExpectedToFailAnnotation(extensionContext);
+ if (expectedToFail.withExceptions().length == 0) {
+ throw new ExtensionConfigurationException("@XFail withExceptions must not be empty");
+ }
+
+ try {
+ invocation.proceed();
+ // at this point, the invocation succeeded, so we'd want to call `fail(...)`,
+ // but that would get handled by the following `catch` and so it's easier
+ // to instead fall through to a `fail(...)` after the `catch` block
+ }
+ catch (Throwable t) {
+ if (shouldPreserveException(t)) {
+ throw t;
+ }
+
+ if (Stream.of(expectedToFail.withExceptions()).noneMatch(clazz -> clazz.isInstance(t))) {
+ throw new AssertionFailedError(
+ "Test marked as temporarily 'expected to fail' failed with an unexpected exception", t);
+ }
+
+ String message = expectedToFail.value();
+ if (message.isEmpty()) {
+ message = "Test marked as temporarily 'expected to fail' failed as expected";
+ }
+
+ throw new TestAbortedException(message, t);
+ }
+ }
+
+ /**
+ * Returns whether the exception should be preserved and reported as is instead
+ * of considering it an 'expected to fail' exception.
+ *
+ * <p>This method is used for exceptions that abort test execution and should
+ * have higher precedence than aborted exceptions thrown by this extension.</p>
+ */
+ private static boolean shouldPreserveException(Throwable t) {
+ // Note: Ideally would use the same logic JUnit uses to determine if exception is aborting
+ // execution, see its class OpenTest4JAndJUnit4AwareThrowableCollector
+ return t instanceof TestAbortedException;
+ }
+
+ private static XFail getExpectedToFailAnnotation(ExtensionContext context) {
+ return AnnotationSupport
+ .findAnnotation(context.getRequiredTestMethod(), XFail.class)
+ .orElseThrow(() -> new IllegalStateException("@XFail is missing."));
+
+ }
+
+} \ No newline at end of file
diff --git a/standalone/build.gradle.kts b/standalone/build.gradle.kts
index 5ad3fb4..e1fc265 100644
--- a/standalone/build.gradle.kts
+++ b/standalone/build.gradle.kts
@@ -1,6 +1,7 @@
plugins {
application
jacoco
+ id("jacoco-report-aggregation")
id("com.google.osdetector") version "1.7.3"
id("com.adarshr.test-logger") version "4.0.0"
}
@@ -42,7 +43,7 @@ tasks.named<Test>("test") {
ignoreFailures = true
useJUnitPlatform()
// Report is always generated after tests run
- finalizedBy(tasks.jacocoTestReport)
+ finalizedBy(tasks.named<JacocoReport>("testCodeCoverageReport"))
if (JavaVersion.current() > JavaVersion.VERSION_1_8 && JavaVersion.current() < JavaVersion.VERSION_22) {
jvmArgs("--add-exports", "jdk.crypto.ec/sun.security.ec=ALL-UNNAMED"
@@ -61,9 +62,12 @@ tasks.named<Test>("test") {
)
}
-tasks.jacocoTestReport {
+tasks.named<JacocoReport>("testCodeCoverageReport") {
reports {
+ html.required = true
+ html.outputLocation.set(layout.buildDirectory.dir("reports/jacoco/test/html"))
xml.required = true
+ xml.outputLocation.set(layout.buildDirectory.file("reports/jacoco/test/jacocoTestReport.xml"))
}
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
index e6d8188..4f76639 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -71,7 +71,7 @@ public class ECTesterStandalone {
private ProviderECLibrary[] libs;
private Config cfg;
- private Options opts = new Options();
+ private final Options opts = new Options();
private TreeParser optParser;
private TreeCommandLine cli;
public static final String VERSION = "v0.3.3";
@@ -903,7 +903,7 @@ public class ECTesterStandalone {
*
*/
public static class Config {
- private ProviderECLibrary[] libs;
+ private final ProviderECLibrary[] libs;
public ProviderECLibrary selected = null;
public boolean color = false;
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java
index c53adb2..13a9e72 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/output/TextTestWriter.java
@@ -46,10 +46,9 @@ public class TextTestWriter extends BaseTextTestWriter {
protected String deviceString(TestSuite suite) {
if (suite instanceof StandaloneTestSuite) {
StandaloneTestSuite standaloneSuite = (StandaloneTestSuite) suite;
- StringBuilder sb = new StringBuilder();
- sb.append("═══ ").append(Colors.underline("ECTester version:")).append(" ").append(ECTesterStandalone.VERSION).append(System.lineSeparator());
- sb.append("═══ ").append(Colors.underline("Library:")).append(" ").append(standaloneSuite.getLibrary().fullName()).append(System.lineSeparator());
- return sb.toString();
+ String sb = "═══ " + Colors.underline("ECTester version:") + " " + ECTesterStandalone.VERSION + System.lineSeparator() +
+ "═══ " + Colors.underline("Library:") + " " + standaloneSuite.getLibrary().fullName() + System.lineSeparator();
+ return sb;
}
return "";
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java
index 7fd1c5a..579904c 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyAgreementTestable.java
@@ -66,7 +66,7 @@ public class KeyAgreementTestable extends StandaloneTestable<KeyAgreementTestabl
}
public KeyAgreementTestable(KeyAgreement ka, KeyGeneratorTestable privKgt, KeyGeneratorTestable pubKgt, ECParameterSpec spec) {
- this(ka, (ECPrivateKey) null, null, spec);
+ this(ka, null, (ECPublicKey) null, spec);
this.kgtPrivate = privKgt;
this.kgtPublic = pubKgt;
}
@@ -76,6 +76,37 @@ public class KeyAgreementTestable extends StandaloneTestable<KeyAgreementTestabl
this.keyAlgo = keyAlgo;
}
+ public KeyAgreementTestable(KeyAgreement ka, KeyGeneratorTestable kgt, ECPrivateKey privateKey) {
+ this(ka, privateKey, null, (ECParameterSpec) null);
+ this.kgtPublic = kgt;
+ }
+
+ public KeyAgreementTestable(KeyAgreement ka, KeyGeneratorTestable kgt, ECPrivateKey privateKey, String keyAlgo) {
+ this(ka, kgt, privateKey, (ECParameterSpec) null);
+ this.keyAlgo = keyAlgo;
+ }
+
+ public KeyAgreementTestable(KeyAgreement ka, ECPublicKey publicKey, KeyGeneratorTestable kgt) {
+ this(ka, null, publicKey, (ECParameterSpec) null);
+ this.kgtPrivate = kgt;
+ }
+
+ public KeyAgreementTestable(KeyAgreement ka, ECPublicKey publicKey, KeyGeneratorTestable kgt, String keyAlgo) {
+ this(ka, publicKey, kgt, (ECParameterSpec) null);
+ this.keyAlgo = keyAlgo;
+ }
+
+ public KeyAgreementTestable(KeyAgreement ka, KeyGeneratorTestable privKgt, KeyGeneratorTestable pubKgt) {
+ this(ka, null, (ECPublicKey) null, (ECParameterSpec) null);
+ this.kgtPrivate = privKgt;
+ this.kgtPublic = pubKgt;
+ }
+
+ public KeyAgreementTestable(KeyAgreement ka, KeyGeneratorTestable privKgt, KeyGeneratorTestable pubKgt, String keyAlgo) {
+ this(ka, privKgt, pubKgt, (ECParameterSpec) null);
+ this.keyAlgo = keyAlgo;
+ }
+
public String getKeyAlgorithm() {
return keyAlgo;
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java
index 8c49224..f35741a 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java
@@ -43,13 +43,13 @@ public class KeyGeneratorTest extends SimpleTest<KeyGeneratorTestable> {
public String getDescription() {
String params = "";
if (testable.getKeysize() != 0) {
- params = String.format("(default %d-bit curve)", testable.getKeysize());
+ params = String.format("on (default %d-bit curve)", testable.getKeysize());
} else if (testable.getSpec() instanceof ECGenParameterSpec) {
String name = ((ECGenParameterSpec)testable.getSpec()).getName();
- params = String.format("(%s)", name);
+ params = String.format("on (%s)", name);
} else if (testable.getSpec() instanceof ECParameterSpec) {
- params = "(custom curve)";
+ params = "on (custom curve)";
}
- return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " on " + params;
+ return "KeyPairGenerator " + testable.getKpg().getAlgorithm() + " " + params;
}
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/PerformanceTest.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/PerformanceTest.java
index d50c7e9..3b15c94 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/PerformanceTest.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/PerformanceTest.java
@@ -13,7 +13,7 @@ import java.util.Arrays;
*/
public class PerformanceTest extends SimpleTest<BaseTestable> {
- private ProviderECLibrary library;
+ private final ProviderECLibrary library;
private long[] times;
private long mean;
private long median;
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java
index fe81b10..76074e4 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/base/SignatureTestable.java
@@ -11,7 +11,7 @@ import java.security.interfaces.ECPublicKey;
* @author Jan Jancar johny@neuromancer.sk
*/
public class SignatureTestable extends StandaloneTestable<SignatureTestable.SignatureStage> {
- private Signature sig;
+ private final Signature sig;
private ECPrivateKey signKey;
private ECPublicKey verifyKey;
private KeyGeneratorTestable kgt;
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java
index bb9a509..003d510 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java
@@ -24,6 +24,8 @@ import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
/**
* @author David Hofman
@@ -41,29 +43,9 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite {
String kaAlgo = cli.getOptionValue("test.ka-type");
List<String> kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
}
Map<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "cofactor");
@@ -77,15 +59,6 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite {
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", generateFail));
- continue;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
List<Test> allKaTests = new LinkedList<>();
for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
@@ -94,7 +67,7 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite {
for (EC_Key.Public pub : keys) {
ECPublicKey ecpub = ECUtil.toPublicKey(pub);
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, kgt);
Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", keyAgreement));
}
@@ -104,8 +77,8 @@ public class StandaloneCofactorSuite extends StandaloneTestSuite {
if (allKaTests.isEmpty()) {
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library."));
}
- Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Cofactor test of " + curve.getId() + ".", generateSuccess, tests));
+ Test kaTests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
+ doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Cofactor test of " + curve.getId() + ".", generate, kaTests));
}
}
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java
index 839bb40..38d76bc 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneCompositeSuite.java
@@ -51,29 +51,9 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>();
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
}
KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
@@ -86,15 +66,6 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
//Generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generateFail));
- continue;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
//Perform KeyAgreement tests
List<Test> allKaTests = new LinkedList<>();
@@ -104,7 +75,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
for (EC_Key.Public pub : curveKeys.getValue()) {
ECPublicKey ecpub = ECUtil.toPublicKey(pub);
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, kgt);
Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ", with generated private key, " + pub.getDesc(), keyAgreement));
}
@@ -115,7 +86,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library."));
}
Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generateSuccess, tests));
+ doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Composite test of " + curve.getId() + ".", generate, tests));
}
@@ -164,24 +135,13 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, curve.toSpec());
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() +
- ". " + " Other tests will be skipped.", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, generateFail));
- continue;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
- ECPublicKey ecpub = (ECPublicKey) kp.getPublic();
//perform KeyAgreement tests
List<Test> kaTests = new LinkedList<>();
for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt);
kaTests.add(KeyAgreementTest.expectError(testable, dhValue));
}
}
@@ -194,7 +154,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
for (SignatureIdent sigIdent : cfg.selected.getSigs()) {
if (sigAlgo == null || sigIdent.containsAny(sigTypes)) {
Signature sig = sigIdent.getInstance(cfg.selected.getProvider());
- SignatureTestable testable = new SignatureTestable(sig, ecpriv, ecpub, null);
+ SignatureTestable testable = new SignatureTestable(sig, kgt, null);
sigTests.add(SignatureTest.expectError(testable, dhValue));
}
}
@@ -204,7 +164,7 @@ public class StandaloneCompositeSuite extends StandaloneTestSuite {
Test performKeyAgreements = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified KeyAgreements.", kaTests.toArray(new Test[0]));
Test performSignatures = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified Signatures.", sigTests.toArray(new Test[0]));
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, description, generateSuccess, performKeyAgreements, performSignatures));
+ doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, description, generate, performKeyAgreements, performSignatures));
}
}
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java
index 1c14ecc..ef9d434 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDefaultSuite.java
@@ -33,32 +33,10 @@ public class StandaloneDefaultSuite extends StandaloneTestSuite {
String sigAlgo = cli.getOptionValue("test.sig-type");
String keyAlgo = cli.getOptionValue("test.key-type", "AES");
-
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
}
-
KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
KeyGeneratorTestable kgtOne;
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java
index d822a83..5a27f95 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java
@@ -1,134 +1,16 @@
package cz.crcs.ectester.standalone.test.suites;
import cz.crcs.ectester.common.cli.TreeCommandLine;
-import cz.crcs.ectester.common.ec.EC_Curve;
-import cz.crcs.ectester.common.ec.EC_Key;
import cz.crcs.ectester.common.output.TestWriter;
-import cz.crcs.ectester.common.test.CompoundTest;
-import cz.crcs.ectester.common.test.Result;
-import cz.crcs.ectester.common.test.Test;
-import cz.crcs.ectester.common.util.ECUtil;
-import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.standalone.ECTesterStandalone;
-import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
-import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
-import cz.crcs.ectester.standalone.test.base.KeyAgreementTest;
-import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable;
-import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest;
-import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable;
-
-import javax.crypto.KeyAgreement;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.*;
/**
* @author David Hofman
*/
-public class StandaloneDegenerateSuite extends StandaloneTestSuite {
+public class StandaloneDegenerateSuite extends StandaloneForeignSuite {
public StandaloneDegenerateSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) {
super(writer, cfg, cli, "degenerate", "The degenerate suite tests whether the library rejects points outside of the curve during ECDH.",
"The tested points lie on a part of the plane for which some Edwards, Hessian and Huff form addition formulas degenerate into exponentiation in the base finite field.",
"Supports options:", "\t - gt/kpg-type", "\t - kt/ka-type (select multiple types by separating them with commas)");
}
-
- @Override
- protected void runTests() throws Exception {
- String kpgAlgo = cli.getOptionValue("test.kpg-type");
- String kaAlgo = cli.getOptionValue("test.ka-type");
- List<String> kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
-
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
- }
-
- Map<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "degenerate");
- Map<EC_Curve, List<EC_Key.Public>> curveList = EC_Store.mapKeyToCurve(pubkeys.values());
- for (Map.Entry<EC_Curve, List<EC_Key.Public>> e : curveList.entrySet()) {
- EC_Curve curve = e.getKey();
- List<EC_Key.Public> keys = e.getValue();
-
- KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
- ECParameterSpec spec = curve.toSpec();
- KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
-
- Test generateSuccess;
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp != null) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- } else {
- // If KeyPair generation fails, try generating it on named curve instead.
- ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
- KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
- Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY);
- runTest(generateOnNamedCurve);
- kp = kgtOnNamedCurve.getKeyPair();
- if (kp != null) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve);
- } else {
- // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key.
- KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
- Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
- runTest(generateOnDefaultCurve);
- kp = kgtOnDefaultCurve.getKeyPair();
- if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve);
- } else {
- Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve);
- Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateFail));
- continue;
- }
- }
- }
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
-
- List<Test> allKaTests = new LinkedList<>();
- for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
- if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
- List<Test> specificKaTests = new LinkedList<>();
- for (EC_Key.Public pub : keys) {
- ECPublicKey ecpub = ECUtil.toPublicKey(pub);
- KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
- Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
- specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " degenerate key test.", keyAgreement));
- }
- allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with degenerate public points..", specificKaTests.toArray(new Test[0])));
- }
- }
- if (allKaTests.isEmpty()) {
- allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library."));
- }
- Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Degenerate curve test of " + curve.getId() + ".", generateSuccess, tests));
- }
- }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java
index 7c46f02..d441235 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneEdgeCasesSuite.java
@@ -51,53 +51,13 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
String kaAlgo = cli.getOptionValue("test.ka-type");
String kpgAlgo = cli.getOptionValue("test.kpg-type");
- if (kaAlgo == null) {
- // try ECDH, if not, fail with: need to specify ka algo.
- Optional<KeyAgreementIdent> kaIdentOpt = cfg.selected.getKAs().stream()
- .filter((ident) -> ident.contains("ECDH"))
- .findFirst();
- if (kaIdentOpt.isPresent()) {
- kaIdent = kaIdentOpt.get();
- } else {
- System.err.println("The default KeyAgreement algorithm type of \"ECDH\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong ka algo/not found.
- Optional<KeyAgreementIdent> kaIdentOpt = cfg.selected.getKAs().stream()
- .filter((ident) -> ident.contains(kaAlgo))
- .findFirst();
- if (kaIdentOpt.isPresent()) {
- kaIdent = kaIdentOpt.get();
- } else {
- System.err.println("The KeyAgreement algorithm type of \"" + kaAlgo + "\" was not found.");
- return;
- }
+ kaIdent = getKeyAgreementIdent(kaAlgo);
+ if (kaIdent == null) {
+ return;
}
-
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
}
KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
@@ -176,20 +136,10 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() +
- ". " + " Other tests will be skipped.", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over" + curve.getId() + ".", generateFail));
- continue;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate KeyPair.", generate);
- ECPublicKey ecpub = (ECPublicKey) kp.getPublic();
//perform ECDH tests
- Test zeroS = ecdhTest(ecpub, BigInteger.ZERO, spec, "ECDH with S = 0.", Result.ExpectedValue.FAILURE);
- Test oneS = ecdhTest(ecpub, BigInteger.ONE, spec, "ECDH with S = 1.", Result.ExpectedValue.FAILURE);
+ Test zeroS = ecdhTest(kgt, BigInteger.ZERO, spec, "ECDH with S = 0.", Result.ExpectedValue.FAILURE);
+ Test oneS = ecdhTest(kgt, BigInteger.ONE, spec, "ECDH with S = 1.", Result.ExpectedValue.FAILURE);
byte[] rParam = curve.getParam(EC_Consts.PARAMETER_R)[0];
BigInteger R = new BigInteger(1, rParam);
@@ -208,14 +158,14 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
BigInteger rm1 = R.subtract(BigInteger.ONE);
BigInteger rp1 = R.add(BigInteger.ONE);
- Test alternateS = ecdhTest(ecpub, alternate, spec, "ECDH with S = 101010101...01010.", Result.ExpectedValue.SUCCESS);
- Test alternateOtherS = ecdhTest(ecpub, alternateOther, spec, "ECDH with S = 010101010...10101.", Result.ExpectedValue.SUCCESS);
- Test fullS = ecdhTest(ecpub, full, spec, "ECDH with S = 111111111...11111 (but < r).", Result.ExpectedValue.SUCCESS);
- Test smallerS = ecdhTest(ecpub, smaller, spec, "ECDH with S < r.", Result.ExpectedValue.SUCCESS);
- Test exactS = ecdhTest(ecpub, R, spec, "ECDH with S = r.", Result.ExpectedValue.FAILURE);
- Test largeS = ecdhTest(ecpub, larger, spec, "ECDH with S > r.", Result.ExpectedValue.ANY);
- Test rm1S = ecdhTest(ecpub, rm1, spec, "ECDH with S = r - 1.", Result.ExpectedValue.SUCCESS);
- Test rp1S = ecdhTest(ecpub, rp1, spec, "ECDH with S = r + 1.", Result.ExpectedValue.ANY);
+ Test alternateS = ecdhTest(kgt, alternate, spec, "ECDH with S = 101010101...01010.", Result.ExpectedValue.SUCCESS);
+ Test alternateOtherS = ecdhTest(kgt, alternateOther, spec, "ECDH with S = 010101010...10101.", Result.ExpectedValue.SUCCESS);
+ Test fullS = ecdhTest(kgt, full, spec, "ECDH with S = 111111111...11111 (but < r).", Result.ExpectedValue.SUCCESS);
+ Test smallerS = ecdhTest(kgt, smaller, spec, "ECDH with S < r.", Result.ExpectedValue.SUCCESS);
+ Test exactS = ecdhTest(kgt, R, spec, "ECDH with S = r.", Result.ExpectedValue.FAILURE);
+ Test largeS = ecdhTest(kgt, larger, spec, "ECDH with S > r.", Result.ExpectedValue.ANY);
+ Test rm1S = ecdhTest(kgt, rm1, spec, "ECDH with S = r - 1.", Result.ExpectedValue.SUCCESS);
+ Test rp1S = ecdhTest(kgt, rp1, spec, "ECDH with S = r + 1.", Result.ExpectedValue.ANY);
byte[] k = curve.getParam(EC_Consts.PARAMETER_K)[0];
BigInteger K = new BigInteger(1, k);
@@ -225,12 +175,12 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
Result.ExpectedValue kExpected = K.equals(BigInteger.ONE) ? Result.ExpectedValue.SUCCESS : Result.ExpectedValue.FAILURE;
- Test krS /*ONE!*/ = ecdhTest(ecpub, kr, spec, "ECDH with S = k * r.", Result.ExpectedValue.FAILURE);
- Test krm1S = ecdhTest(ecpub, krm1, spec, "ECDH with S = (k * r) - 1.", kExpected);
- Test krp1S = ecdhTest(ecpub, krp1, spec, "ECDH with S = (k * r) + 1.", Result.ExpectedValue.ANY);
+ Test krS /*ONE!*/ = ecdhTest(kgt, kr, spec, "ECDH with S = k * r.", Result.ExpectedValue.FAILURE);
+ Test krm1S = ecdhTest(kgt, krm1, spec, "ECDH with S = (k * r) - 1.", kExpected);
+ Test krp1S = ecdhTest(kgt, krp1, spec, "ECDH with S = (k * r) + 1.", Result.ExpectedValue.ANY);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests with edge-case private key values over " + curve.getId() + ".",
- generateSuccess, zeroS, oneS, alternateS, alternateOtherS, fullS, smallerS, exactS, largeS, rm1S, rp1S, krS, krm1S, krp1S));
+ doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Tests with edge-case private key values over " + curve.getId() + ".",
+ generate, zeroS, oneS, alternateS, alternateOtherS, fullS, smallerS, exactS, largeS, rm1S, rp1S, krS, krm1S, krp1S));
}
EC_Curve secp160r1 = EC_Store.getInstance().getObject(EC_Curve.class, "secg/secp160r1");
@@ -265,29 +215,19 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on "
- + secp160r1.getBits() + "b secp160r1." + " Other tests will be skipped.", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test private key values near zero, near p and near/larger than the order on" + secp160r1.getId() + ".", generateFail));
- return;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate KeyPair.", generate);
- ECPublicKey ecpub = (ECPublicKey) kp.getPublic();
//perform ECDH tests
Test[] zeroTests = new Test[n];
int i = 0;
for (BigInteger nearZero : zeros) {
- zeroTests[i++] = ecdhTest(ecpub, nearZero, spec, nearZero.toString(16), Result.ExpectedValue.SUCCESS);
+ zeroTests[i++] = ecdhTest(kgt, nearZero, spec, nearZero.toString(16), Result.ExpectedValue.SUCCESS);
}
Test zeroTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near zero.", zeroTests);
Test[] pTests = new Test[n];
i = 0;
for (BigInteger nearP : ps) {
- pTests[i++] = ecdhTest(ecpub, nearP, spec, nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.SUCCESS);
+ pTests[i++] = ecdhTest(kgt, nearP, spec, nearP.toString(16) + (nearP.compareTo(p) > 0 ? " (>p)" : " (<=p)"), Result.ExpectedValue.SUCCESS);
}
Test pTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near p.", pTests);
@@ -295,19 +235,19 @@ public class StandaloneEdgeCasesSuite extends StandaloneTestSuite {
i = 0;
for (BigInteger nearR : rs) {
if (nearR.compareTo(r) >= 0) {
- rTests[i++] = ecdhTest(ecpub, nearR, spec, nearR.toString(16) + " (>=r)", Result.ExpectedValue.FAILURE);
+ rTests[i++] = ecdhTest(kgt, nearR, spec, nearR.toString(16) + " (>=r)", Result.ExpectedValue.FAILURE);
} else {
- rTests[i++] = ecdhTest(ecpub, nearR, spec, nearR.toString(16) + " (<r)", Result.ExpectedValue.SUCCESS);
+ rTests[i++] = ecdhTest(kgt, nearR, spec, nearR.toString(16) + " (<r)", Result.ExpectedValue.SUCCESS);
}
}
Test rTest = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Near r.", rTests);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Test private key values near zero, near p and near/larger than the order.", generateSuccess, zeroTest, pTest, rTest));
+ doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Test private key values near zero, near p and near/larger than the order.", generate, zeroTest, pTest, rTest));
}
- private Test ecdhTest(ECPublicKey pub, BigInteger SParam, ECParameterSpec spec, String desc, Result.ExpectedValue expect) throws NoSuchAlgorithmException {
+ private Test ecdhTest(KeyGeneratorTestable kgt, BigInteger SParam, ECParameterSpec spec, String desc, Result.ExpectedValue expect) throws NoSuchAlgorithmException {
ECPrivateKey priv = new RawECPrivateKey(SParam, spec);
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, priv, pub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, priv);
return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, KeyAgreementTest.expectError(testable, expect));
}
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java
new file mode 100644
index 0000000..21431ae
--- /dev/null
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneForeignSuite.java
@@ -0,0 +1,173 @@
+package cz.crcs.ectester.standalone.test.suites;
+
+import cz.crcs.ectester.common.cli.TreeCommandLine;
+import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.ec.EC_Key;
+import cz.crcs.ectester.common.output.TestWriter;
+import cz.crcs.ectester.common.test.CompoundTest;
+import cz.crcs.ectester.common.test.Result;
+import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.common.util.ECUtil;
+import cz.crcs.ectester.data.EC_Store;
+import cz.crcs.ectester.standalone.ECTesterStandalone;
+import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
+import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
+import cz.crcs.ectester.standalone.test.base.KeyAgreementTest;
+import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable;
+import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest;
+import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable;
+
+import javax.crypto.KeyAgreement;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.util.*;
+
+public abstract class StandaloneForeignSuite extends StandaloneTestSuite {
+ private String capName;
+
+ public StandaloneForeignSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli, String name, String... description) {
+ super(writer, cfg, cli, name, description);
+ this.capName = name.substring(0, 1).toUpperCase() + name.substring(1);
+ }
+
+ @Override
+ protected void runTests() throws Exception {
+ String kpgAlgo = cli.getOptionValue("test.kpg-type");
+ String kaAlgo = cli.getOptionValue("test.ka-type");
+ List<String> kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
+
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
+ }
+
+ Map<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, this.name);
+ Map<EC_Curve, List<EC_Key.Public>> curveList = EC_Store.mapKeyToCurve(pubkeys.values());
+ for (Map.Entry<EC_Curve, List<EC_Key.Public>> e : curveList.entrySet()) {
+ EC_Curve curve = e.getKey();
+ List<EC_Key.Public> keys = e.getValue();
+ ECPublicKey singlePkey = ECUtil.toPublicKey(keys.get(0));
+
+ KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
+ ECParameterSpec spec = curve.toSpec();
+ ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
+
+ KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
+ KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
+ KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
+
+ // This is some nasty hacking...
+ KeyGeneratorTestable theKgt = new KeyGeneratorTestable(kpg) {
+ private KeyGeneratorTestable current = null;
+
+ @Override
+ public Exception getException() {
+ if (current != null) {
+ return current.getException();
+ }
+ return super.getException();
+ }
+
+ @Override
+ public KeyGeneratorStage getStage() {
+ if (current != null) {
+ return current.getStage();
+ }
+ return super.getStage();
+ }
+
+ @Override
+ public void run() {
+ stage = KeyGeneratorStage.Init;
+ kgt.run();
+ if (kgt.ok()) {
+ ok = true;
+ error = false;
+ current = kgt;
+ hasRun = true;
+ return;
+ }
+ kgtOnNamedCurve.run();
+ if (kgtOnNamedCurve.ok()) {
+ ok = true;
+ error = false;
+ current = kgtOnNamedCurve;
+ hasRun = true;
+ return;
+ }
+ kgtOnDefaultCurve.run();
+ if (kgtOnDefaultCurve.ok() && ECUtil.equalKeyPairParameters((ECPrivateKey) kgtOnDefaultCurve.getKeyPair().getPrivate(), singlePkey)) {
+ ok = true;
+ error = false;
+ current = kgtOnDefaultCurve;
+ hasRun = true;
+ }
+ }
+
+ @Override
+ public KeyPair getKeyPair() {
+ if (current != null) {
+ return current.getKeyPair();
+ }
+ return super.getKeyPair();
+ }
+
+ @Override
+ public KeyPairGenerator getKpg() {
+ if (current != null) {
+ return current.getKpg();
+ }
+ return super.getKpg();
+ }
+
+ @Override
+ public AlgorithmParameterSpec getSpec() {
+ if (current != null) {
+ return current.getSpec();
+ }
+ return super.getSpec();
+ }
+
+ @Override
+ public int getKeysize() {
+ if (current != null) {
+ return current.getKeysize();
+ }
+ return super.getKeysize();
+ }
+ };
+
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.SUCCESS);
+ Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.SUCCESS);
+ Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.SUCCESS);
+ Test generateFinal = KeyGeneratorTest.expectError(theKgt, Result.ExpectedValue.SUCCESS);
+ //generate, generateOnNamedCurve, generateOnDefaultCurve,
+ Test generateAny = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate a keypair on the standard curve.", generateFinal);
+
+ List<Test> allKaTests = new LinkedList<>();
+ for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
+ if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
+ List<Test> specificKaTests = new LinkedList<>();
+ for (EC_Key.Public pub : keys) {
+ ECPublicKey ecpub = ECUtil.toPublicKey(pub);
+ KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpub, theKgt);
+ Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
+ specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement));
+ }
+ allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with invalid public points.", specificKaTests.toArray(new Test[0])));
+ }
+ }
+ if (allKaTests.isEmpty()) {
+ allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library."));
+ }
+ Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
+ doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, this.capName + " curve test of " + curve.getId() + ".", generateAny, tests));
+ }
+ }
+}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java
index 48dfc37..d1b9a88 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java
@@ -1,133 +1,16 @@
package cz.crcs.ectester.standalone.test.suites;
import cz.crcs.ectester.common.cli.TreeCommandLine;
-import cz.crcs.ectester.common.ec.EC_Curve;
-import cz.crcs.ectester.common.ec.EC_Key;
import cz.crcs.ectester.common.output.TestWriter;
-import cz.crcs.ectester.common.test.CompoundTest;
-import cz.crcs.ectester.common.test.Result;
-import cz.crcs.ectester.common.test.Test;
-import cz.crcs.ectester.common.util.ECUtil;
-import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.standalone.ECTesterStandalone;
-import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
-import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
-import cz.crcs.ectester.standalone.test.base.KeyAgreementTest;
-import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable;
-import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest;
-import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable;
-import javax.crypto.KeyAgreement;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.*;
/**
* @author David Hofman
*/
-public class StandaloneInvalidSuite extends StandaloneTestSuite {
+public class StandaloneInvalidSuite extends StandaloneForeignSuite {
public StandaloneInvalidSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) {
super(writer, cfg, cli, "invalid", "The invalid curve suite tests whether the library rejects points outside of the curve during ECDH.",
"Supports options:", "\t - gt/kpg-type", "\t - kt/ka-type (select multiple types by separating them with commas)");
}
-
- @Override
- protected void runTests() throws Exception {
- String kpgAlgo = cli.getOptionValue("test.kpg-type");
- String kaAlgo = cli.getOptionValue("test.ka-type");
- List<String> kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
-
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
- }
-
- Map<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "invalid");
- Map<EC_Curve, List<EC_Key.Public>> curveList = EC_Store.mapKeyToCurve(pubkeys.values());
- for (Map.Entry<EC_Curve, List<EC_Key.Public>> e : curveList.entrySet()) {
- EC_Curve curve = e.getKey();
- List<EC_Key.Public> keys = e.getValue();
-
- KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
- ECParameterSpec spec = curve.toSpec();
- KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
-
- Test generateSuccess;
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp != null) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- } else {
- // If KeyPair generation fails, try generating it on named curve instead.
- ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
- KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
- Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY);
- runTest(generateOnNamedCurve);
- kp = kgtOnNamedCurve.getKeyPair();
- if (kp != null) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve);
- } else {
- // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key.
- KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
- Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
- runTest(generateOnDefaultCurve);
- kp = kgtOnDefaultCurve.getKeyPair();
- if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve);
- } else {
- Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve);
- Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateFail));
- continue;
- }
- }
- }
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
-
- List<Test> allKaTests = new LinkedList<>();
- for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
- if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
- List<Test> specificKaTests = new LinkedList<>();
- for (EC_Key.Public pub : keys) {
- ECPublicKey ecpub = ECUtil.toPublicKey(pub);
- KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
- Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
- specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " invalid key test.", keyAgreement));
- }
- allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with invalid public points.", specificKaTests.toArray(new Test[0])));
- }
- }
- if (allKaTests.isEmpty()) {
- allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library."));
- }
- Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Invalid curve test of " + curve.getId() + ".", generateSuccess, tests));
- }
- }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java
index f3a10eb..657c2ff 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneMiscSuite.java
@@ -6,6 +6,7 @@ import cz.crcs.ectester.common.output.TestWriter;
import cz.crcs.ectester.common.test.CompoundTest;
import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.Test;
+import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.standalone.ECTesterStandalone;
import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
@@ -22,6 +23,8 @@ import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.util.*;
+import static cz.crcs.ectester.common.util.ECUtil.hashCurve;
+
/**
* @author David Hofman
*/
@@ -50,30 +53,10 @@ public class StandaloneMiscSuite extends StandaloneTestSuite {
kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>();
-
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
+
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
}
KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
@@ -98,29 +81,18 @@ public class StandaloneMiscSuite extends StandaloneTestSuite {
private void testCurve(EC_Curve curve, String catName, KeyPairGenerator kpg, Result.ExpectedValue expected) throws NoSuchAlgorithmException {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, curve.toSpec());
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if(kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() +
- ". " + " Other tests will be skipped.", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", generateFail));
- return;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
- ECPublicKey ecpub = (ECPublicKey) kp.getPublic();
+ Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
//perform KeyAgreement tests
List<Test> kaTests = new LinkedList<>();
for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt);
kaTests.add(KeyAgreementTest.expectError(testable, expected));
}
}
- if(kaTests.isEmpty()) {
+ if (kaTests.isEmpty()) {
kaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified KeyAgreement types is supported by the library."));
}
@@ -129,17 +101,17 @@ public class StandaloneMiscSuite extends StandaloneTestSuite {
for (SignatureIdent sigIdent : cfg.selected.getSigs()) {
if (sigAlgo == null || sigIdent.containsAny(sigTypes)) {
Signature sig = sigIdent.getInstance(cfg.selected.getProvider());
- SignatureTestable testable = new SignatureTestable(sig, ecpriv, ecpub, null);
+ SignatureTestable testable = new SignatureTestable(sig, kgt, hashCurve(curve));
sigTests.add(SignatureTest.expectError(testable, expected));
}
}
- if(sigTests.isEmpty()) {
+ if (sigTests.isEmpty()) {
sigTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified Signature types is supported by the library."));
}
Test performKeyAgreements = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified KeyAgreements.", kaTests.toArray(new Test[0]));
Test performSignatures = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform specified Signatures.", sigTests.toArray(new Test[0]));
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", generateSuccess, performKeyAgreements, performSignatures));
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", generate, performKeyAgreements, performSignatures));
}
private void testCurves(Collection<EC_Curve> curves, String catName, KeyPairGenerator kpg, Result.ExpectedValue expected) throws NoSuchAlgorithmException {
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java
index a1b4d75..30a0c0f 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandalonePerformanceSuite.java
@@ -48,26 +48,16 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite {
List<String> sigTypes = sigAlgo != null ? Arrays.asList(sigAlgo.split(",")) : new ArrayList<>();
List<KeyPairGeneratorIdent> kpgIdents = new LinkedList<>();
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdents.add(kpgIdentOpt.get());
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- kpgIdents = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.containsAny(kpgTypes)).collect(Collectors.toList());
- if (kpgIdents.isEmpty()) {
- System.err.println("No KeyPairGenerator algorithms of specified types were found.");
- return;
+ for (String kpgChoice : kpgTypes) {
+ KeyPairGeneratorIdent ident = getKeyPairGeneratorIdent(kpgChoice);
+ if (ident != null && !kpgIdents.contains(ident)) {
+ kpgIdents.add(ident);
}
}
+ if (kpgIdents.isEmpty()) {
+ System.err.println("Need some KeyPairGenerators to be able to generate keys. Select at least one supported one using the -gt/--kpg-type option.");
+ return;
+ }
KeyGeneratorTestable kgtOne = null;
KeyGeneratorTestable kgtOther = null;
@@ -94,8 +84,8 @@ public class StandalonePerformanceSuite extends StandaloneTestSuite {
kgtOther = new KeyGeneratorTestable(kpg);
}
kpgTests.add(PerformanceTest.repeat(kgtOne, cfg.selected, kpgIdent.getName(), count));
+ kpgTests.add(PerformanceTest.repeat(kgtOther, cfg.selected, kpgIdent.getName(), count));
}
- runTest(KeyGeneratorTest.expect(kgtOther, Result.ExpectedValue.SUCCESS));
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "KeyPairGenerator performance tests", kpgTests.toArray(new Test[0])));
List<Test> kaTests = new LinkedList<>();
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java
index 8e5e452..43feb23 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneSignatureSuite.java
@@ -31,29 +31,9 @@ public class StandaloneSignatureSuite extends StandaloneTestSuite {
protected void runTests() throws Exception {
String sigAlgo = cli.getOptionValue("test.sig-type");
- SignatureIdent sigIdent;
- if (sigAlgo == null) {
- // try ECDSA, if not, fail with: need to specify sig algo.
- Optional<SignatureIdent> sigIdentOpt = cfg.selected.getSigs().stream()
- .filter((ident) -> ident.contains("ECDSA"))
- .findFirst();
- if (sigIdentOpt.isPresent()) {
- sigIdent = sigIdentOpt.get();
- } else {
- System.err.println("The default Signature algorithm type of \"ECDSA\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong sig algo/not found.
- Optional<SignatureIdent> sigIdentOpt = cfg.selected.getSigs().stream()
- .filter((ident) -> ident.contains(sigAlgo))
- .findFirst();
- if (sigIdentOpt.isPresent()) {
- sigIdent = sigIdentOpt.get();
- } else {
- System.err.println("The Signature algorithm type of \"" + sigAlgo + "\" was not found.");
- return;
- }
+ SignatureIdent sigIdent = getSignatureIdent(sigAlgo);
+ if (sigIdent == null) {
+ return;
}
Map<String, EC_SigResult> results = EC_Store.getInstance().getObjects(EC_SigResult.class, "wrong");
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java
index e4e0013..ac164e1 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTestSuite.java
@@ -4,8 +4,15 @@ import cz.crcs.ectester.common.cli.TreeCommandLine;
import cz.crcs.ectester.common.output.TestWriter;
import cz.crcs.ectester.common.test.TestSuite;
import cz.crcs.ectester.standalone.ECTesterStandalone;
+import cz.crcs.ectester.standalone.consts.Ident;
+import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
+import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
+import cz.crcs.ectester.standalone.consts.SignatureIdent;
import cz.crcs.ectester.standalone.libs.ProviderECLibrary;
+import java.util.Optional;
+import java.util.Set;
+
/**
* @author Jan Jancar johny@neuromancer.sk
*/
@@ -22,4 +29,44 @@ public abstract class StandaloneTestSuite extends TestSuite {
public ProviderECLibrary getLibrary() {
return cfg.selected;
}
+
+ private <T extends Ident> T getIdent(Set<T> options, String choice, String identName, String defaultChoice) {
+ T ident;
+ if (choice == null) {
+ // try EC, if not, fail with: need to specify kpg algo.
+ Optional<T> identOpt = options.stream()
+ .filter((i) -> i.contains(defaultChoice))
+ .findFirst();
+ if (identOpt.isPresent()) {
+ ident = identOpt.get();
+ } else {
+ System.err.printf("The default %s algorithm type of \"%s\" (default) was not found. Need to specify a type.", identName, defaultChoice);
+ return null;
+ }
+ } else {
+ // try the specified, if not, fail with: wrong kpg algo/not found.
+ Optional<T> identOpt = options.stream()
+ .filter((i) -> i.contains(choice))
+ .findFirst();
+ if (identOpt.isPresent()) {
+ ident = identOpt.get();
+ } else {
+ System.err.printf("The %s algorithm type of \"%s\" was not found.", identName, choice);
+ return null;
+ }
+ }
+ return ident;
+ }
+
+ KeyPairGeneratorIdent getKeyPairGeneratorIdent(String kpgAlgo) {
+ return getIdent(cfg.selected.getKPGs(), kpgAlgo, "KeyPairGenerator", "EC");
+ }
+
+ KeyAgreementIdent getKeyAgreementIdent(String kaAlgo) {
+ return getIdent(cfg.selected.getKAs(), kaAlgo, "KeyAgreement", "ECDH");
+ }
+
+ SignatureIdent getSignatureIdent(String sigAlgo) {
+ return getIdent(cfg.selected.getSigs(), sigAlgo, "Signature", "ECDSA");
+ }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java
index 37adbb2..1f08a80 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java
@@ -1,133 +1,15 @@
package cz.crcs.ectester.standalone.test.suites;
import cz.crcs.ectester.common.cli.TreeCommandLine;
-import cz.crcs.ectester.common.ec.EC_Curve;
-import cz.crcs.ectester.common.ec.EC_Key;
import cz.crcs.ectester.common.output.TestWriter;
-import cz.crcs.ectester.common.test.CompoundTest;
-import cz.crcs.ectester.common.test.Result;
-import cz.crcs.ectester.common.test.Test;
-import cz.crcs.ectester.common.util.ECUtil;
-import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.standalone.ECTesterStandalone;
-import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
-import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent;
-import cz.crcs.ectester.standalone.test.base.KeyAgreementTest;
-import cz.crcs.ectester.standalone.test.base.KeyAgreementTestable;
-import cz.crcs.ectester.standalone.test.base.KeyGeneratorTest;
-import cz.crcs.ectester.standalone.test.base.KeyGeneratorTestable;
-
-import javax.crypto.KeyAgreement;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.*;
/**
* @author David Hofman
*/
-public class StandaloneTwistSuite extends StandaloneTestSuite {
+public class StandaloneTwistSuite extends StandaloneForeignSuite {
public StandaloneTwistSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) {
super(writer, cfg, cli, "twist", "The twist test suite tests whether the library correctly rejects points on the quadratic twist of the curve during ECDH.",
"Supports options:", "\t - gt/kpg-type", "\t - kt/ka-type (select multiple types by separating them with commas)");
}
-
- @Override
- protected void runTests() throws Exception {
- String kpgAlgo = cli.getOptionValue("test.kpg-type");
- String kaAlgo = cli.getOptionValue("test.ka-type");
- List<String> kaTypes = kaAlgo != null ? Arrays.asList(kaAlgo.split(",")) : new ArrayList<>();
-
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
- }
-
- Map<String, EC_Key.Public> pubkeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "twist");
- Map<EC_Curve, List<EC_Key.Public>> curveList = EC_Store.mapKeyToCurve(pubkeys.values());
- for (Map.Entry<EC_Curve, List<EC_Key.Public>> e : curveList.entrySet()) {
- EC_Curve curve = e.getKey();
- List<EC_Key.Public> keys = e.getValue();
-
- KeyPairGenerator kpg = kpgIdent.getInstance(cfg.selected.getProvider());
- ECParameterSpec spec = curve.toSpec();
- KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
-
- Test generateSuccess;
- Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp != null) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- } else {
- // If KeyPair generation fails, try generating it on named curve instead.
- ECGenParameterSpec namedSpec = new ECGenParameterSpec(curve.getId());
- KeyGeneratorTestable kgtOnNamedCurve = new KeyGeneratorTestable(kpg, namedSpec);
- Test generateOnNamedCurve = KeyGeneratorTest.expectError(kgtOnNamedCurve, Result.ExpectedValue.ANY);
- runTest(generateOnNamedCurve);
- kp = kgtOnNamedCurve.getKeyPair();
- if (kp != null) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (named curve).", generateOnNamedCurve);
- } else {
- // If even the named curve generation fails, try generating with the default curve instead. Use this key only if it has the same domain parameters as our public key.
- KeyGeneratorTestable kgtOnDefaultCurve = new KeyGeneratorTestable(kpg, curve.getBits());
- Test generateOnDefaultCurve = KeyGeneratorTest.expectError(kgtOnDefaultCurve, Result.ExpectedValue.ANY);
- runTest(generateOnDefaultCurve);
- kp = kgtOnDefaultCurve.getKeyPair();
- if (kp != null && ECUtil.equalKeyPairParameters((ECPrivateKey) kp.getPrivate(), ECUtil.toPublicKey(keys.get(0)))) {
- generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair (default curve).", generateOnDefaultCurve);
- } else {
- Test generateNotEqual = CompoundTest.function(tests -> new Result(Result.Value.FAILURE, "Default parameters do not match the curve " + curve.getId()), "Default parameters do not match the curve " + curve.getId(), generateOnDefaultCurve);
- Test generateFail = CompoundTest.any(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ". " + "KeyAgreement tests will be skipped.", generate, generateOnNamedCurve, generateNotEqual);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateFail));
- continue;
- }
- }
- }
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
-
- List<Test> allKaTests = new LinkedList<>();
- for (KeyAgreementIdent kaIdent : cfg.selected.getKAs()) {
- if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
- List<Test> specificKaTests = new LinkedList<>();
- for (EC_Key.Public pub : keys) {
- ECPublicKey ecpub = ECUtil.toPublicKey(pub);
- KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
- Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
- specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " twist key test.", keyAgreement));
- }
- allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on twist.", specificKaTests.toArray(new Test[0])));
- }
- }
- if (allKaTests.isEmpty()) {
- allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "None of the specified key agreement types is supported by the library."));
- }
- Test tests = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Do tests.", allKaTests.toArray(new Test[0]));
- doTest(CompoundTest.greedyAllTry(Result.ExpectedValue.SUCCESS, "Twist test of " + curve.getId() + ".", generateSuccess, tests));
- }
- }
}
diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java
index 1aae9d5..4634ab0 100644
--- a/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java
+++ b/standalone/src/main/java/cz/crcs/ectester/standalone/test/suites/StandaloneWrongSuite.java
@@ -50,54 +50,15 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
String kaAlgo = cli.getOptionValue("test.ka-type");
boolean skip = cli.getArg(1).equalsIgnoreCase("-skip");
- KeyPairGeneratorIdent kpgIdent;
- if (kpgAlgo == null) {
- // try EC, if not, fail with: need to specify kpg algo.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The default KeyPairGenerator algorithm type of \"EC\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong kpg algo/not found.
- Optional<KeyPairGeneratorIdent> kpgIdentOpt = cfg.selected.getKPGs().stream()
- .filter((ident) -> ident.contains(kpgAlgo))
- .findFirst();
- if (kpgIdentOpt.isPresent()) {
- kpgIdent = kpgIdentOpt.get();
- } else {
- System.err.println("The KeyPairGenerator algorithm type of \"" + kpgAlgo + "\" was not found.");
- return;
- }
+ KeyPairGeneratorIdent kpgIdent = getKeyPairGeneratorIdent(kpgAlgo);
+ if (kpgIdent == null) {
+ return;
}
kpg = kpgIdent.getInstance(cfg.selected.getProvider());
- if (kaAlgo == null) {
- // try ECDH, if not, fail with: need to specify ka algo.
- Optional<KeyAgreementIdent> kaIdentOpt = cfg.selected.getKAs().stream()
- .filter((ident) -> ident.contains("ECDH"))
- .findFirst();
- if (kaIdentOpt.isPresent()) {
- kaIdent = kaIdentOpt.get();
- } else {
- System.err.println("The default KeyAgreement algorithm type of \"ECDH\" was not found. Need to specify a type.");
- return;
- }
- } else {
- // try the specified, if not, fail with: wrong ka algo/not found.
- Optional<KeyAgreementIdent> kaIdentOpt = cfg.selected.getKAs().stream()
- .filter((ident) -> ident.contains(kaAlgo))
- .findFirst();
- if (kaIdentOpt.isPresent()) {
- kaIdent = kaIdentOpt.get();
- } else {
- System.err.println("The KeyAgreement algorithm type of \"" + kaAlgo + "\" was not found.");
- return;
- }
+ kaIdent = getKeyAgreementIdent(kaAlgo);
+ if (kaIdent == null) {
+ return;
}
/* Just do the default run on the wrong curves.
@@ -108,29 +69,18 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
for (Map.Entry<String, EC_Curve> e : wrongCurves.entrySet()) {
EC_Curve curve = e.getValue();
- ECParameterSpec spec = curve.toSpec();
+ ECParameterSpec spec = toCustomSpec(curve);
String type = curve.getField() == javacard.security.KeyPair.ALG_EC_FP ? "FP" : "F2M";
//try generating a keypair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.ANY);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- Test generateFail = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generating KeyPair has failed on " + curve.getId() + ".", generate);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Wrong curve test of " + curve.getBits()
- + "b " + type + ". " + curve.getDesc(), generateFail));
- continue;
- }
- Test generateSuccess = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Generate keypair.", generate);
- ECPrivateKey ecpriv = (ECPrivateKey) kp.getPrivate();
- ECPublicKey ecpub = (ECPublicKey) kp.getPublic();
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt);
Test ecdh = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
- doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Wrong curve test of " + curve.getBits()
- + "b " + type + ". " + curve.getDesc(), generateSuccess, ecdh));
+ doTest(CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, "Wrong curve test of " + curve.getBits()
+ + "b " + type + ". " + curve.getDesc(), generate, ecdh));
}
}
@@ -264,7 +214,7 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
ByteUtil.shortToBytes((short) 0),
ByteUtil.shortToBytes((short) 0)};
curve.setParam(EC_Consts.PARAMETER_F2M, coeffBytes);
- Test coeff0 = ecdhTest(toCustomSpec(curve), "ECDH with wrong field polynomial: x^");
+ Test coeff0 = ecdhTest(toCustomSpec(curve), "ECDH with wrong field polynomial: 0");
short e1 = (short) (2 * bits);
short e2 = (short) (3 * bits);
@@ -285,50 +235,17 @@ public class StandaloneWrongSuite extends StandaloneTestSuite {
//generate KeyPair
KeyGeneratorTestable kgt = new KeyGeneratorTestable(kpg, spec);
Test generate = KeyGeneratorTest.expectError(kgt, Result.ExpectedValue.FAILURE);
- runTest(generate);
- KeyPair kp = kgt.getKeyPair();
- if (kp == null) {
- return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate);
- }
- ECPublicKey pub = (ECPublicKey) kp.getPublic();
- ECPrivateKey priv = (ECPrivateKey) kp.getPrivate();
//perform ECDH
KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
- KeyAgreementTestable testable = new KeyAgreementTestable(ka, priv, pub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, kgt, kgt);
Test ecdh = KeyAgreementTest.expect(testable, Result.ExpectedValue.FAILURE);
- return CompoundTest.all(Result.ExpectedValue.SUCCESS, desc, generate, ecdh);
- }
-
- //constructs EllipticCurve from EC_Curve even if the parameters of the curve are wrong
- private EllipticCurve toCustomCurve(EC_Curve curve) {
- ECField field;
- if (curve.getField() == javacard.security.KeyPair.ALG_EC_FP) {
- field = new CustomECFieldFp(new BigInteger(1, curve.getData(0)));
- } else {
- byte[][] fieldData = curve.getParam(EC_Consts.PARAMETER_F2M);
- int m = ByteUtil.getShort(fieldData[0], 0);
- int e1 = ByteUtil.getShort(fieldData[1], 0);
- int e2 = ByteUtil.getShort(fieldData[2], 0);
- int e3 = ByteUtil.getShort(fieldData[3], 0);
- int[] powers;
- if (e2 == 0 && e3 == 0) {
- powers = new int[]{e1};
- } else {
- powers = new int[]{e1, e2, e3};
- }
- field = new CustomECFieldF2m(m, powers);
- }
-
- BigInteger a = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_A)[0]);
- BigInteger b = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_B)[0]);
-
- return new CustomEllipticCurve(field, a, b);
+ return CompoundTest.function(CompoundTest.EXPECT_ALL_SUCCESS, CompoundTest.RUN_ALL_IF_FIRST, desc, generate, ecdh);
}
//constructs ECParameterSpec from EC_Curve even if the parameters of the curve are wrong
private ECParameterSpec toCustomSpec(EC_Curve curve) {
- EllipticCurve customCurve = toCustomCurve(curve);
+ EllipticCurve customCurve = curve.toCustomCurve();
byte[][] G = curve.getParam(EC_Consts.PARAMETER_G);
BigInteger gx = new BigInteger(1, G[0]);
diff --git a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp
index c5bc5f1..4227997 100644
--- a/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp
+++ b/standalone/src/main/resources/cz/crcs/ectester/standalone/libs/jni/botan.cpp
@@ -496,11 +496,16 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig
emsa = "EMSA1(SHA-512)";
}
+ Botan::Signature_Format sigformat = Botan::Signature_Format::DER_SEQUENCE;
+ if (type_str.find("ECKCDSA") != std::string::npos) {
+ sigformat = Botan::Signature_Format::IEEE_1363;
+ }
+
jsize data_length = env->GetArrayLength(data);
jbyte *data_bytes = env->GetByteArrayElements(data, nullptr);
std::vector<uint8_t> sig;
try {
- Botan::PK_Signer signer(*skey, rng, emsa, Botan::DER_SEQUENCE);
+ Botan::PK_Signer signer(*skey, rng, emsa, sigformat);
native_timing_start();
sig = signer.sign_message((uint8_t*) data_bytes, data_length, rng);
@@ -581,6 +586,11 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
emsa = "EMSA1(SHA-512)";
}
+ Botan::Signature_Format sigformat = Botan::Signature_Format::DER_SEQUENCE;
+ if (type_str.find("ECKCDSA") != std::string::npos) {
+ sigformat = Botan::Signature_Format::IEEE_1363;
+ }
+
jsize data_length = env->GetArrayLength(data);
jsize sig_length = env->GetArrayLength(signature);
jbyte *data_bytes = env->GetByteArrayElements(data, nullptr);
@@ -589,7 +599,7 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
bool result;
try {
- Botan::PK_Verifier verifier(*pkey, emsa, Botan::DER_SEQUENCE);
+ Botan::PK_Verifier verifier(*pkey, emsa, sigformat);
native_timing_start();
result = verifier.verify_message((uint8_t*)data_bytes, data_length, (uint8_t*)sig_bytes, sig_length);