diff options
| author | J08nY | 2018-01-23 17:31:15 +0100 |
|---|---|---|
| committer | J08nY | 2018-01-23 17:31:15 +0100 |
| commit | cb6c6b8b1274fe5a340c4317a4b015ea0ef15396 (patch) | |
| tree | 864a54dcdf07da33cd139312c8b0ee693e1a0eff /src/cz/crcs/ectester/common/ec | |
| parent | 6c46a27a52854aee24f7a37e74002bd6f4485723 (diff) | |
| parent | c581e39e539e6dadb49d9f83f563ab2b375f6e0b (diff) | |
| download | ECTester-0.2.0.tar.gz ECTester-0.2.0.tar.zst ECTester-0.2.0.zip | |
Merge branch 'devel'v0.2.0
Diffstat (limited to '')
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Category.java (renamed from src/cz/crcs/ectester/reader/ec/EC_Category.java) | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Curve.java | 132 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Data.java (renamed from src/cz/crcs/ectester/reader/ec/EC_Data.java) | 41 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_KAResult.java (renamed from src/cz/crcs/ectester/reader/ec/EC_KAResult.java) | 22 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Key.java (renamed from src/cz/crcs/ectester/reader/ec/EC_Key.java) | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Keypair.java (renamed from src/cz/crcs/ectester/reader/ec/EC_Keypair.java) | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/common/ec/EC_Params.java (renamed from src/cz/crcs/ectester/reader/ec/EC_Params.java) | 69 |
7 files changed, 232 insertions, 38 deletions
diff --git a/src/cz/crcs/ectester/reader/ec/EC_Category.java b/src/cz/crcs/ectester/common/ec/EC_Category.java index 41cbad8..32a788d 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Category.java +++ b/src/cz/crcs/ectester/common/ec/EC_Category.java @@ -1,4 +1,4 @@ -package cz.crcs.ectester.reader.ec; +package cz.crcs.ectester.common.ec; import java.util.Collections; import java.util.Map; diff --git a/src/cz/crcs/ectester/common/ec/EC_Curve.java b/src/cz/crcs/ectester/common/ec/EC_Curve.java new file mode 100644 index 0000000..173fd29 --- /dev/null +++ b/src/cz/crcs/ectester/common/ec/EC_Curve.java @@ -0,0 +1,132 @@ +package cz.crcs.ectester.common.ec; + +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.common.util.ByteUtil; +import javacard.security.KeyPair; + +import java.math.BigInteger; +import java.security.spec.*; + +/** + * An Elliptic curve, contains parameters Fp/F2M, A, B, G, R, (K)?. + * + * @author Jan Jancar johny@neuromancer.sk + */ +public class EC_Curve extends EC_Params { + private short bits; + private byte field; + private String desc; + + /** + * @param bits + * @param field KeyPair.ALG_EC_FP or KeyPair.ALG_EC_F2M + */ + public EC_Curve(short bits, byte field) { + super(field == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M); + this.bits = bits; + this.field = field; + } + + public EC_Curve(String id, short bits, byte field) { + this(bits, field); + this.id = id; + } + + public EC_Curve(String id, short bits, byte field, String desc) { + this(id, bits, field); + this.desc = desc; + } + + public short getBits() { + return bits; + } + + public byte getField() { + return field; + } + + public String getDesc() { + return desc; + } + + @Override + public String toString() { + return "<" + getId() + "> " + (field == KeyPair.ALG_EC_FP ? "Prime" : "Binary") + " field Elliptic curve (" + String.valueOf(bits) + "b)" + (desc == null ? "" : ": " + desc); + } + + public ECParameterSpec toSpec() { + ECField field; + if (this.field == KeyPair.ALG_EC_FP) { + field = new ECFieldFp(new BigInteger(1, getData(0))); + } 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 = new int[]{e1, e2, e3}; + field = new ECFieldF2m(m, powers); + } + + BigInteger a = new BigInteger(1, getParam(EC_Consts.PARAMETER_A)[0]); + BigInteger b = new BigInteger(1, getParam(EC_Consts.PARAMETER_B)[0]); + + EllipticCurve curve = new EllipticCurve(field, a, b); + + byte[][] G = getParam(EC_Consts.PARAMETER_G); + BigInteger gx = new BigInteger(1, G[0]); + BigInteger gy = new BigInteger(1, G[1]); + ECPoint generator = new ECPoint(gx, gy); + + BigInteger n = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]); + + int h = ByteUtil.getShort(getParam(EC_Consts.PARAMETER_K)[0], 0); + + return new ECParameterSpec(curve, generator, n, h); + } + + public static EC_Curve fromSpec(ECParameterSpec spec) { + EllipticCurve curve = spec.getCurve(); + ECField field = curve.getField(); + + short bits = (short) field.getFieldSize(); + byte[][] params; + int paramIndex = 0; + byte fieldType; + if (field instanceof ECFieldFp) { + ECFieldFp primeField = (ECFieldFp) field; + params = new byte[7][]; + params[paramIndex++] = primeField.getP().toByteArray(); + fieldType = KeyPair.ALG_EC_FP; + } else if (field instanceof ECFieldF2m) { + ECFieldF2m binaryField = (ECFieldF2m) field; + params = new byte[10][]; + params[paramIndex] = new byte[2]; + ByteUtil.setShort(params[paramIndex++], 0, (short) binaryField.getM()); + int[] powers = binaryField.getMidTermsOfReductionPolynomial(); + for (int i = 0; i < 3; ++i) { + params[paramIndex] = new byte[2]; + ByteUtil.setShort(params[paramIndex++], 0, (short) powers[i]); + } + fieldType = KeyPair.ALG_EC_F2M; + } else { + throw new IllegalArgumentException("ECParameterSpec with an unknown field."); + } + + ECPoint generator = spec.getGenerator(); + + params[paramIndex++] = curve.getA().toByteArray(); + params[paramIndex++] = curve.getB().toByteArray(); + + params[paramIndex++] = generator.getAffineX().toByteArray(); + params[paramIndex++] = generator.getAffineY().toByteArray(); + + params[paramIndex++] = spec.getOrder().toByteArray(); + params[paramIndex] = new byte[2]; + ByteUtil.setShort(params[paramIndex], 0, (short) spec.getCofactor()); + + EC_Curve result = new EC_Curve(bits, fieldType); + result.readByteArray(params); + return result; + } +} diff --git a/src/cz/crcs/ectester/reader/ec/EC_Data.java b/src/cz/crcs/ectester/common/ec/EC_Data.java index 0ceddef..c048ef7 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Data.java +++ b/src/cz/crcs/ectester/common/ec/EC_Data.java @@ -1,6 +1,6 @@ -package cz.crcs.ectester.reader.ec; +package cz.crcs.ectester.common.ec; -import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.common.util.ByteUtil; import java.io.*; import java.util.*; @@ -8,9 +8,10 @@ import java.util.regex.Pattern; /** * A list of byte arrays for holding EC data. - * + * <p> * The data can be read from a byte array via <code>readBytes()</code>, from a CSV via <code>readCSV()</code>. * The data can be exported to a byte array via <code>flatten()</code> or to a string array via <code>expand()</code>. + * * @author Jan Jancar johny@neuromancer.sk */ public abstract class EC_Data { @@ -55,19 +56,19 @@ public abstract class EC_Data { return data; } - public boolean hasData() { - return data != null; + public byte[] getData(int index) { + return data[index]; } - public byte[] getParam(int index) { - return data[index]; + public boolean hasData() { + return data != null; } public byte[] flatten() { ByteArrayOutputStream out = new ByteArrayOutputStream(); for (byte[] param : data) { byte[] length = new byte[2]; - Util.setShort(length, 0, (short) param.length); + ByteUtil.setShort(length, 0, (short) param.length); out.write(length, 0, 2); out.write(param, 0, param.length); @@ -79,7 +80,7 @@ public abstract class EC_Data { public String[] expand() { List<String> out = new ArrayList<>(count); for (byte[] param : data) { - out.add(Util.bytesToHex(param, false)); + out.add(ByteUtil.bytesToHex(param, false)); } return out.toArray(new String[out.size()]); @@ -97,9 +98,9 @@ public abstract class EC_Data { private static byte[] parse(String param) { byte[] data; if (param.startsWith("0x") || param.startsWith("0X")) { - data = Util.hexToBytes(param.substring(2)); + data = ByteUtil.hexToBytes(param.substring(2)); } else { - data = Util.hexToBytes(param); + data = ByteUtil.hexToBytes(param); } if (data == null) return new byte[0]; @@ -141,12 +142,16 @@ public abstract class EC_Data { } public boolean readBytes(byte[] bytes) { + if (bytes == null) { + return false; + } + int offset = 0; for (int i = 0; i < count; i++) { if (bytes.length - offset < 2) { return false; } - short paramLength = Util.getShort(bytes, offset); + short paramLength = ByteUtil.getShort(bytes, offset); offset += 2; if (bytes.length < offset + paramLength) { return false; @@ -158,6 +163,18 @@ public abstract class EC_Data { return true; } + public boolean readByteArray(byte[][] bytes) { + if (bytes == null || count != bytes.length) { + return false; + } + + for (int i = 0; i < count; ++i) { + data[i] = new byte[bytes[i].length]; + System.arraycopy(bytes[i], 0, data[i], 0, bytes[i].length); + } + return true; + } + public void writeCSV(OutputStream out) throws IOException { Writer w = new OutputStreamWriter(out); w.write(String.join(",", expand())); diff --git a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java b/src/cz/crcs/ectester/common/ec/EC_KAResult.java index 4a67bbe..8a5fcb4 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java +++ b/src/cz/crcs/ectester/common/ec/EC_KAResult.java @@ -1,6 +1,6 @@ -package cz.crcs.ectester.reader.ec; +package cz.crcs.ectester.common.ec; -import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.common.util.CardUtil; /** * A result of EC based Key agreement operation. @@ -8,15 +8,14 @@ import cz.crcs.ectester.reader.Util; * @author Jan Jancar johny@neuromancer.sk */ public class EC_KAResult extends EC_Data { - - private byte ka; + private String ka; private String curve; private String oneKey; private String otherKey; private String desc; - public EC_KAResult(byte ka, String curve, String oneKey, String otherKey) { + public EC_KAResult(String ka, String curve, String oneKey, String otherKey) { super(1); this.ka = ka; this.curve = curve; @@ -24,20 +23,24 @@ public class EC_KAResult extends EC_Data { this.otherKey = otherKey; } - public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey) { + public EC_KAResult(String id, String ka, String curve, String oneKey, String otherKey) { this(ka, curve, oneKey, otherKey); this.id = id; } - public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey, String desc) { + public EC_KAResult(String id, String ka, String curve, String oneKey, String otherKey, String desc) { this(id, ka, curve, oneKey, otherKey); this.desc = desc; } - public byte getKA() { + public String getKA() { return ka; } + public byte getJavaCardKA() { + return CardUtil.getKA(ka); + } + public String getCurve() { return curve; } @@ -56,8 +59,7 @@ public class EC_KAResult extends EC_Data { @Override public String toString() { - String algo = Util.getKA(ka); - return "<" + getId() + "> " + algo + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); + return "<" + getId() + "> " + ka + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Key.java b/src/cz/crcs/ectester/common/ec/EC_Key.java index 5077d5b..a34b0e7 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Key.java +++ b/src/cz/crcs/ectester/common/ec/EC_Key.java @@ -1,4 +1,4 @@ -package cz.crcs.ectester.reader.ec; +package cz.crcs.ectester.common.ec; import cz.crcs.ectester.applet.EC_Consts; diff --git a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java b/src/cz/crcs/ectester/common/ec/EC_Keypair.java index 2643346..53632cd 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java +++ b/src/cz/crcs/ectester/common/ec/EC_Keypair.java @@ -1,4 +1,4 @@ -package cz.crcs.ectester.reader.ec; +package cz.crcs.ectester.common.ec; import cz.crcs.ectester.applet.EC_Consts; diff --git a/src/cz/crcs/ectester/reader/ec/EC_Params.java b/src/cz/crcs/ectester/common/ec/EC_Params.java index 6fb164b..1c066e7 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Params.java +++ b/src/cz/crcs/ectester/common/ec/EC_Params.java @@ -1,7 +1,7 @@ -package cz.crcs.ectester.reader.ec; +package cz.crcs.ectester.common.ec; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.reader.Util; +import cz.crcs.ectester.common.util.ByteUtil; import java.io.ByteArrayOutputStream; import java.util.ArrayList; @@ -44,6 +44,49 @@ public class EC_Params extends EC_Data { return params; } + public byte[][] getParam(short param) { + if (!hasParam(param)) { + return null; + } + if (Integer.bitCount(param) != 1) { + return null; + } + short paramMask = EC_Consts.PARAMETER_FP; + byte[][] result = null; + int i = 0; + while (paramMask <= EC_Consts.PARAMETER_S) { + short masked = (short) (this.params & param & paramMask); + short shallow = (short) (this.params & paramMask); + if (masked != 0) { + if (masked == EC_Consts.PARAMETER_F2M) { + result = new byte[4][]; + result[0] = data[i].clone(); + result[1] = data[i+1].clone(); + result[2] = data[i+2].clone(); + result[3] = data[i+3].clone(); + break; + } + if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) { + result = new byte[2][]; + result[0] = data[i].clone(); + result[1] = data[i+1].clone(); + break; + } + result = new byte[1][]; + result[0] = data[i].clone(); + } + if (shallow == EC_Consts.PARAMETER_F2M) { + i += 4; + } else if (shallow == EC_Consts.PARAMETER_G || shallow == EC_Consts.PARAMETER_W) { + i += 2; + } else if (shallow != 0) { + i++; + } + paramMask = (short) (paramMask << 1); + } + return result; + } + public boolean hasParam(short param) { return (params & param) != 0; } @@ -82,12 +125,12 @@ public class EC_Params extends EC_Data { byte[] param = data[i]; if (masked == EC_Consts.PARAMETER_F2M) { //add m, e_1, e_2, e_3 - param = Util.concatenate(param, data[i + 1]); - if (!Util.allValue(data[i + 2], (byte) 0)) { - param = Util.concatenate(param, data[i + 2]); + param = ByteUtil.concatenate(param, data[i + 1]); + if (!ByteUtil.allValue(data[i + 2], (byte) 0)) { + param = ByteUtil.concatenate(param, data[i + 2]); } - if (!Util.allValue(data[i + 3], (byte) 0)) { - param = Util.concatenate(param, data[i + 3]); + if (!ByteUtil.allValue(data[i + 3], (byte) 0)) { + param = ByteUtil.concatenate(param, data[i + 3]); } if (!(param.length == 4 || param.length == 8)) throw new RuntimeException("PARAMETER_F2M length is not 8.(should be)"); @@ -95,14 +138,14 @@ public class EC_Params extends EC_Data { if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) { //read another param (the y coord) and put into X962 format. byte[] y = data[i + 1]; - param = Util.concatenate(new byte[]{4}, param, y); //<- ugly but works! + param = ByteUtil.concatenate(new byte[]{4}, param, y); //<- ugly but works! } if (param.length == 0) throw new RuntimeException("Empty parameter read?"); //write length byte[] length = new byte[2]; - Util.setShort(length, 0, (short) param.length); + ByteUtil.setShort(length, 0, (short) param.length); out.write(length, 0, 2); //write data out.write(param, 0, param.length); @@ -132,15 +175,15 @@ public class EC_Params extends EC_Data { byte[] param = data[index]; if (masked == EC_Consts.PARAMETER_F2M) { for (int i = 0; i < 4; ++i) { - out.add(Util.bytesToHex(data[index + i], false)); + out.add(ByteUtil.bytesToHex(data[index + i], false)); } index += 4; } else if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) { - out.add(Util.bytesToHex(param, false)); - out.add(Util.bytesToHex(data[index + 1], false)); + out.add(ByteUtil.bytesToHex(param, false)); + out.add(ByteUtil.bytesToHex(data[index + 1], false)); index += 2; } else { - out.add(Util.bytesToHex(param, false)); + out.add(ByteUtil.bytesToHex(param, false)); index++; } } |
