aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/ec/EC_Data.java1
-rw-r--r--common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java63
-rw-r--r--common/src/test/java/cz/crcs/ectester/common/ParamSerializationTests.java33
-rw-r--r--reader/src/main/java/cz/crcs/ectester/reader/command/Command.java7
4 files changed, 103 insertions, 1 deletions
diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Data.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Data.java
index 14ae1c5..8a46553 100644
--- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Data.java
+++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Data.java
@@ -152,6 +152,7 @@ public abstract class EC_Data implements Comparable<EC_Data> {
return false;
}
short paramLength = ByteUtil.getShort(bytes, offset);
+ System.out.println("paramLength: " + paramLength);
offset += 2;
if (bytes.length < offset + paramLength) {
return false;
diff --git a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java
index 146c8d6..8d15437 100644
--- a/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java
+++ b/common/src/main/java/cz/crcs/ectester/common/ec/EC_Params.java
@@ -1,6 +1,7 @@
package cz.crcs.ectester.common.ec;
import cz.crcs.ectester.common.util.ByteUtil;
+import cz.crcs.ectester.common.util.CardUtil;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
@@ -202,6 +203,68 @@ public class EC_Params extends EC_Data {
return (out.size() == 0) ? null : out.toByteArray();
}
+ public boolean inflate(byte[] flattened) {
+ short paramMask = EC_Consts.PARAMETER_FP;
+ int i = 0;
+ int offset = 0;
+ while (paramMask <= EC_Consts.PARAMETER_S) {
+ short masked = (short) (this.params & paramMask);
+ if (masked != 0) {
+ short length = ByteUtil.getShort(flattened, offset);
+ offset += 2;
+ byte[] param = new byte[length];
+ System.arraycopy(flattened, offset, param, 0, length);
+ offset += length;
+ //System.out.println(CardUtil.getParams(masked) + " Length: " + length + " Param: " + ByteUtil.bytesToHex(param, false));
+ //System.out.println();
+ if (masked == EC_Consts.PARAMETER_F2M) {
+ data[i] = new byte[2];
+ data[i + 1] = new byte[2];
+ data[i + 2] = new byte[2];
+ data[i + 3] = new byte[2];
+ if (length == 4) {
+ // only m and e_1, other e are zero
+ System.arraycopy(param, 0, data[i], 0, 2);
+ System.arraycopy(param, 2, data[i + 1], 0, 2);
+ } else if (length == 8) {
+ // all m, e_1, e_2, e_3 are specified
+ System.arraycopy(param, 0, data[i], 0, 2);
+ System.arraycopy(param, 2, data[i + 1], 0, 2);
+ System.arraycopy(param, 4, data[i + 2], 0, 2);
+ System.arraycopy(param, 6, data[i + 3], 0, 2);
+ }
+ } else if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) {
+ if ((length - 1) % 2 != 0) {
+ return false;
+ }
+ int half = (length - 1) / 2;
+ data[i] = new byte[half];
+ data[i + 1] = new byte[half];
+ System.arraycopy(param, 1, data[i], 0, half);
+ System.arraycopy(param, 1 + half, data[i + 1], 0, half);
+ } else {
+ data[i] = param;
+ }
+ }
+
+ if (masked == EC_Consts.PARAMETER_F2M) {
+ i += 4;
+ } else if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) {
+ i += 2;
+ } else if (masked != 0) {
+ i++;
+ }
+ paramMask = (short) (paramMask << 1);
+ }
+ return true;
+ }
+
+ public static EC_Params inflate(short params, byte[] flattened) {
+ EC_Params p = new EC_Params(params);
+ p.inflate(flattened);
+ return p;
+ }
+
@Override
public String[] expand() {
List<String> out = new ArrayList<>();
diff --git a/common/src/test/java/cz/crcs/ectester/common/ParamSerializationTests.java b/common/src/test/java/cz/crcs/ectester/common/ParamSerializationTests.java
new file mode 100644
index 0000000..f1fe5e9
--- /dev/null
+++ b/common/src/test/java/cz/crcs/ectester/common/ParamSerializationTests.java
@@ -0,0 +1,33 @@
+package cz.crcs.ectester.common;
+
+import cz.crcs.ectester.common.ec.EC_Category;
+import cz.crcs.ectester.common.ec.EC_Data;
+import cz.crcs.ectester.common.ec.EC_Params;
+import cz.crcs.ectester.data.EC_Store;
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ParamSerializationTests {
+
+ @Test
+ public void test() {
+ EC_Store store = EC_Store.getInstance();
+ Map<String, EC_Category> categories = store.getCategories();
+
+ for (EC_Category category : categories.values()) {
+ Map<String, EC_Data> objects = category.getObjects();
+ for (EC_Data object : objects.values()) {
+ if (object instanceof EC_Params) {
+ EC_Params params = (EC_Params) object;
+ byte[] serialized = params.flatten();
+ EC_Params deserialized = new EC_Params(params.getId(), params.getParams());
+ deserialized.inflate(serialized);
+ assertEquals(params, deserialized, "Category: " + category.getName() + ", Params: " + params.getId());
+ }
+ }
+ }
+ }
+}
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 451dda0..71ba599 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
@@ -373,13 +373,18 @@ public abstract class Command implements Cloneable {
System.arraycopy(external, 0, data, 2, external.length);
if ((params & EC_Consts.PARAMETER_FP) != 0) {
EC_Params par = new EC_Params(params);
- par.readBytes(external);
+ boolean read = par.inflate(external);
+ if (!read) {
+ throw new IllegalArgumentException("External curve data does not match parameters.");
+ }
byte[][] prime = par.getParam(EC_Consts.PARAMETER_FP);
byte[] p = prime[0];
int bytes = p.length;
if ((params & EC_Consts.PARAMETER_G) != 0) {
byte[][] generator = par.getParam(EC_Consts.PARAMETER_G);
if (generator[0].length != bytes || generator[1].length != bytes) {
+ System.err.println("Generator x length: " + generator[0].length + " vs " + bytes);
+ System.err.println("Generator y length: " + generator[1].length + " vs " + bytes);
throw new IllegalArgumentException("Generator point does not match prime field size.");
}
}