aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java22
-rw-r--r--src/cz/crcs/ectester/standalone/consts/Ident.java14
-rw-r--r--src/cz/crcs/ectester/standalone/test/base/KeyAgreementTest.java10
-rw-r--r--src/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java10
-rw-r--r--src/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java109
-rw-r--r--src/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java109
-rw-r--r--src/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java108
-rw-r--r--src/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java108
8 files changed, 482 insertions, 8 deletions
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index f5686b2..072926c 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -39,9 +39,7 @@ import cz.crcs.ectester.standalone.libs.*;
import cz.crcs.ectester.standalone.output.TextTestWriter;
import cz.crcs.ectester.standalone.output.XMLTestWriter;
import cz.crcs.ectester.standalone.output.YAMLTestWriter;
-import cz.crcs.ectester.standalone.test.suites.StandaloneDefaultSuite;
-import cz.crcs.ectester.standalone.test.suites.StandaloneTestSuite;
-import cz.crcs.ectester.standalone.test.suites.StandaloneTestVectorSuite;
+import cz.crcs.ectester.standalone.test.suites.*;
import org.apache.commons.cli.*;
import javax.crypto.KeyAgreement;
@@ -314,7 +312,11 @@ public class ECTesterStandalone {
private void listSuites() {
StandaloneTestSuite[] suites = new StandaloneTestSuite[]{
new StandaloneDefaultSuite(null, null, null),
- new StandaloneTestVectorSuite(null, null, null)};
+ new StandaloneTestVectorSuite(null, null, null),
+ new StandaloneInvalidSuite(null, null, null),
+ new StandaloneDegenerateSuite(null, null, null),
+ new StandaloneCofactorSuite(null, null, null),
+ new StandaloneTwistSuite(null, null, null)};
for (StandaloneTestSuite suite : suites) {
System.out.println(" - " + suite.getName());
for (String line : suite.getDescription()) {
@@ -748,6 +750,18 @@ public class ECTesterStandalone {
case "test-vectors":
suite = new StandaloneTestVectorSuite(writer, cfg, cli);
break;
+ case "degenerate":
+ suite = new StandaloneDegenerateSuite(writer, cfg, cli);
+ break;
+ case "cofactor":
+ suite = new StandaloneCofactorSuite(writer, cfg, cli);
+ break;
+ case "invalid":
+ suite = new StandaloneInvalidSuite(writer, cfg, cli);
+ break;
+ case "twist":
+ suite = new StandaloneTwistSuite(writer, cfg, cli);
+ break;
case "default":
default:
suite = new StandaloneDefaultSuite(writer, cfg, cli);
diff --git a/src/cz/crcs/ectester/standalone/consts/Ident.java b/src/cz/crcs/ectester/standalone/consts/Ident.java
index 1c7a962..fcc811d 100644
--- a/src/cz/crcs/ectester/standalone/consts/Ident.java
+++ b/src/cz/crcs/ectester/standalone/consts/Ident.java
@@ -2,10 +2,7 @@ package cz.crcs.ectester.standalone.consts;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.*;
import java.util.function.BiFunction;
public abstract class Ident {
@@ -31,6 +28,15 @@ public abstract class Ident {
return name.equals(other) || idents.contains(other);
}
+ public boolean containsAny(List<String> others) {
+ for(String other : others) {
+ if(name.equals(other) || idents.contains(other)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
<T> T getInstance(BiFunction<String, Provider, T> getter, Provider provider) throws NoSuchAlgorithmException {
T instance = null;
try {
diff --git a/src/cz/crcs/ectester/standalone/test/base/KeyAgreementTest.java b/src/cz/crcs/ectester/standalone/test/base/KeyAgreementTest.java
index bfd39fc..fd48212 100644
--- a/src/cz/crcs/ectester/standalone/test/base/KeyAgreementTest.java
+++ b/src/cz/crcs/ectester/standalone/test/base/KeyAgreementTest.java
@@ -37,6 +37,16 @@ public class KeyAgreementTest extends SimpleTest<KeyAgreementTestable> {
});
}
+ public static KeyAgreementTest expectError(KeyAgreementTestable ka, Result.ExpectedValue expected) {
+ return new KeyAgreementTest(ka, new TestCallback<KeyAgreementTestable>() {
+ @Override
+ public Result apply(KeyAgreementTestable keyAgreementTestable) {
+ Result.Value value = Result.Value.fromExpected(expected, keyAgreementTestable.ok(), false);
+ return new Result(value, value.description());
+ }
+ });
+ }
+
public static KeyAgreementTest function(KeyAgreementTestable ka, TestCallback<KeyAgreementTestable> callback) {
return new KeyAgreementTest(ka, callback);
}
diff --git a/src/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java b/src/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java
index b232456..32f82cb 100644
--- a/src/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java
+++ b/src/cz/crcs/ectester/standalone/test/base/KeyGeneratorTest.java
@@ -22,6 +22,16 @@ public class KeyGeneratorTest extends SimpleTest<KeyGeneratorTestable> {
});
}
+ public static KeyGeneratorTest expectError(KeyGeneratorTestable kg, Result.ExpectedValue expected) {
+ return new KeyGeneratorTest(kg, new TestCallback<KeyGeneratorTestable>() {
+ @Override
+ public Result apply(KeyGeneratorTestable keyGenerationTestable) {
+ Result.Value value = Result.Value.fromExpected(expected, keyGenerationTestable.ok(), false);
+ return new Result(value, value.description());
+ }
+ });
+ }
+
public static KeyGeneratorTest function(KeyGeneratorTestable ka, TestCallback<KeyGeneratorTestable> callback) {
return new KeyGeneratorTest(ka, callback);
}
diff --git a/src/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java b/src/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java
new file mode 100644
index 0000000..92a89fe
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/test/suites/StandaloneCofactorSuite.java
@@ -0,0 +1,109 @@
+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.ECParameterSpec;
+import java.util.*;
+
+public class StandaloneCofactorSuite extends StandaloneTestSuite {
+ public StandaloneCofactorSuite(TestWriter writer, ECTesterStandalone.Config cfg, TreeCommandLine cli) {
+ super(writer, cfg, cli, "cofactor", "The cofactor test suite tests whether the library correctly rejects points on the curve",
+ "but not in the subgroup generated by the generator (so of small order, dividing the cofactor) 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, "cofactor");
+ 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 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()) {
+ if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
+ KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
+
+ List<Test> specificKaTests = new LinkedList<>();
+ for (EC_Key.Public pub : keys) {
+ ECPublicKey ecpub = ECUtil.toPublicKey(pub);
+ KeyAgreementTestable testable = new KeyAgreementTestable(ka, ecpriv, ecpub);
+ Test keyAgreement = KeyAgreementTest.expectError(testable, Result.ExpectedValue.FAILURE);
+ specificKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, pub.getId() + " cofactor key test.", keyAgreement));
+ }
+ allKaTests.add(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform " + kaIdent.getName() + " with public points on non-generator subgroup.", 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, "Cofactor test of " + curve.getId() + ".", generateSuccess, tests));
+ }
+ }
+}
diff --git a/src/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java b/src/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java
new file mode 100644
index 0000000..5024bb7
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/test/suites/StandaloneDegenerateSuite.java
@@ -0,0 +1,109 @@
+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.ECParameterSpec;
+import java.util.*;
+
+public class StandaloneDegenerateSuite extends StandaloneTestSuite {
+ 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 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, "Degenerate curve 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()) {
+ if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
+ KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
+
+ List<Test> specificKaTests = new LinkedList<>();
+ for (EC_Key.Public pub : keys) {
+ ECPublicKey ecpub = ECUtil.toPublicKey(pub);
+ 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/src/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java b/src/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java
new file mode 100644
index 0000000..47e939e
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/test/suites/StandaloneInvalidSuite.java
@@ -0,0 +1,108 @@
+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.ECParameterSpec;
+import java.util.*;
+
+public class StandaloneInvalidSuite extends StandaloneTestSuite {
+ 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 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, "Invalid curve 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()) {
+ if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
+ KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
+
+ List<Test> specificKaTests = new LinkedList<>();
+ for (EC_Key.Public pub : keys) {
+ ECPublicKey ecpub = ECUtil.toPublicKey(pub);
+ 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/src/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java b/src/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java
new file mode 100644
index 0000000..0e410a0
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/test/suites/StandaloneTwistSuite.java
@@ -0,0 +1,108 @@
+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.ECParameterSpec;
+import java.util.*;
+
+public class StandaloneTwistSuite extends StandaloneTestSuite {
+ 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 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, "Twist 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()) {
+ if (kaAlgo == null || kaIdent.containsAny(kaTypes)) {
+ KeyAgreement ka = kaIdent.getInstance(cfg.selected.getProvider());
+
+ List<Test> specificKaTests = new LinkedList<>();
+ for (EC_Key.Public pub : keys) {
+ ECPublicKey ecpub = ECUtil.toPublicKey(pub);
+ 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));
+ }
+ }
+}