aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-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/output/BaseYAMLTestWriter.java2
-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--common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java10
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/util/Util.java23
9 files changed, 201 insertions, 82 deletions
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/output/BaseYAMLTestWriter.java b/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java
index c3a42ea..e9efbc1 100644
--- a/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java
+++ b/common/src/main/java/cz/crcs/ectester/common/output/BaseYAMLTestWriter.java
@@ -125,6 +125,6 @@ public abstract class BaseYAMLTestWriter implements TestWriter {
String out = yaml.dump(result);
output.println(out);
- output.println("---");
+ output.println("...");
}
}
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/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java
index da682b6..734e957 100644
--- a/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java
+++ b/common/src/main/java/cz/crcs/ectester/common/util/FileUtil.java
@@ -44,16 +44,20 @@ public class FileUtil {
if (System.getProperty("os.name").startsWith("Windows")) {
appData = Paths.get(System.getenv("AppData"));
+ return appData;
} else {
if (System.getProperty("os.name").startsWith("Linux")) {
String dataHome = System.getenv("XDG_DATA_HOME");
if (dataHome != null) {
appData = Paths.get(dataHome);
- } else {
- appData = Paths.get(System.getProperty("user.home"), ".local", "share");
+ return appData;
}
+ }
+ String userHome = System.getProperty("user.home");
+ if (userHome != null && !userHome.equals("?")) {
+ appData = Paths.get(userHome, ".local", "share");
} else {
- appData = Paths.get(System.getProperty("user.home"), ".local", "share");
+ appData = Paths.get(System.getenv("HOME"), ".local", "share");
}
}
return appData;
diff --git a/common/src/main/java/cz/crcs/ectester/common/util/Util.java b/common/src/main/java/cz/crcs/ectester/common/util/Util.java
index 5b0cd79..1d9bcf4 100644
--- a/common/src/main/java/cz/crcs/ectester/common/util/Util.java
+++ b/common/src/main/java/cz/crcs/ectester/common/util/Util.java
@@ -1,5 +1,8 @@
package cz.crcs.ectester.common.util;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
/**
* @author Jan Jancar johny@neuromancer.sk
*/
@@ -18,11 +21,25 @@ public class Util {
public static int getVersion() {
String version = System.getProperty("java.version");
- if(version.startsWith("1.")) {
+ if (version.startsWith("1.")) {
version = version.substring(2, 3);
} else {
int dot = version.indexOf(".");
- if(dot != -1) { version = version.substring(0, dot); }
- } return Integer.parseInt(version);
+ if (dot != -1) {
+ version = version.substring(0, dot);
+ }
+ }
+ return Integer.parseInt(version);
+ }
+
+ public static SecureRandom getRandom(byte[] seed) {
+ SecureRandom random;
+ try {
+ random = SecureRandom.getInstance("SHA1PRNG");
+ } catch (NoSuchAlgorithmException ignored) {
+ return null;
+ }
+ random.setSeed(seed);
+ return random;
}
}