From 0e1498d43c14b5a739f3bc780df9045defd4cacf Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 28 Dec 2017 15:55:39 +0100 Subject: Add script for plotting key genration results. --- util/plot_gen.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100755 util/plot_gen.py (limited to 'util') diff --git a/util/plot_gen.py b/util/plot_gen.py new file mode 100755 index 0000000..9c824a6 --- /dev/null +++ b/util/plot_gen.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# Script for plotting ECTester key generation results. +# +# Example usage: +# +# > java -jar ECTesterReader.jar -g 10000 -b 192 -fp -o gen.csv +# ... +# > ./plot_gen.py gen.csv +# ... +# + +import numpy as np +import matplotlib.pyplot as plt +from operator import itemgetter +import argparse + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Plot results of ECTester key generation timing.") + parser.add_argument("-o", "--output", dest="output", type=argparse.FileType("wb"), help="Write image to [file], do not display.", metavar="file") + parser.add_argument("--pub", dest="pub", action="store_true", help="Show public key scatter plot.") + parser.add_argument("--priv", dest="priv", action="store_true", help="Show private key scatter plot.") + parser.add_argument("--hist", dest="hist", action="store_true", help="Show histogram.") + parser.add_argument("file", type=str, help="The file to plot(csv).") + + opts = parser.parse_args() + + plots = [opts.priv, opts.pub, opts.hist] + n_plots = sum(plots) + if n_plots == 0: + n_plots = 3 + plots = [True, True, True] + + hx = lambda x: int(x, 16) + data = np.genfromtxt(opts.file, delimiter=";", skip_header=1, converters={2: hx, 3: hx}, dtype=np.dtype([("index","u4"), ("time","u4"), ("pub", "O"), ("priv", "O")])) + + time_data = map(itemgetter(1), data) + priv_data = map(itemgetter(2), data) + pub_data = map(itemgetter(3), data) + + fig = plt.figure(tight_layout=True) + fig.suptitle(opts.file) + + plot_i = 1 + if plots[0]: + axe_private = fig.add_subplot(n_plots, 1, plot_i) + axe_private.scatter(time_data, priv_data, marker="x", s=10) + axe_private.set_ylabel("private key value\n(big endian)") + axe_private.set_xlabel("time (ms)") + plot_i += 1 + + if plots[1]: + axe_public = fig.add_subplot(n_plots, 1, plot_i) + axe_public.scatter(time_data, pub_data, marker="x", s=10) + axe_public.set_ylabel("public key value\n(big endian)") + axe_public.set_xlabel("time (ms)") + plot_i += 1 + + if plots[2]: + axe_hist = fig.add_subplot(n_plots, 1, plot_i) + axe_hist.hist(time_data, bins=400, log=True) + axe_hist.set_ylabel("count\n(log)") + axe_hist.set_xlabel("time (ms)") + + if opts.output is None: + plt.show() + else: + plt.savefig(opts.output, dpi=400) -- cgit v1.2.3-70-g09d2 From 552289fd86446416eefec6356659a8333d091f79 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 28 Dec 2017 17:53:05 +0100 Subject: Add script to plot ECDH timing. --- util/plot_dh.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 util/plot_dh.py (limited to 'util') diff --git a/util/plot_dh.py b/util/plot_dh.py new file mode 100755 index 0000000..eb1886a --- /dev/null +++ b/util/plot_dh.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Script for plotting ECTester ECDH results. +# +# Example usage: +# +# > java -jar ECTesterReader.jar -dh 10000 -b 192 -fp -o dh.csv +# ... +# > ./plot_dh.py dh.csv +# ... +# + +import numpy as np +import matplotlib.pyplot as plt +import argparse +from operator import itemgetter + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Plot ECTester ECDH timing.") + parser.add_argument("-o", "--output", dest="output", type=argparse.FileType("wb"), help="Write image to [file], do not display.", metavar="file") + parser.add_argument("file", type=str, help="The file to plot(csv).") + + opts = parser.parse_args() + + hx = lambda x: int(x, 16) + data = np.genfromtxt(opts.file, delimiter=";", skip_header=1, converters={2: hx, 3: hx, 4: hx}, dtype=np.dtype([("index","u4"), ("time","u4"), ("pub", "O"), ("priv", "O"), ("secret","O")])) + + time_data = map(itemgetter(1), data) + priv_data = map(itemgetter(2), data) + pub_data = map(itemgetter(3), data) + secret_data = map(itemgetter(4), data) + + fig = plt.figure(tight_layout=True) + fig.suptitle(opts.file) + + axe_hist = fig.add_subplot(1,1,1) + axe_hist.hist(time_data, bins=400, log=True) + axe_hist.set_ylabel("count\n(log)") + axe_hist.set_xlabel("time (ms)") + + if opts.output is None: + plt.show() + else: + plt.savefig(opts.output, dpi=400) -- cgit v1.2.3-70-g09d2 From 70bcab713bcc36f3f6a5886f4651967e1585fad6 Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 28 Dec 2017 18:54:19 +0100 Subject: Add average and median plotting. --- util/plot_dh.py | 10 +++++++++- util/plot_gen.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'util') diff --git a/util/plot_dh.py b/util/plot_dh.py index eb1886a..62a2f86 100755 --- a/util/plot_dh.py +++ b/util/plot_dh.py @@ -12,6 +12,7 @@ import numpy as np import matplotlib.pyplot as plt +import matplotlib.ticker as ticker import argparse from operator import itemgetter @@ -34,9 +35,16 @@ if __name__ == "__main__": fig.suptitle(opts.file) axe_hist = fig.add_subplot(1,1,1) - axe_hist.hist(time_data, bins=400, log=True) + time_max = max(time_data) + time_avg = np.average(time_data) + time_median = np.median(time_data) + axe_hist.hist(time_data, bins=time_max/3, log=True) + axe_hist.axvline(x=time_avg, alpha=0.7, linestyle="dotted", color="red", label="avg = {}".format(time_avg)) + axe_hist.axvline(x=time_median, alpha=0.7, linestyle="dotted", color="green", label="median = {}".format(time_median)) axe_hist.set_ylabel("count\n(log)") axe_hist.set_xlabel("time (ms)") + axe_hist.xaxis.set_major_locator(ticker.MaxNLocator()) + axe_hist.legend(loc="best") if opts.output is None: plt.show() diff --git a/util/plot_gen.py b/util/plot_gen.py index 9c824a6..00892b5 100755 --- a/util/plot_gen.py +++ b/util/plot_gen.py @@ -12,6 +12,7 @@ import numpy as np import matplotlib.pyplot as plt +import matplotlib.ticker as ticker from operator import itemgetter import argparse @@ -58,9 +59,16 @@ if __name__ == "__main__": if plots[2]: axe_hist = fig.add_subplot(n_plots, 1, plot_i) - axe_hist.hist(time_data, bins=400, log=True) + time_max = max(time_data) + time_avg = np.average(time_data) + time_median = np.median(time_data) + axe_hist.hist(time_data, bins=time_max/3, log=True) + axe_hist.axvline(x=time_avg, alpha=0.7, linestyle="dotted", color="red", label="avg = {}".format(time_avg)) + axe_hist.axvline(x=time_median, alpha=0.7, linestyle="dotted", color="green", label="median = {}".format(time_median)) axe_hist.set_ylabel("count\n(log)") axe_hist.set_xlabel("time (ms)") + axe_hist.xaxis.set_major_locator(ticker.MaxNLocator()) + axe_hist.legend(loc="best") if opts.output is None: plt.show() -- cgit v1.2.3-70-g09d2 From f0cc9ea002d6e853075e2d99a81d8537e2b2f41f Mon Sep 17 00:00:00 2001 From: J08nY Date: Thu, 28 Dec 2017 20:38:56 +0100 Subject: Properly plot data from standalone app. --- util/plot_dh.py | 17 +++++++++++++++-- util/plot_gen.py | 21 +++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'util') diff --git a/util/plot_dh.py b/util/plot_dh.py index 62a2f86..2aa7d21 100755 --- a/util/plot_dh.py +++ b/util/plot_dh.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: UTF-8 -*- # # Script for plotting ECTester ECDH results. # @@ -23,10 +24,19 @@ if __name__ == "__main__": opts = parser.parse_args() + with open(opts.file, "r") as f: + header = f.readline() + header_names = header.split(";") + hx = lambda x: int(x, 16) data = np.genfromtxt(opts.file, delimiter=";", skip_header=1, converters={2: hx, 3: hx, 4: hx}, dtype=np.dtype([("index","u4"), ("time","u4"), ("pub", "O"), ("priv", "O"), ("secret","O")])) - time_data = map(itemgetter(1), data) + if "nano" in header_names[1]: + unit = r"$\mu s$" + time_data = map(lambda x: x[1]/1000, data) + else: + unit = r"ms" + time_data = map(itemgetter(1), data) priv_data = map(itemgetter(2), data) pub_data = map(itemgetter(3), data) secret_data = map(itemgetter(4), data) @@ -42,11 +52,14 @@ if __name__ == "__main__": axe_hist.axvline(x=time_avg, alpha=0.7, linestyle="dotted", color="red", label="avg = {}".format(time_avg)) axe_hist.axvline(x=time_median, alpha=0.7, linestyle="dotted", color="green", label="median = {}".format(time_median)) axe_hist.set_ylabel("count\n(log)") - axe_hist.set_xlabel("time (ms)") + axe_hist.set_xlabel("time ({})".format(unit)) axe_hist.xaxis.set_major_locator(ticker.MaxNLocator()) axe_hist.legend(loc="best") + fig.text(0.01, 0.02, "Data size: {}".format(len(time_data)), size="small") + if opts.output is None: plt.show() else: + fig.set_size_inches(12, 10) plt.savefig(opts.output, dpi=400) diff --git a/util/plot_gen.py b/util/plot_gen.py index 00892b5..db78f8d 100755 --- a/util/plot_gen.py +++ b/util/plot_gen.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- coding: UTF-8 -*- # # Script for plotting ECTester key generation results. # @@ -26,6 +27,10 @@ if __name__ == "__main__": opts = parser.parse_args() + with open(opts.file, "r") as f: + header = f.readline() + header_names = header.split(";") + plots = [opts.priv, opts.pub, opts.hist] n_plots = sum(plots) if n_plots == 0: @@ -35,7 +40,12 @@ if __name__ == "__main__": hx = lambda x: int(x, 16) data = np.genfromtxt(opts.file, delimiter=";", skip_header=1, converters={2: hx, 3: hx}, dtype=np.dtype([("index","u4"), ("time","u4"), ("pub", "O"), ("priv", "O")])) - time_data = map(itemgetter(1), data) + if "nano" in header_names[1]: + unit = r"$\mu s$" + time_data = map(lambda x: x[1]/1000, data) + else: + unit = r"ms" + time_data = map(itemgetter(1), data) priv_data = map(itemgetter(2), data) pub_data = map(itemgetter(3), data) @@ -47,14 +57,14 @@ if __name__ == "__main__": axe_private = fig.add_subplot(n_plots, 1, plot_i) axe_private.scatter(time_data, priv_data, marker="x", s=10) axe_private.set_ylabel("private key value\n(big endian)") - axe_private.set_xlabel("time (ms)") + axe_private.set_xlabel("time ({})".format(unit)) plot_i += 1 if plots[1]: axe_public = fig.add_subplot(n_plots, 1, plot_i) axe_public.scatter(time_data, pub_data, marker="x", s=10) axe_public.set_ylabel("public key value\n(big endian)") - axe_public.set_xlabel("time (ms)") + axe_public.set_xlabel("time ({})".format(unit)) plot_i += 1 if plots[2]: @@ -66,11 +76,14 @@ if __name__ == "__main__": axe_hist.axvline(x=time_avg, alpha=0.7, linestyle="dotted", color="red", label="avg = {}".format(time_avg)) axe_hist.axvline(x=time_median, alpha=0.7, linestyle="dotted", color="green", label="median = {}".format(time_median)) axe_hist.set_ylabel("count\n(log)") - axe_hist.set_xlabel("time (ms)") + axe_hist.set_xlabel("time ({})".format(unit)) axe_hist.xaxis.set_major_locator(ticker.MaxNLocator()) axe_hist.legend(loc="best") + fig.text(0.01, 0.02, "Data size: {}".format(len(time_data)), size="small") + if opts.output is None: plt.show() else: + fig.set_size_inches(12, 10) plt.savefig(opts.output, dpi=400) -- cgit v1.2.3-70-g09d2 From 9b2cb89738abd4c83d8175069bcb1902ebe2997b Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 30 Dec 2017 19:05:34 +0100 Subject: Fixed XML and YAML standalone output in case some tests fail. --- src/cz/crcs/ectester/common/util/ByteUtil.java | 6 +++ .../ectester/standalone/output/XMLTestWriter.java | 22 +++++++---- .../ectester/standalone/output/YAMLTestWriter.java | 45 ++++++++++++++++------ .../ectester/standalone/test/KeyAgreementTest.java | 2 +- .../ectester/standalone/test/KeyGeneratorTest.java | 2 +- .../ectester/standalone/test/SignatureTest.java | 2 +- util/plot_dh.py | 1 + util/plot_gen.py | 1 + 8 files changed, 59 insertions(+), 22 deletions(-) (limited to 'util') diff --git a/src/cz/crcs/ectester/common/util/ByteUtil.java b/src/cz/crcs/ectester/common/util/ByteUtil.java index 939e487..90c6eaa 100644 --- a/src/cz/crcs/ectester/common/util/ByteUtil.java +++ b/src/cz/crcs/ectester/common/util/ByteUtil.java @@ -84,6 +84,9 @@ public class ByteUtil { } public static String bytesToHex(byte[] data, boolean addSpace) { + if (data == null) { + return ""; + } return bytesToHex(data, 0, data.length, addSpace); } @@ -92,6 +95,9 @@ public class ByteUtil { } public static String bytesToHex(byte[] data, int offset, int len, boolean addSpace) { + if (data == null) { + return ""; + } StringBuilder buf = new StringBuilder(); for (int i = offset; i < (offset + len); i++) { buf.append(byteToHex(data[i])); diff --git a/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java b/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java index f1503cb..9606646 100644 --- a/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java +++ b/src/cz/crcs/ectester/standalone/output/XMLTestWriter.java @@ -24,6 +24,9 @@ public class XMLTestWriter extends BaseXMLTestWriter { private Element pkeyElement(PublicKey pkey) { Element pubkey = doc.createElement("pubkey"); + if (pkey == null) { + return pubkey; + } pubkey.setAttribute("algorithm", pkey.getAlgorithm()); pubkey.setAttribute("format", pkey.getFormat()); pubkey.setTextContent(ByteUtil.bytesToHex(pkey.getEncoded())); @@ -32,6 +35,9 @@ public class XMLTestWriter extends BaseXMLTestWriter { private Element skeyElement(PrivateKey skey) { Element privkey = doc.createElement("privkey"); + if (skey == null) { + return privkey; + } privkey.setAttribute("algorithm", skey.getAlgorithm()); privkey.setAttribute("format", skey.getFormat()); privkey.setTextContent(ByteUtil.bytesToHex(skey.getEncoded())); @@ -62,13 +68,15 @@ public class XMLTestWriter extends BaseXMLTestWriter { kgtElem.setAttribute("algo", kgt.getKpg().getAlgorithm()); Element keyPair = doc.createElement("key-pair"); - PublicKey pkey = kgt.getKeyPair().getPublic(); - Element pubkey = pkeyElement(pkey); - keyPair.appendChild(pubkey); - - PrivateKey skey = kgt.getKeyPair().getPrivate(); - Element privkey = skeyElement(skey); - keyPair.appendChild(privkey); + if (kgt.getKeyPair() != null) { + PublicKey pkey = kgt.getKeyPair().getPublic(); + Element pubkey = pkeyElement(pkey); + keyPair.appendChild(pubkey); + + PrivateKey skey = kgt.getKeyPair().getPrivate(); + Element privkey = skeyElement(skey); + keyPair.appendChild(privkey); + } kgtElem.appendChild(keyPair); return kgtElem; diff --git a/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java b/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java index 7ede623..2133a8e 100644 --- a/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java +++ b/src/cz/crcs/ectester/standalone/output/YAMLTestWriter.java @@ -8,6 +8,7 @@ import cz.crcs.ectester.standalone.test.KeyGeneratorTestable; import cz.crcs.ectester.standalone.test.SignatureTestable; import java.io.PrintStream; +import java.security.Key; import java.security.PrivateKey; import java.security.PublicKey; import java.util.HashMap; @@ -21,32 +22,52 @@ public class YAMLTestWriter extends BaseYAMLTestWriter { super(output); } + private Map keyObject(Key key) { + Map kObject = new HashMap<>(); + if (key == null) { + return kObject; + } + kObject.put("algo", key.getAlgorithm()); + kObject.put("format", key.getFormat()); + kObject.put("raw", ByteUtil.bytesToHex(key.getEncoded())); + return kObject; + } + private Map kaObject(KeyAgreementTestable kat) { Map katObject = new HashMap<>(); + katObject.put("algo", kat.getKa().getAlgorithm()); katObject.put("secret", ByteUtil.bytesToHex(kat.getSecret())); + + PublicKey pkey = kat.getPublicKey(); + katObject.put("pubkey", keyObject(pkey)); + + PrivateKey skey = kat.getPrivateKey(); + katObject.put("privkey", keyObject(skey)); return katObject; } private Map kgtObject(KeyGeneratorTestable kgt) { Map kgtObject = new HashMap<>(); - Map pubObject = new HashMap<>(); - PublicKey pkey = kgt.getKeyPair().getPublic(); - pubObject.put("algorithm", pkey.getAlgorithm()); - pubObject.put("format", pkey.getFormat()); - pubObject.put("raw", ByteUtil.bytesToHex(pkey.getEncoded())); - kgtObject.put("pubkey", pubObject); + kgtObject.put("algo", kgt.getKpg().getAlgorithm()); + + Map keypair = new HashMap<>(); + if (kgt.getKeyPair() != null) { + PublicKey pkey = kgt.getKeyPair().getPublic(); + Map pubObject = keyObject(pkey); + keypair.put("pubkey", pubObject); + + PrivateKey skey = kgt.getKeyPair().getPrivate(); + Map privObject = keyObject(skey); + keypair.put("privkey", privObject); + } - Map privObject = new HashMap<>(); - PrivateKey skey = kgt.getKeyPair().getPrivate(); - privObject.put("algorithm", skey.getAlgorithm()); - privObject.put("format", skey.getFormat()); - privObject.put("raw", ByteUtil.bytesToHex(skey.getEncoded())); - kgtObject.put("privkey", privObject); + kgtObject.put("keypair", keypair); return kgtObject; } private Map sigObject(SignatureTestable sig) { Map sigObject = new HashMap<>(); + sigObject.put("algo", sig.getSig().getAlgorithm()); sigObject.put("verified", sig.getVerified()); sigObject.put("raw", ByteUtil.bytesToHex(sig.getSignature())); return sigObject; diff --git a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java index e273a44..16a2080 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java +++ b/src/cz/crcs/ectester/standalone/test/KeyAgreementTest.java @@ -43,7 +43,7 @@ public class KeyAgreementTest extends SimpleTest { @Override public String getDescription() { - return "KeyAgreement test"; + return "KeyAgreement " + testable.getKa().getAlgorithm(); } @Override diff --git a/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java b/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java index a57e28c..93273ca 100644 --- a/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java +++ b/src/cz/crcs/ectester/standalone/test/KeyGeneratorTest.java @@ -28,7 +28,7 @@ public class KeyGeneratorTest extends SimpleTest { @Override public String getDescription() { - return "KeyPairGenerator test"; + return "KeyPairGenerator " + testable.getKpg().getAlgorithm(); } @Override diff --git a/src/cz/crcs/ectester/standalone/test/SignatureTest.java b/src/cz/crcs/ectester/standalone/test/SignatureTest.java index 97e387c..9746b91 100644 --- a/src/cz/crcs/ectester/standalone/test/SignatureTest.java +++ b/src/cz/crcs/ectester/standalone/test/SignatureTest.java @@ -28,7 +28,7 @@ public class SignatureTest extends SimpleTest { @Override public String getDescription() { - return "Signature test"; + return "Signature " + testable.getSig().getAlgorithm(); } @Override diff --git a/util/plot_dh.py b/util/plot_dh.py index 2aa7d21..8c1dfff 100755 --- a/util/plot_dh.py +++ b/util/plot_dh.py @@ -41,6 +41,7 @@ if __name__ == "__main__": pub_data = map(itemgetter(3), data) secret_data = map(itemgetter(4), data) + plt.style.use("ggplot") fig = plt.figure(tight_layout=True) fig.suptitle(opts.file) diff --git a/util/plot_gen.py b/util/plot_gen.py index db78f8d..016dd15 100755 --- a/util/plot_gen.py +++ b/util/plot_gen.py @@ -49,6 +49,7 @@ if __name__ == "__main__": priv_data = map(itemgetter(2), data) pub_data = map(itemgetter(3), data) + plt.style.use("ggplot") fig = plt.figure(tight_layout=True) fig.suptitle(opts.file) -- cgit v1.2.3-70-g09d2 From 3a654a1b6919c8d4c5982dac645c227a8ff2c5f1 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 5 Jan 2018 15:56:34 +0100 Subject: Throw exceptions when operations fail in standalone providers. --- src/cz/crcs/ectester/standalone/libs/jni/botan.cpp | 53 ++++++++++++++++------ src/cz/crcs/ectester/standalone/libs/jni/c_utils.c | 7 ++- src/cz/crcs/ectester/standalone/libs/jni/c_utils.h | 15 +++++- .../ectester/standalone/libs/jni/cpp_utils.cpp | 5 ++ .../ectester/standalone/libs/jni/cpp_utils.hpp | 15 +++++- .../crcs/ectester/standalone/libs/jni/tomcrypt.c | 7 +-- util/plot_dh.py | 3 ++ util/plot_gen.py | 3 ++ 8 files changed, 86 insertions(+), 22 deletions(-) (limited to 'util') diff --git a/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp b/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp index f87d68b..8e666d6 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp +++ b/src/cz/crcs/ectester/standalone/libs/jni/botan.cpp @@ -347,14 +347,19 @@ static jobject generate_from_group(JNIEnv* env, jobject self, Botan::EC_Group gr env->ReleaseStringUTFChars(type, type_data); std::unique_ptr skey; - if (type_str == "ECDH") { - skey = std::make_unique(rng, group); - } else if (type_str == "ECDSA") { - skey = std::make_unique(rng, group); - } else if (type_str == "ECKCDSA") { - skey = std::make_unique(rng, group); - } else if (type_str == "ECGDSA") { - skey = std::make_unique(rng, group); + try { + if (type_str == "ECDH") { + skey = std::make_unique(rng, group); + } else if (type_str == "ECDSA") { + skey = std::make_unique(rng, group); + } else if (type_str == "ECKCDSA") { + skey = std::make_unique(rng, group); + } else if (type_str == "ECGDSA") { + skey = std::make_unique(rng, group); + } + } catch (Botan::Exception & ex) { + throw_new(env, "java/security/GeneralSecurityException", ex.what()); + return NULL; } jobject ec_param_spec = params_from_group(env, group); @@ -403,7 +408,8 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return generate_from_group(env, self, curve_group); } } - //TODO throw an exception here? InvalidAlgorithmParameters one? + + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); return NULL; } @@ -469,13 +475,17 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKey } else if (type_str == "ECDHwithSHA512KDF") { kdf = "KDF1(SHA-512)"; key_len = 64; - } else { - //TODO what? } Botan::PK_Key_Agreement ka(skey, rng, kdf); - std::vector derived = Botan::unlock(ka.derive_key(key_len, pkey.public_value()).bits_of()); + std::vector derived; + try { + derived = Botan::unlock(ka.derive_key(key_len, pkey.public_value()).bits_of()); + } catch (Botan::Exception & ex) { + throw_new(env, "java/security/GeneralSecurityException", ex.what()); + return NULL; + } jbyteArray result = env->NewByteArray(derived.size()); jbyte *result_data = env->GetByteArrayElements(result, NULL); std::copy(derived.begin(), derived.end(), result_data); @@ -534,7 +544,14 @@ JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSig jsize data_length = env->GetArrayLength(data); jbyte *data_bytes = env->GetByteArrayElements(data, NULL); - std::vector sig = signer.sign_message((uint8_t*) data_bytes, data_length, rng); + std::vector sig; + try { + sig = signer.sign_message((uint8_t*) data_bytes, data_length, rng); + } catch (Botan::Exception & ex) { + throw_new(env, "java/security/GeneralSecurityException", ex.what()); + env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); + return NULL; + } env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); jbyteArray result = env->NewByteArray(sig.size()); @@ -596,7 +613,15 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna jbyte *data_bytes = env->GetByteArrayElements(data, NULL); jbyte *sig_bytes = env->GetByteArrayElements(signature, NULL); - bool result = verifier.verify_message((uint8_t*)data_bytes, data_length, (uint8_t*)sig_bytes, sig_length); + bool result; + try { + result = verifier.verify_message((uint8_t*)data_bytes, data_length, (uint8_t*)sig_bytes, sig_length); + } catch (Botan::Exception & ex) { + throw_new(env, "java/security/GeneralSecurityException", ex.what()); + env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); + env->ReleaseByteArrayElements(signature, sig_bytes, JNI_ABORT); + return JNI_FALSE; + } env->ReleaseByteArrayElements(data, data_bytes, JNI_ABORT); env->ReleaseByteArrayElements(signature, sig_bytes, JNI_ABORT); if (result) { diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c index 230f516..336f4a1 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c @@ -58,4 +58,9 @@ void init_classes(JNIEnv *env, const char* lib_name) { jclass local_illegal_state_exception_class = (*env)->FindClass(env, "java/lang/IllegalStateException"); illegal_state_exception_class = (*env)->NewGlobalRef(env, local_illegal_state_exception_class); -} \ No newline at end of file +} + +void throw_new(JNIEnv *env, const char *class, const char *message) { + jclass clazz = (*env)->FindClass(env, class); + (*env)->ThrowNew(env, clazz, message); +} diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h index edd0bda..d925dfe 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h +++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.h @@ -1,5 +1,10 @@ +#pragma once + #include "native.h" +/** + * Classes that are accessed alot are cached here, manually. + */ extern jclass ec_parameter_spec_class; extern jclass ecgen_parameter_spec_class; extern jclass pubkey_class; @@ -12,4 +17,12 @@ extern jclass point_class; extern jclass biginteger_class; extern jclass illegal_state_exception_class; -void init_classes(JNIEnv *env, const char* lib_name); \ No newline at end of file +/** + * Initialize the classes. + */ +void init_classes(JNIEnv *env, const char* lib_name); + +/** + * Throw a new exception of class with message. + */ +void throw_new(JNIEnv *env, const char *class, const char *message); \ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.cpp b/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.cpp index ed59d51..cef4bfe 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.cpp +++ b/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.cpp @@ -51,4 +51,9 @@ void init_classes(JNIEnv *env, std::string lib_name) { jclass local_illegal_state_exception_class = env->FindClass("java/lang/IllegalStateException"); illegal_state_exception_class = (jclass) env->NewGlobalRef(local_illegal_state_exception_class); +} + +void throw_new(JNIEnv *env, const std::string& klass, const std::string& message) { + jclass clazz = env->FindClass(klass.c_str()); + env->ThrowNew(clazz, message.c_str()); } \ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.hpp b/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.hpp index d0bf8f2..bbca521 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.hpp +++ b/src/cz/crcs/ectester/standalone/libs/jni/cpp_utils.hpp @@ -1,6 +1,11 @@ +#pragma once + #include "native.h" #include +/** + * Classes that are accessed alot are cached here, manually. + */ extern jclass ec_parameter_spec_class; extern jclass ecgen_parameter_spec_class; extern jclass pubkey_class; @@ -13,4 +18,12 @@ extern jclass point_class; extern jclass biginteger_class; extern jclass illegal_state_exception_class; -void init_classes(JNIEnv *env, std::string lib_name); \ No newline at end of file +/** + * Initialize the classes. + */ +void init_classes(JNIEnv *env, std::string lib_name); + +/** + * Throw a new exception of class with message. + */ +void throw_new(JNIEnv *env, const std::string& klass, const std::string& message); \ No newline at end of file diff --git a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c index 0fb69a3..29ee707 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c @@ -229,11 +229,6 @@ static ltc_ecc_set_type* create_curve(JNIEnv *env, jobject params) { return curve; } -static void throw_new(JNIEnv *env, const char *class, const char *message) { - jclass clazz = (*env)->FindClass(env, class); - (*env)->ThrowNew(env, clazz, message); -} - static jobject generate_from_curve(JNIEnv *env, const ltc_ecc_set_type *curve) { ecc_key key; int err; @@ -280,6 +275,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai } if (curve->size == 0) { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve for given bitsize not found."); return NULL; } @@ -307,6 +303,7 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai return generate_from_curve(env, curve); } else { + throw_new(env, "java/security/InvalidAlgorithmParameterException", "Curve not found."); return NULL; } } diff --git a/util/plot_dh.py b/util/plot_dh.py index 8c1dfff..2354688 100755 --- a/util/plot_dh.py +++ b/util/plot_dh.py @@ -20,6 +20,7 @@ from operator import itemgetter if __name__ == "__main__": parser = argparse.ArgumentParser(description="Plot ECTester ECDH timing.") parser.add_argument("-o", "--output", dest="output", type=argparse.FileType("wb"), help="Write image to [file], do not display.", metavar="file") + parser.add_argument("--skip-first", dest="skip_first", action="store_true", help="Skip first entry, as it's usually a large outlier.") parser.add_argument("file", type=str, help="The file to plot(csv).") opts = parser.parse_args() @@ -30,6 +31,8 @@ if __name__ == "__main__": hx = lambda x: int(x, 16) data = np.genfromtxt(opts.file, delimiter=";", skip_header=1, converters={2: hx, 3: hx, 4: hx}, dtype=np.dtype([("index","u4"), ("time","u4"), ("pub", "O"), ("priv", "O"), ("secret","O")])) + if opts.skip_first: + data = data[1:] if "nano" in header_names[1]: unit = r"$\mu s$" diff --git a/util/plot_gen.py b/util/plot_gen.py index 016dd15..12f7089 100755 --- a/util/plot_gen.py +++ b/util/plot_gen.py @@ -23,6 +23,7 @@ if __name__ == "__main__": parser.add_argument("--pub", dest="pub", action="store_true", help="Show public key scatter plot.") parser.add_argument("--priv", dest="priv", action="store_true", help="Show private key scatter plot.") parser.add_argument("--hist", dest="hist", action="store_true", help="Show histogram.") + parser.add_argument("--skip-first", dest="skip_first", action="store_true", help="Skip first entry, as it's usually a large outlier.") parser.add_argument("file", type=str, help="The file to plot(csv).") opts = parser.parse_args() @@ -39,6 +40,8 @@ if __name__ == "__main__": hx = lambda x: int(x, 16) data = np.genfromtxt(opts.file, delimiter=";", skip_header=1, converters={2: hx, 3: hx}, dtype=np.dtype([("index","u4"), ("time","u4"), ("pub", "O"), ("priv", "O")])) + if opts.skip_first: + data = data[1:] if "nano" in header_names[1]: unit = r"$\mu s$" -- cgit v1.2.3-70-g09d2