diff options
| author | J08nY | 2025-01-30 16:00:21 +0100 |
|---|---|---|
| committer | J08nY | 2025-01-30 16:00:21 +0100 |
| commit | 08623da26afae75aeeb66a13fd36c173ddcd40ce (patch) | |
| tree | c2cae1c21f109300300dce3e2068795078fd62fa | |
| parent | 79a611acbc2f22023ebe2ee25372de3ef40c3dbc (diff) | |
| download | ECTester-08623da26afae75aeeb66a13fd36c173ddcd40ce.tar.gz ECTester-08623da26afae75aeeb66a13fd36c173ddcd40ce.tar.zst ECTester-08623da26afae75aeeb66a13fd36c173ddcd40ce.zip | |
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."); } } |
