From 832bb8ddbe0d5b19813fa48491b1c9f21c146098 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 1 Dec 2018 21:21:44 +0100 Subject: Add entropy estimation to plot_gen. --- util/plot_gen.py | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'util/plot_gen.py') diff --git a/util/plot_gen.py b/util/plot_gen.py index 0d518e6..b562404 100755 --- a/util/plot_gen.py +++ b/util/plot_gen.py @@ -18,12 +18,13 @@ from matplotlib import ticker, colors from copy import deepcopy import argparse -from utils import hw, moving_average, plot_hist +from utils import hw, moving_average, plot_hist, jackknife_entropy, miller_correction 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("--priv", dest="priv", action="store_true", help="Show private key MSB heatmap plot.") + parser.add_argument("--entropy", dest="entropy", action="store_true", help="Show estimated entropy of private key MSB conditioned on time of generation.") parser.add_argument("--hist", dest="hist", action="store_true", help="Show keygen time histogram.") parser.add_argument("--export-hist", dest="export_hist", action="store_true", help="Show export time histogram.") parser.add_argument("--avg", dest="avg", action="store_true", help="Show moving average of keygen time.") @@ -103,21 +104,6 @@ if __name__ == "__main__": sorted_data = np.sort(data, order="gen_time") - i = 0 - entropies = {} - while i < len(data): - time_val = sorted_data["gen_time"][i] - j = i - msbs = [0 for _ in range(256)] - while j < len(data) and sorted_data["gen_time"][j] == time_val: - msbs[(sorted_data["priv"][j] >> (bit_size - 8)) & 0xff] += 1 - j += 1 - if j - 100 > i: - entropies[time_val] = entropy(msbs, base=2) - i = j - - entropy = sum(entropies.values())/len(entropies) - cmap = deepcopy(plt.cm.plasma) cmap.set_bad("black") @@ -174,7 +160,23 @@ if __name__ == "__main__": fig.colorbar(im, ax=axe_priv_hist) fig.text(0.01, 0.02, "Data size: {}".format(len(gen_time_data)), size="small") - fig.text(0.01, 0.04, "Entropy of privkey MSB(estimated): {:.2f} b".format(entropy), size="small") + + if opts.entropy: + i = 0 + entropies = {} + while i < len(data): + time_val = sorted_data["gen_time"][i] + j = i + msbs = [0 for _ in range(256)] + while j < len(data) and sorted_data["gen_time"][j] == time_val: + msbs[(sorted_data["priv"][j] >> (bit_size - 8)) & 0xff] += 1 + j += 1 + if j - 100 > i: + entropies[time_val] = miller_correction(entropy(msbs, base=2), j - i, 256) + i = j + + entropy = sum(entropies.values())/len(entropies) + fig.text(0.01, 0.04, "Entropy of privkey MSB(estimated): {:.2f} b".format(entropy), size="small") if opts.output is None: plt.show() -- cgit v1.2.3-70-g09d2 From 9577bff6eca3b713c9c29b2f0cff2f13368df527 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 17 Dec 2018 10:53:59 +0100 Subject: Allow fixed key in ECDH. --- src/cz/crcs/ectester/reader/ECTesterReader.java | 68 +++++++++++++++++-------- util/plot_gen.py | 2 +- 2 files changed, 47 insertions(+), 23 deletions(-) (limited to 'util/plot_gen.py') diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 9f0d8cc..382f2e1 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -332,7 +332,9 @@ public class ECTesterReader { opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build()); opts.addOption(Option.builder().longOpt("format").desc("Output format to use. One of: text,yml,xml.").hasArg().argName("format").build()); - opts.addOption(Option.builder().longOpt("static").desc("Generate key(s) only once, keep them for later operations.").build()); + opts.addOption(Option.builder().longOpt("fixed").desc("Generate key(s) only once, keep them for later operations.").build()); + opts.addOption(Option.builder().longOpt("fixed-private").desc("Generate private key only once, keep it for later ECDH.").build()); + opts.addOption(Option.builder().longOpt("fixed-public").desc("Generate public key only once, keep it for later ECDH.").build()); opts.addOption(Option.builder("f").longOpt("fresh").desc("Generate fresh keys (set domain parameters before every generation).").build()); opts.addOption(Option.builder().longOpt("cleanup").desc("Send the cleanup command trigerring JCSystem.requestObjectDeletion() after some operations.").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); @@ -574,35 +576,53 @@ public class ECTesterReader { respWriter.outputResponse(r); } - byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; - byte privkey = (cfg.anyPrivateKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; - - List generate = new LinkedList<>(); - generate.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); - if (cfg.anyPublicKey || cfg.anyPrivateKey || cfg.anyKey) { - generate.add(Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_REMOTE)); - } - OutputStreamWriter out = null; if (cfg.outputs != null) { out = FileUtil.openFiles(cfg.outputs); - out.write("index;time;pubW;privS;secret\n"); + out.write("index;time[milli];pubW;privS;secret\n"); + } + + Response gen = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH).send(); + respWriter.outputResponse(gen); + if (cfg.anyPublicKey || cfg.anyKey) { + Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_REMOTE).send(); + respWriter.outputResponse(prep); + } + if (cfg.anyPrivateKey || cfg.anyKey) { + Response prep = Command.prepareKey(cardManager, EC_Store.getInstance(), cfg, ECTesterApplet.KEYPAIR_LOCAL).send(); + respWriter.outputResponse(prep); + } + + byte kp = ECTesterApplet.KEYPAIR_BOTH; + if (cfg.fixedPrivate || cfg.anyPrivateKey) { + kp ^= ECTesterApplet.KEYPAIR_LOCAL; + } + if (cfg.fixedPublic || cfg.anyPublicKey) { + kp ^= ECTesterApplet.KEYPAIR_REMOTE; + } + if (cfg.fixedKey || cfg.anyKey) { + kp = 0; + } + + Command generate = null; + if (kp != 0) { + generate = new Command.Generate(cardManager, kp); } int retry = 0; int done = 0; while (done < cfg.ECKACount) { - List ecdh = Command.sendAll(generate); - for (Response r : ecdh) { - respWriter.outputResponse(r); + if (generate != null) { + Response regen = generate.send(); + respWriter.outputResponse(regen); } Response.Export export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.KEY_BOTH, EC_Consts.PARAMETERS_KEYPAIR).send(); respWriter.outputResponse(export); - byte[] pubkey_bytes = export.getParameter(pubkey, EC_Consts.PARAMETER_W); - byte[] privkey_bytes = export.getParameter(privkey, EC_Consts.PARAMETER_S); + byte[] pubkey_bytes = export.getParameter(ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.PARAMETER_W); + byte[] privkey_bytes = export.getParameter(ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.PARAMETER_S); - Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType).send(); + Response.ECDH perform = new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.TRANSFORMATION_NONE, cfg.ECKAType).send(); respWriter.outputResponse(perform); if (!perform.successful() || !perform.hasSecret()) { @@ -674,12 +694,12 @@ public class ECTesterReader { OutputStreamWriter out = FileUtil.openFiles(cfg.outputs); if (out != null) { - out.write("index;signTime;verifyTime;data;pubW;privS;signature;nonce;valid\n"); + out.write("index;signTime[milli];verifyTime[milli];data;pubW;privS;signature;nonce;valid\n"); } Command.Export export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_BOTH, EC_Consts.PARAMETERS_KEYPAIR); Response.Export exported = null; - if (cfg.staticKey) { + if (cfg.fixedKey) { respWriter.outputResponse(generate.send()); exported = export.send(); respWriter.outputResponse(exported); @@ -688,7 +708,7 @@ public class ECTesterReader { int retry = 0; int done = 0; while (done < cfg.ECDSACount) { - if (!cfg.staticKey) { + if (!cfg.fixedKey) { respWriter.outputResponse(generate.send()); exported = export.send(); respWriter.outputResponse(exported); @@ -777,7 +797,9 @@ public class ECTesterReader { public String key; public boolean anyKeypart = false; - public boolean staticKey = false; + public boolean fixedKey = false; + public boolean fixedPrivate = false; + public boolean fixedPublic = false; public String log; @@ -831,7 +853,9 @@ public class ECTesterReader { key = cli.getOptionValue("key"); anyKey = (key != null) || (namedKey != null); anyKeypart = anyKey || anyPublicKey || anyPrivateKey; - staticKey = cli.hasOption("static"); + fixedKey = cli.hasOption("fixed"); + fixedPrivate = cli.hasOption("fixed-private"); + fixedPublic = cli.hasOption("fixed-public"); if (cli.hasOption("log")) { log = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000)); diff --git a/util/plot_gen.py b/util/plot_gen.py index b562404..4ee1ddc 100755 --- a/util/plot_gen.py +++ b/util/plot_gen.py @@ -18,7 +18,7 @@ from matplotlib import ticker, colors from copy import deepcopy import argparse -from utils import hw, moving_average, plot_hist, jackknife_entropy, miller_correction +from utils import hw, moving_average, plot_hist, miller_correction if __name__ == "__main__": parser = argparse.ArgumentParser(description="Plot results of ECTester key generation timing.") -- cgit v1.2.3-70-g09d2