aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
diff options
context:
space:
mode:
authorJ08nY2024-03-22 23:58:55 +0100
committerJ08nY2024-03-25 14:52:43 +0100
commit73af477a8774e1ede5dd8de6491eb353dc0b12bd (patch)
tree2d4e3b19bc5fb55308b886032312be76341736d4 /src/cz/crcs/ectester/standalone/ECTesterStandalone.java
parent64b95fa059295e1dc23371c849f2302c1c18f5b4 (diff)
downloadECTester-73af477a8774e1ede5dd8de6491eb353dc0b12bd.tar.gz
ECTester-73af477a8774e1ede5dd8de6491eb353dc0b12bd.tar.zst
ECTester-73af477a8774e1ede5dd8de6491eb353dc0b12bd.zip
Basic Gradle setup.
Diffstat (limited to 'src/cz/crcs/ectester/standalone/ECTesterStandalone.java')
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java942
1 files changed, 0 insertions, 942 deletions
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
deleted file mode 100644
index a26cc7c..0000000
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ /dev/null
@@ -1,942 +0,0 @@
-/*
- * ECTester, tool for testing Elliptic curve cryptography implementations.
- * Copyright (c) 2016-2018 Petr Svenda <petr@svenda.com>
- * Copyright (c) 2016-2019 Jan Jancar <johny@neuromancer.sk>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package cz.crcs.ectester.standalone;
-
-import cz.crcs.ectester.applet.EC_Consts;
-import cz.crcs.ectester.common.cli.*;
-import cz.crcs.ectester.common.ec.EC_Curve;
-import cz.crcs.ectester.common.output.TestWriter;
-import cz.crcs.ectester.common.test.TestException;
-import cz.crcs.ectester.common.util.ByteUtil;
-import cz.crcs.ectester.common.util.ECUtil;
-import cz.crcs.ectester.common.util.FileUtil;
-import cz.crcs.ectester.data.EC_Store;
-import cz.crcs.ectester.standalone.consts.KeyAgreementIdent;
-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.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 javax.crypto.KeyAgreement;
-import javax.crypto.SecretKey;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-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.spec.AlgorithmParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * Standalone part of ECTester, a tool for testing Elliptic curve implementations in software libraries.
- *
- * @author Jan Jancar johny@neuromancer.sk
- * @version v0.3.3
- */
-public class ECTesterStandalone {
- private ProviderECLibrary[] libs;
- private Config cfg;
-
- private Options opts = new Options();
- private TreeParser optParser;
- private TreeCommandLine cli;
- public static final String VERSION = "v0.3.3";
- private static final String DESCRIPTION = "ECTesterStandalone " + VERSION + ", an Elliptic Curve Cryptography support tester/utility.";
- private static final String LICENSE = "MIT Licensed\nCopyright © 2016-2019 Petr Svenda <petr@svenda.com>\nCopyright © 2016-2019 Jan Jancar <johny@neuromancer.sk>";
- private static final String CLI_HEADER = "\n" + DESCRIPTION + "\n\n";
- private static final String CLI_FOOTER = "\n" + LICENSE;
-
- public static String LIB_RESOURCE_DIR = "/cz/crcs/ectester/standalone/libs/jni/";
-
- private void run(String[] args) {
- try {
- cli = parseArgs(args);
-
- if (cli.hasOption("version")) {
- CLITools.version(DESCRIPTION, LICENSE);
- return;
- } else if (cli.hasOption("help") || cli.getNext() == null) {
- String command = cli.getOptionValue("help");
- if (command == null) {
- CLITools.help("ECTesterStandalone.jar", CLI_HEADER, opts, optParser, CLI_FOOTER, true);
- } else {
- CLITools.help(CLI_HEADER, optParser, CLI_FOOTER, command);
- }
- return;
- }
-
- Path reqs = FileUtil.getRequirementsDir();
- reqs.toFile().mkdirs();
-
- if (!System.getProperty("os.name").startsWith("Windows")) {
- FileUtil.writeNewer(LIB_RESOURCE_DIR + "lib_timing.so", reqs.resolve("lib_timing.so"));
- System.load(reqs.resolve("lib_timing.so").toString());
- }
-
- List<ProviderECLibrary> libObjects = new LinkedList<>();
- Class[] libClasses = new Class[]{SunECLib.class,
- BouncyCastleLib.class,
- TomcryptLib.class,
- BotanLib.class,
- CryptoppLib.class,
- OpensslLib.class,
- BoringsslLib.class,
- GcryptLib.class,
- MscngLib.class,
- WolfCryptLib.class,
- MbedTLSLib.class,
- IppcpLib.class,
- MatrixsslLib.class,
- NettleLib.class,
- LibresslLib.class};
- for (Class c : libClasses) {
- try {
- libObjects.add((ProviderECLibrary) c.getDeclaredConstructor().newInstance());
- } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
- InvocationTargetException e) {
-
- }
- }
- libs = libObjects.toArray(new ProviderECLibrary[0]);
-
- //TODO: push this further down to only initialize if necessary.
- // and only initialize the chosen lib (so give libs a name in Java only)
- for (ECLibrary lib : libs) {
- try {
- lib.initialize();
- } catch (Exception ex) {
- System.err.println(ex.getMessage());
- }
- }
-
- cfg = new Config(libs);
- if (!cfg.readOptions(cli)) {
- return;
- }
-
- if (cli.isNext("list-libs")) {
- listLibraries();
- } else if (cli.isNext("list-data")) {
- CLITools.listNamed(EC_Store.getInstance(), cli.getNext().getArg(0));
- } else if (cli.isNext("list-suites")) {
- listSuites();
- } else if (cli.isNext("list-types")) {
- listIdents();
- } else if (cli.isNext("ecdh")) {
- ecdh();
- } else if (cli.isNext("ecdsa")) {
- ecdsa();
- } else if (cli.isNext("generate")) {
- generate();
- } else if (cli.isNext("test")) {
- test();
- } else if (cli.isNext("export")) {
- export();
- }
-
- } catch (ParseException | ParserConfigurationException | IOException ex) {
- System.err.println(ex.getMessage());
- } catch (InvalidAlgorithmParameterException | InvalidParameterException e) {
- System.err.println("Invalid algorithm parameter: " + e.getMessage());
- } catch (NoSuchAlgorithmException nsaex) {
- System.err.println("Algorithm not supported by the selected library: " + nsaex.getMessage());
- } catch (InvalidKeyException | SignatureException e) {
- e.printStackTrace();
- }
- }
-
- private TreeCommandLine parseArgs(String[] args) throws ParseException {
- Map<String, ParserOptions> actions = new TreeMap<>();
-
- Option namedCurve = Option.builder("nc").longOpt("named-curve").desc("Use a named curve, from CurveDB: <cat/id>").hasArg().argName("cat/id").optionalArg(false).numberOfArgs(1).build();
- Option namedPublic = Option.builder("npub").longOpt("named-public").desc("Use a named public key, from CurveDB: <cat/id>").hasArg().argName("cat/id").optionalArg(false).numberOfArgs(1).build();
- Option filePublic = Option.builder("pub").longOpt("public").desc("Use a given public key from file.").hasArg().argName("pubkey").optionalArg(false).numberOfArgs(1).build();
- OptionGroup publicKey = new OptionGroup();
- publicKey.addOption(namedPublic);
- publicKey.addOption(filePublic);
- Option namedPrivate = Option.builder("npriv").longOpt("named-private").desc("Use a named private key, from CurveDB: <cat/id>").hasArg().argName("cat/id").optionalArg(false).numberOfArgs(1).build();
- Option filePrivate = Option.builder("priv").longOpt("private").desc("Use a given private key from file.").hasArg().argName("privkey").optionalArg(false).numberOfArgs(1).build();
- OptionGroup privateKey = new OptionGroup();
- privateKey.addOption(namedPrivate);
- privateKey.addOption(filePrivate);
- Option curveName = Option.builder("cn").longOpt("curve-name").desc("Use a named curve, search from curves supported by the library: <name>").hasArg().argName("name").optionalArg(false).numberOfArgs(1).build();
- Option bits = Option.builder("b").longOpt("bits").hasArg().argName("n").optionalArg(false).desc("What size of curve to use.").numberOfArgs(1).build();
- Option output = Option.builder("o").longOpt("output").desc("Output into file <output_file>.").hasArgs().argName("output_file").optionalArg(false).numberOfArgs(1).build();
- Option timeSource = Option.builder("ts").longOpt("time-source").desc("Use a given native timing source: {rdtsc, monotonic, monotonic-raw, cputime-process, cputime-thread, perfcount}").hasArgs().argName("source").optionalArg(false).numberOfArgs(1).build();
-
- Options testOpts = new Options();
- testOpts.addOption(bits);
- testOpts.addOption(namedCurve);
- testOpts.addOption(curveName);
- testOpts.addOption(Option.builder("gt").longOpt("kpg-type").desc("Set the KeyPairGenerator object [type].").hasArg().argName("type").optionalArg(false).build());
- testOpts.addOption(Option.builder("kt").longOpt("ka-type").desc("Set the KeyAgreement object [type].").hasArg().argName("type").optionalArg(false).build());
- testOpts.addOption(Option.builder("st").longOpt("sig-type").desc("Set the Signature object [type].").hasArg().argName("type").optionalArg(false).build());
- testOpts.addOption(Option.builder("f").longOpt("format").desc("Set the output format, one of text,yaml,xml.").hasArg().argName("format").optionalArg(false).build());
- testOpts.addOption(Option.builder().longOpt("key-type").desc("Set the key [algorithm] for which the key should be derived in KeyAgreements with KDF. Default is \"AES\".").hasArg().argName("algorithm").optionalArg(false).build());
- List<Argument> testArgs = new LinkedList<>();
- testArgs.add(new Argument("test-suite", "The test suite to run.", true));
- ParserOptions test = new ParserOptions(new TreeParser(Collections.emptyMap(), true, testArgs), testOpts, "Test a library.");
- actions.put("test", test);
-
- Options ecdhOpts = new Options();
- ecdhOpts.addOption(bits);
- ecdhOpts.addOption(namedCurve);
- ecdhOpts.addOption(curveName);
- ecdhOpts.addOption(output);
- ecdhOpts.addOption(timeSource);
- ecdhOpts.addOption(Option.builder("t").longOpt("type").desc("Set KeyAgreement object [type].").hasArg().argName("type").optionalArg(false).build());
- ecdhOpts.addOption(Option.builder().longOpt("key-type").desc("Set the key [algorithm] for which the key should be derived in KeyAgreements with KDF. Default is \"AES\".").hasArg().argName("algorithm").optionalArg(false).build());
- ecdhOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do ECDH [amount] times.").build());
- ecdhOpts.addOptionGroup(publicKey);
- ecdhOpts.addOption(Option.builder().longOpt("fixed-private").desc("Perform ECDH with fixed private key.").build());
- ecdhOpts.addOptionGroup(privateKey);
- ecdhOpts.addOption(Option.builder().longOpt("fixed-public").desc("Perform ECDH with fixed public key.").build());
- ParserOptions ecdh = new ParserOptions(new DefaultParser(), ecdhOpts, "Perform EC based KeyAgreement.");
- actions.put("ecdh", ecdh);
-
- Options ecdsaOpts = new Options();
- ecdsaOpts.addOption(bits);
- ecdsaOpts.addOption(namedCurve);
- ecdsaOpts.addOption(curveName);
- ecdsaOpts.addOption(output);
- ecdsaOpts.addOption(timeSource);
- ecdsaOpts.addOptionGroup(privateKey);
- ecdsaOpts.addOptionGroup(publicKey);
- ecdsaOpts.addOption(Option.builder().longOpt("fixed").desc("Perform all ECDSA with fixed keypair.").build());
- ecdsaOpts.addOption(Option.builder("t").longOpt("type").desc("Set Signature object [type].").hasArg().argName("type").optionalArg(false).build());
- ecdsaOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do ECDSA [amount] times.").build());
- ecdsaOpts.addOption(Option.builder("f").longOpt("file").hasArg().argName("file").optionalArg(false).desc("Input [file] to sign.").build());
- ParserOptions ecdsa = new ParserOptions(new DefaultParser(), ecdsaOpts, "Perform EC based Signature.");
- actions.put("ecdsa", ecdsa);
-
- Options generateOpts = new Options();
- generateOpts.addOption(bits);
- generateOpts.addOption(namedCurve);
- generateOpts.addOption(curveName);
- generateOpts.addOption(output);
- generateOpts.addOption(timeSource);
- generateOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Generate [amount] of EC keys.").build());
- generateOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPairGenerator object [type].").build());
- ParserOptions generate = new ParserOptions(new DefaultParser(), generateOpts, "Generate EC keypairs.");
- actions.put("generate", generate);
-
- Options exportOpts = new Options();
- exportOpts.addOption(bits);
- exportOpts.addOption(output);
- exportOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPair object [type].").build());
- ParserOptions export = new ParserOptions(new DefaultParser(), exportOpts, "Export default curve parameters.");
- actions.put("export", export);
-
- Options listDataOpts = new Options();
- List<Argument> listDataArgs = new LinkedList<>();
- listDataArgs.add(new Argument("what", "what to list.", false));
- ParserOptions listData = new ParserOptions(new TreeParser(Collections.emptyMap(), false, listDataArgs), listDataOpts, "List/show contained EC domain parameters/keys.");
- actions.put("list-data", listData);
-
- Options listLibsOpts = new Options();
- ParserOptions listLibs = new ParserOptions(new DefaultParser(), listLibsOpts, "List supported libraries.");
- actions.put("list-libs", listLibs);
-
- Options listSuitesOpts = new Options();
- ParserOptions listSuites = new ParserOptions(new DefaultParser(), listSuitesOpts, "List supported test suites.");
- actions.put("list-suites", listSuites);
-
- Options listIdentsOpts = new Options();
- ParserOptions listIdents = new ParserOptions(new DefaultParser(), listIdentsOpts, "List KeyPairGenerator, KeyAgreement and Signature types.");
- actions.put("list-types", listIdents);
-
- List<Argument> baseArgs = new LinkedList<>();
- baseArgs.add(new Argument("lib", "What library to use.", false));
- optParser = new TreeParser(actions, false, baseArgs);
-
- opts.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build());
- opts.addOption(Option.builder("h").longOpt("help").desc("Print help(about <command>).").hasArg().argName("command").optionalArg(true).build());
- opts.addOption(Option.builder("C").longOpt("color").desc("Print stuff with color, requires ANSI terminal.").build());
-
- return optParser.parse(opts, args);
- }
-
- /**
- *
- */
- private void listLibraries() {
- for (ProviderECLibrary lib : libs) {
- if (lib.isInitialized() && (cfg.selected == null || lib == cfg.selected)) {
- System.out.println("\t- " + Colors.bold(lib.name()));
- System.out.println(Colors.bold("\t\t- Version: ") + String.format("%f", lib.getProvider().getVersion()));
- System.out.println(Colors.bold("\t\t- Supports native timing: ") + lib.getNativeTimingSupport().toString());
- Set<KeyPairGeneratorIdent> kpgs = lib.getKPGs();
- if (!kpgs.isEmpty()) {
- System.out.println(Colors.bold("\t\t- KeyPairGenerators: ") + String.join(", ", kpgs.stream().map(KeyPairGeneratorIdent::getName).collect(Collectors.toList())));
- }
- Set<KeyAgreementIdent> eckas = lib.getKAs();
- if (!eckas.isEmpty()) {
- System.out.println(Colors.bold("\t\t- KeyAgreements: ") + String.join(", ", eckas.stream().map(KeyAgreementIdent::getName).collect(Collectors.toList())));
- }
- Set<SignatureIdent> sigs = lib.getSigs();
- if (!sigs.isEmpty()) {
- System.out.println(Colors.bold("\t\t- Signatures: ") + String.join(", ", sigs.stream().map(SignatureIdent::getName).collect(Collectors.toList())));
- }
- Set<String> curves = lib.getCurves();
- if (!curves.isEmpty()) {
- System.out.println(Colors.bold("\t\t- Curves: ") + String.join(", ", curves));
- }
- System.out.println();
- }
- }
- }
-
- /**
- *
- */
- private void listSuites() {
- StandaloneTestSuite[] suites = new StandaloneTestSuite[]{
- new StandaloneDefaultSuite(null, null, null),
- new StandaloneTestVectorSuite(null, null, null),
- new StandaloneInvalidSuite(null, null, null),
- new StandaloneWrongSuite(null, null, null),
- new StandaloneDegenerateSuite(null, null, null),
- new StandaloneCofactorSuite(null, null, null),
- new StandaloneEdgeCasesSuite(null, null, null),
- new StandaloneSignatureSuite(null, null, null),
- new StandaloneCompositeSuite(null, null, null),
- new StandaloneTwistSuite(null, null, null),
- new StandaloneMiscSuite(null, null, null),
- new StandalonePerformanceSuite(null, null, null)};
- for (StandaloneTestSuite suite : suites) {
- System.out.println(" - " + suite.getName());
- for (String line : suite.getDescription()) {
- System.out.println("\t" + line);
- }
- }
- }
-
- /**
- *
- */
- private void listIdents() {
- System.out.println(Colors.bold("\t- KeyPairGenerator"));
- for (KeyPairGeneratorIdent kpgIdent : KeyPairGeneratorIdent.list()) {
- System.out.println("\t\t- " + Colors.underline(kpgIdent.getName()) + " " + kpgIdent.toString());
- }
- System.out.println(Colors.bold("\t- KeyAgreement"));
- for (KeyAgreementIdent kaIdent : KeyAgreementIdent.list()) {
- System.out.println("\t\t- " + Colors.underline(kaIdent.getName()) + " " + kaIdent.toString());
- }
- System.out.println(Colors.bold("\t- Signature"));
- for (SignatureIdent sigIdent : SignatureIdent.list()) {
- System.out.println("\t\t- " + Colors.underline(sigIdent.getName()) + " " + sigIdent.toString());
- }
- }
-
- /**
- *
- */
- private void ecdh() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException {
- ProviderECLibrary lib = cfg.selected;
-
- String algo = cli.getOptionValue("ecdh.type", "ECDH");
- String keyAlgo = cli.getOptionValue("ecdh.key-type", "AES");
- KeyAgreementIdent kaIdent = lib.getKAs().stream()
- .filter((ident) -> ident.contains(algo))
- .findFirst()
- .orElse(null);
-
- String baseAlgo;
- if (algo.contains("with")) {
- baseAlgo = algo.split("with")[0];
- } else {
- baseAlgo = algo;
- }
-
- KeyPairGeneratorIdent kpIdent = lib.getKPGs().stream()
- .filter((ident) -> ident.contains(algo))
- .findFirst()
- .orElse(lib.getKPGs().stream()
- .filter((ident) -> ident.contains(baseAlgo))
- .findFirst()
- .orElse(lib.getKPGs().stream()
- .filter((ident) -> ident.contains("ECDH"))
- .findFirst()
- .orElse(lib.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst()
- .orElse(null))));
-
- if (kaIdent == null || kpIdent == null) {
- throw new NoSuchAlgorithmException(algo);
- }
-
- KeyAgreement ka = kaIdent.getInstance(lib.getProvider());
- KeyPairGenerator kpg = kpIdent.getInstance(lib.getProvider());
- AlgorithmParameterSpec spec = null;
- if (cli.hasOption("ecdh.bits")) {
- int bits = Integer.parseInt(cli.getOptionValue("ecdh.bits"));
- kpg.initialize(bits);
- } else if (cli.hasOption("ecdh.named-curve")) {
- String curveName = cli.getOptionValue("ecdh.named-curve");
- EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName);
- if (curve == null) {
- System.err.println("Curve not found: " + curveName);
- return;
- }
- spec = curve.toSpec();
- kpg.initialize(spec);
- } else if (cli.hasOption("ecdh.curve-name")) {
- String curveName = cli.getOptionValue("ecdh.curve-name");
- spec = new ECGenParameterSpec(curveName);
- kpg.initialize(spec);
- }
-
- if (cli.hasOption("ecdh.time-source")) {
- if (!lib.setNativeTimingType(cli.getOptionValue("ecdh.time-source"))) {
- System.err.println("Couldn't set native time source.");
- return;
- }
- }
-
- PrintStream out;
- if (cli.hasOption("ecdh.output")) {
- out = new PrintStream(FileUtil.openStream(cli.getOptionValues("ecdh.output")));
- } else {
- out = System.out;
- }
-
- String timeUnit = "nano";
- if (!lib.getNativeTimingSupport().isEmpty()) {
- timeUnit = lib.getNativeTimingUnit();
- }
-
- String hashAlgo = kaIdent.getBaseAlgo() != null ? String.format("[%s]", kaIdent.getBaseAlgo()) : "[NONE]";
- out.println(String.format("index;time[%s];pubW;privS;secret%s", timeUnit, hashAlgo));
-
- KeyPair one = null;
- if (cli.hasOption("ecdh.fixed-private") && !cli.hasOption("ecdh.named-private") && !cli.hasOption("ecdh.private")) {
- one = kpg.genKeyPair();
- }
- KeyPair other = null;
- if (cli.hasOption("ecdh.fixed-public") && !cli.hasOption("ecdh.named-public") && !cli.hasOption("ecdh.public")) {
- 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);
-
- int amount = Integer.parseInt(cli.getOptionValue("ecdh.amount", "1"));
- for (int i = 0; i < amount || amount == 0; ++i) {
- if (!cli.hasOption("ecdh.fixed-private") && !cli.hasOption("ecdh.named-private") && !cli.hasOption("ecdh.private")) {
- one = kpg.genKeyPair();
- }
- if (!cli.hasOption("ecdh.fixed-public") && !cli.hasOption("ecdh.named-public") && !cli.hasOption("ecdh.public")) {
- other = kpg.genKeyPair();
- }
-
- if (!cli.hasOption("ecdh.named-private") && !cli.hasOption("ecdh.private")) {
- privkey = (ECPrivateKey) one.getPrivate();
- }
-
- if (!cli.hasOption("ecdh.named-public") && !cli.hasOption("ecdh.public")) {
- pubkey = (ECPublicKey) other.getPublic();
- }
-
- long elapsed = -System.nanoTime();
- if (spec instanceof ECParameterSpec && lib instanceof NativeECLibrary) {
- ka.init(privkey, spec);
- } else {
- ka.init(privkey);
- }
- ka.doPhase(pubkey, true);
- elapsed += System.nanoTime();
- SecretKey derived;
- byte[] result;
- elapsed -= System.nanoTime();
- if (kaIdent.requiresKeyAlgo()) {
- derived = ka.generateSecret(keyAlgo);
- result = derived.getEncoded();
- } else {
- result = ka.generateSecret();
- }
- elapsed += System.nanoTime();
- if (!lib.getNativeTimingSupport().isEmpty()) {
- elapsed = lib.getLastNativeTiming();
- }
- 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 dh = ByteUtil.bytesToHex(result, false);
- out.println(String.format("%d;%d;%s;%s;%s", i, elapsed, pub, priv, dh));
- }
-
- if (cli.hasOption("ecdh.output")) {
- out.close();
- }
- }
-
- /**
- *
- */
- private void ecdsa() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, IOException, SignatureException {
- byte[] data;
- String dataString;
- if (cli.hasOption("ecdsa.file")) {
- String fileName = cli.getOptionValue("ecdsa.file");
- File in = new File(fileName);
- long len = in.length();
- if (len == 0) {
- throw new FileNotFoundException(fileName);
- }
- data = Files.readAllBytes(in.toPath());
- dataString = "";
- } else {
- Random random = new Random();
- data = new byte[32];
- random.nextBytes(data);
- dataString = ByteUtil.bytesToHex(data, false);
- }
- ProviderECLibrary lib = cfg.selected;
- String algo = cli.getOptionValue("ecdsa.type", "ECDSA");
- SignatureIdent sigIdent = lib.getSigs().stream()
- .filter((ident) -> ident.contains(algo))
- .findFirst()
- .orElse(null);
-
- String baseAlgo;
- if (algo.contains("with")) {
- baseAlgo = algo.split("with")[1];
- } else {
- baseAlgo = algo;
- }
- KeyPairGeneratorIdent kpIdent = lib.getKPGs().stream()
- .filter((ident) -> ident.contains(algo))
- .findFirst()
- .orElse(lib.getKPGs().stream()
- .filter((ident) -> ident.contains(baseAlgo))
- .findFirst()
- .orElse(lib.getKPGs().stream()
- .filter((ident) -> ident.contains("ECDSA"))
- .findFirst()
- .orElse(lib.getKPGs().stream()
- .filter((ident) -> ident.contains("EC"))
- .findFirst()
- .orElse(null))));
-
- if (sigIdent == null || kpIdent == null) {
- throw new NoSuchAlgorithmException(algo);
- }
- Signature sig = sigIdent.getInstance(lib.getProvider());
- KeyPairGenerator kpg = kpIdent.getInstance(lib.getProvider());
- ECParameterSpec spec = null;
- if (cli.hasOption("ecdsa.bits")) {
- int bits = Integer.parseInt(cli.getOptionValue("ecdsa.bits"));
- kpg.initialize(bits);
- } else if (cli.hasOption("ecdsa.named-curve")) {
- String curveName = cli.getOptionValue("ecdsa.named-curve");
- EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName);
- if (curve == null) {
- System.err.println("Curve not found: " + curveName);
- return;
- }
- spec = curve.toSpec();
- kpg.initialize(spec);
- } else if (cli.hasOption("ecdsa.curve-name")) {
- String curveName = cli.getOptionValue("ecdsa.curve-name");
- kpg.initialize(new ECGenParameterSpec(curveName));
- }
-
- if (cli.hasOption("ecdsa.time-source")) {
- if (!lib.setNativeTimingType(cli.getOptionValue("ecdsa.time-source"))) {
- System.err.println("Couldn't set native time source.");
- return;
- }
- }
-
- PrintStream out;
- if (cli.hasOption("ecdsa.output")) {
- out = new PrintStream(FileUtil.openStream(cli.getOptionValues("ecdsa.output")));
- } else {
- out = System.out;
- }
-
- String timeUnit = "nano";
- if (!lib.getNativeTimingSupport().isEmpty()) {
- timeUnit = lib.getNativeTimingUnit();
- }
-
- String hashAlgo = sigIdent.getHashAlgo() != null ? String.format("[%s]", sigIdent.getHashAlgo()) : "";
- out.println(String.format("index;signTime[%s];verifyTime[%s];data;pubW;privS;signature%s;nonce;verified", timeUnit, timeUnit, hashAlgo));
-
- 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);
-
- KeyPair one;
- if (cli.hasOption("ecdsa.fixed")) {
- one = kpg.genKeyPair();
- if (!cli.hasOption("ecdsa.named-private")) {
- privkey = (ECPrivateKey) one.getPrivate();
- }
- if (!cli.hasOption("ecdsa.named-public")) {
- pubkey = (ECPublicKey) one.getPublic();
- }
- }
-
-
- int amount = Integer.parseInt(cli.getOptionValue("ecdsa.amount", "1"));
- for (int i = 0; i < amount || amount == 0; ++i) {
- if ((!cli.hasOption("ecdsa.named-private") || !cli.hasOption("ecdsa.named-public")) && !cli.hasOption("ecdsa.fixed")) {
- one = kpg.genKeyPair();
-
- if (!cli.hasOption("ecdsa.named-private")) {
- privkey = (ECPrivateKey) one.getPrivate();
- }
- if (!cli.hasOption("ecdsa.named-public")) {
- pubkey = (ECPublicKey) one.getPublic();
- }
- }
-
- sig.initSign(privkey);
- sig.update(data);
-
- long signTime = -System.nanoTime();
- byte[] signature = sig.sign();
- signTime += System.nanoTime();
- if (!lib.getNativeTimingSupport().isEmpty()) {
- signTime = lib.getLastNativeTiming();
- }
-
- sig.initVerify(pubkey);
- sig.update(data);
-
- long verifyTime = -System.nanoTime();
- boolean verified = sig.verify(signature);
- verifyTime += System.nanoTime();
- if (!lib.getNativeTimingSupport().isEmpty()) {
- verifyTime = lib.getLastNativeTiming();
- }
-
- String pub = ByteUtil.bytesToHex(ECUtil.toX962Uncompressed(pubkey.getW(), pubkey.getParams()), false);
- String priv = ByteUtil.bytesToHex(privkey.getS().toByteArray(), false);
- String sign = ByteUtil.bytesToHex(signature, false);
- String k = "";
- ECParameterSpec kSpec = spec;
- if (kSpec == null) {
- kSpec = privkey.getParams();
- }
- if (kSpec != null) {
- BigInteger kValue = ECUtil.recoverSignatureNonce(signature, data, privkey.getS(), kSpec, sigIdent);
- if (kValue != null) {
- k = ByteUtil.bytesToHex(kValue.toByteArray(), false);
- }
- }
- out.println(String.format("%d;%d;%d;%s;%s;%s;%s;%s;%d", i, signTime, verifyTime, dataString, pub, priv, sign, k, verified ? 1 : 0));
- }
-
- if (cli.hasOption("ecdsa.output")) {
- out.close();
- }
- }
-
- /**
- *
- */
- private void generate() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, FileNotFoundException {
- ProviderECLibrary lib = cfg.selected;
- KeyPairGeneratorIdent ident = null;
- String algo = cli.getOptionValue("generate.type", "EC");
- for (KeyPairGeneratorIdent kpIdent : lib.getKPGs()) {
- if (kpIdent.contains(algo)) {
- ident = kpIdent;
- break;
- }
- }
- if (ident == null) {
- throw new NoSuchAlgorithmException(algo);
- }
- KeyPairGenerator kpg = ident.getInstance(lib.getProvider());
- if (cli.hasOption("generate.bits")) {
- int bits = Integer.parseInt(cli.getOptionValue("generate.bits"));
- kpg.initialize(bits);
- } else if (cli.hasOption("generate.named-curve")) {
- String curveName = cli.getOptionValue("generate.named-curve");
- EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, curveName);
- if (curve == null) {
- System.err.println("Curve not found: " + curveName);
- return;
- }
- kpg.initialize(curve.toSpec());
- } else if (cli.hasOption("generate.curve-name")) {
- String curveName = cli.getOptionValue("generate.curve-name");
- kpg.initialize(new ECGenParameterSpec(curveName));
- }
-
- if (cli.hasOption("generate.time-source")) {
- if (!lib.setNativeTimingType(cli.getOptionValue("generate.time-source"))) {
- System.err.println("Couldn't set native time source.");
- return;
- }
- }
-
- String timeUnit = "nano";
- if (!lib.getNativeTimingSupport().isEmpty()) {
- timeUnit = lib.getNativeTimingUnit();
- }
-
- PrintStream out;
- if (cli.hasOption("generate.output")) {
- out = new PrintStream(FileUtil.openStream(cli.getOptionValues("generate.output")));
- } else {
- out = System.out;
- }
-
- out.println(String.format("index;time[%s];pubW;privS", timeUnit));
-
- int amount = Integer.parseInt(cli.getOptionValue("generate.amount", "1"));
- for (int i = 0; i < amount || amount == 0; ++i) {
- long elapsed = -System.nanoTime();
- KeyPair kp = kpg.genKeyPair();
- elapsed += System.nanoTime();
- 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);
- out.println(String.format("%d;%d;%s;%s", i, elapsed, pub, priv));
- }
-
- if (cli.hasOption("generate.output")) {
- out.close();
- }
- }
-
- /**
- *
- */
- private void test() throws TestException, ParserConfigurationException {
- TestWriter writer;
- switch (cli.getOptionValue("test.format", "text").toLowerCase()) {
- case "yaml":
- case "yml":
- writer = new YAMLTestWriter(System.out);
- break;
- case "xml":
- writer = new XMLTestWriter(System.out);
- break;
- case "text":
- default:
- writer = new TextTestWriter(System.out);
- break;
- }
-
- StandaloneTestSuite suite;
-
- switch (cli.getArg(0).toLowerCase()) {
- case "test-vectors":
- suite = new StandaloneTestVectorSuite(writer, cfg, cli);
- break;
- case "wrong":
- suite = new StandaloneWrongSuite(writer, cfg, cli);
- break;
- case "degenerate":
- suite = new StandaloneDegenerateSuite(writer, cfg, cli);
- break;
- case "cofactor":
- suite = new StandaloneCofactorSuite(writer, cfg, cli);
- break;
- case "composite":
- suite = new StandaloneCompositeSuite(writer, cfg, cli);
- break;
- case "invalid":
- suite = new StandaloneInvalidSuite(writer, cfg, cli);
- break;
- case "edge-cases":
- suite = new StandaloneEdgeCasesSuite(writer, cfg, cli);
- break;
- case "signature":
- suite = new StandaloneSignatureSuite(writer, cfg, cli);
- break;
- case "twist":
- suite = new StandaloneTwistSuite(writer, cfg, cli);
- break;
- case "miscellaneous":
- suite = new StandaloneMiscSuite(writer, cfg, cli);
- break;
- case "performance":
- suite = new StandalonePerformanceSuite(writer, cfg, cli);
- break;
- case "default":
- default:
- suite = new StandaloneDefaultSuite(writer, cfg, cli);
- }
-
- suite.run();
- }
-
- /**
- *
- */
- private void export() throws NoSuchAlgorithmException, IOException {
- ProviderECLibrary lib = cfg.selected;
- KeyPairGeneratorIdent ident = null;
- String algo = cli.getOptionValue("export.type", "EC");
- for (KeyPairGeneratorIdent kpIdent : lib.getKPGs()) {
- if (kpIdent.contains(algo)) {
- ident = kpIdent;
- break;
- }
- }
- if (ident == null) {
- throw new NoSuchAlgorithmException(algo);
- }
- KeyPairGenerator kpg = ident.getInstance(lib.getProvider());
- if (cli.hasOption("export.bits")) {
- int bits = Integer.parseInt(cli.getOptionValue("export.bits"));
- kpg.initialize(bits);
- }
- KeyPair kp = kpg.genKeyPair();
- ECPrivateKey privateKey = (ECPrivateKey) kp.getPrivate();
- ECParameterSpec params = privateKey.getParams();
- System.out.println(params);
- EC_Curve curve = EC_Curve.fromSpec(params);
- curve.writeCSV(System.out);
- }
-
- public static void main(String[] args) {
- ECTesterStandalone app = new ECTesterStandalone();
- app.run(args);
- }
-
-
- /**
- *
- */
- public static class Config {
- private ProviderECLibrary[] libs;
- public ProviderECLibrary selected = null;
- public boolean color = false;
-
- public Config(ProviderECLibrary[] libs) {
- this.libs = libs;
- }
-
- boolean readOptions(TreeCommandLine cli) {
- color = cli.hasOption("color");
- Colors.enabled = color;
-
- String next = cli.getNextName();
-
- if (cli.isNext("generate") || cli.isNext("export") || cli.isNext("ecdh") || cli.isNext("ecdsa") || cli.isNext("test")) {
- if (!cli.hasArg(-1)) {
- System.err.println("Missing library name argument.");
- return false;
- }
-
- boolean hasBits = cli.hasOption(next + ".bits");
- boolean hasNamedCurve = cli.hasOption(next + ".named-curve");
- boolean hasCurveName = cli.hasOption(next + ".curve-name");
- if (hasBits ^ hasNamedCurve ? hasCurveName : hasBits) {
- System.err.println("You can only specify bitsize or a named curve/curve name, nor both.");
- return false;
- }
-
- if (hasCurveName && (cli.hasOption(next + ".named-public") || cli.hasOption(next + ".named-private") || cli.hasOption(next + ".public") || cli.hasOption(next + ".private"))) {
- System.err.println("Cannot specify key with a curve name switch, needs explicit parameteres.");
- return false;
- }
- }
-
- if (!cli.isNext("list-data") && !cli.isNext("list-suites") && !cli.isNext("list-types")) {
- String libraryName = cli.getArg(-1);
- if (libraryName != null) {
- List<ProviderECLibrary> matchedLibs = new LinkedList<>();
- for (ProviderECLibrary lib : libs) {
- if (lib.isInitialized() && lib.name().toLowerCase().contains(libraryName.toLowerCase())) {
- matchedLibs.add(lib);
- }
- }
- if (matchedLibs.size() == 0) {
- System.err.println("No library " + libraryName + " found.");
- return false;
- } else if (matchedLibs.size() > 1) {
- System.err.println("Multiple matching libraries found: " + String.join(",", matchedLibs.stream().map(ECLibrary::name).collect(Collectors.toList())));
- return false;
- } else {
- selected = matchedLibs.get(0);
- }
- }
- }
-
- if (cli.hasOption("test.format")) {
- String fmt = cli.getOptionValue("test.format");
- String[] formats = new String[]{"text", "xml", "yaml", "yml"};
- if (!Arrays.asList(formats).contains(fmt.toLowerCase())) {
- System.err.println("Invalid format specified.");
- return false;
- }
- }
-
- if (cli.isNext("ecdh")) {
- if ((cli.hasOption("ecdh.public") || cli.hasOption("ecdh.private")) && !cli.hasOption("ecdh.named-curve")) {
- System.err.println("Need to specify a named curve when specifying public/private key in file.");
- return false;
- }
- }
-
- if (cli.isNext("ecdsa")) {
- if ((cli.hasOption("ecdsa.public") || cli.hasOption("ecdsa.private")) && !cli.hasOption("ecdsa.named-curve")) {
- System.err.println("Need to specify a named curve when specifying public/private key in file.");
- return false;
- }
- }
-
- if (cli.isNext("generate") || cli.isNext("ecdh") || cli.isNext("ecdsa")) {
- if (cli.hasOption(next + ".time-source")) {
- String source = cli.getOptionValue(next + ".time-source");
- if (!selected.getNativeTimingSupport().contains(source)) {
- System.err.println(String.format("Time source %s unavailable for library %s.", source, selected.name()));
- return false;
- }
- }
- }
-
- return true;
- }
- }
-}