From 1ec0cd462865f06c673e54ed4556079d3a0917a6 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 25 Apr 2024 17:08:37 +0200 Subject: Add XDH and EdDSA keygen. --- .../ectester/standalone/ECTesterStandalone.java | 58 ++++++++++++++++++---- .../standalone/consts/KeyPairGeneratorIdent.java | 9 ++++ 2 files changed, 57 insertions(+), 10 deletions(-) (limited to 'standalone/src/main/java') diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index c702dee..bf9a9ef 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -37,11 +37,14 @@ import cz.crcs.ectester.standalone.consts.KeyPairGeneratorIdent; import cz.crcs.ectester.standalone.consts.SignatureIdent; import cz.crcs.ectester.standalone.libs.*; import cz.crcs.ectester.standalone.output.FileTestWriter; -import cz.crcs.ectester.standalone.output.TextTestWriter; -import cz.crcs.ectester.standalone.output.XMLTestWriter; -import cz.crcs.ectester.standalone.output.YAMLTestWriter; import cz.crcs.ectester.standalone.test.suites.*; import org.apache.commons.cli.*; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +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 javax.crypto.KeyAgreement; import javax.crypto.SecretKey; @@ -55,8 +58,7 @@ import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.security.*; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; +import java.security.interfaces.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; @@ -158,6 +160,8 @@ public class ECTesterStandalone { listIdents(); } else if (cli.isNext("ecdh")) { ecdh(); + } else if (cli.isNext("xdh")) { + xdh(); } else if (cli.isNext("ecdsa")) { ecdsa(); } else if (cli.isNext("generate")) { @@ -232,6 +236,11 @@ public class ECTesterStandalone { ParserOptions ecdh = new ParserOptions(new DefaultParser(), ecdhOpts, "Perform EC based KeyAgreement."); actions.put("ecdh", ecdh); + Options xdhOpts = new Options(); + xdhOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do XDH [amount] times.").build()); + ParserOptions xdh = new ParserOptions(new DefaultParser(), xdhOpts, "Perform XDH (x25519/x448)."); + actions.put("xdh", xdh); + Options ecdsaOpts = new Options(); ecdsaOpts.addOption(bits); ecdsaOpts.addOption(namedCurve); @@ -512,6 +521,10 @@ public class ECTesterStandalone { } } + private void xdh() { + + } + /** * */ @@ -744,11 +757,36 @@ public class ECTesterStandalone { if (!lib.getNativeTimingSupport().isEmpty()) { elapsed = lib.getLastNativeTiming(); } - ECPublicKey publicKey = (ECPublicKey) kp.getPublic(); - ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate(); - - String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false); - String priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false); + PublicKey pubkey = kp.getPublic(); + PrivateKey privkey = kp.getPrivate(); + String pub; + String priv; + if (pubkey instanceof ECPublicKey && privkey instanceof ECPrivateKey) { + ECPublicKey publicKey = (ECPublicKey) pubkey; + ECPrivateKey privateKey = (ECPrivateKey) privkey; + pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false); + priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false); + } else if (pubkey instanceof XECPublicKey && privkey instanceof XECPrivateKey) { + pub = ByteUtil.bytesToHex(((XECPublicKey) pubkey).getU().toByteArray(), false); + priv = ByteUtil.bytesToHex(((XECPrivateKey) privkey).getScalar().get(), false); + } else if (pubkey instanceof EdECPublicKey && privkey instanceof EdECPrivateKey) { + pub = ByteUtil.bytesToHex(((EdECPublicKey) pubkey).getPoint().getY().toByteArray(), false); + priv = ByteUtil.bytesToHex(((EdECPrivateKey) privkey).getBytes().get(), false); + } else if (pubkey instanceof XDHPublicKey && privkey instanceof XDHPrivateKey) { + // Special-case BouncyCastle XDH + pub = ByteUtil.bytesToHex(((XDHPublicKey) pubkey).getU().toByteArray(), false); + PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); + priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); + } else if (pubkey instanceof EdDSAPublicKey && privkey instanceof EdDSAPrivateKey) { + // Special-case BouncyCastle EdDSA + pub = ByteUtil.bytesToHex(((EdDSAPublicKey) pubkey).getPointEncoding(), false); + PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); + priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); + } else { + System.err.println(pubkey.getClass().getCanonicalName()); + System.err.println(privkey.getClass().getCanonicalName()); + break; + } out.printf("%d;%d;%s;%s%n", i, elapsed, pub, priv); } diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java index 83eef75..49b982b 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyPairGeneratorIdent.java @@ -11,6 +11,7 @@ public class KeyPairGeneratorIdent extends Ident { private static final List ALL = new LinkedList<>(); static { + // Short-Weierstrass ALL.add(new KeyPairGeneratorIdent("EC")); ALL.add(new KeyPairGeneratorIdent("ECDH")); ALL.add(new KeyPairGeneratorIdent("ECDSA")); @@ -22,6 +23,14 @@ public class KeyPairGeneratorIdent extends Ident { ALL.add(new KeyPairGeneratorIdent("ECKCDSA")); // ECGDSA? Botan provides. ALL.add(new KeyPairGeneratorIdent("ECGDSA")); + // Montgomery + ALL.add(new KeyPairGeneratorIdent("XDH")); + ALL.add(new KeyPairGeneratorIdent("X25519")); + ALL.add(new KeyPairGeneratorIdent("X448")); + // Twisted-Edwards + ALL.add(new KeyPairGeneratorIdent("EdDSA")); + ALL.add(new KeyPairGeneratorIdent("Ed25519")); + ALL.add(new KeyPairGeneratorIdent("Ed448")); } public static KeyPairGeneratorIdent get(String ident) { -- cgit v1.3.1 From 05bb80b365928e232416b2b0d4a7a915a00078e9 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 26 Apr 2024 23:35:53 +0200 Subject: Sort lists of items in standalone CLI. --- .../main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'standalone/src/main/java') diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index bf9a9ef..c5693e8 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -315,19 +315,19 @@ public class ECTesterStandalone { System.out.println(Colors.bold("\t\t- Supports native timing: ") + lib.getNativeTimingSupport().toString()); Set kpgs = lib.getKPGs(); if (!kpgs.isEmpty()) { - System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.joining(", "))); + System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + kpgs.stream().map(KeyPairGeneratorIdent::getName).sorted().collect(Collectors.joining(", "))); } Set eckas = lib.getKAs(); if (!eckas.isEmpty()) { - System.out.println(Colors.bold("\t\t- KeyAgreements: ") + eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.joining(", "))); + System.out.println(Colors.bold("\t\t- KeyAgreements: ") + eckas.stream().map(KeyAgreementIdent::getName).sorted().collect(Collectors.joining(", "))); } Set sigs = lib.getSigs(); if (!sigs.isEmpty()) { - System.out.println(Colors.bold("\t\t- Signatures: ") + sigs.stream().map(SignatureIdent::getName).collect(Collectors.joining(", "))); + System.out.println(Colors.bold("\t\t- Signatures: ") + sigs.stream().map(SignatureIdent::getName).sorted().collect(Collectors.joining(", "))); } Set curves = lib.getCurves(); if (!curves.isEmpty()) { - System.out.println(Colors.bold("\t\t- Curves: ") + String.join(", ", curves)); + System.out.println(Colors.bold("\t\t- Curves: ") + curves.stream().sorted().collect(Collectors.joining(", "))); } System.out.println(); } -- cgit v1.3.1 From 8f9179da726be18ab883ac716296dbe2c411d805 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 26 Apr 2024 23:36:06 +0200 Subject: Add XDH and EdDSA idents --- .../crcs/ectester/standalone/consts/KeyAgreementIdent.java | 12 +++++++++++- .../cz/crcs/ectester/standalone/consts/SignatureIdent.java | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'standalone/src/main/java') diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java index 60c60e8..c0cf793 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/KeyAgreementIdent.java @@ -18,10 +18,11 @@ public class KeyAgreementIdent extends Ident { private static final List ALL = new LinkedList<>(); static { - //https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html + // https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html // Basic ECDH and ECDHC (plain/raw) ALL.add(new KeyAgreementIdent("ECDH")); ALL.add(new KeyAgreementIdent("ECDHC", "ECCDH")); + // ECDH and ECDHC with SHA as KDF, OIDs from RFC 3278 ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF", true, "1.3.133.16.840.63.0.2")); ALL.add(new KeyAgreementIdent("ECCDHwithSHA1KDF", true, "1.3.133.16.840.63.0.3")); @@ -33,11 +34,13 @@ public class KeyAgreementIdent extends Ident { ALL.add(new KeyAgreementIdent("ECCDHwithSHA384KDF", true, "1.3.132.1.14.2")); ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF", true, "1.3.132.1.11.3")); ALL.add(new KeyAgreementIdent("ECCDHwithSHA512KDF", true, "1.3.132.1.14.3")); + // Microsoft specific KDF ALL.add(new KeyAgreementIdent("ECDHwithSHA1KDF(CNG)")); ALL.add(new KeyAgreementIdent("ECDHwithSHA256KDF(CNG)")); ALL.add(new KeyAgreementIdent("ECDHwithSHA384KDF(CNG)")); ALL.add(new KeyAgreementIdent("ECDHwithSHA512KDF(CNG)")); + // CKDF requires custom AlgorithmParameterSpec (only BouncyCastle) //ALL.add(new KeyAgreementIdent("ECDHwithSHA1CKDF", true)); //ALL.add(new KeyAgreementIdent("ECCDHwithSHA1CKDF", true)); @@ -47,6 +50,7 @@ public class KeyAgreementIdent extends Ident { //ALL.add(new KeyAgreementIdent("ECCDHwithSHA384CKDF", true)); //ALL.add(new KeyAgreementIdent("ECDHwithSHA512CKDF", true)); //ALL.add(new KeyAgreementIdent("ECCDHwithSHA512CKDF", true)); + // ECMQV - Disable for now as it needs diferent params(too different from DH) //ALL.add(new KeyAgreementIdent("ECMQV")); //ALL.add(new KeyAgreementIdent("ECMQVwithSHA1KDF", true)); @@ -59,10 +63,16 @@ public class KeyAgreementIdent extends Ident { //ALL.add(new KeyAgreementIdent("ECMQVwithSHA256CKDF", true, "1.3.132.1.15.1")); //ALL.add(new KeyAgreementIdent("ECMQVwithSHA384CKDF", true, "1.3.132.1.15.2")); //ALL.add(new KeyAgreementIdent("ECMQVwithSHA512CKDF", true, "1.3.132.1.15.3")); + // ECVKO - Disable for now as it needs diferent params(too different from DH) //ALL.add(new KeyAgreementIdent("ECVKO", "ECGOST3410", "1.2.643.2.2.19", "GOST-3410-2001", "1.2.643.2.2.96")); //ALL.add(new KeyAgreementIdent("ECVKO256", "ECGOST3410-2012-256", "1.2.643.7.1.1.6.1", "1.2.643.7.1.1.1.1")); //ALL.add(new KeyAgreementIdent("ECVKO512", "ECGOST3410-2012-512", "1.2.643.7.1.1.6.2", "1.2.643.7.1.1.1.2")); + + // XDH (RFC 7748) + ALL.add(new KeyAgreementIdent("XDH")); + ALL.add(new KeyAgreementIdent("X25519")); + ALL.add(new KeyAgreementIdent("X448")); } public static KeyAgreementIdent get(String ident) { diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java index c3913b7..a65d0c5 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/consts/SignatureIdent.java @@ -30,17 +30,20 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA3-384withECDSA", "SHA3-384/ECDSA", "2.16.840.1.101.3.4.3.11")); ALL.add(new SignatureIdent("SHA3-512withECDSA", "SHA3-512/ECDSA", "2.16.840.1.101.3.4.3.12")); ALL.add(new SignatureIdent("RIPEMD160withECDSA", "RIPEMD160/ECDSA", "1.3.36.3.3.2.2")); + // ECNR ALL.add(new SignatureIdent("SHA1withECNR")); ALL.add(new SignatureIdent("SHA224withECNR")); ALL.add(new SignatureIdent("SHA256withECNR")); ALL.add(new SignatureIdent("SHA512withECNR")); + // CVC-ECDSA ALL.add(new SignatureIdent("SHA1withCVC-ECDSA", "SHA1/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.1")); ALL.add(new SignatureIdent("SHA224withCVC-ECDSA", "SHA224/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.2")); ALL.add(new SignatureIdent("SHA256withCVC-ECDSA", "SHA256/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.3")); ALL.add(new SignatureIdent("SHA384withCVC-ECDSA", "SHA384/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.4")); ALL.add(new SignatureIdent("SHA512withCVC-ECDSA", "SHA512/CVC-ECDSA", "0.4.0.127.0.7.2.2.2.2.5")); + // PLAIN-ECDSA ALL.add(new SignatureIdent("SHA1withPLAIN-ECDSA", "SHA1/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.1")); ALL.add(new SignatureIdent("SHA224withPLAIN-ECDSA", "SHA224/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.2")); @@ -48,6 +51,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA384withPLAIN-ECDSA", "SHA384/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.4")); ALL.add(new SignatureIdent("SHA512withPLAIN-ECDSA", "SHA512/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.5")); ALL.add(new SignatureIdent("RIPEMD160withPLAIN-ECDSA", "RIPEMD160/PLAIN-ECDSA", "0.4.0.127.0.7.1.1.4.1.6")); + // ECGOST ALL.add(new SignatureIdent("ECGOST3410", "ECGOST-3410", "GOST-3410-2001")); ALL.add(new SignatureIdent("GOST3411withECGOST3410", "GOST3411/ECGOST3410", "1.2.643.2.2.3")); @@ -56,6 +60,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("ECGOST3410-2012-512", "GOST-3410-2012-512")); ALL.add(new SignatureIdent("GOST3411-2012-512withECGOST3410-2012-512", "GOST3411-2012-512/ECGOST3410-2012-5120", "1.2.643.7.1.1.3.3")); ALL.add(new SignatureIdent("SM3withSM2")); + // ECDDSA (rfc6979?) ALL.add(new SignatureIdent("ECDDSA", "SHA1withECDDSA", "SHA1withDETECDSA", "DETECDSA", "ECDETDSA")); ALL.add(new SignatureIdent("SHA224withECDDSA", "SHA224withDETECDSA")); @@ -66,6 +71,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA3-256withECDDSA", "SHA3-256withDETECDSA")); ALL.add(new SignatureIdent("SHA3-384withECDDSA", "SHA3-384withDETECDSA")); ALL.add(new SignatureIdent("SHA3-512withECDDSA", "SHA3-512withDETECDSA")); + // ECKCDSA? Botan provides. ALL.add(new SignatureIdent("ECKCDSA", "SHA1withECKCDSA", "1.2.410.200004.1.100.4.3")); ALL.add(new SignatureIdent("NONEwithECKCDSA")); @@ -74,6 +80,7 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA256withECKCDSA", "1.2.410.200004.1.100.4.5")); ALL.add(new SignatureIdent("SHA384withECKCDSA")); ALL.add(new SignatureIdent("SHA512withECKCDSA")); + // ECGDSA? Botan provides. ALL.add(new SignatureIdent("ECGDSA", "SHA1withECGDSA", "1.3.36.3.3.2.5.4.2")); ALL.add(new SignatureIdent("NONEwithECGDSA")); @@ -82,6 +89,11 @@ public class SignatureIdent extends Ident { ALL.add(new SignatureIdent("SHA224withECGDSA", "1.3.36.3.3.2.5.4.4")); ALL.add(new SignatureIdent("SHA384withECGDSA", "1.3.36.3.3.2.5.4.5")); ALL.add(new SignatureIdent("SHA512withECGDSA", "1.3.36.3.3.2.5.4.6")); + + // EdDSA (RFC 8032) + ALL.add(new SignatureIdent("EdDSA")); + ALL.add(new SignatureIdent("Ed25519")); + ALL.add(new SignatureIdent("Ed448")); } public static SignatureIdent get(String ident) { -- cgit v1.3.1 From 6a9f2181e9fa0fad8732261bb923b0c24b232747 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 27 Apr 2024 00:06:25 +0200 Subject: Add XDH to standalone CLI. --- .../java/cz/crcs/ectester/common/util/ECUtil.java | 54 ++++++++++++++++++--- .../ectester/standalone/ECTesterStandalone.java | 56 +++++----------------- 2 files changed, 61 insertions(+), 49 deletions(-) (limited to 'standalone/src/main/java') 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 f9be536..74fccc9 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 @@ -2,20 +2,22 @@ package cz.crcs.ectester.common.util; import cz.crcs.ectester.common.ec.*; import cz.crcs.ectester.data.EC_Store; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.signers.PlainDSAEncoding; import org.bouncycastle.crypto.signers.StandardDSAEncoding; +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 java.io.FileInputStream; 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.ECKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; +import java.security.*; +import java.security.interfaces.*; import java.security.spec.*; import java.util.LinkedList; import java.util.List; @@ -456,6 +458,46 @@ public class ECUtil { return null; } + public static byte[] pubkeyToBytes(PublicKey pubkey) { + if (pubkey instanceof ECPublicKey) { + ECPublicKey ecPublicKey = (ECPublicKey) pubkey; + return ECUtil.toX962Uncompressed(ecPublicKey.getW(), ecPublicKey.getParams()); + } else if (pubkey instanceof XECPublicKey) { + XECPublicKey xedPublicKey = (XECPublicKey) pubkey; + return xedPublicKey.getU().toByteArray(); + } else if (pubkey instanceof EdECPublicKey) { + EdECPublicKey edECPublicKey = (EdECPublicKey) pubkey; + return edECPublicKey.getPoint().getY().toByteArray(); + } else if (pubkey instanceof XDHPublicKey) { + XDHPublicKey xdhPublicKey = (XDHPublicKey) pubkey; + return xdhPublicKey.getU().toByteArray(); + // Special-case BouncyCastle XDH + } else if (pubkey instanceof EdDSAPublicKey) { + EdDSAPublicKey edDSAPublicKey = (EdDSAPublicKey) pubkey; + // Special-case BouncyCastle EdDSA + return edDSAPublicKey.getPointEncoding(); + } + return null; + } + + public static byte[] privkeyToBytes(PrivateKey privkey) { + if (privkey instanceof ECPrivateKey) { + ECPrivateKey ecPrivateKey = (ECPrivateKey) privkey; + return ecPrivateKey.getS().toByteArray(); + } else if (privkey instanceof XECPrivateKey) { + XECPrivateKey xecPrivateKey = (XECPrivateKey) privkey; + return xecPrivateKey.getScalar().get(); + } else if (privkey instanceof EdECPrivateKey) { + EdECPrivateKey edECPrivateKey = (EdECPrivateKey) privkey; + return edECPrivateKey.getBytes().get(); + } else if (privkey instanceof XDHPrivateKey || privkey instanceof EdDSAPrivateKey) { + // Special-case BouncyCastle XDH and EdDSA + PrivateKeyInfo xpkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); + return ASN1OctetString.getInstance(xpkinfo.getPrivateKey().getOctets()).getOctets(); + } + return null; + } + public static boolean equalKeyPairParameters(ECPrivateKey priv, ECPublicKey pub) { if (priv == null || pub == null) { return false; diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index c5693e8..2dc5040 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -62,6 +62,7 @@ import java.security.interfaces.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; +import java.security.spec.NamedParameterSpec; import java.util.*; import java.util.stream.Collectors; @@ -160,8 +161,6 @@ public class ECTesterStandalone { listIdents(); } else if (cli.isNext("ecdh")) { ecdh(); - } else if (cli.isNext("xdh")) { - xdh(); } else if (cli.isNext("ecdsa")) { ecdsa(); } else if (cli.isNext("generate")) { @@ -236,11 +235,6 @@ public class ECTesterStandalone { ParserOptions ecdh = new ParserOptions(new DefaultParser(), ecdhOpts, "Perform EC based KeyAgreement."); actions.put("ecdh", ecdh); - Options xdhOpts = new Options(); - xdhOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do XDH [amount] times.").build()); - ParserOptions xdh = new ParserOptions(new DefaultParser(), xdhOpts, "Perform XDH (x25519/x448)."); - actions.put("xdh", xdh); - Options ecdsaOpts = new Options(); ecdsaOpts.addOption(bits); ecdsaOpts.addOption(namedCurve); @@ -467,8 +461,8 @@ public class ECTesterStandalone { other = kpg.genKeyPair(); } - ECPrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdh.named-private"), cli.getOptionValue("ecdh.private"), spec); - ECPublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdh.named-public"), cli.getOptionValue("ecdh.public"), spec); + PrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdh.named-private"), cli.getOptionValue("ecdh.private"), spec); + PublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdh.named-public"), cli.getOptionValue("ecdh.public"), spec); int amount = Integer.parseInt(cli.getOptionValue("ecdh.amount", "1")); for (int i = 0; i < amount || amount == 0; ++i) { @@ -480,11 +474,11 @@ public class ECTesterStandalone { } if (!cli.hasOption("ecdh.named-private") && !cli.hasOption("ecdh.private")) { - privkey = (ECPrivateKey) one.getPrivate(); + privkey = one.getPrivate(); } if (!cli.hasOption("ecdh.named-public") && !cli.hasOption("ecdh.public")) { - pubkey = (ECPublicKey) other.getPublic(); + pubkey = other.getPublic(); } long elapsed = -System.nanoTime(); @@ -510,8 +504,8 @@ public class ECTesterStandalone { } ka = kaIdent.getInstance(lib.getProvider()); - String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false); - String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false); + String pub = ByteUtil.bytesToHex(ECUtil.pubkeyToBytes(pubkey), false); + String priv = ByteUtil.bytesToHex(ECUtil.privkeyToBytes(privkey), false); String dh = ByteUtil.bytesToHex(result, false); out.printf("%d;%d;%s;%s;%s%n", i, elapsed, pub, priv, dh); } @@ -521,10 +515,6 @@ public class ECTesterStandalone { } } - private void xdh() { - - } - /** * */ @@ -759,30 +749,11 @@ public class ECTesterStandalone { } PublicKey pubkey = kp.getPublic(); PrivateKey privkey = kp.getPrivate(); - String pub; - String priv; - if (pubkey instanceof ECPublicKey && privkey instanceof ECPrivateKey) { - ECPublicKey publicKey = (ECPublicKey) pubkey; - ECPrivateKey privateKey = (ECPrivateKey) privkey; - pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(publicKey.getW(), publicKey.getParams()), false); - priv = ByteUtil.bytesToHex(privateKey.getS().toByteArray(), false); - } else if (pubkey instanceof XECPublicKey && privkey instanceof XECPrivateKey) { - pub = ByteUtil.bytesToHex(((XECPublicKey) pubkey).getU().toByteArray(), false); - priv = ByteUtil.bytesToHex(((XECPrivateKey) privkey).getScalar().get(), false); - } else if (pubkey instanceof EdECPublicKey && privkey instanceof EdECPrivateKey) { - pub = ByteUtil.bytesToHex(((EdECPublicKey) pubkey).getPoint().getY().toByteArray(), false); - priv = ByteUtil.bytesToHex(((EdECPrivateKey) privkey).getBytes().get(), false); - } else if (pubkey instanceof XDHPublicKey && privkey instanceof XDHPrivateKey) { - // Special-case BouncyCastle XDH - pub = ByteUtil.bytesToHex(((XDHPublicKey) pubkey).getU().toByteArray(), false); - PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); - priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); - } else if (pubkey instanceof EdDSAPublicKey && privkey instanceof EdDSAPrivateKey) { - // Special-case BouncyCastle EdDSA - pub = ByteUtil.bytesToHex(((EdDSAPublicKey) pubkey).getPointEncoding(), false); - PrivateKeyInfo pkinfo = PrivateKeyInfo.getInstance(privkey.getEncoded()); - priv = ByteUtil.bytesToHex(ASN1OctetString.getInstance(pkinfo.getPrivateKey().getOctets()).getOctets(), false); - } else { + byte[] pubBytes = ECUtil.pubkeyToBytes(pubkey); + byte[] privBytes = ECUtil.privkeyToBytes(privkey); + String pub = ByteUtil.bytesToHex(pubBytes, false); + String priv = ByteUtil.bytesToHex(privBytes, false); + if (pubBytes == null || privBytes == null) { System.err.println(pubkey.getClass().getCanonicalName()); System.err.println(privkey.getClass().getCanonicalName()); break; @@ -801,7 +772,6 @@ public class ECTesterStandalone { private void test() throws TestException, ParserConfigurationException, FileNotFoundException { TestWriter writer = new FileTestWriter(cli.getOptionValue("test.format", "text"), !cli.hasOption("test.quiet"), cli.getOptionValues("test.output")); StandaloneTestSuite suite; - switch (cli.getArg(0).toLowerCase()) { case "test-vectors": suite = new StandaloneTestVectorSuite(writer, cfg, cli); @@ -836,9 +806,9 @@ public class ECTesterStandalone { case "performance": suite = new StandalonePerformanceSuite(writer, cfg, cli); break; - case "default": default: suite = new StandaloneDefaultSuite(writer, cfg, cli); + break; } suite.run(); -- cgit v1.3.1 From e5e8072363c53b155df42238e049d7929b2380f1 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 27 Apr 2024 00:10:57 +0200 Subject: Add EdDSA to standalone CLI. --- .../ectester/standalone/ECTesterStandalone.java | 53 ++++++++++------------ 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'standalone/src/main/java') diff --git a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java index 2dc5040..ab7e45b 100644 --- a/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java +++ b/standalone/src/main/java/cz/crcs/ectester/standalone/ECTesterStandalone.java @@ -39,12 +39,6 @@ import cz.crcs.ectester.standalone.libs.*; import cz.crcs.ectester.standalone.output.FileTestWriter; import cz.crcs.ectester.standalone.test.suites.*; import org.apache.commons.cli.*; -import org.bouncycastle.asn1.ASN1OctetString; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -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 javax.crypto.KeyAgreement; import javax.crypto.SecretKey; @@ -62,7 +56,6 @@ import java.security.interfaces.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; -import java.security.spec.NamedParameterSpec; import java.util.*; import java.util.stream.Collectors; @@ -608,17 +601,17 @@ public class ECTesterStandalone { String hashAlgoOut = sigIdent.getHashAlgo() != null ? String.format("[%s]", sigIdent.getHashAlgo()) : ""; out.printf("index;signTime[%s];verifyTime[%s];data;pubW;privS;signature%s;nonce;verified%n", timeUnit, timeUnit, hashAlgoOut); - ECPrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdsa.named-private"), cli.getOptionValue("ecdsa.private"), spec); - ECPublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdsa.named-public"), cli.getOptionValue("ecdsa.public"), spec); + PrivateKey privkey = (ECPrivateKey) ECUtil.loadKey(EC_Consts.PARAMETER_S, cli.getOptionValue("ecdsa.named-private"), cli.getOptionValue("ecdsa.private"), spec); + PublicKey pubkey = (ECPublicKey) ECUtil.loadKey(EC_Consts.PARAMETER_W, cli.getOptionValue("ecdsa.named-public"), cli.getOptionValue("ecdsa.public"), spec); KeyPair one; if (cli.hasOption("ecdsa.fixed")) { one = kpg.genKeyPair(); if (!cli.hasOption("ecdsa.named-private")) { - privkey = (ECPrivateKey) one.getPrivate(); + privkey = one.getPrivate(); } if (!cli.hasOption("ecdsa.named-public")) { - pubkey = (ECPublicKey) one.getPublic(); + pubkey = one.getPublic(); } } @@ -629,10 +622,10 @@ public class ECTesterStandalone { one = kpg.genKeyPair(); if (!cli.hasOption("ecdsa.named-private")) { - privkey = (ECPrivateKey) one.getPrivate(); + privkey = one.getPrivate(); } if (!cli.hasOption("ecdsa.named-public")) { - pubkey = (ECPublicKey) one.getPublic(); + pubkey = one.getPublic(); } } @@ -656,27 +649,31 @@ public class ECTesterStandalone { verifyTime = lib.getLastNativeTiming(); } - String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false); - String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false); + String pub = ByteUtil.bytesToHex(ECUtil.pubkeyToBytes(pubkey), false); + String priv = ByteUtil.bytesToHex(ECUtil.privkeyToBytes(privkey), false); String sign = ByteUtil.bytesToHex(signature, false); String k = ""; - ECParameterSpec kSpec = spec; - if (kSpec == null) { - kSpec = privkey.getParams(); - } - if (kSpec != null) { - // Parse the types out of SignatureIdent. - String hashAlgo = sigIdent.getHashAlgo(); - String sigType = sigIdent.getSigType(); - if (sigType == null) { - sigType = sigIdent.toString(); + if (privkey instanceof ECPrivateKey) { + ECPrivateKey ecPrivateKey = (ECPrivateKey) privkey; + ECParameterSpec kSpec = spec; + if (kSpec == null) { + kSpec = ecPrivateKey.getParams(); } + if (kSpec != null) { + // Parse the types out of SignatureIdent. + String hashAlgo = sigIdent.getHashAlgo(); + String sigType = sigIdent.getSigType(); + if (sigType == null) { + sigType = sigIdent.toString(); + } - BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, privkey.getS(), kSpec, hashAlgo, sigType); - if (kValue != null) { - k = ByteUtil.bytesToHex(kValue.toByteArray(), false); + BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, ecPrivateKey.getS(), kSpec, hashAlgo, sigType); + if (kValue != null) { + k = ByteUtil.bytesToHex(kValue.toByteArray(), false); + } } } + out.printf("%d;%d;%d;%s;%s;%s;%s;%s;%d%n", i, signTime, verifyTime, dataString, pub, priv, sign, k, verified ? 1 : 0); } -- cgit v1.3.1