aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/common/util/ECUtil.java
diff options
context:
space:
mode:
authorJ08nY2019-02-22 10:29:28 +0100
committerJ08nY2019-02-22 10:29:28 +0100
commitb6daaef0a884bd154a848bdb73919b3b82d0df98 (patch)
tree7a4034a9862324b0988050cfe9f13c66d633daec /src/cz/crcs/ectester/common/util/ECUtil.java
parent687a09baf6fd858d393b8f284cfe7236b52d7457 (diff)
parentfea5c7b1cbd539b105b42c4bde65d0b9b6f0b8fc (diff)
downloadECTester-b6daaef0a884bd154a848bdb73919b3b82d0df98.tar.gz
ECTester-b6daaef0a884bd154a848bdb73919b3b82d0df98.tar.zst
ECTester-b6daaef0a884bd154a848bdb73919b3b82d0df98.zip
Diffstat (limited to 'src/cz/crcs/ectester/common/util/ECUtil.java')
-rw-r--r--src/cz/crcs/ectester/common/util/ECUtil.java74
1 files changed, 71 insertions, 3 deletions
diff --git a/src/cz/crcs/ectester/common/util/ECUtil.java b/src/cz/crcs/ectester/common/util/ECUtil.java
index 1706ca0..511f93f 100644
--- a/src/cz/crcs/ectester/common/util/ECUtil.java
+++ b/src/cz/crcs/ectester/common/util/ECUtil.java
@@ -3,9 +3,18 @@ package cz.crcs.ectester.common.util;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.ec.*;
import cz.crcs.ectester.data.EC_Store;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1StreamParser;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERSequenceParser;
+import org.bouncycastle.crypto.digests.SHA1Digest;
+import java.io.IOException;
import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;
@@ -183,6 +192,27 @@ public class ECUtil {
}
}
+ public static byte[] semiRandomKey(EC_Curve curve) {
+ int bytes = (curve.getBits() + 7) / 8;
+ byte[] result = new byte[bytes];
+ SHA1Digest digest = new SHA1Digest();
+ byte[] curveName = curve.getId().getBytes(StandardCharsets.US_ASCII);
+ digest.update(curveName, 0, curveName.length);
+ int written = 0;
+ while (written < bytes) {
+ byte[] dig = new byte[digest.getDigestSize()];
+ digest.doFinal(dig, 0);
+ int toWrite = digest.getDigestSize() > bytes - written ? bytes - written : digest.getDigestSize();
+ System.arraycopy(dig, 0, result, written, toWrite);
+ written += toWrite;
+ digest.update(dig, 0, dig.length);
+ }
+ BigInteger priv = new BigInteger(1, result);
+ BigInteger order = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_R)[0]);
+ priv = priv.mod(order);
+ return toByteArray(priv, curve.getBits());
+ }
+
private static ECPoint toPoint(EC_Params params) {
return new ECPoint(
new BigInteger(1, params.getParam(EC_Consts.PARAMETER_W)[0]),
@@ -194,25 +224,34 @@ public class ECUtil {
}
public static ECPublicKey toPublicKey(EC_Key.Public pubkey) {
+ if (pubkey == null) {
+ return null;
+ }
EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, pubkey.getCurve());
if (curve == null) {
- throw new IllegalArgumentException("pubkey curve nor found: " + pubkey.getCurve());
+ throw new IllegalArgumentException("pubkey curve not found: " + pubkey.getCurve());
}
return new RawECPublicKey(toPoint(pubkey), curve.toSpec());
}
public static ECPrivateKey toPrivateKey(EC_Key.Private privkey) {
+ if (privkey == null) {
+ return null;
+ }
EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, privkey.getCurve());
if (curve == null) {
- throw new IllegalArgumentException("privkey curve nor found: " + privkey.getCurve());
+ throw new IllegalArgumentException("privkey curve not found: " + privkey.getCurve());
}
return new RawECPrivateKey(toScalar(privkey), curve.toSpec());
}
public static KeyPair toKeyPair(EC_Keypair kp) {
+ if (kp == null) {
+ return null;
+ }
EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, kp.getCurve());
if (curve == null) {
- throw new IllegalArgumentException("keypair curve nor found: " + kp.getCurve());
+ throw new IllegalArgumentException("keypair curve not found: " + kp.getCurve());
}
ECPublicKey pubkey = new RawECPublicKey(toPoint(kp), curve.toSpec());
ECPrivateKey privkey = new RawECPrivateKey(toScalar(kp), curve.toSpec());
@@ -222,4 +261,33 @@ public class ECUtil {
public static byte[] toDERSignature(byte[] r, byte[] s) {
return ByteUtil.concatenate(new byte[]{0x30, (byte) (r.length + s.length + 4), 0x02, (byte) r.length}, r, new byte[]{0x02, (byte) s.length}, s);
}
+
+ public static BigInteger[] fromDERSignature(byte[] signature) throws IOException {
+ ASN1StreamParser parser = new ASN1StreamParser(signature);
+ DERSequence sequence = (DERSequence) ((DERSequenceParser) parser.readObject()).getLoadedObject();
+ ASN1Integer r = (ASN1Integer) sequence.getObjectAt(0);
+ ASN1Integer s = (ASN1Integer) sequence.getObjectAt(1);
+ return new BigInteger[]{r.getPositiveValue(), s.getPositiveValue()};
+ }
+
+ public static BigInteger recoverSignatureNonce(byte[] signature, byte[] data, BigInteger privkey, ECParameterSpec params, String hashType) {
+ try {
+ int bitSize = params.getOrder().bitLength();
+ MessageDigest md = MessageDigest.getInstance(hashType);
+ byte[] hash = md.digest(data);
+ BigInteger hashInt = new BigInteger(1, hash);
+ hashInt = hashInt.and(BigInteger.ONE.shiftLeft(bitSize + 1).subtract(BigInteger.ONE));
+
+ BigInteger[] sigPair = fromDERSignature(signature);
+ BigInteger r = sigPair[0];
+ BigInteger s = sigPair[1];
+
+ BigInteger rd = privkey.multiply(r).mod(params.getOrder());
+ BigInteger hrd = hashInt.add(rd).mod(params.getOrder());
+ return s.modInverse(params.getOrder()).multiply(hrd).mod(params.getOrder());
+ } catch (NoSuchAlgorithmException | IOException nsae) {
+ nsae.printStackTrace();
+ return null;
+ }
+ }
}