diff options
| author | J08nY | 2019-03-18 19:37:51 +0100 |
|---|---|---|
| committer | J08nY | 2019-03-18 19:37:51 +0100 |
| commit | 8dda00c46e73f2a44e7c387a6b4e86055ffecea2 (patch) | |
| tree | 679635c157298b8e429f0d91fe4a251effe51041 /util/plot_gen.ipynb | |
| parent | b99057bc15e72397f3951ddee28d4db481caad02 (diff) | |
| download | ECTester-8dda00c46e73f2a44e7c387a6b4e86055ffecea2.tar.gz ECTester-8dda00c46e73f2a44e7c387a6b4e86055ffecea2.tar.zst ECTester-8dda00c46e73f2a44e7c387a6b4e86055ffecea2.zip | |
Diffstat (limited to 'util/plot_gen.ipynb')
| -rw-r--r-- | util/plot_gen.ipynb | 155 |
1 files changed, 97 insertions, 58 deletions
diff --git a/util/plot_gen.ipynb b/util/plot_gen.ipynb index 5f02a00..db618cc 100644 --- a/util/plot_gen.ipynb +++ b/util/plot_gen.ipynb @@ -18,7 +18,7 @@ }, "outputs": [], "source": [ - " %matplotlib notebook \n", + "%matplotlib notebook\n", "import numpy as np\n", "from scipy.stats import describe\n", "from scipy.stats import norm as norm_dist\n", @@ -27,7 +27,7 @@ "import matplotlib.pyplot as plt\n", "from matplotlib import ticker, colors, gridspec\n", "from copy import deepcopy\n", - "from utils import plot_hist, moving_average, hw\n", + "from utils import plot_hist, moving_average, hw, time_scale\n", "from binascii import unhexlify\n", "from IPython.display import display, HTML\n", "from ipywidgets import interact, interactive, fixed, interact_manual\n", @@ -57,6 +57,15 @@ "# File name with output from ECTesterReader or ECTesterStandalone key generation.\n", "fname = \"filename.csv\"\n", "\n", + "# The time unit used in displaying the plots. One of \"milli\", \"micro\", \"nano\".\n", + "# WARNING: Using nano might lead to very large plots/histograms and to the\n", + "# notebook to freeze or run out of memory, as well as bad visualization\n", + "# quality, due to noise and low density.\n", + "gen_unit = \"milli\" # Unit of key generation command\n", + "export_unit = \"milli\" # Unit of key export command\n", + "# A number which will be used to divide the time into sub-units, e.g. for 5, time will be in fifths of units\n", + "scaling_factor = 1\n", + "\n", "# The amount of entries skipped from the beginning of the file, as they are usually outliers.\n", "skip_first = 10\n", "\n", @@ -111,20 +120,8 @@ "if log_scale:\n", " norm = colors.LogNorm()\n", "else:\n", - " norm = colors.Normalize()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2019-03-17T19:16:42.300146Z", - "start_time": "2019-03-17T19:16:40.259135Z" - } - }, - "outputs": [], - "source": [ + " norm = colors.Normalize()\n", + "\n", "# Read the header line.\n", "\n", "with open(fname, \"r\") as f:\n", @@ -144,37 +141,19 @@ " data = np.genfromtxt(fname, delimiter=\";\", skip_header=1, converters={3: unhexlify, 4: hx},\n", " dtype=np.dtype([(\"index\", \"u4\"), (\"gen_time\", \"u4\"), (\"export_time\", \"u4\"),\n", " (\"pub\", \"O\"), (\"priv\", \"O\")]))\n", - " \n", - "gen_unit = \"ms\"\n", - "export_unit = \"ms\"\n", - "# Setup the datatrimmed = False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2019-03-17T19:16:42.417415Z", - "start_time": "2019-03-17T19:16:42.302353Z" - } - }, - "outputs": [], - "source": [ - "# Setup the data\n", "\n", "# Skip first (outliers?)\n", "\n", "data = data[skip_first:]\n", "\n", - "# If in nanoseconds, scale to microseconds\n", - "if header_names[1].endswith(\"[nano]\") and gen_unit == \"ms\":\n", - " gen_unit = r\"$\\mu s$\"\n", - " np.floor_divide(data[\"gen_time\"], 1000, out=data[\"gen_time\"])\n", + "# Setup the data\n", "\n", - "if len(header_names) == 5 and header_names[2].endswith(\"[nano]\") and export_unit == \"ms\":\n", - " export_unit = r\"$\\mu s$\"\n", - " np.floor_divide(data[\"export_time\"], 1000, out=data[\"export_time\"])\n", + "# Convert time data\n", + "orig_gen_unit = header_names[1].split(\"[\")[1][:-1]\n", + "gen_disp_unit = time_scale(data[\"gen_time\"], orig_gen_unit, gen_unit, scaling_factor)\n", + "if len(header_names) == 5:\n", + " orig_export_unit = header_names[2].split(\"[\")[1][:-1]\n", + " export_disp_unit = time_scale(data[\"export_time\"], orig_export_unit, export_unit, scaling_factor)\n", "\n", "# Trim gen times\n", "quant_low_bound = trim_low if 0 <= trim_low <= 1 else 0.01\n", @@ -199,6 +178,7 @@ "min_gen_time = description_gen.minmax[0]\n", "bit_size = len(bin(max(data[\"priv\"]))) - 2\n", "byte_size = (bit_size + 7) // 8\n", + "bit_size = byte_size * 8\n", "\n", "if hist_size == \"sqrt\":\n", " hist_size_func = lambda n, xmin, xmax, var, xlower, xupper: int(sqrt(n)) + 1\n", @@ -276,7 +256,7 @@ "outputs": [], "source": [ "tbl = [(quant_low_bound, \"0.25\", \"0.5\", \"0.75\", quant_high_bound),\n", - " list(map(lambda x: \"{} {}\".format(x, gen_unit), quantiles_gen))]\n", + " list(map(lambda x: \"{} {}\".format(x, gen_disp_unit), quantiles_gen))]\n", "display(HTML(tabulate.tabulate(tbl, tablefmt=\"html\")))" ] }, @@ -312,7 +292,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Private key MSB vs time heatmap" + "### Private key MSB vs time heatmap\n", + "The heatmap should show uncorrelated variables." ] }, { @@ -337,7 +318,7 @@ "im = axe_private.imshow(heatmap.T, extent=extent, aspect=\"auto\", cmap=cmap, origin=\"low\",\n", " interpolation=\"nearest\", norm=norm)\n", "axe_private.set_xlabel(\"private key MSB value\")\n", - "axe_private.set_ylabel(\"keygen time ({})\".format(gen_unit))\n", + "axe_private.set_ylabel(\"keygen time ({})\".format(gen_disp_unit))\n", "fig_private.colorbar(im, ax=axe_private)\n", "\n", "del priv_msb" @@ -347,7 +328,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Private key Hamming Weight vs time heatmap" + "### Private key Hamming Weight vs time heatmap\n", + "The heatmap should show uncorrelated variables.\n", + "\n", + "Also contains a private key Hamming Weight histogram, which should be binomially distributed." ] }, { @@ -370,7 +354,7 @@ "im = axe_priv_hist.imshow(h.T, origin=\"low\", cmap=cmap, aspect=\"auto\", extent=[xe[0], xe[-1], ye[0], ye[-1]], norm=norm)\n", "axe_priv_hist.axvline(x=bit_size//2, alpha=0.7, linestyle=\"dotted\", color=\"white\", label=str(bit_size//2) + \" bits\")\n", "axe_priv_hist.set_xlabel(\"private key Hamming weight\")\n", - "axe_priv_hist.set_ylabel(\"keygen time ({})\".format(gen_unit))\n", + "axe_priv_hist.set_ylabel(\"keygen time ({})\".format(gen_disp_unit))\n", "axe_priv_hist.legend(loc=\"best\")\n", "\n", "plot_hist(axe_priv_hist_hw, priv_hw, \"private key Hamming weight\", log_scale, None)\n", @@ -409,8 +393,8 @@ "fig_kg_hist = plt.figure(figsize=(10.5, 8), dpi=90)\n", "axe_hist_full = fig_kg_hist.add_subplot(2, 1, 1)\n", "axe_hist_trim = fig_kg_hist.add_subplot(2, 1, 2)\n", - "plot_hist(axe_hist_full, data[\"gen_time\"], \"keygen time ({})\".format(gen_unit), log_scale, hist_size_gen_time);\n", - "plot_hist(axe_hist_trim, data_trimmed[\"gen_time\"], \"keygen time ({})\".format(gen_unit), log_scale, hist_size_gen_time_trim);" + "plot_hist(axe_hist_full, data[\"gen_time\"], \"keygen time ({})\".format(gen_disp_unit), log_scale, hist_size_gen_time);\n", + "plot_hist(axe_hist_trim, data_trimmed[\"gen_time\"], \"keygen time ({})\".format(gen_disp_unit), log_scale, hist_size_gen_time_trim);" ] }, { @@ -436,8 +420,8 @@ " fig_exp_hist = plt.figure(figsize=(10.5, 8), dpi=90)\n", " axe_hist_full = fig_exp_hist.add_subplot(2, 1, 1)\n", " axe_hist_trim = fig_exp_hist.add_subplot(2, 1, 2)\n", - " plot_hist(axe_hist_full, data[\"export_time\"], \"export time ({})\".format(export_unit), log_scale, hist_size_gen_time);\n", - " plot_hist(axe_hist_trim, data_trimmed[\"export_time\"], \"export time ({})\".format(export_unit), log_scale, hist_size_gen_time_trim);" + " plot_hist(axe_hist_full, data[\"export_time\"], \"export time ({})\".format(export_disp_unit), log_scale, hist_size_gen_time);\n", + " plot_hist(axe_hist_trim, data_trimmed[\"export_time\"], \"export time ({})\".format(export_disp_unit), log_scale, hist_size_gen_time_trim);" ] }, { @@ -468,7 +452,7 @@ " axe_avg.axhline(y=low_bound, alpha=0.7, linestyle=\"dotted\", color=\"green\", label=\"Low trim bound = {}\".format(low_bound))\n", "if high_bound is not None:\n", " axe_avg.axhline(y=high_bound, alpha=0.7, linestyle=\"dotted\", color=\"orange\", label=\"Hight trim bound = {}\".format(high_bound))\n", - "axe_avg.set_ylabel(\"keygen time ({})\".format(gen_unit))\n", + "axe_avg.set_ylabel(\"keygen time ({})\".format(gen_disp_unit))\n", "axe_avg.set_xlabel(\"index\")\n", "axe_avg.legend(loc=\"best\")\n", "del avg_100, avg_1000" @@ -478,7 +462,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Private key MSB and LSB histograms" + "### Private key MSB and LSB histograms\n", + "Expected to be uniform over [0, 255]." ] }, { @@ -506,7 +491,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Public key coordinate MSB and LSB histograms" + "### Public key coordinate MSB and LSB histograms\n", + "Expected to be somewhat uniform over [0, 255]." ] }, { @@ -549,7 +535,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Private key bit length vs time heatmap" + "### Private key bit length vs time heatmap\n", + "Also contains private key bit length histogram, which is expected to be axis flipped geometric distribution with $p = \\frac{1}{2}$ peaking at the bit size of the order of the curve." ] }, { @@ -573,7 +560,7 @@ "h, xe, ye = np.histogram2d(bl_data, data_trimmed[\"gen_time\"], bins=[max(bl_data) - min(bl_data), hist_size_gen_time_trim])\n", "im = axe_bl_heat.imshow(h.T, origin=\"low\", cmap=cmap, aspect=\"auto\", extent=[xe[0], xe[-1], ye[0], ye[-1]], norm=norm)\n", "axe_bl_heat.set_xlabel(\"private key bit length\")\n", - "axe_bl_heat.set_ylabel(\"keygen time ({})\".format(gen_unit))\n", + "axe_bl_heat.set_ylabel(\"keygen time ({})\".format(gen_disp_unit))\n", "\n", "plot_hist(axe_bl_hist, bl_data, \"Private key bit length\", log_scale, align=\"right\")\n", "fig_priv_hist.colorbar(im, ax=[axe_bl_heat, axe_bl_hist])\n", @@ -582,17 +569,69 @@ ] }, { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Validation\n", + "Perform some tests on the produced data and compare to expected results.\n", + "\n", + "This requires some information about the used curve, enter it below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-03-18T18:27:02.748493Z", + "start_time": "2019-03-18T18:27:01.294850Z" + } + }, + "outputs": [], + "source": [ + "p_str = input(\"The prime specifying the finite field:\")\n", + "p = int(p_str, 16) if p_str.startswith(\"0x\") else int(p_str)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2019-03-18T18:27:09.351619Z", + "start_time": "2019-03-18T18:27:08.674272Z" + } + }, + "outputs": [], + "source": [ + "r_str = input(\"The order of the curve:\")\n", + "r = int(r_str, 16) if r_str.startswith(\"0x\") else int(r_str)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All of the following tests should pass (e.g. be true):" + ] + }, + { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "max_priv = max(data[\"priv\"])\n", + "display(max_priv < r)\n", + "display(r <= p or max_priv > p)\n", + "display(max_priv.bit_length() == r.bit_length())" + ] } ], "metadata": { "@webio": { - "lastCommId": "eaf134b2342a4b71afa1ac9334e37e07", - "lastKernelId": "95d0d16c-1dde-451e-94cb-8bd0fefb8378" + "lastCommId": "a0b5176ec9b441fc87297b9ed343c5b3", + "lastKernelId": "a6864201-5c88-44d7-8438-ea96f7295d78" }, "hide_input": false, "kernelspec": { |
